Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_NeuronPop1.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-2014 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_NeuronPop1.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.41.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 
49 // ---------- Standard Includes ----------
50 // for random() function
51 #include <stdlib.h>
52 
53 #include <N_UTL_Misc.h>
54 
55 // ---------- Xyce Includes ----------
56 #include <N_DEV_DeviceOptions.h>
57 #include <N_DEV_DeviceMaster.h>
58 #include <N_DEV_ExternData.h>
59 #include <N_DEV_MatrixLoadData.h>
60 #include <N_DEV_MembraneCS.h>
61 #include <N_DEV_MembraneHH.h>
62 #include <N_DEV_MembranePassive.h>
64 #include <N_DEV_NeuronPop1.h>
66 #include <N_DEV_SolverState.h>
67 #include <N_DEV_Message.h>
68 #include <N_ERH_ErrorMgr.h>
69 
70 #include <N_LAS_Vector.h>
71 #include <N_LAS_Matrix.h>
72 #include <N_UTL_BreakPoint.h>
73 
74 namespace Xyce {
75 namespace Device {
76 
77 
78 namespace NeuronPop1 {
79 
80 
82 {
83 // Set up map so parser knows how to set instance values
84  p.addPar ("CTP", std::vector<std::string>(), false, ParameterType::NO_DEP,
87  U_NONE, CAT_NONE, "Connected Target Population list");
88 }
89 
91 {
92  p.addPar ("NEURONS_MAX", 10, &NeuronPop1::Model::neuronsMax)
93  .setGivenMember(&NeuronPop1::Model::neuronsMaxGiven)
94  .setDescription("Maximum number of neurons in the device");
97  .setDescription("Maximum number of internal connections in the device");
100  .setDescription("Maximum number of external connections in the device");
101  p.addPar ("NEUROGENESIS_RATE", 0.0, &NeuronPop1::Model::populationNeurogenesisRate)
103  .setUnit(U_SECOND)
104  .setDescription("Rate in days of GC neurogenesis in the population");
105  p.addPar ("UPDATE_PERIOD", 1.0, &NeuronPop1::Model::populationUpdatePeriod)
107  .setUnit(U_SECOND)
108  .setDescription("Time in days for population updates");
109  p.addPar ("OUTPUTPOPULATIONVARS", 0, &NeuronPop1::Model::outputPopulationVars)
110  .setDescription("Flag to save population variables" );
111 }
112 
113 
114 
115 //
116 // static class member inits
117 //
118 
119 //-----------------------------------------------------------------------------
120 // Function : Instance::Instance
121 // Purpose : constructor
122 // Special Notes :
123 // Scope : public
124 // Creator : Richard Schiek, Electrical and Microsytem Modeling
125 // Creation Date : 06/10/09
126 //-----------------------------------------------------------------------------
128  const Configuration & configuration,
129  const InstanceBlock & IB,
130  Model & Miter,
131  const FactoryBlock & factory_block)
132  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
133  model_(Miter),
134  liNodeIn(-1),
135  liNodeOut(-1),
136  jsOffsetNodeIn(-1),
137  jsOffsetNodeOut(-1),
138  populationInitialized(false),
139  neuronPopSize(0),
140  connectionTargetPopulationGiven(false),
141  numberOfUpdatesDone(0),
142  lastPopulationUpdateTime(0.0),
143  lastNeurogenesisUpdateTime(0.0),
144  outputPopulationVarsFlag(false),
145  newStateToOutput(false)
146 {
147  // Set up the number of internal, external and state vars
148  numExtVars = 2; // input and output voltage
149  // numIntVars number of internal vars
150  // currently we have 3 variables per neuron, Voltage, X-position, Y-Position plus internal and external connections (maximum)
151  // These will all be in the state vector as: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn
152  // We do this rather than have individual containers because it will be easier to push the
153  // state vector around for working with these in parallel.
154 
155  // number of vars per neuron: 3
157 
158  // there is a lot of setup to do, but we don't want to do in the constructor.
159  // so it will be put off until the updateIntermediateVars, or moved into its own function
160 
161  // locate any external target populations passed in on the instance line
162  /*
163  if( connectionTargetPopulation.size() > 0 )
164  {
165  Xyce::dout() << name << " connectionTargetPopulation = { ";
166  for(int i=0; i<connectionTargetPopulation.size(); i++ )
167  {
168  Xyce::dout() << connectionTargetPopulation[i];
169  if( i < (connectionTargetPopulation.size() - 1))
170  {
171  Xyce::dout() << ", ";
172  }
173  }
174  }
175  else
176  {
177  Xyce::dout() << name << " connectionTargetPopulationGiven == false" << std::endl;
178  }
179  */
180 
181  // Set params to constant default values:
182  setDefaultParams ();
183 
184  // Set params according to instance line
185  setParams (IB.params);
186 
187  // Set any non-constant parameter defaults:
188 
189  //if (!given("TEMP"))
190  // temp = getDeviceOptions().temp.dVal();
191 
192  // Calculate any parameters specified as expressions:
194 
195  // calculate dependent (ie computed) params and check for errors:
196  processParams ();
197  /*
198  numIntVars = numIntVarsPerSegment*nSeg;
199  numStateVars = numStateVarsPerSegment*nSeg;
200  */
201  // total up number of vars.
202  int numVars = numExtVars + numIntVars;
203 
204  // need to work out what if-any real jac stap I need here.
205 
206 
207  // set up jacStamp. This is dependant on the membrane model. The only part this
208  // constructor really knows about is the external variables Vin and vOut
209 
210  if( jacStamp.empty() ) // redundant as jacStamp is not static for this device
211  { // it can't be as each cable may have a different number of nodes
212  jacStamp.resize(numVars);
213  jacStamp[0].resize(1);
214  jacStamp[0][0] = 0; // NodeIn
215  jacStamp[1].resize(1);
216  jacStamp[1][0] = 1; // NodeOut
217  }
218 
219  /*
220  // print out jacStamp
221  Xyce::dout() << "jacStamp for NeuronPop1" << std::endl;
222  int numRows = jacStamp.size();
223  for( int i=0; i< numRows; i++ )
224  {
225  int numCol = jacStamp[i].size();
226  Xyce::dout() << "jacStamp[ " << i << " ] = { ";
227  for(int j=0; j<numCol; j++)
228  {
229  Xyce::dout() << jacStamp[i][j] << " ";
230  }
231  Xyce::dout() << " } " << std::endl;
232  }
233  Xyce::dout() << std::endl;
234  */
235  // if the user has requested output of the state variables M, H and R
236  // then open a file for that output.
237  if( model_.outputPopulationVars > 0 )
238  {
240  std::string filename( "NeuronPop_" );
241  filename.append( getName() );
242  filename.append( ".dat" );
243  // convert any embeded ':' or '%' characters to '_'
244  replace( filename.begin(), filename.end(), '%', '_' );
245  replace( filename.begin(), filename.end(), ':', '_' );
246 
247  outputFileStreamPtr = rcp( new std::ofstream() );
248  outputFileStreamPtr->open( filename.c_str() );
249  if( !(*outputFileStreamPtr) )
250  {
251  std::string msg("Instance constructor.\n");
252  msg += "\tCould not open file for output of population variables. name =" + getName();
253  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
254  }
255  (*outputFileStreamPtr).setf(std::ios::scientific, std::ios::floatfield );
256  (*outputFileStreamPtr).width(20);
257  (*outputFileStreamPtr).precision(12);
258  }
259 
260 }
261 
262 //-----------------------------------------------------------------------------
263 // Function : Instance::~Instance
264 // Purpose : destructor
265 // Special Notes :
266 // Scope : public
267 // Creator : Richard Schiek, Electrical and Microsytem Modeling
268 // Creation Date : 06/10/09
269 //-----------------------------------------------------------------------------
271 {
272 }
273 
274 //-----------------------------------------------------------------------------
275 // Function : Instance::processParams
276 // Purpose :
277 // Special Notes :
278 // Scope : public
279 // Creator : Richard Schiek, Electrical and Microsytem Modeling
280 // Creation Date : 06/10/09
281 //-----------------------------------------------------------------------------
283 {
284  // If there are any time dependent parameters, set their values at for
285  // the current time.
286 
287  // now set the temperature related stuff.
288  //updateTemperature(temp);
289 
290  return true;
291 }
292 
293 //-----------------------------------------------------------------------------
294 // Function : Instance::updateTemperature
295 // Purpose :
296 // Special Notes :
297 // Scope : public
298 // Creator : Richard Schiek, Electrical and Microsytem Modeling
299 // Creation Date : 06/10/09
300 //-----------------------------------------------------------------------------
301 bool Instance::updateTemperature ( const double & temp)
302 {
303  bool bsuccess = true;
304  return bsuccess;
305 }
306 
307 //-----------------------------------------------------------------------------
308 // Function : Instance::registerLIDs
309 // Purpose :
310 // Special Notes :
311 // Scope : public
312 // Creator : Richard Schiek, Electrical and Microsytem Modeling
313 // Creation Date : 06/10/09
314 //-----------------------------------------------------------------------------
315 void Instance::registerLIDs(const std::vector<int> & intLIDVecRef,
316  const std::vector<int> & extLIDVecRef)
317 {
318  AssertLIDs(intLIDVecRef.size() == numIntVars);
319  AssertLIDs(extLIDVecRef.size() == numExtVars);
320 
321 #ifdef Xyce_DEBUG_DEVICE
322  if (getDeviceOptions().debugLevel > 0)
323  {
324  Xyce::dout() << std::endl << section_divider << std::endl;
325  Xyce::dout() << " Instance::registerLIDs" << std::endl;
326  Xyce::dout() << " name = " << getName() << std::endl;
327  }
328 #endif
329 
330  // copy over the global ID lists.
331  intLIDVec = intLIDVecRef;
332  extLIDVec = extLIDVecRef;
333 
334  liNodeIn = extLIDVec[0];
335  liNodeOut = extLIDVec[1];
336 
337 }
338 
339 //-----------------------------------------------------------------------------
340 // Function : Instance::getIntNameMap
341 // Purpose :
342 // Special Notes :
343 // Scope : public
344 // Creator : Richard Schiek, Electrical and Microsytem Modeling
345 // Creation Date : 06/10/09
346 //-----------------------------------------------------------------------------
347 std::map<int,std::string> & Instance::getIntNameMap ()
348 {
349 
350 #if 0
351  // set up the internal name map, if it hasn't been already.
352  if (intNameMap.empty ())
353  {
354  std::ostringstream segNumber;
355  segNumber << i;
356  std::string segNumStr = segNumber.str();
357 
358  tmpstr = name + "_" + "V" + segNumStr;
359  spiceInternalName (tmpstr);
360  intNameMap[ li_internalVars[i*numIntVarsPerSegment] ] = tmpstr;
361  }
362 #endif
363 
364  return intNameMap;
365 }
366 
367 //-----------------------------------------------------------------------------
368 // Function : Instance::registerStateLIDs
369 // Purpose :
370 // Special Notes :
371 // Scope : public
372 // Creator : Richard Schiek, Electrical and Microsytem Modeling
373 // Creation Date : 06/10/09
374 //-----------------------------------------------------------------------------
375 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
376 {
377  AssertLIDs(staLIDVecRef.size() == numStateVars);
378 
379  // copy over the global ID lists.
380  staLIDVec = staLIDVecRef;
381  // this resize won't be true when we store more data in the state
382  // vector. (i.e. not just voltages, but connectivities firing state)
383  liNeuronPopState.resize( numStateVars );
384  for( int i=0; i<numStateVars; i++ )
385  {
386  liNeuronPopState[i] = staLIDVec[i];
387  }
388 
389 }
390 
391 //-----------------------------------------------------------------------------
392 // Function : Instance::loadDeviceMask
393 //
394 // Purpose : Loads the zero elements of the device mask
395 //
396 // Special Notes : elements of the error vector associated with zero
397 // elements of the mask will not be included in weighted
398 // norms by the time integrator.
399 //
400 // Scope : public
401 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
402 // Creation Date : 06/10/09
403 //-----------------------------------------------------------------------------
405 {
406  bool returnVal=false;
407  N_LAS_Vector * maskVectorPtr = extData.deviceMaskVectorPtr;
408 
409  return (returnVal);
410 }
411 
412 //-----------------------------------------------------------------------------
413 // Function : Instance::jacobianStamp
414 // Purpose :
415 // Special Notes :
416 // Scope : public
417 // Creator : Richard Schiek, Electrical and Microsytem Modeling
418 // Creation Date : 06/10/09
419 //-----------------------------------------------------------------------------
420 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
421 {
422  return jacStamp;
423 }
424 
425 //-----------------------------------------------------------------------------
426 // Function : Instance::registerJacLIDs
427 // Purpose :
428 // Special Notes :
429 // Scope : public
430 // Creator : Richard Schiek, Electrical and Microsytem Modeling
431 // Creation Date : 06/10/09
432 //-----------------------------------------------------------------------------
433 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
434 {
435  DeviceInstance::registerJacLIDs( jacLIDVec );
436 
437  // resize our storage location and store the results
438 
439  int numRows = jacLIDVec.size();
440 
441  jsOffsetNodeIn = jacLIDVec[0][0];
442  jsOffsetNodeOut = jacLIDVec[1][0];
443 
444 }
445 
446 //-----------------------------------------------------------------------------
447 // Function : Instance::initializePopulation
448 // Purpose : Steps in initializing a population of neurons
449 // Special Notes :
450 // Scope : public
451 // Creator : Richard Schiek, Electrical and Microsytem Modeling
452 // Creation Date : 06/10/09
453 //-----------------------------------------------------------------------------
455 {
456  // population lives in the state vector, so get a reference to that.
457  // note that the state vector is packed in the form of: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn, internal connections, external connections
458  N_LAS_Vector & staVector = *(extData.nextStaVectorPtr);
459 
460  // seed the random number generator
461  //srandom(unsigned seed)
462  // figure out how many neurons we will start with
463  const double random_max = std::pow(2.0,31)-1; // this may be the same as RAND_MAX but it's not
464  // clear from the man page. Should move random
465  // number generation to the utl package.
466  // try to get a random population from 1..(neuronsMax-1) inclusive of ends
467  neuronPopSize = (rand()/random_max) * model_.neuronsMax + 1;
470 
471 #ifdef Xyce_DEBUG_DEVICE
473  {
474  Xyce::dout() << "Instance::initializePopulation "
475  << "neuronsMax = " << model_.neuronsMax
476  << " neuronPopSize = " << neuronPopSize
477  << std::endl;
478  }
479 #endif
480 
481  int maxPopSize = model_.neuronsMax;
482  // now initialize the locations
483  for(int i=0; i<maxPopSize; i++)
484  {
485  // zero out voltages
486  staVector[ liNeuronPopState[ i ] ] = 0.0;
487  // randomize x positions
488  staVector[ liNeuronPopState[ model_.neuronsMax + i ] ] = (rand()/random_max);
489  // randomize y positions
490  staVector[ liNeuronPopState[2 * model_.neuronsMax + i ] ] = (rand()/random_max);
491  }
492 
493  // now initialize the internal and external connections
494  for(int i=0; i<maxPopSize; i++)
495  {
496  // randomly connect internal connections
497  int numConnections = (rand()/random_max) * model_.internalMaxConnections;
498  int k = 0;
499  for(; k<numConnections; k++)
500  {
501  int postNeuron = (rand()/random_max) * maxPopSize;
502  staVector[ liNeuronPopState[3 * model_.neuronsMax + i * model_.internalMaxConnections + k] ] = postNeuron;
503  }
504  for(int j=k; j<model_.internalMaxConnections; j++)
505  {
506  staVector[ liNeuronPopState[3 * model_.neuronsMax + i * model_.internalMaxConnections + j] ] = 0.0;
507  }
508 
509  // zero out external connections
510  for(int j=0; j<model_.externalMaxConnections; j++)
511  {
513  }
514  }
515 
516  // now rescale update period and neurogenesis rate in terms of seconds (instead of days)
519 
521  // this flag is to signal to outputPlotFiles() function that the state of the system has
522  // changed and should be output at the next call back
523  newStateToOutput=true;
524  return;
525 }
526 
527 //-----------------------------------------------------------------------------
528 // Function : Instance::updatePopulation
529 // Purpose : Steps in updating a population of neurons
530 // Special Notes :
531 // Scope : public
532 // Creator : Richard Schiek, Electrical and Microsytem Modeling
533 // Creation Date : 03/23/11
534 //-----------------------------------------------------------------------------
536 {
537  // population lives in the state vector, so get a reference to that.
538  // note that the state vector is packed in the form of: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn
539  N_LAS_Vector & staVector = *(extData.nextStaVectorPtr);
540 
541 #ifdef Xyce_DEBUG_DEVICE
543  {
544  Xyce::dout() << "Instance::updatePopulation "
545  << "time = " << getSolverState().currTime
546  << std::endl;
547  }
548 #endif
549 
550  double time = getSolverState().currTime;
551 
552  // this check ensures that we've progressed far enough for another neurogenesis event to occur
553  // and we will not exceed the maximum number of neurons allowed
557  {
558  neuronPopSize++;
560 
561  // this flag is to signal to outputPlotFiles() function that the state of the system has
562  // changed and should be output at the next call back
563  newStateToOutput=true;
564  }
565 
568  return;
569 }
570 
571 //-----------------------------------------------------------------------------
572 // Function : Instance::getInstanceBreakPoints
573 // Purpose :
574 // Special Notes :
575 // Scope : public
576 // Creator : Richard Schiek, Electrical Systems Modeling
577 // Creation Date : 03/22/2011
578 //-----------------------------------------------------------------------------
579 bool Instance::getInstanceBreakPoints (std::vector<N_UTL_BreakPoint> &breakPointTimes)
580 {
581  // push on to the vector the next two update times
582  breakPointTimes.push_back((numberOfUpdatesDone+1) * model_.populationUpdatePeriod);
583  breakPointTimes.push_back((numberOfUpdatesDone+2) * model_.populationUpdatePeriod);
584 
585  return true;
586 }
587 
588 
589 //-----------------------------------------------------------------------------
590 // Function : Instance::updateIntermediateVars
591 // Purpose :
592 // Special Notes :
593 // Scope : public
594 // Creator : Richard Schiek, Electrical and Microsytem Modeling
595 // Creation Date : 06/10/09
596 //-----------------------------------------------------------------------------
598 {
599  bool bsuccess = true;
600  if( !populationInitialized )
601  {
603  }
604 
605 
606  double time = getSolverState().currTime;
607 
608  // only do the population updates under the following conditions
609  // 1. when we're at one of the population update times
610  // 2. current time is after the last update time.
611  //
612  // I was going to do this like updateSource() in voltage/current sources, but I can't because
613  // this device isn't derived from that type. This is abit of a hack, but I'll
614  // see if this works for now.
615 
616  // this check ensures that we're at least bpTol past the lastPopulationUpdateTime
617  if( fabs(lastPopulationUpdateTime - time) > getSolverState().bpTol)
618  {
619 #ifdef Xyce_DEBUG_DEVICE
620  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
621  {
622  Xyce::dout() << " Instance::updateIntermediateVars\n";
623  }
624 #endif
625 
626 
627 
628 #ifdef Xyce_DEBUG_DEVICE
629  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
630  {
631  Xyce::dout() << " Time = " << time << std::endl;
632  }
633 #endif
634  // subtract off any delay time
635  // time -= TD;
636 
638  {
639  // repeating signal - figure out where we are in period
640  double basetime = model_.populationUpdatePeriod * floor(time/model_.populationUpdatePeriod);
641  time -= basetime;
642  }
643 
644  // The basetime correction above could take a time right at 2 perionds and make time=0
645  // Thus, we check if time is zero or if it's within bpTol of a period to find out if we
646  // update the population
647 
648  if (fabs(time) < getSolverState().bpTol || (fabs(time - model_.populationUpdatePeriod) < getSolverState().bpTol) )
649  {
650  // we're at a point to update the population
652  }
653  }
654 
655  return bsuccess;
656 }
657 //-----------------------------------------------------------------------------
658 // Function : Instance::updatePrimaryState
659 // Purpose :
660 // Special Notes :
661 // Scope : public
662 // Creator : Richard Schiek, Electrical and Microsytem Modeling
663 // Creation Date : 06/10/09
664 //-----------------------------------------------------------------------------
666 {
667  bool bsuccess = true;
669 
670  return bsuccess;
671 }
672 
673 //-----------------------------------------------------------------------------
674 // Function : Instance::updateSecondaryState
675 // Purpose :
676 // Special Notes :
677 // Scope : public
678 // Creator : Richard Schiek, Electrical and Microsytem Modeling
679 // Creation Date : 06/10/09
680 //-----------------------------------------------------------------------------
682 {
683  bool bsuccess = true;
684 
685  return bsuccess;
686 }
687 
688 //-----------------------------------------------------------------------------
689 // Function : Instance::loadDAEQVector
690 // Purpose :
691 // Special Notes :
692 // Scope : public
693 // Creator : Richard Schiek, Electrical and Microsytem Modeling
694 // Creation Date : 06/10/09
695 //-----------------------------------------------------------------------------
697 {
698  bool bsuccess = true;
699 
700  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
701  N_LAS_Vector * daeQVecPtr = extData.daeQVectorPtr;
702 
703  // no Q component for the cable component of this devcie
704 
705  return bsuccess;
706 }
707 
708 //-----------------------------------------------------------------------------
709 // Function : Instance::loadDAEFVector
710 // Purpose :
711 // Special Notes :
712 // Scope : public
713 // Creator : Richard Schiek, Electrical and Microsytem Modeling
714 // Creation Date : 06/10/09
715 //-----------------------------------------------------------------------------
717 {
718  bool bsuccess=true;
719 
720  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
721  N_LAS_Vector * daeFVecPtr = extData.daeFVectorPtr;
722 
723  // take care of the input and output nodes as they are different
724  (*daeFVecPtr)[liNodeIn] += 0.0;
725  (*daeFVecPtr)[liNodeOut] += 0.0;
726 
727  return bsuccess;
728 }
729 
730 //-----------------------------------------------------------------------------
731 // Function : Instance::loadDAEdQdx
732 // Purpose :
733 // Special Notes :
734 // Scope : public
735 // Creator : Richard Schiek, Electrical and Microsytem Modeling
736 // Creation Date : 06/10/09
737 //-----------------------------------------------------------------------------
739 {
740  bool bsuccess = true;
741 
742  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
743  N_LAS_Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
744 
745 
746  return bsuccess;
747 }
748 
749 //-----------------------------------------------------------------------------
750 // Function : Instance::loadDAEdFdx ()
751 // Purpose :
752 // Special Notes :
753 // Scope : public
754 // Creator : Richard Schiek, Electrical and Microsytem Modeling
755 // Creation Date : 06/10/09
756 //-----------------------------------------------------------------------------
758 {
759  bool bsuccess = true;
760 
761  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
762  N_LAS_Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
763 
764  (*dFdxMatPtr)[liNodeIn][jsOffsetNodeIn] += 1.0;
765  (*dFdxMatPtr)[liNodeOut][jsOffsetNodeOut] += 1.0;
766 
767  return bsuccess;
768 }
769 
770 //-----------------------------------------------------------------------------
771 // Function : Instance::outputPlotFiles
772 // Purpose : If requested by the user output all the variables
773 // associated with the population
774 // Special Notes :
775 // Scope : public
776 // Creator : Rich Schiek, SNL, Parallel Computational Sciences
777 // Creation Date : 03/10/2011
778 //-----------------------------------------------------------------------------
780 {
781 
782  bool bsuccess = true;
783 
784  // only output when the population has changed to avoid lots of duplicate output
785  // the newStateToOutput flag is set in initializePopulation() and updatePopulation()
787  {
788  // population lives in the state vector, so get a reference to that.
789  // note that the state vector is packed in the form of: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn
790  N_LAS_Vector & solVector = *(extData.nextSolVectorPtr);
791  N_LAS_Vector & staVector = *(extData.nextStaVectorPtr);
792  N_LAS_Vector & staDerivVec = *(extData.nextStaDerivVectorPtr);
793 
794  // output format is
795  // time, population_size, x1, ..., xn, y1, ..., yn, v1, ..., vn
796  //
797  (*outputFileStreamPtr)
798  << getSolverState().currTime << ", "
799  << neuronPopSize << ", ";
800 
801  // the state vector is packed in the order
802  for( int i=0; i < neuronPopSize; i++)
803  {
804  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ model_.neuronsMax + i]] << ", ";
805  }
806 
807  for( int i=0; i < neuronPopSize; i++)
808  {
809  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ 2*model_.neuronsMax + i]] << ", ";
810  }
811 
812  for( int i=0; i < neuronPopSize; i++)
813  {
814  (*outputFileStreamPtr) << staVector[ liNeuronPopState[i] ] << ", ";
815  }
816 
817  for( int i=0; i < neuronPopSize; i++)
818  {
819  for( int j=0; j < model_.internalMaxConnections; j++)
820  {
821  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ 3*model_.neuronsMax + i*model_.internalMaxConnections + j]] << ", ";
822  }
823  }
824 
825  for( int i=0; i < neuronPopSize; i++)
826  {
827  for( int j=0; j < model_.externalMaxConnections; j++)
828  {
829  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ (3 + model_.internalMaxConnections)*model_.neuronsMax + i*model_.externalMaxConnections + j]];
830  if( (i != (neuronPopSize-1)) || (j != (model_.externalMaxConnections-1)) )
831  {
832  (*outputFileStreamPtr) << ", ";
833  }
834  }
835  }
836  (*outputFileStreamPtr) << std::endl;
837 
838  // we've output this state, so reset flag
839  newStateToOutput=false;
840 
841  }
842  return bsuccess;
843 }
844 
845 //-----------------------------------------------------------------------------
846 // Function : Instance::setIC
847 // Purpose :
848 // Special Notes :
849 // Scope : public
850 // Creator : Richard Schiek, Electrical and Microsytem Modeling
851 // Creation Date : 06/10/09
852 //-----------------------------------------------------------------------------
854 {
855  bool bsuccess = true;
856 
857  return bsuccess;
858 }
859 
860 //-----------------------------------------------------------------------------
861 // Function : Instance::varTypes
862 // Purpose :
863 // Special Notes :
864 // Scope : public
865 // Creator : Richard Schiek, Electrical and Microsytem Modeling
866 // Creation Date : 06/10/09
867 //-----------------------------------------------------------------------------
868 void Instance::varTypes( std::vector<char> & varTypeVec )
869 {
870  //varTypeVec.resize(1);
871  //varTypeVec[0] = 'I';
872 }
873 
874 
875 //-----------------------------------------------------------------------------
876 // Function : Model::Model
877 // Purpose : block constructor
878 // Special Notes :
879 // Scope : public
880 // Creator : Richard Schiek, Electrical and Microsytem Modeling
881 // Creation Date : 06/10/09
882 //-----------------------------------------------------------------------------
884  const Configuration & configuration,
885  const ModelBlock & MB,
886  const FactoryBlock & factory_block)
887  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
888  neuronsMax(0),
889  neuronsMaxGiven(false),
890  internalMaxConnections(0),
891  internalMaxConnectionsGiven(false),
892  externalMaxConnections(0),
893  externalMaxConnectionsGiven(false),
894  populationNeurogenesisRate(0.0),
895  populationNeurogenesisRateGiven(false),
896  populationUpdatePeriod(0.0),
897  populationUpdatePeriodGiven(false),
898  outputPopulationVars(0)
899 {
900 
901  // Set params to constant default values:
902  setDefaultParams ();
903 
904  // Set params according to .model line and constant defaults from metadata:
905  setModParams (MB.params);
906 
907  // Set any non-constant parameter defaults:
908  //if (!given("TNOM"))
909  // tnom = getDeviceOptions().tnom;
910 
911  // Calculate any parameters specified as expressions:
913 
914  // calculate dependent (ie computed) params and check for errors:
915 
916  processParams ();
917 
918 }
919 
920 
921 //-----------------------------------------------------------------------------
922 // Function : Model::~Model
923 // Purpose : destructor
924 // Special Notes :
925 // Scope : public
926 // Creator : Richard Schiek, Electrical and Microsytem Modeling
927 // Creation Date : 06/10/09
928 //-----------------------------------------------------------------------------
930 {
931  std::vector<Instance*>::iterator iter;
932  std::vector<Instance*>::iterator first = instanceContainer.begin();
933  std::vector<Instance*>::iterator last = instanceContainer.end();
934 
935  for (iter=first; iter!=last; ++iter)
936  {
937  delete (*iter);
938  }
939 
940 }
941 
942 // additional Declarations
943 //-----------------------------------------------------------------------------
944 // Function : Model::processParams
945 // Purpose :
946 // Special Notes :
947 // Scope : public
948 // Creator : Richard Schiek, Electrical and Microsytem Modeling
949 // Creation Date : 06/10/09
950 //-----------------------------------------------------------------------------
952 {
953  return true;
954 }
955 
956 //----------------------------------------------------------------------------
957 // Function : Model::processInstanceParams
958 // Purpose :
959 // Special Notes :
960 // Scope : public
961 // Creator : Richard Schiek, Electrical and Microsytem Modeling
962 // Creation Date : 06/10/09
963 //----------------------------------------------------------------------------
965 {
966 
967  std::vector<Instance*>::iterator iter;
968  std::vector<Instance*>::iterator first = instanceContainer.begin();
969  std::vector<Instance*>::iterator last = instanceContainer.end();
970 
971  for (iter=first; iter!=last; ++iter)
972  {
973  (*iter)->processParams();
974  }
975 
976  return true;
977 }
978 //-----------------------------------------------------------------------------
979 // Function : Model::printOutInstances
980 // Purpose : debugging tool.
981 // Special Notes :
982 // Scope : public
983 // Creator : Richard Schiek, Electrical and Microsytem Modeling
984 // Creation Date : 06/10/09
985 //-----------------------------------------------------------------------------
986 std::ostream &Model::printOutInstances(std::ostream &os) const
987 {
988  std::vector<Instance*>::const_iterator iter;
989  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
990  std::vector<Instance*>::const_iterator last = instanceContainer.end();
991 
992  int i, isize;
993  isize = instanceContainer.size();
994 
995  os << std::endl;
996  os << "Number of Neuron instances: " << isize << std::endl;
997  os << " name=\t\tmodelName\tParameters" << std::endl;
998  for (i=0, iter=first; iter!=last; ++iter, ++i)
999  {
1000  os << " " << i << ": " << (*iter)->getName() << "\t";
1001  os << getName();
1002  os << std::endl;
1003  }
1004 
1005  os << std::endl;
1006  return os;
1007 }
1008 
1009 //-----------------------------------------------------------------------------
1010 // Function : Model::forEachInstance
1011 // Purpose :
1012 // Special Notes :
1013 // Scope : public
1014 // Creator : David Baur
1015 // Creation Date : 2/4/2014
1016 //-----------------------------------------------------------------------------
1017 /// Apply a device instance "op" to all instances associated with this
1018 /// model
1019 ///
1020 /// @param[in] op Operator to apply to all instances.
1021 ///
1022 ///
1023 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1024 {
1025  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1026  op(*it);
1027 }
1028 
1029 
1030 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1031 {
1032 
1033  return new DeviceMaster<Traits>(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1034 }
1035 
1037 {
1039  .registerDevice("neuronpop", 1)
1040  .registerModelType("neuronpop", 1);
1041 }
1042 
1043 } // namespace NeuronPop1
1044 } // namespace Device
1045 } // namespace Xyce