Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_Synapse.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_Synapse.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
33 //
34 // Creation Date : 02/28/00
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.43 $
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 
49 // ---------- Standard Includes ----------
50 
51 // ---------- Xyce Includes ----------
52 //
53 #include <N_DEV_Const.h>
54 #include <N_DEV_DeviceOptions.h>
55 #include <N_DEV_DeviceMaster.h>
56 #include <N_DEV_ExternData.h>
57 #include <N_DEV_MatrixLoadData.h>
58 #include <N_DEV_SolverState.h>
59 #include <N_DEV_Synapse.h>
60 #include <N_DEV_Message.h>
61 #include <N_ERH_ErrorMgr.h>
62 
63 #include <N_LAS_Matrix.h>
64 #include <N_LAS_Vector.h>
65 
66 namespace Xyce {
67 namespace Device {
68 
69 namespace Synapse {
70 
71 
73 {
74  // Set up configuration constants:
75 }
76 
78 {
79  // Default values are taken from Destexhe 98, values for AMPA receptor
80  p.addPar ("GMAX", 1.0E-9, &Synapse::Model::gMax)
81  .setUnit(U_OHMM1)
82  .setDescription("Maximal Synaptic Conductance");
83 
84  p.addPar ("EREV", 0.0, &Synapse::Model::eRev)
85  .setUnit(U_VOLT)
86  .setDescription("Reversal Potential");
87 
88  p.addPar ("ALPHA", 1.1E-6, &Synapse::Model::alpha)
89  .setUnit(U_SECM1)
90  .setDescription("Forward rate constant for receptor opening");
91 
92  p.addPar ("BETA", 190.0, &Synapse::Model::beta)
93  .setUnit(U_SECM1)
94  .setDescription("Backward rate constant for receptor opening");
95 
96  p.addPar ("VP", 0.002, &Synapse::Model::vP)
97  .setUnit(U_VOLT)
98  .setDescription("Presynaptic voltage at which neurotransmitter concentration is half-maximal");
99 
100  // KP should NOT be 0
101  p.addPar ("KP", 0.005, &Synapse::Model::kP)
102  .setUnit(U_VOLT)
103  .setDescription("Steepness parameter for neurotransmitter concentration");
104 
105  p.addPar ("TMAX", 0.001, &Synapse::Model::tMax)
106  .setDescription("Maximal neurotransmitter concentration");
107 
108  // NOTE: not including concentration units - TMAX should be in moles/liter, and
109  // alpha has concentration in the denominator; they cancel out
110 }
111 
112 
113 
114 std::vector< std::vector<int> > Instance::jacStamp;
115 
116 // Class Instance
117 //-----------------------------------------------------------------------------
118 // Function : Instance::processParams
119 // Purpose :
120 // Special Notes :
121 // Scope : public
122 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
123 // Creation Date : 6/03/02
124 //-----------------------------------------------------------------------------
126 {
127  // now set the temperature related stuff.
128  //updateTemperature(temp);
129 
130  return true;
131 }
132 
133 //-----------------------------------------------------------------------------
134 // Function : Instance::Instance
135 // Purpose : instance block constructor
136 // Special Notes :
137 // Scope : public
138 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
139 // Creation Date : 3/16/00
140 //-----------------------------------------------------------------------------
142  const Configuration & configuration,
143  const InstanceBlock & IB,
144  Model & Riter,
145  const FactoryBlock & factory_block)
146 
147  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
148  model_(Riter),
149  li_Prev(-1),
150  li_Post(-1),
151  APostEquPostNodeOffset(-1),
152  APostEquRNodeOffset(-1),
153  AREquPostNodeOffset(-1),
154  AREquRNodeOffset(-1),
155  f_PostEquPostNodePtr(0),
156  f_PostEquRNodePtr(0),
157  f_REquPostNodePtr(0),
158  f_REquRNodePtr(0)
159 {
160  numIntVars = 1;
161  numExtVars = 2;
162  numStateVars = 0;
163 
164  if( jacStamp.empty() )
165  {
166  // Vpre, Vpost, r
167  jacStamp.resize(3);
168  jacStamp[0].resize(0);
169  jacStamp[1].resize(2);
170  jacStamp[2].resize(2);
171  jacStamp[1][0] = 1; // Vpost PostPostVar
172  jacStamp[1][1] = 2; // r PostRVar
173  jacStamp[2][0] = 0; // Vpre RVpre
174  jacStamp[2][1] = 2; // r RR
175  }
176 
177 
178  // Set params to constant default values:
179  setDefaultParams ();
180 
181  // Set params according to instance line and constant defaults from metadata:
182  setParams (IB.params);
183 
184  // Set any non-constant parameter defaults:
185 
186  // Calculate any parameters specified as expressions:
188 
189  // calculate dependent (ie computed) params and check for errors:
190  processParams ();
191 }
192 
193 //-----------------------------------------------------------------------------
194 // Function : Instance::~Instance
195 // Purpose : destructor
196 // Special Notes :
197 // Scope : public
198 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
199 // Creation Date : 3/16/00
200 //-----------------------------------------------------------------------------
202 {
203 }
204 
205 //-----------------------------------------------------------------------------
206 // Function : Instance::registerLIDs
207 // Purpose :
208 // Special Notes :
209 // Scope : public
210 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
211 // Creation Date : 6/12/02
212 //-----------------------------------------------------------------------------
213 void Instance::registerLIDs( const std::vector<int> & intLIDVecRef,
214  const std::vector<int> & extLIDVecRef )
215 {
216  AssertLIDs(intLIDVecRef.size() == numIntVars);
217  AssertLIDs(extLIDVecRef.size() == numExtVars);
218 
219 #ifdef Xyce_DEBUG_DEVICE
220  if (getDeviceOptions().debugLevel > 0)
221  {
222  Xyce::dout() << std::endl << section_divider << std::endl;
223  Xyce::dout() << " SynapseInstance::registerLIDs" << std::endl;
224  Xyce::dout() << " name = " << getName() << std::endl;
225  }
226 #endif
227 
228  // copy over the global ID lists.
229  intLIDVec = intLIDVecRef;
230  extLIDVec = extLIDVecRef;
231 
232  li_Prev = extLIDVec[0];
233  li_Post = extLIDVec[1];
234 
235 #ifdef Xyce_DEBUG_DEVICE
236  if (getDeviceOptions().debugLevel > 0 )
237  {
238  Xyce::dout() << " li_Prev = " << li_Prev << std::endl;
239  Xyce::dout() << " li_Post = " << li_Post << std::endl;
240  }
241 #endif
242 
243  li_rVar = intLIDVec[0];
244 
245 #ifdef Xyce_DEBUG_DEVICE
246  if (getDeviceOptions().debugLevel > 0 )
247  {
248  Xyce::dout() << section_divider << std::endl;
249  }
250 #endif
251 }
252 
253 //-----------------------------------------------------------------------------
254 // Function : Instance::getIntNameMap
255 // Purpose :
256 // Special Notes :
257 // Scope : public
258 // Creator : Christina Warrender, SNL, Cognitive Modeling
259 // Creation Date : 10/17/11
260 //-----------------------------------------------------------------------------
261 std::map<int,std::string> & Instance::getIntNameMap ()
262 {
263  // set up the internal name map, if it hasn't been already.
264  if (intNameMap.empty ())
265  {
267  }
268  return intNameMap;
269 }
270 
271 
272 
273 //-----------------------------------------------------------------------------
274 // Function : Instance::registerStateLIDs
275 // Purpose : Note that the Synapse does not have any state vars.
276 // Special Notes :
277 // Scope : public
278 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
279 // Creation Date : 06/12/02
280 //-----------------------------------------------------------------------------
281 void Instance::registerStateLIDs(const std::vector<int> & staLIDVecRef )
282 {
283  AssertLIDs(staLIDVecRef.size() == numStateVars);
284 }
285 
286 //-----------------------------------------------------------------------------
287 // Function : Instance::jacobianStamp
288 // Purpose :
289 // Special Notes :
290 // Scope : public
291 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
292 // Creation Date : 08/20/01
293 //-----------------------------------------------------------------------------
294 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
295 {
296  return jacStamp;
297 }
298 
299 //-----------------------------------------------------------------------------
300 // Function : Instance::registerJacLIDs
301 // Purpose :
302 // Special Notes :
303 // Scope : public
304 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
305 // Creation Date : 08/27/01
306 //-----------------------------------------------------------------------------
307 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
308 {
309  DeviceInstance::registerJacLIDs( jacLIDVec );
310 
311  APostEquPostNodeOffset = jacLIDVec[1][0];
312  APostEquRNodeOffset = jacLIDVec[1][1];
313  AREquPostNodeOffset = jacLIDVec[2][0];
314  AREquRNodeOffset = jacLIDVec[2][1];
315 }
316 
317 //-----------------------------------------------------------------------------
318 // Function : Instance::setupPointers
319 // Purpose :
320 // Special Notes :
321 // Scope : public
322 // Creator : Eric Keiter, SNL
323 // Creation Date : 11/30/08
324 //-----------------------------------------------------------------------------
326 {
327 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
328  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
333 #endif
334 }
335 
336 //-----------------------------------------------------------------------------
337 // Function : Instance::updateIntermediateVars
338 // Purpose : update intermediate variables for one diode instance
339 // Special Notes :
340 // Scope : public
341 // Creator : Eric R. Keiter, Dept. 9233.
342 // Creation Date : 3/05/04
343 //-----------------------------------------------------------------------------
345 {
346  bool bsuccess = true;
347 
348  N_LAS_Vector * solVecPtr = extData.nextSolVectorPtr;
349 
350  double vPre = (*solVecPtr)[li_Prev];
351  double vPost = (*solVecPtr)[li_Post];
352  double rVar = (*solVecPtr)[li_rVar];
353 
354  // Load RHS vector element for the positive circuit node KCL equ.
355  {
356  Sacado::Fad::SFad<double,2> vPostVar( 2, 0, vPost );
357  Sacado::Fad::SFad<double,2> rVarS( 2, 1, rVar);
358 
359  // parameters
360  Sacado::Fad::SFad<double,2> gMaxVar( model_.gMax );
361  Sacado::Fad::SFad<double,2> eRevVar( model_.eRev );
362 
363  Sacado::Fad::SFad<double,2> resultFad;
364  resultFad = PostCurrentEqu( vPostVar, rVarS, gMaxVar, eRevVar );
365  ipost = resultFad.val();
366  didVpost = resultFad.dx(0);
367  didr = resultFad.dx(1);
368  }
369  {
370  Sacado::Fad::SFad<double,2> vPreVar( 2, 0, vPre );
371  Sacado::Fad::SFad<double,2> rVarS( 2, 1, rVar);
372 
373  // parameters
374  Sacado::Fad::SFad<double,2> alphaVar( model_.alpha );
375  Sacado::Fad::SFad<double,2> betaVar( model_.beta );
376  Sacado::Fad::SFad<double,2> tMaxVar( model_.tMax );
377  Sacado::Fad::SFad<double,2> vPVar( model_.vP );
378  Sacado::Fad::SFad<double,2> kPVar( model_.kP );
379 
380  Sacado::Fad::SFad<double,2> resultFad;
381  resultFad = rEquF( vPreVar, rVarS, alphaVar, betaVar, tMaxVar, vPVar, kPVar);
382  rFval = resultFad.val();
383  drFdVpre = resultFad.dx(0);
384  drFdr = resultFad.dx(1);
385  }
386  return bsuccess;
387 }
388 
389 //-----------------------------------------------------------------------------
390 // Function : Instance::updatePrimaryState
391 // Purpose :
392 // Special Notes :
393 // Scope : public
394 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
395 // Creation Date : 01/29/01
396 //-----------------------------------------------------------------------------
398 {
399  bool bsuccess = updateIntermediateVars();
400  return bsuccess;
401 }
402 
403 //-----------------------------------------------------------------------------
404 // Function : Instance::updateSecondaryState
405 // Purpose :
406 // Special Notes :
407 // Scope : public
408 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
409 // Creation Date : 01/29/01
410 //-----------------------------------------------------------------------------
412 {
413  return true;
414 }
415 
416 //-----------------------------------------------------------------------------
417 // Function : Instance::loadDAEQVector
418 //
419 // Purpose : Loads the Q-vector contributions for a single
420 // synapse
421 //
422 // Special Notes : The "Q" vector is part of a standard DAE formalism in
423 // which the system of equations is represented as:
424 //
425 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
426 //
427 // Scope : public
428 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
429 // Creation Date : 8/31/2010
430 //-----------------------------------------------------------------------------
432 {
433  N_LAS_Vector * qVecPtr = extData.daeQVectorPtr;
434  N_LAS_Vector * solVecPtr = extData.nextSolVectorPtr;
435  double rVar = (*solVecPtr)[li_rVar];
436  (*qVecPtr)[li_rVar] -= rVar;
437 
438  return true;
439 }
440 //-----------------------------------------------------------------------------
441 // Function : Instance::loadDAEFVector
442 //
443 // Purpose : Loads the F-vector contributions for a single
444 // Synapse instance.
445 // Special Notes :
446 // Scope : public
447 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
448 // Creation Date : 01/24/03
449 //-----------------------------------------------------------------------------
451 {
452  N_LAS_Vector * fVecPtr = extData.daeFVectorPtr;
453  (*fVecPtr)[li_Prev] += 0.0;
454  (*fVecPtr)[li_Post] += ipost;
455  (*fVecPtr)[li_rVar] += rFval;
456  return true;
457 }
458 
459 //-----------------------------------------------------------------------------
460 // Function : Instance::loadDAEdQdx
461 //
462 // Purpose : Loads the dQdx-matrix contributions for a single
463 // synapse instance.
464 //
465 // Special Notes : The "Q" vector is part of a standard DAE formalism in
466 // which the system of equations is represented as:
467 //
468 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
469 //
470 // Scope : public
471 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
472 // Creation Date : 03/05/04
473 //-----------------------------------------------------------------------------
475 {
476  N_LAS_Matrix & dQdx = *(extData.dQdxMatrixPtr);
477  dQdx[li_rVar][AREquRNodeOffset] += -1.0;
478 
479  return true;
480 }
481 
482 //-----------------------------------------------------------------------------
483 // Function : Instance::loadDAEdFdx ()
484 // Purpose : Loads the F-vector contributions for a single
485 // Synapse instance.
486 // Special Notes :
487 // Scope : public
488 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
489 // Creation Date : 03/05/04
490 //-----------------------------------------------------------------------------
492 {
493  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
495  dFdx[li_Post][APostEquRNodeOffset] += didr;
497  dFdx[li_rVar][AREquRNodeOffset] += drFdr;
498 
499  return true;
500 }
501 
502 //-----------------------------------------------------------------------------
503 // Function : Instance::updateTemperature
504 // Purpose :
505 // Special Notes :
506 // Scope : public
507 // Creator : Tom Russo, Component Information and Models
508 // Creation Date : 02/27/01
509 //-----------------------------------------------------------------------------
510 bool Instance::updateTemperature ( const double & temp_tmp)
511 {
512  bool bsuccess = true;
513  return bsuccess;
514 }
515 
516 //-----------------------------------------------------------------------------
517 // Function : Model::processParams
518 // Purpose :
519 // Special Notes :
520 // Scope : public
521 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
522 // Creation Date : 6/03/02
523 //-----------------------------------------------------------------------------
525 {
526  if (kP == 0.0)
527  kP = 0.001;
528 
529  return true;
530 }
531 
532 //----------------------------------------------------------------------------
533 // Function : Model::processInstanceParams
534 // Purpose :
535 // Special Notes :
536 // Scope : public
537 // Creator : Dave Shirely, PSSI
538 // Creation Date : 03/23/06
539 //----------------------------------------------------------------------------
541 {
542 
543  std::vector<Instance*>::iterator iter;
544  std::vector<Instance*>::iterator first = instanceContainer.begin();
545  std::vector<Instance*>::iterator last = instanceContainer.end();
546 
547  for (iter=first; iter!=last; ++iter)
548  {
549  (*iter)->processParams();
550  }
551 
552  return true;
553 }
554 
555 //-----------------------------------------------------------------------------
556 // Function : Model::Model
557 // Purpose : model block constructor
558 // Special Notes :
559 // Scope : public
560 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
561 // Creation Date : 5/16/00
562 //-----------------------------------------------------------------------------
564  const Configuration & configuration,
565  const ModelBlock & MB,
566  const FactoryBlock & factory_block)
567  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
568  gMax(0.0),
569  eRev(0.0),
570  alpha(0.0),
571  beta(0.0),
572  vP(0.0),
573  kP(0.0),
574  tMax(0.0)
575 {
576 
577  // Set params to constant default values:
578  setDefaultParams ();
579 
580  // Set params according to .model line and constant defaults from metadata:
581  setModParams (MB.params);
582 
583  // Set any non-constant parameter defaults:
584 
585  // Calculate any parameters specified as expressions:
587 
588  // calculate dependent (ie computed) params and check for errors:
589  processParams();
590 }
591 
592 //-----------------------------------------------------------------------------
593 // Function : Model::~Model
594 // Purpose : destructor
595 // Special Notes :
596 // Scope : public
597 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
598 // Creation Date : 3/16/00
599 //-----------------------------------------------------------------------------
601 {
602  std::vector<Instance*>::iterator iter;
603  std::vector<Instance*>::iterator first = instanceContainer.begin();
604  std::vector<Instance*>::iterator last = instanceContainer.end();
605 
606  for (iter=first; iter!=last; ++iter)
607  {
608  delete (*iter);
609  }
610 }
611 
612 //-----------------------------------------------------------------------------
613 // Function : Model::printOutInstances
614 // Purpose : debugging tool.
615 // Special Notes :
616 // Scope : public
617 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
618 // Creation Date : 4/03/00
619 //-----------------------------------------------------------------------------
620 std::ostream &Model::printOutInstances(std::ostream &os) const
621 {
622  std::vector<Instance*>::const_iterator iter;
623  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
624  std::vector<Instance*>::const_iterator last = instanceContainer.end();
625 
626  int i,isize;
627  isize = instanceContainer.size();
628  os << std::endl;
629  os << "Number of Synapse Instances: " << isize << std::endl;
630  os << " name model name Parameters" << std::endl;
631  for (i=0, iter=first; iter!=last; ++iter, ++i)
632  {
633  os << " " << i << ": " << (*iter)->getName() << "\t";
634  os << getName();
635  os << std::endl;
636  }
637 
638  os << std::endl;
639  return os;
640 }
641 
642 //-----------------------------------------------------------------------------
643 // Function : Model::forEachInstance
644 // Purpose :
645 // Special Notes :
646 // Scope : public
647 // Creator : David Baur
648 // Creation Date : 2/4/2014
649 //-----------------------------------------------------------------------------
650 /// Apply a device instance "op" to all instances associated with this
651 /// model
652 ///
653 /// @param[in] op Operator to apply to all instances.
654 ///
655 ///
656 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
657 {
658  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
659  op(*it);
660 }
661 
662 
663 // Synapse Master functions:
664 
665 //-----------------------------------------------------------------------------
666 // Function : Master::updateState
667 // Purpose :
668 // Special Notes :
669 // Scope : public
670 // Creator : Eric Keiter, SNL
671 // Creation Date : 11/26/08
672 //-----------------------------------------------------------------------------
673 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
674 {
675  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
676  {
677  (*it)->updateIntermediateVars();
678  }
679 
680  return true;
681 }
682 
683 //-----------------------------------------------------------------------------
684 // Function : Master::updateSecondaryState
685 // Purpose :
686 // Special Notes :
687 // Scope : public
688 // Creator : Eric Keiter, SNL
689 // Creation Date : 11/26/08
690 //-----------------------------------------------------------------------------
691 bool Master::updateSecondaryState ( double * staDerivVec, double * stoVec )
692 {
693  return true;
694 }
695 
696 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
697 {
698 
699  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
700 }
701 
703 {
705  .registerDevice("synapse", 1)
706  .registerModelType("synapse", 1);
707 }
708 
709 } // namespace Synapse
710 } // namespace Device
711 } // namespace Xyce