Xyce  6.1
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-2015 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.57 $
40 //
41 // Revision Date : $Date: 2015/10/20 22:32:48 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 // ---------- Standard Includes ----------
49 // for random() function
50 #include <cstdlib>
51 
52 // ---------- Xyce Includes ----------
53 #include <N_DEV_DeviceOptions.h>
54 #include <N_DEV_DeviceMaster.h>
55 #include <N_DEV_ExternData.h>
56 #include <N_DEV_MatrixLoadData.h>
57 #include <N_DEV_MembraneCS.h>
58 #include <N_DEV_MembraneHH.h>
59 #include <N_DEV_MembranePassive.h>
61 #include <N_DEV_NeuronPop1.h>
63 #include <N_DEV_SolverState.h>
64 #include <N_DEV_Message.h>
65 #include <N_ERH_ErrorMgr.h>
66 
67 #include <N_LAS_Vector.h>
68 #include <N_LAS_Matrix.h>
69 #include <N_UTL_BreakPoint.h>
70 #include <N_UTL_FeatureTest.h>
71 
72 namespace Xyce {
73 namespace Device {
74 
75 namespace NeuronPop1 {
76 
78 {
79  p.addPar ("CTP",std::vector<std::string>(),&NeuronPop1::Instance::connectionTargetPopulation)
81  .setUnit(U_NONE)
82  .setCategory(CAT_NONE)
83  .setDescription("Connected Target Population list");
84 }
85 
87 {
88  p.addPar ("NEURONS_MAX",10,&NeuronPop1::Model::neuronsMax)
89  .setGivenMember(&NeuronPop1::Model::neuronsMaxGiven)
90  .setDescription("Maximum number of neurons in the device");
91 
94  .setDescription("Maximum number of internal connections in the device");
95 
98  .setDescription("Maximum number of external connections in the device");
99 
100  p.addPar ("NEUROGENESIS_RATE",0.0,&NeuronPop1::Model::populationNeurogenesisRate)
102  .setUnit(U_SECOND)
103  .setDescription("Rate in days of GC neurogenesis in the population");
104 
105  p.addPar ("UPDATE_PERIOD",1.0,&NeuronPop1::Model::populationUpdatePeriod)
107  .setUnit(U_SECOND)
108  .setDescription("Time in days for population updates");
109 
110  p.addPar ("OUTPUTPOPULATIONVARS",0,&NeuronPop1::Model::outputPopulationVars)
111  .setDescription("Flag to save population variables" );
112 }
113 
114 
115 
116 //
117 // static class member inits
118 //
119 
120 //-----------------------------------------------------------------------------
121 // Function : Instance::Instance
122 // Purpose : constructor
123 // Special Notes :
124 // Scope : public
125 // Creator : Richard Schiek, Electrical and Microsytem Modeling
126 // Creation Date : 06/10/09
127 //-----------------------------------------------------------------------------
129  const Configuration & configuration,
130  const InstanceBlock & IB,
131  Model & Miter,
132  const FactoryBlock & factory_block)
133  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
134  model_(Miter),
135  liNodeIn(-1),
136  liNodeOut(-1),
137  jsOffsetNodeIn(-1),
138  jsOffsetNodeOut(-1),
139  populationInitialized(false),
140  neuronPopSize(0),
141  connectionTargetPopulationGiven(false),
142  numberOfUpdatesDone(0),
143  lastPopulationUpdateTime(0.0),
144  lastNeurogenesisUpdateTime(0.0),
145  outputPopulationVarsFlag(false),
146  newStateToOutput(false)
147 {
148  // Set up the number of internal, external and state vars
149  numExtVars = 2; // input and output voltage
150  // numIntVars number of internal vars
151  // currently we have 3 variables per neuron, Voltage, X-position, Y-Position plus internal and external connections (maximum)
152  // These will all be in the state vector as: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn
153  // We do this rather than have individual containers because it will be easier to push the
154  // state vector around for working with these in parallel.
155 
156  // number of vars per neuron: 3
158 
159  // Set params to constant default values:
160  setDefaultParams ();
161 
162  // Set params according to instance line
163  setParams (IB.params);
164 
165  // Set any non-constant parameter defaults:
166 
167  // Calculate any parameters specified as expressions:
169 
170  // calculate dependent (ie computed) params and check for errors:
171  processParams ();
172 
173  // total up number of vars.
174  int numVars = numExtVars + numIntVars;
175 
176  // need to work out what if-any real jac stap I need here.
177 
178 
179  // set up jacStamp. This is dependant on the membrane model. The only part this
180  // constructor really knows about is the external variables Vin and vOut
181 
182  if( jacStamp.empty() ) // redundant as jacStamp is not static for this device
183  { // it can't be as each cable may have a different number of nodes
184  jacStamp.resize(numVars);
185  jacStamp[0].resize(1);
186  jacStamp[0][0] = 0; // NodeIn
187  jacStamp[1].resize(1);
188  jacStamp[1][0] = 1; // NodeOut
189  }
190 
191  // if the user has requested output of the state variables M, H and R
192  // then open a file for that output.
193  if( model_.outputPopulationVars > 0 )
194  {
196  std::string filename( "NeuronPop_" );
197  filename.append( getName().getEncodedName() );
198  filename.append( ".dat" );
199  // convert any embeded ':' or '%' characters to '_'
200  replace( filename.begin(), filename.end(), '%', '_' );
201  replace( filename.begin(), filename.end(), ':', '_' );
202 
203  outputFileStreamPtr = rcp( new std::ofstream() );
204  outputFileStreamPtr->open( filename.c_str() );
205  if( !(*outputFileStreamPtr) )
206  {
207  UserError(*this) << "Could not open file " << filename << " for output of population variables";
208  }
209  else {
210  (*outputFileStreamPtr).setf(std::ios::scientific, std::ios::floatfield );
211  (*outputFileStreamPtr).width(20);
212  (*outputFileStreamPtr).precision(12);
213  }
214  }
215 }
216 
217 //-----------------------------------------------------------------------------
218 // Function : Instance::~Instance
219 // Purpose : destructor
220 // Special Notes :
221 // Scope : public
222 // Creator : Richard Schiek, Electrical and Microsytem Modeling
223 // Creation Date : 06/10/09
224 //-----------------------------------------------------------------------------
226 {
227 }
228 
229 //-----------------------------------------------------------------------------
230 // Function : Instance::processParams
231 // Purpose :
232 // Special Notes :
233 // Scope : public
234 // Creator : Richard Schiek, Electrical and Microsytem Modeling
235 // Creation Date : 06/10/09
236 //-----------------------------------------------------------------------------
238 {
239  // If there are any time dependent parameters, set their values at for
240  // the current time.
241 
242  return true;
243 }
244 
245 //-----------------------------------------------------------------------------
246 // Function : Instance::updateTemperature
247 // Purpose :
248 // Special Notes :
249 // Scope : public
250 // Creator : Richard Schiek, Electrical and Microsytem Modeling
251 // Creation Date : 06/10/09
252 //-----------------------------------------------------------------------------
253 bool Instance::updateTemperature ( const double & temp)
254 {
255  bool bsuccess = true;
256  return bsuccess;
257 }
258 
259 //-----------------------------------------------------------------------------
260 // Function : Instance::registerLIDs
261 // Purpose :
262 // Special Notes :
263 // Scope : public
264 // Creator : Richard Schiek, Electrical and Microsytem Modeling
265 // Creation Date : 06/10/09
266 //-----------------------------------------------------------------------------
267 void Instance::registerLIDs(const std::vector<int> & intLIDVecRef,
268  const std::vector<int> & extLIDVecRef)
269 {
270  AssertLIDs(intLIDVecRef.size() == numIntVars);
271  AssertLIDs(extLIDVecRef.size() == numExtVars);
272 
273  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
274  {
275  Xyce::dout() << std::endl << section_divider << std::endl;
276  Xyce::dout() << " Instance::registerLIDs" << std::endl;
277  Xyce::dout() << " name = " << getName() << std::endl;
278  }
279 
280  // copy over the global ID lists.
281  intLIDVec = intLIDVecRef;
282  extLIDVec = extLIDVecRef;
283 
284  liNodeIn = extLIDVec[0];
285  liNodeOut = extLIDVec[1];
286 
287 }
288 
289 //-----------------------------------------------------------------------------
290 // Function : Instance::loadNodeSymbols
291 // Purpose :
292 // Special Notes :
293 // Scope : public
294 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
295 // Creation Date : 05/13/05
296 //-----------------------------------------------------------------------------
297 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
298 {}
299 
300 //-----------------------------------------------------------------------------
301 // Function : Instance::registerStateLIDs
302 // Purpose :
303 // Special Notes :
304 // Scope : public
305 // Creator : Richard Schiek, Electrical and Microsytem Modeling
306 // Creation Date : 06/10/09
307 //-----------------------------------------------------------------------------
308 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
309 {
310  AssertLIDs(staLIDVecRef.size() == numStateVars);
311 
312  // copy over the global ID lists.
313  staLIDVec = staLIDVecRef;
314  // this resize won't be true when we store more data in the state
315  // vector. (i.e. not just voltages, but connectivities firing state)
316  liNeuronPopState.resize( numStateVars );
317  for( int i=0; i<numStateVars; i++ )
318  {
319  liNeuronPopState[i] = staLIDVec[i];
320  }
321 
322 }
323 
324 //-----------------------------------------------------------------------------
325 // Function : Instance::jacobianStamp
326 // Purpose :
327 // Special Notes :
328 // Scope : public
329 // Creator : Richard Schiek, Electrical and Microsytem Modeling
330 // Creation Date : 06/10/09
331 //-----------------------------------------------------------------------------
332 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
333 {
334  return jacStamp;
335 }
336 
337 //-----------------------------------------------------------------------------
338 // Function : Instance::registerJacLIDs
339 // Purpose :
340 // Special Notes :
341 // Scope : public
342 // Creator : Richard Schiek, Electrical and Microsytem Modeling
343 // Creation Date : 06/10/09
344 //-----------------------------------------------------------------------------
345 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
346 {
347  DeviceInstance::registerJacLIDs( jacLIDVec );
348 
349  // resize our storage location and store the results
350 
351  int numRows = jacLIDVec.size();
352 
353  jsOffsetNodeIn = jacLIDVec[0][0];
354  jsOffsetNodeOut = jacLIDVec[1][0];
355 
356 }
357 
358 //-----------------------------------------------------------------------------
359 // Function : Instance::initializePopulation
360 // Purpose : Steps in initializing a population of neurons
361 // Special Notes :
362 // Scope : public
363 // Creator : Richard Schiek, Electrical and Microsytem Modeling
364 // Creation Date : 06/10/09
365 //-----------------------------------------------------------------------------
367 {
368  // population lives in the state vector, so get a reference to that.
369  // note that the state vector is packed in the form of: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn, internal connections, external connections
370  Linear::Vector & staVector = *(extData.nextStaVectorPtr);
371 
372  // seed the random number generator
373  //srandom(unsigned seed)
374  // figure out how many neurons we will start with
375  const double random_max = std::pow(2.0,31)-1; // this may be the same as RAND_MAX but it's not
376  // clear from the man page. Should move random
377  // number generation to the utl package.
378  // try to get a random population from 1..(neuronsMax-1) inclusive of ends
379  neuronPopSize = (rand()/random_max) * model_.neuronsMax + 1;
382 
383  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
384  {
385  Xyce::dout() << "Instance::initializePopulation "
386  << "neuronsMax = " << model_.neuronsMax
387  << " neuronPopSize = " << neuronPopSize
388  << std::endl;
389  }
390 
391  int maxPopSize = model_.neuronsMax;
392  // now initialize the locations
393  for(int i=0; i<maxPopSize; i++)
394  {
395  // zero out voltages
396  staVector[ liNeuronPopState[ i ] ] = 0.0;
397  // randomize x positions
398  staVector[ liNeuronPopState[ model_.neuronsMax + i ] ] = (rand()/random_max);
399  // randomize y positions
400  staVector[ liNeuronPopState[2 * model_.neuronsMax + i ] ] = (rand()/random_max);
401  }
402 
403  // now initialize the internal and external connections
404  for(int i=0; i<maxPopSize; i++)
405  {
406  // randomly connect internal connections
407  int numConnections = (rand()/random_max) * model_.internalMaxConnections;
408  int k = 0;
409  for(; k<numConnections; k++)
410  {
411  int postNeuron = (rand()/random_max) * maxPopSize;
412  staVector[ liNeuronPopState[3 * model_.neuronsMax + i * model_.internalMaxConnections + k] ] = postNeuron;
413  }
414  for(int j=k; j<model_.internalMaxConnections; j++)
415  {
416  staVector[ liNeuronPopState[3 * model_.neuronsMax + i * model_.internalMaxConnections + j] ] = 0.0;
417  }
418 
419  // zero out external connections
420  for(int j=0; j<model_.externalMaxConnections; j++)
421  {
423  }
424  }
425 
426  // now rescale update period and neurogenesis rate in terms of seconds (instead of days)
429 
431  // this flag is to signal to outputPlotFiles() function that the state of the system has
432  // changed and should be output at the next call back
433  newStateToOutput=true;
434  return;
435 }
436 
437 //-----------------------------------------------------------------------------
438 // Function : Instance::updatePopulation
439 // Purpose : Steps in updating a population of neurons
440 // Special Notes :
441 // Scope : public
442 // Creator : Richard Schiek, Electrical and Microsytem Modeling
443 // Creation Date : 03/23/11
444 //-----------------------------------------------------------------------------
446 {
447  // population lives in the state vector, so get a reference to that.
448  // note that the state vector is packed in the form of: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn
449  Linear::Vector & staVector = *(extData.nextStaVectorPtr);
450 
451  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
452  {
453  Xyce::dout() << "Instance::updatePopulation "
454  << "time = " << getSolverState().currTime_
455  << std::endl;
456  }
457 
458  double time = getSolverState().currTime_;
459 
460  // this check ensures that we've progressed far enough for another neurogenesis event to occur
461  // and we will not exceed the maximum number of neurons allowed
465  {
466  neuronPopSize++;
468 
469  // this flag is to signal to outputPlotFiles() function that the state of the system has
470  // changed and should be output at the next call back
471  newStateToOutput=true;
472  }
473 
476  return;
477 }
478 
479 //-----------------------------------------------------------------------------
480 // Function : Instance::getInstanceBreakPoints
481 // Purpose :
482 // Special Notes :
483 // Scope : public
484 // Creator : Richard Schiek, Electrical Systems Modeling
485 // Creation Date : 03/22/2011
486 //-----------------------------------------------------------------------------
487 bool Instance::getInstanceBreakPoints (std::vector<Util::BreakPoint> &breakPointTimes)
488 {
489  // push on to the vector the next two update times
490  breakPointTimes.push_back((numberOfUpdatesDone+1) * model_.populationUpdatePeriod);
491  breakPointTimes.push_back((numberOfUpdatesDone+2) * model_.populationUpdatePeriod);
492 
493  return true;
494 }
495 
496 
497 //-----------------------------------------------------------------------------
498 // Function : Instance::updateIntermediateVars
499 // Purpose :
500 // Special Notes :
501 // Scope : public
502 // Creator : Richard Schiek, Electrical and Microsytem Modeling
503 // Creation Date : 06/10/09
504 //-----------------------------------------------------------------------------
506 {
507  bool bsuccess = true;
508  if( !populationInitialized )
509  {
511  }
512 
513 
514  double time = getSolverState().currTime_;
515 
516  // only do the population updates under the following conditions
517  // 1. when we're at one of the population update times
518  // 2. current time is after the last update time.
519  //
520  // I was going to do this like updateSource() in voltage/current sources, but I can't because
521  // this device isn't derived from that type. This is abit of a hack, but I'll
522  // see if this works for now.
523 
524  // this check ensures that we're at least bpTol past the lastPopulationUpdateTime
525  if( fabs(lastPopulationUpdateTime - time) > getSolverState().bpTol_)
526  {
527  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
528  {
529  Xyce::dout() << " Instance::updateIntermediateVars\n";
530  }
531 
532 
533 
534  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
535  {
536  Xyce::dout() << " Time = " << time << std::endl;
537  }
538  // subtract off any delay time
539  // time -= TD;
540 
542  {
543  // repeating signal - figure out where we are in period
544  double basetime = model_.populationUpdatePeriod * floor(time/model_.populationUpdatePeriod);
545  time -= basetime;
546  }
547 
548  // The basetime correction above could take a time right at 2 perionds and make time=0
549  // Thus, we check if time is zero or if it's within bpTol of a period to find out if we
550  // update the population
551 
552  if (fabs(time) < getSolverState().bpTol_ || (fabs(time - model_.populationUpdatePeriod) < getSolverState().bpTol_) )
553  {
554  // we're at a point to update the population
556  }
557  }
558 
559  return bsuccess;
560 }
561 //-----------------------------------------------------------------------------
562 // Function : Instance::updatePrimaryState
563 // Purpose :
564 // Special Notes :
565 // Scope : public
566 // Creator : Richard Schiek, Electrical and Microsytem Modeling
567 // Creation Date : 06/10/09
568 //-----------------------------------------------------------------------------
570 {
571  bool bsuccess = true;
573 
574  return bsuccess;
575 }
576 
577 //-----------------------------------------------------------------------------
578 // Function : Instance::updateSecondaryState
579 // Purpose :
580 // Special Notes :
581 // Scope : public
582 // Creator : Richard Schiek, Electrical and Microsytem Modeling
583 // Creation Date : 06/10/09
584 //-----------------------------------------------------------------------------
586 {
587  bool bsuccess = true;
588 
589  return bsuccess;
590 }
591 
592 //-----------------------------------------------------------------------------
593 // Function : Instance::loadDAEQVector
594 // Purpose :
595 // Special Notes :
596 // Scope : public
597 // Creator : Richard Schiek, Electrical and Microsytem Modeling
598 // Creation Date : 06/10/09
599 //-----------------------------------------------------------------------------
601 {
602  bool bsuccess = true;
603 
604  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
605  Linear::Vector * daeQVecPtr = extData.daeQVectorPtr;
606 
607  // no Q component for the cable component of this devcie
608 
609  return bsuccess;
610 }
611 
612 //-----------------------------------------------------------------------------
613 // Function : Instance::loadDAEFVector
614 // Purpose :
615 // Special Notes :
616 // Scope : public
617 // Creator : Richard Schiek, Electrical and Microsytem Modeling
618 // Creation Date : 06/10/09
619 //-----------------------------------------------------------------------------
621 {
622  bool bsuccess=true;
623 
624  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
625  Linear::Vector * daeFVecPtr = extData.daeFVectorPtr;
626 
627  // take care of the input and output nodes as they are different
628  (*daeFVecPtr)[liNodeIn] += 0.0;
629  (*daeFVecPtr)[liNodeOut] += 0.0;
630 
631  return bsuccess;
632 }
633 
634 //-----------------------------------------------------------------------------
635 // Function : Instance::loadDAEdQdx
636 // Purpose :
637 // Special Notes :
638 // Scope : public
639 // Creator : Richard Schiek, Electrical and Microsytem Modeling
640 // Creation Date : 06/10/09
641 //-----------------------------------------------------------------------------
643 {
644  bool bsuccess = true;
645 
646  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
647  Linear::Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
648 
649 
650  return bsuccess;
651 }
652 
653 //-----------------------------------------------------------------------------
654 // Function : Instance::loadDAEdFdx ()
655 // Purpose :
656 // Special Notes :
657 // Scope : public
658 // Creator : Richard Schiek, Electrical and Microsytem Modeling
659 // Creation Date : 06/10/09
660 //-----------------------------------------------------------------------------
662 {
663  bool bsuccess = true;
664 
665  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
666  Linear::Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
667 
668  (*dFdxMatPtr)[liNodeIn][jsOffsetNodeIn] += 1.0;
669  (*dFdxMatPtr)[liNodeOut][jsOffsetNodeOut] += 1.0;
670 
671  return bsuccess;
672 }
673 
674 //-----------------------------------------------------------------------------
675 // Function : Instance::outputPlotFiles
676 // Purpose : If requested by the user output all the variables
677 // associated with the population
678 // Special Notes :
679 // Scope : public
680 // Creator : Rich Schiek, SNL, Parallel Computational Sciences
681 // Creation Date : 03/10/2011
682 //-----------------------------------------------------------------------------
683 bool Instance::outputPlotFiles(bool force_final_output)
684 {
685 
686  bool bsuccess = true;
687 
688  // only output when the population has changed to avoid lots of duplicate output
689  // the newStateToOutput flag is set in initializePopulation() and updatePopulation()
690  if( outputPopulationVarsFlag && newStateToOutput && outputFileStreamPtr.get() && (*outputFileStreamPtr) )
691  {
692  // population lives in the state vector, so get a reference to that.
693  // note that the state vector is packed in the form of: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn
694  Linear::Vector & solVector = *(extData.nextSolVectorPtr);
695  Linear::Vector & staVector = *(extData.nextStaVectorPtr);
696  Linear::Vector & staDerivVec = *(extData.nextStaDerivVectorPtr);
697 
698  // output format is
699  // time, population_size, x1, ..., xn, y1, ..., yn, v1, ..., vn
700  //
701  (*outputFileStreamPtr)
702  << getSolverState().currTime_ << ", "
703  << neuronPopSize << ", ";
704 
705  // the state vector is packed in the order
706  for( int i=0; i < neuronPopSize; i++)
707  {
708  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ model_.neuronsMax + i]] << ", ";
709  }
710 
711  for( int i=0; i < neuronPopSize; i++)
712  {
713  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ 2*model_.neuronsMax + i]] << ", ";
714  }
715 
716  for( int i=0; i < neuronPopSize; i++)
717  {
718  (*outputFileStreamPtr) << staVector[ liNeuronPopState[i] ] << ", ";
719  }
720 
721  for( int i=0; i < neuronPopSize; i++)
722  {
723  for( int j=0; j < model_.internalMaxConnections; j++)
724  {
725  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ 3*model_.neuronsMax + i*model_.internalMaxConnections + j]] << ", ";
726  }
727  }
728 
729  for( int i=0; i < neuronPopSize; i++)
730  {
731  for( int j=0; j < model_.externalMaxConnections; j++)
732  {
733  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ (3 + model_.internalMaxConnections)*model_.neuronsMax + i*model_.externalMaxConnections + j]];
734  if( (i != (neuronPopSize-1)) || (j != (model_.externalMaxConnections-1)) )
735  {
736  (*outputFileStreamPtr) << ", ";
737  }
738  }
739  }
740  (*outputFileStreamPtr) << std::endl;
741 
742  // we've output this state, so reset flag
743  newStateToOutput=false;
744 
745  }
746  return bsuccess;
747 }
748 
749 //-----------------------------------------------------------------------------
750 // Function : Instance::setIC
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  return bsuccess;
762 }
763 
764 //-----------------------------------------------------------------------------
765 // Function : Instance::varTypes
766 // Purpose :
767 // Special Notes :
768 // Scope : public
769 // Creator : Richard Schiek, Electrical and Microsytem Modeling
770 // Creation Date : 06/10/09
771 //-----------------------------------------------------------------------------
772 void Instance::varTypes( std::vector<char> & varTypeVec )
773 {
774  //varTypeVec.resize(1);
775  //varTypeVec[0] = 'I';
776 }
777 
778 
779 //-----------------------------------------------------------------------------
780 // Function : Model::Model
781 // Purpose : block constructor
782 // Special Notes :
783 // Scope : public
784 // Creator : Richard Schiek, Electrical and Microsytem Modeling
785 // Creation Date : 06/10/09
786 //-----------------------------------------------------------------------------
788  const Configuration & configuration,
789  const ModelBlock & MB,
790  const FactoryBlock & factory_block)
791  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
792  neuronsMax(0),
793  neuronsMaxGiven(false),
794  internalMaxConnections(0),
795  internalMaxConnectionsGiven(false),
796  externalMaxConnections(0),
797  externalMaxConnectionsGiven(false),
798  populationNeurogenesisRate(0.0),
799  populationNeurogenesisRateGiven(false),
800  populationUpdatePeriod(0.0),
801  populationUpdatePeriodGiven(false),
802  outputPopulationVars(0)
803 {
804 
805  // Set params to constant default values:
806  setDefaultParams ();
807 
808  // Set params according to .model line and constant defaults from metadata:
809  setModParams (MB.params);
810 
811  // Set any non-constant parameter defaults:
812  //if (!given("TNOM"))
813  // tnom = getDeviceOptions().tnom;
814 
815  // Calculate any parameters specified as expressions:
817 
818  // calculate dependent (ie computed) params and check for errors:
819 
820  processParams ();
821 
822 }
823 
824 
825 //-----------------------------------------------------------------------------
826 // Function : Model::~Model
827 // Purpose : destructor
828 // Special Notes :
829 // Scope : public
830 // Creator : Richard Schiek, Electrical and Microsytem Modeling
831 // Creation Date : 06/10/09
832 //-----------------------------------------------------------------------------
834 {
835  std::vector<Instance*>::iterator iter;
836  std::vector<Instance*>::iterator first = instanceContainer.begin();
837  std::vector<Instance*>::iterator last = instanceContainer.end();
838 
839  for (iter=first; iter!=last; ++iter)
840  {
841  delete (*iter);
842  }
843 
844 }
845 
846 // additional Declarations
847 //-----------------------------------------------------------------------------
848 // Function : Model::processParams
849 // Purpose :
850 // Special Notes :
851 // Scope : public
852 // Creator : Richard Schiek, Electrical and Microsytem Modeling
853 // Creation Date : 06/10/09
854 //-----------------------------------------------------------------------------
856 {
857  return true;
858 }
859 
860 //----------------------------------------------------------------------------
861 // Function : Model::processInstanceParams
862 // Purpose :
863 // Special Notes :
864 // Scope : public
865 // Creator : Richard Schiek, Electrical and Microsytem Modeling
866 // Creation Date : 06/10/09
867 //----------------------------------------------------------------------------
869 {
870 
871  std::vector<Instance*>::iterator iter;
872  std::vector<Instance*>::iterator first = instanceContainer.begin();
873  std::vector<Instance*>::iterator last = instanceContainer.end();
874 
875  for (iter=first; iter!=last; ++iter)
876  {
877  (*iter)->processParams();
878  }
879 
880  return true;
881 }
882 //-----------------------------------------------------------------------------
883 // Function : Model::printOutInstances
884 // Purpose : debugging tool.
885 // Special Notes :
886 // Scope : public
887 // Creator : Richard Schiek, Electrical and Microsytem Modeling
888 // Creation Date : 06/10/09
889 //-----------------------------------------------------------------------------
890 std::ostream &Model::printOutInstances(std::ostream &os) const
891 {
892  std::vector<Instance*>::const_iterator iter;
893  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
894  std::vector<Instance*>::const_iterator last = instanceContainer.end();
895 
896  int i, isize;
897  isize = instanceContainer.size();
898 
899  os << std::endl;
900  os << "Number of Neuron instances: " << isize << std::endl;
901  os << " name=\t\tmodelName\tParameters" << std::endl;
902  for (i=0, iter=first; iter!=last; ++iter, ++i)
903  {
904  os << " " << i << ": " << (*iter)->getName() << "\t";
905  os << getName();
906  os << std::endl;
907  }
908 
909  os << std::endl;
910  return os;
911 }
912 
913 //-----------------------------------------------------------------------------
914 // Function : Model::forEachInstance
915 // Purpose :
916 // Special Notes :
917 // Scope : public
918 // Creator : David Baur
919 // Creation Date : 2/4/2014
920 //-----------------------------------------------------------------------------
921 /// Apply a device instance "op" to all instances associated with this
922 /// model
923 ///
924 /// @param[in] op Operator to apply to all instances.
925 ///
926 ///
927 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
928 {
929  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
930  op(*it);
931 }
932 
933 
934 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
935 {
936 
937  return new DeviceMaster<Traits>(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
938 }
939 
941 {
943  .registerDevice("neuronpop", 1)
944  .registerModelType("neuronpop", 1);
945 }
946 
947 } // namespace NeuronPop1
948 } // namespace Device
949 } // namespace Xyce
const InstanceName & getName() const
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
const SolverState & solverState_
Descriptor & addPar(const char *parName, T default_value, T U::*varPtr)
Adds the parameter description to the parameter map.
Definition: N_DEV_Pars.h:1429
std::vector< Instance * > instanceContainer
bool processInstanceParams()
processInstanceParams
Linear::Vector * nextSolVectorPtr
const std::vector< std::vector< int > > & jacobianStamp() const
bool outputPlotFiles(bool force_final_output)
Linear::Vector * daeQVectorPtr
Pure virtual class to augment a linear system.
void varTypes(std::vector< char > &varTypeVec)
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
std::vector< std::string > connectionTargetPopulation
#define AssertLIDs(cmp)
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
bool processParams()
processParams
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
std::vector< std::vector< int > > jacStamp
static void loadModelParameters(ParametricData< Model > &model_parameters)
std::vector< Param > params
Parameters from the line.
RCP< std::ofstream > outputFileStreamPtr
void setParams(const std::vector< Param > &params)
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &Miter, const FactoryBlock &factory_block)
const std::string & getName() const
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
virtual std::ostream & printOutInstances(std::ostream &os) const
const DeviceOptions & deviceOptions_
Linear::Vector * nextStaVectorPtr
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
Linear::Matrix * dFdxMatrixPtr
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
bool getInstanceBreakPoints(std::vector< Util::BreakPoint > &breakPointTimes)
Class Configuration contains device configuration data.
const SolverState & getSolverState() const
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
Linear::Vector * daeFVectorPtr
bool updateTemperature(const double &temp_tmp)
ModelBlock represents a .MODEL line from the netlist.
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
InstanceBlock represent a device instance line from the netlist.
double currTime_
DeviceEntity for expression time, breakpoints DeviceMgr for dependent parameters, breakpoints...
std::vector< Param > params
Linear::Matrix * dQdxMatrixPtr
Linear::Vector * nextStaDerivVectorPtr
void setModParams(const std::vector< Param > &params)