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.53.2.1 $
40 //
41 // Revision Date : $Date: 2015/04/02 18:20:10 $
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  // there is a lot of setup to do, but we don't want to do in the constructor.
160  // so it will be put off until the updateIntermediateVars, or moved into its own function
161 
162  // locate any external target populations passed in on the instance line
163  /*
164  if( connectionTargetPopulation.size() > 0 )
165  {
166  Xyce::dout() << name << " connectionTargetPopulation = { ";
167  for(int i=0; i<connectionTargetPopulation.size(); i++ )
168  {
169  Xyce::dout() << connectionTargetPopulation[i];
170  if( i < (connectionTargetPopulation.size() - 1))
171  {
172  Xyce::dout() << ", ";
173  }
174  }
175  }
176  else
177  {
178  Xyce::dout() << name << " connectionTargetPopulationGiven == false" << std::endl;
179  }
180  */
181 
182  // Set params to constant default values:
183  setDefaultParams ();
184 
185  // Set params according to instance line
186  setParams (IB.params);
187 
188  // Set any non-constant parameter defaults:
189 
190  //if (!given("TEMP"))
191  // temp = getDeviceOptions().temp.dVal();
192 
193  // Calculate any parameters specified as expressions:
195 
196  // calculate dependent (ie computed) params and check for errors:
197  processParams ();
198  /*
199  numIntVars = numIntVarsPerSegment*nSeg;
200  numStateVars = numStateVarsPerSegment*nSeg;
201  */
202  // total up number of vars.
203  int numVars = numExtVars + numIntVars;
204 
205  // need to work out what if-any real jac stap I need here.
206 
207 
208  // set up jacStamp. This is dependant on the membrane model. The only part this
209  // constructor really knows about is the external variables Vin and vOut
210 
211  if( jacStamp.empty() ) // redundant as jacStamp is not static for this device
212  { // it can't be as each cable may have a different number of nodes
213  jacStamp.resize(numVars);
214  jacStamp[0].resize(1);
215  jacStamp[0][0] = 0; // NodeIn
216  jacStamp[1].resize(1);
217  jacStamp[1][0] = 1; // NodeOut
218  }
219 
220  /*
221  // print out jacStamp
222  Xyce::dout() << "jacStamp for NeuronPop1" << std::endl;
223  int numRows = jacStamp.size();
224  for( int i=0; i< numRows; i++ )
225  {
226  int numCol = jacStamp[i].size();
227  Xyce::dout() << "jacStamp[ " << i << " ] = { ";
228  for(int j=0; j<numCol; j++)
229  {
230  Xyce::dout() << jacStamp[i][j] << " ";
231  }
232  Xyce::dout() << " } " << std::endl;
233  }
234  Xyce::dout() << std::endl;
235  */
236  // if the user has requested output of the state variables M, H and R
237  // then open a file for that output.
238  if( model_.outputPopulationVars > 0 )
239  {
241  std::string filename( "NeuronPop_" );
242  filename.append( getName().getEncodedName() );
243  filename.append( ".dat" );
244  // convert any embeded ':' or '%' characters to '_'
245  replace( filename.begin(), filename.end(), '%', '_' );
246  replace( filename.begin(), filename.end(), ':', '_' );
247 
248  outputFileStreamPtr = rcp( new std::ofstream() );
249  outputFileStreamPtr->open( filename.c_str() );
250  if( !(*outputFileStreamPtr) )
251  {
252  UserError(*this) << "Could not open file " << filename << " for output of population variables";
253  }
254  else {
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  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
322  {
323  Xyce::dout() << std::endl << section_divider << std::endl;
324  Xyce::dout() << " Instance::registerLIDs" << std::endl;
325  Xyce::dout() << " name = " << getName() << std::endl;
326  }
327 
328  // copy over the global ID lists.
329  intLIDVec = intLIDVecRef;
330  extLIDVec = extLIDVecRef;
331 
332  liNodeIn = extLIDVec[0];
333  liNodeOut = extLIDVec[1];
334 
335 }
336 
337 //-----------------------------------------------------------------------------
338 // Function : Instance::loadNodeSymbols
339 // Purpose :
340 // Special Notes :
341 // Scope : public
342 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
343 // Creation Date : 05/13/05
344 //-----------------------------------------------------------------------------
345 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
346 {}
347 
348 //-----------------------------------------------------------------------------
349 // Function : Instance::registerStateLIDs
350 // Purpose :
351 // Special Notes :
352 // Scope : public
353 // Creator : Richard Schiek, Electrical and Microsytem Modeling
354 // Creation Date : 06/10/09
355 //-----------------------------------------------------------------------------
356 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
357 {
358  AssertLIDs(staLIDVecRef.size() == numStateVars);
359 
360  // copy over the global ID lists.
361  staLIDVec = staLIDVecRef;
362  // this resize won't be true when we store more data in the state
363  // vector. (i.e. not just voltages, but connectivities firing state)
364  liNeuronPopState.resize( numStateVars );
365  for( int i=0; i<numStateVars; i++ )
366  {
367  liNeuronPopState[i] = staLIDVec[i];
368  }
369 
370 }
371 
372 //-----------------------------------------------------------------------------
373 // Function : Instance::jacobianStamp
374 // Purpose :
375 // Special Notes :
376 // Scope : public
377 // Creator : Richard Schiek, Electrical and Microsytem Modeling
378 // Creation Date : 06/10/09
379 //-----------------------------------------------------------------------------
380 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
381 {
382  return jacStamp;
383 }
384 
385 //-----------------------------------------------------------------------------
386 // Function : Instance::registerJacLIDs
387 // Purpose :
388 // Special Notes :
389 // Scope : public
390 // Creator : Richard Schiek, Electrical and Microsytem Modeling
391 // Creation Date : 06/10/09
392 //-----------------------------------------------------------------------------
393 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
394 {
395  DeviceInstance::registerJacLIDs( jacLIDVec );
396 
397  // resize our storage location and store the results
398 
399  int numRows = jacLIDVec.size();
400 
401  jsOffsetNodeIn = jacLIDVec[0][0];
402  jsOffsetNodeOut = jacLIDVec[1][0];
403 
404 }
405 
406 //-----------------------------------------------------------------------------
407 // Function : Instance::initializePopulation
408 // Purpose : Steps in initializing a population of neurons
409 // Special Notes :
410 // Scope : public
411 // Creator : Richard Schiek, Electrical and Microsytem Modeling
412 // Creation Date : 06/10/09
413 //-----------------------------------------------------------------------------
415 {
416  // population lives in the state vector, so get a reference to that.
417  // note that the state vector is packed in the form of: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn, internal connections, external connections
418  Linear::Vector & staVector = *(extData.nextStaVectorPtr);
419 
420  // seed the random number generator
421  //srandom(unsigned seed)
422  // figure out how many neurons we will start with
423  const double random_max = std::pow(2.0,31)-1; // this may be the same as RAND_MAX but it's not
424  // clear from the man page. Should move random
425  // number generation to the utl package.
426  // try to get a random population from 1..(neuronsMax-1) inclusive of ends
427  neuronPopSize = (rand()/random_max) * model_.neuronsMax + 1;
430 
431  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
432  {
433  Xyce::dout() << "Instance::initializePopulation "
434  << "neuronsMax = " << model_.neuronsMax
435  << " neuronPopSize = " << neuronPopSize
436  << std::endl;
437  }
438 
439  int maxPopSize = model_.neuronsMax;
440  // now initialize the locations
441  for(int i=0; i<maxPopSize; i++)
442  {
443  // zero out voltages
444  staVector[ liNeuronPopState[ i ] ] = 0.0;
445  // randomize x positions
446  staVector[ liNeuronPopState[ model_.neuronsMax + i ] ] = (rand()/random_max);
447  // randomize y positions
448  staVector[ liNeuronPopState[2 * model_.neuronsMax + i ] ] = (rand()/random_max);
449  }
450 
451  // now initialize the internal and external connections
452  for(int i=0; i<maxPopSize; i++)
453  {
454  // randomly connect internal connections
455  int numConnections = (rand()/random_max) * model_.internalMaxConnections;
456  int k = 0;
457  for(; k<numConnections; k++)
458  {
459  int postNeuron = (rand()/random_max) * maxPopSize;
460  staVector[ liNeuronPopState[3 * model_.neuronsMax + i * model_.internalMaxConnections + k] ] = postNeuron;
461  }
462  for(int j=k; j<model_.internalMaxConnections; j++)
463  {
464  staVector[ liNeuronPopState[3 * model_.neuronsMax + i * model_.internalMaxConnections + j] ] = 0.0;
465  }
466 
467  // zero out external connections
468  for(int j=0; j<model_.externalMaxConnections; j++)
469  {
471  }
472  }
473 
474  // now rescale update period and neurogenesis rate in terms of seconds (instead of days)
477 
479  // this flag is to signal to outputPlotFiles() function that the state of the system has
480  // changed and should be output at the next call back
481  newStateToOutput=true;
482  return;
483 }
484 
485 //-----------------------------------------------------------------------------
486 // Function : Instance::updatePopulation
487 // Purpose : Steps in updating a population of neurons
488 // Special Notes :
489 // Scope : public
490 // Creator : Richard Schiek, Electrical and Microsytem Modeling
491 // Creation Date : 03/23/11
492 //-----------------------------------------------------------------------------
494 {
495  // population lives in the state vector, so get a reference to that.
496  // note that the state vector is packed in the form of: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn
497  Linear::Vector & staVector = *(extData.nextStaVectorPtr);
498 
499  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
500  {
501  Xyce::dout() << "Instance::updatePopulation "
502  << "time = " << getSolverState().currTime
503  << std::endl;
504  }
505 
506  double time = getSolverState().currTime;
507 
508  // this check ensures that we've progressed far enough for another neurogenesis event to occur
509  // and we will not exceed the maximum number of neurons allowed
513  {
514  neuronPopSize++;
516 
517  // this flag is to signal to outputPlotFiles() function that the state of the system has
518  // changed and should be output at the next call back
519  newStateToOutput=true;
520  }
521 
524  return;
525 }
526 
527 //-----------------------------------------------------------------------------
528 // Function : Instance::getInstanceBreakPoints
529 // Purpose :
530 // Special Notes :
531 // Scope : public
532 // Creator : Richard Schiek, Electrical Systems Modeling
533 // Creation Date : 03/22/2011
534 //-----------------------------------------------------------------------------
535 bool Instance::getInstanceBreakPoints (std::vector<Util::BreakPoint> &breakPointTimes)
536 {
537  // push on to the vector the next two update times
538  breakPointTimes.push_back((numberOfUpdatesDone+1) * model_.populationUpdatePeriod);
539  breakPointTimes.push_back((numberOfUpdatesDone+2) * model_.populationUpdatePeriod);
540 
541  return true;
542 }
543 
544 
545 //-----------------------------------------------------------------------------
546 // Function : Instance::updateIntermediateVars
547 // Purpose :
548 // Special Notes :
549 // Scope : public
550 // Creator : Richard Schiek, Electrical and Microsytem Modeling
551 // Creation Date : 06/10/09
552 //-----------------------------------------------------------------------------
554 {
555  bool bsuccess = true;
556  if( !populationInitialized )
557  {
559  }
560 
561 
562  double time = getSolverState().currTime;
563 
564  // only do the population updates under the following conditions
565  // 1. when we're at one of the population update times
566  // 2. current time is after the last update time.
567  //
568  // I was going to do this like updateSource() in voltage/current sources, but I can't because
569  // this device isn't derived from that type. This is abit of a hack, but I'll
570  // see if this works for now.
571 
572  // this check ensures that we're at least bpTol past the lastPopulationUpdateTime
573  if( fabs(lastPopulationUpdateTime - time) > getSolverState().bpTol)
574  {
575  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
576  {
577  Xyce::dout() << " Instance::updateIntermediateVars\n";
578  }
579 
580 
581 
582  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
583  {
584  Xyce::dout() << " Time = " << time << std::endl;
585  }
586  // subtract off any delay time
587  // time -= TD;
588 
590  {
591  // repeating signal - figure out where we are in period
592  double basetime = model_.populationUpdatePeriod * floor(time/model_.populationUpdatePeriod);
593  time -= basetime;
594  }
595 
596  // The basetime correction above could take a time right at 2 perionds and make time=0
597  // Thus, we check if time is zero or if it's within bpTol of a period to find out if we
598  // update the population
599 
600  if (fabs(time) < getSolverState().bpTol || (fabs(time - model_.populationUpdatePeriod) < getSolverState().bpTol) )
601  {
602  // we're at a point to update the population
604  }
605  }
606 
607  return bsuccess;
608 }
609 //-----------------------------------------------------------------------------
610 // Function : Instance::updatePrimaryState
611 // Purpose :
612 // Special Notes :
613 // Scope : public
614 // Creator : Richard Schiek, Electrical and Microsytem Modeling
615 // Creation Date : 06/10/09
616 //-----------------------------------------------------------------------------
618 {
619  bool bsuccess = true;
621 
622  return bsuccess;
623 }
624 
625 //-----------------------------------------------------------------------------
626 // Function : Instance::updateSecondaryState
627 // Purpose :
628 // Special Notes :
629 // Scope : public
630 // Creator : Richard Schiek, Electrical and Microsytem Modeling
631 // Creation Date : 06/10/09
632 //-----------------------------------------------------------------------------
634 {
635  bool bsuccess = true;
636 
637  return bsuccess;
638 }
639 
640 //-----------------------------------------------------------------------------
641 // Function : Instance::loadDAEQVector
642 // Purpose :
643 // Special Notes :
644 // Scope : public
645 // Creator : Richard Schiek, Electrical and Microsytem Modeling
646 // Creation Date : 06/10/09
647 //-----------------------------------------------------------------------------
649 {
650  bool bsuccess = true;
651 
652  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
653  Linear::Vector * daeQVecPtr = extData.daeQVectorPtr;
654 
655  // no Q component for the cable component of this devcie
656 
657  return bsuccess;
658 }
659 
660 //-----------------------------------------------------------------------------
661 // Function : Instance::loadDAEFVector
662 // Purpose :
663 // Special Notes :
664 // Scope : public
665 // Creator : Richard Schiek, Electrical and Microsytem Modeling
666 // Creation Date : 06/10/09
667 //-----------------------------------------------------------------------------
669 {
670  bool bsuccess=true;
671 
672  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
673  Linear::Vector * daeFVecPtr = extData.daeFVectorPtr;
674 
675  // take care of the input and output nodes as they are different
676  (*daeFVecPtr)[liNodeIn] += 0.0;
677  (*daeFVecPtr)[liNodeOut] += 0.0;
678 
679  return bsuccess;
680 }
681 
682 //-----------------------------------------------------------------------------
683 // Function : Instance::loadDAEdQdx
684 // Purpose :
685 // Special Notes :
686 // Scope : public
687 // Creator : Richard Schiek, Electrical and Microsytem Modeling
688 // Creation Date : 06/10/09
689 //-----------------------------------------------------------------------------
691 {
692  bool bsuccess = true;
693 
694  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
695  Linear::Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
696 
697 
698  return bsuccess;
699 }
700 
701 //-----------------------------------------------------------------------------
702 // Function : Instance::loadDAEdFdx ()
703 // Purpose :
704 // Special Notes :
705 // Scope : public
706 // Creator : Richard Schiek, Electrical and Microsytem Modeling
707 // Creation Date : 06/10/09
708 //-----------------------------------------------------------------------------
710 {
711  bool bsuccess = true;
712 
713  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
714  Linear::Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
715 
716  (*dFdxMatPtr)[liNodeIn][jsOffsetNodeIn] += 1.0;
717  (*dFdxMatPtr)[liNodeOut][jsOffsetNodeOut] += 1.0;
718 
719  return bsuccess;
720 }
721 
722 //-----------------------------------------------------------------------------
723 // Function : Instance::outputPlotFiles
724 // Purpose : If requested by the user output all the variables
725 // associated with the population
726 // Special Notes :
727 // Scope : public
728 // Creator : Rich Schiek, SNL, Parallel Computational Sciences
729 // Creation Date : 03/10/2011
730 //-----------------------------------------------------------------------------
732 {
733 
734  bool bsuccess = true;
735 
736  // only output when the population has changed to avoid lots of duplicate output
737  // the newStateToOutput flag is set in initializePopulation() and updatePopulation()
738  if( outputPopulationVarsFlag && newStateToOutput && outputFileStreamPtr.get() && (*outputFileStreamPtr) )
739  {
740  // population lives in the state vector, so get a reference to that.
741  // note that the state vector is packed in the form of: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn
742  Linear::Vector & solVector = *(extData.nextSolVectorPtr);
743  Linear::Vector & staVector = *(extData.nextStaVectorPtr);
744  Linear::Vector & staDerivVec = *(extData.nextStaDerivVectorPtr);
745 
746  // output format is
747  // time, population_size, x1, ..., xn, y1, ..., yn, v1, ..., vn
748  //
749  (*outputFileStreamPtr)
750  << getSolverState().currTime << ", "
751  << neuronPopSize << ", ";
752 
753  // the state vector is packed in the order
754  for( int i=0; i < neuronPopSize; i++)
755  {
756  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ model_.neuronsMax + i]] << ", ";
757  }
758 
759  for( int i=0; i < neuronPopSize; i++)
760  {
761  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ 2*model_.neuronsMax + i]] << ", ";
762  }
763 
764  for( int i=0; i < neuronPopSize; i++)
765  {
766  (*outputFileStreamPtr) << staVector[ liNeuronPopState[i] ] << ", ";
767  }
768 
769  for( int i=0; i < neuronPopSize; i++)
770  {
771  for( int j=0; j < model_.internalMaxConnections; j++)
772  {
773  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ 3*model_.neuronsMax + i*model_.internalMaxConnections + j]] << ", ";
774  }
775  }
776 
777  for( int i=0; i < neuronPopSize; i++)
778  {
779  for( int j=0; j < model_.externalMaxConnections; j++)
780  {
781  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ (3 + model_.internalMaxConnections)*model_.neuronsMax + i*model_.externalMaxConnections + j]];
782  if( (i != (neuronPopSize-1)) || (j != (model_.externalMaxConnections-1)) )
783  {
784  (*outputFileStreamPtr) << ", ";
785  }
786  }
787  }
788  (*outputFileStreamPtr) << std::endl;
789 
790  // we've output this state, so reset flag
791  newStateToOutput=false;
792 
793  }
794  return bsuccess;
795 }
796 
797 //-----------------------------------------------------------------------------
798 // Function : Instance::setIC
799 // Purpose :
800 // Special Notes :
801 // Scope : public
802 // Creator : Richard Schiek, Electrical and Microsytem Modeling
803 // Creation Date : 06/10/09
804 //-----------------------------------------------------------------------------
806 {
807  bool bsuccess = true;
808 
809  return bsuccess;
810 }
811 
812 //-----------------------------------------------------------------------------
813 // Function : Instance::varTypes
814 // Purpose :
815 // Special Notes :
816 // Scope : public
817 // Creator : Richard Schiek, Electrical and Microsytem Modeling
818 // Creation Date : 06/10/09
819 //-----------------------------------------------------------------------------
820 void Instance::varTypes( std::vector<char> & varTypeVec )
821 {
822  //varTypeVec.resize(1);
823  //varTypeVec[0] = 'I';
824 }
825 
826 
827 //-----------------------------------------------------------------------------
828 // Function : Model::Model
829 // Purpose : block constructor
830 // Special Notes :
831 // Scope : public
832 // Creator : Richard Schiek, Electrical and Microsytem Modeling
833 // Creation Date : 06/10/09
834 //-----------------------------------------------------------------------------
836  const Configuration & configuration,
837  const ModelBlock & MB,
838  const FactoryBlock & factory_block)
839  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
840  neuronsMax(0),
841  neuronsMaxGiven(false),
842  internalMaxConnections(0),
843  internalMaxConnectionsGiven(false),
844  externalMaxConnections(0),
845  externalMaxConnectionsGiven(false),
846  populationNeurogenesisRate(0.0),
847  populationNeurogenesisRateGiven(false),
848  populationUpdatePeriod(0.0),
849  populationUpdatePeriodGiven(false),
850  outputPopulationVars(0)
851 {
852 
853  // Set params to constant default values:
854  setDefaultParams ();
855 
856  // Set params according to .model line and constant defaults from metadata:
857  setModParams (MB.params);
858 
859  // Set any non-constant parameter defaults:
860  //if (!given("TNOM"))
861  // tnom = getDeviceOptions().tnom;
862 
863  // Calculate any parameters specified as expressions:
865 
866  // calculate dependent (ie computed) params and check for errors:
867 
868  processParams ();
869 
870 }
871 
872 
873 //-----------------------------------------------------------------------------
874 // Function : Model::~Model
875 // Purpose : destructor
876 // Special Notes :
877 // Scope : public
878 // Creator : Richard Schiek, Electrical and Microsytem Modeling
879 // Creation Date : 06/10/09
880 //-----------------------------------------------------------------------------
882 {
883  std::vector<Instance*>::iterator iter;
884  std::vector<Instance*>::iterator first = instanceContainer.begin();
885  std::vector<Instance*>::iterator last = instanceContainer.end();
886 
887  for (iter=first; iter!=last; ++iter)
888  {
889  delete (*iter);
890  }
891 
892 }
893 
894 // additional Declarations
895 //-----------------------------------------------------------------------------
896 // Function : Model::processParams
897 // Purpose :
898 // Special Notes :
899 // Scope : public
900 // Creator : Richard Schiek, Electrical and Microsytem Modeling
901 // Creation Date : 06/10/09
902 //-----------------------------------------------------------------------------
904 {
905  return true;
906 }
907 
908 //----------------------------------------------------------------------------
909 // Function : Model::processInstanceParams
910 // Purpose :
911 // Special Notes :
912 // Scope : public
913 // Creator : Richard Schiek, Electrical and Microsytem Modeling
914 // Creation Date : 06/10/09
915 //----------------------------------------------------------------------------
917 {
918 
919  std::vector<Instance*>::iterator iter;
920  std::vector<Instance*>::iterator first = instanceContainer.begin();
921  std::vector<Instance*>::iterator last = instanceContainer.end();
922 
923  for (iter=first; iter!=last; ++iter)
924  {
925  (*iter)->processParams();
926  }
927 
928  return true;
929 }
930 //-----------------------------------------------------------------------------
931 // Function : Model::printOutInstances
932 // Purpose : debugging tool.
933 // Special Notes :
934 // Scope : public
935 // Creator : Richard Schiek, Electrical and Microsytem Modeling
936 // Creation Date : 06/10/09
937 //-----------------------------------------------------------------------------
938 std::ostream &Model::printOutInstances(std::ostream &os) const
939 {
940  std::vector<Instance*>::const_iterator iter;
941  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
942  std::vector<Instance*>::const_iterator last = instanceContainer.end();
943 
944  int i, isize;
945  isize = instanceContainer.size();
946 
947  os << std::endl;
948  os << "Number of Neuron instances: " << isize << std::endl;
949  os << " name=\t\tmodelName\tParameters" << std::endl;
950  for (i=0, iter=first; iter!=last; ++iter, ++i)
951  {
952  os << " " << i << ": " << (*iter)->getName() << "\t";
953  os << getName();
954  os << std::endl;
955  }
956 
957  os << std::endl;
958  return os;
959 }
960 
961 //-----------------------------------------------------------------------------
962 // Function : Model::forEachInstance
963 // Purpose :
964 // Special Notes :
965 // Scope : public
966 // Creator : David Baur
967 // Creation Date : 2/4/2014
968 //-----------------------------------------------------------------------------
969 /// Apply a device instance "op" to all instances associated with this
970 /// model
971 ///
972 /// @param[in] op Operator to apply to all instances.
973 ///
974 ///
975 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
976 {
977  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
978  op(*it);
979 }
980 
981 
982 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
983 {
984 
985  return new DeviceMaster<Traits>(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
986 }
987 
989 {
991  .registerDevice("neuronpop", 1)
992  .registerModelType("neuronpop", 1);
993 }
994 
995 } // namespace NeuronPop1
996 } // namespace Device
997 } // 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
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.
std::vector< Param > params
Linear::Matrix * dQdxMatrixPtr
Linear::Vector * nextStaDerivVectorPtr
void setModParams(const std::vector< Param > &params)