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.44 $
40 //
41 // Revision Date : $Date: 2014/05/19 15:49:14 $
42 //
43 // Current Owner : $Author: dgbaur $
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().getEncodedName() );
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  UserError(*this) << "Could not open file " << filename << " for output of population variables";
252  }
253  else {
254  (*outputFileStreamPtr).setf(std::ios::scientific, std::ios::floatfield );
255  (*outputFileStreamPtr).width(20);
256  (*outputFileStreamPtr).precision(12);
257  }
258  }
259 }
260 
261 //-----------------------------------------------------------------------------
262 // Function : Instance::~Instance
263 // Purpose : destructor
264 // Special Notes :
265 // Scope : public
266 // Creator : Richard Schiek, Electrical and Microsytem Modeling
267 // Creation Date : 06/10/09
268 //-----------------------------------------------------------------------------
270 {
271 }
272 
273 //-----------------------------------------------------------------------------
274 // Function : Instance::processParams
275 // Purpose :
276 // Special Notes :
277 // Scope : public
278 // Creator : Richard Schiek, Electrical and Microsytem Modeling
279 // Creation Date : 06/10/09
280 //-----------------------------------------------------------------------------
282 {
283  // If there are any time dependent parameters, set their values at for
284  // the current time.
285 
286  // now set the temperature related stuff.
287  //updateTemperature(temp);
288 
289  return true;
290 }
291 
292 //-----------------------------------------------------------------------------
293 // Function : Instance::updateTemperature
294 // Purpose :
295 // Special Notes :
296 // Scope : public
297 // Creator : Richard Schiek, Electrical and Microsytem Modeling
298 // Creation Date : 06/10/09
299 //-----------------------------------------------------------------------------
300 bool Instance::updateTemperature ( const double & temp)
301 {
302  bool bsuccess = true;
303  return bsuccess;
304 }
305 
306 //-----------------------------------------------------------------------------
307 // Function : Instance::registerLIDs
308 // Purpose :
309 // Special Notes :
310 // Scope : public
311 // Creator : Richard Schiek, Electrical and Microsytem Modeling
312 // Creation Date : 06/10/09
313 //-----------------------------------------------------------------------------
314 void Instance::registerLIDs(const std::vector<int> & intLIDVecRef,
315  const std::vector<int> & extLIDVecRef)
316 {
317  AssertLIDs(intLIDVecRef.size() == numIntVars);
318  AssertLIDs(extLIDVecRef.size() == numExtVars);
319 
320 #ifdef Xyce_DEBUG_DEVICE
321  if (getDeviceOptions().debugLevel > 0)
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 #endif
328 
329  // copy over the global ID lists.
330  intLIDVec = intLIDVecRef;
331  extLIDVec = extLIDVecRef;
332 
333  liNodeIn = extLIDVec[0];
334  liNodeOut = extLIDVec[1];
335 
336 }
337 
338 //-----------------------------------------------------------------------------
339 // Function : Instance::getIntNameMap
340 // Purpose :
341 // Special Notes :
342 // Scope : public
343 // Creator : Richard Schiek, Electrical and Microsytem Modeling
344 // Creation Date : 06/10/09
345 //-----------------------------------------------------------------------------
346 std::map<int,std::string> & Instance::getIntNameMap ()
347 {
348 #if 0
349  // set up the internal name map, if it hasn't been already.
350  if (intNameMap.empty ())
351  {
352  std::ostringstream segNumber;
353  segNumber << i;
354  intNameMap[ li_internalVars[i*numIntVarsPerSegment] ] = spiceInternalName(getName(), "V" + segNumber.str());
355  }
356 #endif
357 
358  return intNameMap;
359 }
360 
361 //-----------------------------------------------------------------------------
362 // Function : Instance::registerStateLIDs
363 // Purpose :
364 // Special Notes :
365 // Scope : public
366 // Creator : Richard Schiek, Electrical and Microsytem Modeling
367 // Creation Date : 06/10/09
368 //-----------------------------------------------------------------------------
369 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
370 {
371  AssertLIDs(staLIDVecRef.size() == numStateVars);
372 
373  // copy over the global ID lists.
374  staLIDVec = staLIDVecRef;
375  // this resize won't be true when we store more data in the state
376  // vector. (i.e. not just voltages, but connectivities firing state)
377  liNeuronPopState.resize( numStateVars );
378  for( int i=0; i<numStateVars; i++ )
379  {
380  liNeuronPopState[i] = staLIDVec[i];
381  }
382 
383 }
384 
385 //-----------------------------------------------------------------------------
386 // Function : Instance::loadDeviceMask
387 //
388 // Purpose : Loads the zero elements of the device mask
389 //
390 // Special Notes : elements of the error vector associated with zero
391 // elements of the mask will not be included in weighted
392 // norms by the time integrator.
393 //
394 // Scope : public
395 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
396 // Creation Date : 06/10/09
397 //-----------------------------------------------------------------------------
399 {
400  bool returnVal=false;
401  N_LAS_Vector * maskVectorPtr = extData.deviceMaskVectorPtr;
402 
403  return (returnVal);
404 }
405 
406 //-----------------------------------------------------------------------------
407 // Function : Instance::jacobianStamp
408 // Purpose :
409 // Special Notes :
410 // Scope : public
411 // Creator : Richard Schiek, Electrical and Microsytem Modeling
412 // Creation Date : 06/10/09
413 //-----------------------------------------------------------------------------
414 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
415 {
416  return jacStamp;
417 }
418 
419 //-----------------------------------------------------------------------------
420 // Function : Instance::registerJacLIDs
421 // Purpose :
422 // Special Notes :
423 // Scope : public
424 // Creator : Richard Schiek, Electrical and Microsytem Modeling
425 // Creation Date : 06/10/09
426 //-----------------------------------------------------------------------------
427 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
428 {
429  DeviceInstance::registerJacLIDs( jacLIDVec );
430 
431  // resize our storage location and store the results
432 
433  int numRows = jacLIDVec.size();
434 
435  jsOffsetNodeIn = jacLIDVec[0][0];
436  jsOffsetNodeOut = jacLIDVec[1][0];
437 
438 }
439 
440 //-----------------------------------------------------------------------------
441 // Function : Instance::initializePopulation
442 // Purpose : Steps in initializing a population of neurons
443 // Special Notes :
444 // Scope : public
445 // Creator : Richard Schiek, Electrical and Microsytem Modeling
446 // Creation Date : 06/10/09
447 //-----------------------------------------------------------------------------
449 {
450  // population lives in the state vector, so get a reference to that.
451  // note that the state vector is packed in the form of: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn, internal connections, external connections
452  N_LAS_Vector & staVector = *(extData.nextStaVectorPtr);
453 
454  // seed the random number generator
455  //srandom(unsigned seed)
456  // figure out how many neurons we will start with
457  const double random_max = std::pow(2.0,31)-1; // this may be the same as RAND_MAX but it's not
458  // clear from the man page. Should move random
459  // number generation to the utl package.
460  // try to get a random population from 1..(neuronsMax-1) inclusive of ends
461  neuronPopSize = (rand()/random_max) * model_.neuronsMax + 1;
464 
465 #ifdef Xyce_DEBUG_DEVICE
467  {
468  Xyce::dout() << "Instance::initializePopulation "
469  << "neuronsMax = " << model_.neuronsMax
470  << " neuronPopSize = " << neuronPopSize
471  << std::endl;
472  }
473 #endif
474 
475  int maxPopSize = model_.neuronsMax;
476  // now initialize the locations
477  for(int i=0; i<maxPopSize; i++)
478  {
479  // zero out voltages
480  staVector[ liNeuronPopState[ i ] ] = 0.0;
481  // randomize x positions
482  staVector[ liNeuronPopState[ model_.neuronsMax + i ] ] = (rand()/random_max);
483  // randomize y positions
484  staVector[ liNeuronPopState[2 * model_.neuronsMax + i ] ] = (rand()/random_max);
485  }
486 
487  // now initialize the internal and external connections
488  for(int i=0; i<maxPopSize; i++)
489  {
490  // randomly connect internal connections
491  int numConnections = (rand()/random_max) * model_.internalMaxConnections;
492  int k = 0;
493  for(; k<numConnections; k++)
494  {
495  int postNeuron = (rand()/random_max) * maxPopSize;
496  staVector[ liNeuronPopState[3 * model_.neuronsMax + i * model_.internalMaxConnections + k] ] = postNeuron;
497  }
498  for(int j=k; j<model_.internalMaxConnections; j++)
499  {
500  staVector[ liNeuronPopState[3 * model_.neuronsMax + i * model_.internalMaxConnections + j] ] = 0.0;
501  }
502 
503  // zero out external connections
504  for(int j=0; j<model_.externalMaxConnections; j++)
505  {
507  }
508  }
509 
510  // now rescale update period and neurogenesis rate in terms of seconds (instead of days)
513 
515  // this flag is to signal to outputPlotFiles() function that the state of the system has
516  // changed and should be output at the next call back
517  newStateToOutput=true;
518  return;
519 }
520 
521 //-----------------------------------------------------------------------------
522 // Function : Instance::updatePopulation
523 // Purpose : Steps in updating a population of neurons
524 // Special Notes :
525 // Scope : public
526 // Creator : Richard Schiek, Electrical and Microsytem Modeling
527 // Creation Date : 03/23/11
528 //-----------------------------------------------------------------------------
530 {
531  // population lives in the state vector, so get a reference to that.
532  // note that the state vector is packed in the form of: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn
533  N_LAS_Vector & staVector = *(extData.nextStaVectorPtr);
534 
535 #ifdef Xyce_DEBUG_DEVICE
537  {
538  Xyce::dout() << "Instance::updatePopulation "
539  << "time = " << getSolverState().currTime
540  << std::endl;
541  }
542 #endif
543 
544  double time = getSolverState().currTime;
545 
546  // this check ensures that we've progressed far enough for another neurogenesis event to occur
547  // and we will not exceed the maximum number of neurons allowed
551  {
552  neuronPopSize++;
554 
555  // this flag is to signal to outputPlotFiles() function that the state of the system has
556  // changed and should be output at the next call back
557  newStateToOutput=true;
558  }
559 
562  return;
563 }
564 
565 //-----------------------------------------------------------------------------
566 // Function : Instance::getInstanceBreakPoints
567 // Purpose :
568 // Special Notes :
569 // Scope : public
570 // Creator : Richard Schiek, Electrical Systems Modeling
571 // Creation Date : 03/22/2011
572 //-----------------------------------------------------------------------------
573 bool Instance::getInstanceBreakPoints (std::vector<N_UTL_BreakPoint> &breakPointTimes)
574 {
575  // push on to the vector the next two update times
576  breakPointTimes.push_back((numberOfUpdatesDone+1) * model_.populationUpdatePeriod);
577  breakPointTimes.push_back((numberOfUpdatesDone+2) * model_.populationUpdatePeriod);
578 
579  return true;
580 }
581 
582 
583 //-----------------------------------------------------------------------------
584 // Function : Instance::updateIntermediateVars
585 // Purpose :
586 // Special Notes :
587 // Scope : public
588 // Creator : Richard Schiek, Electrical and Microsytem Modeling
589 // Creation Date : 06/10/09
590 //-----------------------------------------------------------------------------
592 {
593  bool bsuccess = true;
594  if( !populationInitialized )
595  {
597  }
598 
599 
600  double time = getSolverState().currTime;
601 
602  // only do the population updates under the following conditions
603  // 1. when we're at one of the population update times
604  // 2. current time is after the last update time.
605  //
606  // I was going to do this like updateSource() in voltage/current sources, but I can't because
607  // this device isn't derived from that type. This is abit of a hack, but I'll
608  // see if this works for now.
609 
610  // this check ensures that we're at least bpTol past the lastPopulationUpdateTime
611  if( fabs(lastPopulationUpdateTime - time) > getSolverState().bpTol)
612  {
613 #ifdef Xyce_DEBUG_DEVICE
614  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
615  {
616  Xyce::dout() << " Instance::updateIntermediateVars\n";
617  }
618 #endif
619 
620 
621 
622 #ifdef Xyce_DEBUG_DEVICE
623  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
624  {
625  Xyce::dout() << " Time = " << time << std::endl;
626  }
627 #endif
628  // subtract off any delay time
629  // time -= TD;
630 
632  {
633  // repeating signal - figure out where we are in period
634  double basetime = model_.populationUpdatePeriod * floor(time/model_.populationUpdatePeriod);
635  time -= basetime;
636  }
637 
638  // The basetime correction above could take a time right at 2 perionds and make time=0
639  // Thus, we check if time is zero or if it's within bpTol of a period to find out if we
640  // update the population
641 
642  if (fabs(time) < getSolverState().bpTol || (fabs(time - model_.populationUpdatePeriod) < getSolverState().bpTol) )
643  {
644  // we're at a point to update the population
646  }
647  }
648 
649  return bsuccess;
650 }
651 //-----------------------------------------------------------------------------
652 // Function : Instance::updatePrimaryState
653 // Purpose :
654 // Special Notes :
655 // Scope : public
656 // Creator : Richard Schiek, Electrical and Microsytem Modeling
657 // Creation Date : 06/10/09
658 //-----------------------------------------------------------------------------
660 {
661  bool bsuccess = true;
663 
664  return bsuccess;
665 }
666 
667 //-----------------------------------------------------------------------------
668 // Function : Instance::updateSecondaryState
669 // Purpose :
670 // Special Notes :
671 // Scope : public
672 // Creator : Richard Schiek, Electrical and Microsytem Modeling
673 // Creation Date : 06/10/09
674 //-----------------------------------------------------------------------------
676 {
677  bool bsuccess = true;
678 
679  return bsuccess;
680 }
681 
682 //-----------------------------------------------------------------------------
683 // Function : Instance::loadDAEQVector
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  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
695  N_LAS_Vector * daeQVecPtr = extData.daeQVectorPtr;
696 
697  // no Q component for the cable component of this devcie
698 
699  return bsuccess;
700 }
701 
702 //-----------------------------------------------------------------------------
703 // Function : Instance::loadDAEFVector
704 // Purpose :
705 // Special Notes :
706 // Scope : public
707 // Creator : Richard Schiek, Electrical and Microsytem Modeling
708 // Creation Date : 06/10/09
709 //-----------------------------------------------------------------------------
711 {
712  bool bsuccess=true;
713 
714  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
715  N_LAS_Vector * daeFVecPtr = extData.daeFVectorPtr;
716 
717  // take care of the input and output nodes as they are different
718  (*daeFVecPtr)[liNodeIn] += 0.0;
719  (*daeFVecPtr)[liNodeOut] += 0.0;
720 
721  return bsuccess;
722 }
723 
724 //-----------------------------------------------------------------------------
725 // Function : Instance::loadDAEdQdx
726 // Purpose :
727 // Special Notes :
728 // Scope : public
729 // Creator : Richard Schiek, Electrical and Microsytem Modeling
730 // Creation Date : 06/10/09
731 //-----------------------------------------------------------------------------
733 {
734  bool bsuccess = true;
735 
736  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
737  N_LAS_Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
738 
739 
740  return bsuccess;
741 }
742 
743 //-----------------------------------------------------------------------------
744 // Function : Instance::loadDAEdFdx ()
745 // Purpose :
746 // Special Notes :
747 // Scope : public
748 // Creator : Richard Schiek, Electrical and Microsytem Modeling
749 // Creation Date : 06/10/09
750 //-----------------------------------------------------------------------------
752 {
753  bool bsuccess = true;
754 
755  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
756  N_LAS_Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
757 
758  (*dFdxMatPtr)[liNodeIn][jsOffsetNodeIn] += 1.0;
759  (*dFdxMatPtr)[liNodeOut][jsOffsetNodeOut] += 1.0;
760 
761  return bsuccess;
762 }
763 
764 //-----------------------------------------------------------------------------
765 // Function : Instance::outputPlotFiles
766 // Purpose : If requested by the user output all the variables
767 // associated with the population
768 // Special Notes :
769 // Scope : public
770 // Creator : Rich Schiek, SNL, Parallel Computational Sciences
771 // Creation Date : 03/10/2011
772 //-----------------------------------------------------------------------------
774 {
775 
776  bool bsuccess = true;
777 
778  // only output when the population has changed to avoid lots of duplicate output
779  // the newStateToOutput flag is set in initializePopulation() and updatePopulation()
780  if( outputPopulationVarsFlag && newStateToOutput && outputFileStreamPtr.get() && (*outputFileStreamPtr) )
781  {
782  // population lives in the state vector, so get a reference to that.
783  // note that the state vector is packed in the form of: V1, V2, ..., Vn, X1, X2, ..., Xn, Y1, ..., Yn
784  N_LAS_Vector & solVector = *(extData.nextSolVectorPtr);
785  N_LAS_Vector & staVector = *(extData.nextStaVectorPtr);
786  N_LAS_Vector & staDerivVec = *(extData.nextStaDerivVectorPtr);
787 
788  // output format is
789  // time, population_size, x1, ..., xn, y1, ..., yn, v1, ..., vn
790  //
791  (*outputFileStreamPtr)
792  << getSolverState().currTime << ", "
793  << neuronPopSize << ", ";
794 
795  // the state vector is packed in the order
796  for( int i=0; i < neuronPopSize; i++)
797  {
798  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ model_.neuronsMax + i]] << ", ";
799  }
800 
801  for( int i=0; i < neuronPopSize; i++)
802  {
803  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ 2*model_.neuronsMax + i]] << ", ";
804  }
805 
806  for( int i=0; i < neuronPopSize; i++)
807  {
808  (*outputFileStreamPtr) << staVector[ liNeuronPopState[i] ] << ", ";
809  }
810 
811  for( int i=0; i < neuronPopSize; i++)
812  {
813  for( int j=0; j < model_.internalMaxConnections; j++)
814  {
815  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ 3*model_.neuronsMax + i*model_.internalMaxConnections + j]] << ", ";
816  }
817  }
818 
819  for( int i=0; i < neuronPopSize; i++)
820  {
821  for( int j=0; j < model_.externalMaxConnections; j++)
822  {
823  (*outputFileStreamPtr) << staVector[ liNeuronPopState[ (3 + model_.internalMaxConnections)*model_.neuronsMax + i*model_.externalMaxConnections + j]];
824  if( (i != (neuronPopSize-1)) || (j != (model_.externalMaxConnections-1)) )
825  {
826  (*outputFileStreamPtr) << ", ";
827  }
828  }
829  }
830  (*outputFileStreamPtr) << std::endl;
831 
832  // we've output this state, so reset flag
833  newStateToOutput=false;
834 
835  }
836  return bsuccess;
837 }
838 
839 //-----------------------------------------------------------------------------
840 // Function : Instance::setIC
841 // Purpose :
842 // Special Notes :
843 // Scope : public
844 // Creator : Richard Schiek, Electrical and Microsytem Modeling
845 // Creation Date : 06/10/09
846 //-----------------------------------------------------------------------------
848 {
849  bool bsuccess = true;
850 
851  return bsuccess;
852 }
853 
854 //-----------------------------------------------------------------------------
855 // Function : Instance::varTypes
856 // Purpose :
857 // Special Notes :
858 // Scope : public
859 // Creator : Richard Schiek, Electrical and Microsytem Modeling
860 // Creation Date : 06/10/09
861 //-----------------------------------------------------------------------------
862 void Instance::varTypes( std::vector<char> & varTypeVec )
863 {
864  //varTypeVec.resize(1);
865  //varTypeVec[0] = 'I';
866 }
867 
868 
869 //-----------------------------------------------------------------------------
870 // Function : Model::Model
871 // Purpose : block constructor
872 // Special Notes :
873 // Scope : public
874 // Creator : Richard Schiek, Electrical and Microsytem Modeling
875 // Creation Date : 06/10/09
876 //-----------------------------------------------------------------------------
878  const Configuration & configuration,
879  const ModelBlock & MB,
880  const FactoryBlock & factory_block)
881  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
882  neuronsMax(0),
883  neuronsMaxGiven(false),
884  internalMaxConnections(0),
885  internalMaxConnectionsGiven(false),
886  externalMaxConnections(0),
887  externalMaxConnectionsGiven(false),
888  populationNeurogenesisRate(0.0),
889  populationNeurogenesisRateGiven(false),
890  populationUpdatePeriod(0.0),
891  populationUpdatePeriodGiven(false),
892  outputPopulationVars(0)
893 {
894 
895  // Set params to constant default values:
896  setDefaultParams ();
897 
898  // Set params according to .model line and constant defaults from metadata:
899  setModParams (MB.params);
900 
901  // Set any non-constant parameter defaults:
902  //if (!given("TNOM"))
903  // tnom = getDeviceOptions().tnom;
904 
905  // Calculate any parameters specified as expressions:
907 
908  // calculate dependent (ie computed) params and check for errors:
909 
910  processParams ();
911 
912 }
913 
914 
915 //-----------------------------------------------------------------------------
916 // Function : Model::~Model
917 // Purpose : destructor
918 // Special Notes :
919 // Scope : public
920 // Creator : Richard Schiek, Electrical and Microsytem Modeling
921 // Creation Date : 06/10/09
922 //-----------------------------------------------------------------------------
924 {
925  std::vector<Instance*>::iterator iter;
926  std::vector<Instance*>::iterator first = instanceContainer.begin();
927  std::vector<Instance*>::iterator last = instanceContainer.end();
928 
929  for (iter=first; iter!=last; ++iter)
930  {
931  delete (*iter);
932  }
933 
934 }
935 
936 // additional Declarations
937 //-----------------------------------------------------------------------------
938 // Function : Model::processParams
939 // Purpose :
940 // Special Notes :
941 // Scope : public
942 // Creator : Richard Schiek, Electrical and Microsytem Modeling
943 // Creation Date : 06/10/09
944 //-----------------------------------------------------------------------------
946 {
947  return true;
948 }
949 
950 //----------------------------------------------------------------------------
951 // Function : Model::processInstanceParams
952 // Purpose :
953 // Special Notes :
954 // Scope : public
955 // Creator : Richard Schiek, Electrical and Microsytem Modeling
956 // Creation Date : 06/10/09
957 //----------------------------------------------------------------------------
959 {
960 
961  std::vector<Instance*>::iterator iter;
962  std::vector<Instance*>::iterator first = instanceContainer.begin();
963  std::vector<Instance*>::iterator last = instanceContainer.end();
964 
965  for (iter=first; iter!=last; ++iter)
966  {
967  (*iter)->processParams();
968  }
969 
970  return true;
971 }
972 //-----------------------------------------------------------------------------
973 // Function : Model::printOutInstances
974 // Purpose : debugging tool.
975 // Special Notes :
976 // Scope : public
977 // Creator : Richard Schiek, Electrical and Microsytem Modeling
978 // Creation Date : 06/10/09
979 //-----------------------------------------------------------------------------
980 std::ostream &Model::printOutInstances(std::ostream &os) const
981 {
982  std::vector<Instance*>::const_iterator iter;
983  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
984  std::vector<Instance*>::const_iterator last = instanceContainer.end();
985 
986  int i, isize;
987  isize = instanceContainer.size();
988 
989  os << std::endl;
990  os << "Number of Neuron instances: " << isize << std::endl;
991  os << " name=\t\tmodelName\tParameters" << std::endl;
992  for (i=0, iter=first; iter!=last; ++iter, ++i)
993  {
994  os << " " << i << ": " << (*iter)->getName() << "\t";
995  os << getName();
996  os << std::endl;
997  }
998 
999  os << std::endl;
1000  return os;
1001 }
1002 
1003 //-----------------------------------------------------------------------------
1004 // Function : Model::forEachInstance
1005 // Purpose :
1006 // Special Notes :
1007 // Scope : public
1008 // Creator : David Baur
1009 // Creation Date : 2/4/2014
1010 //-----------------------------------------------------------------------------
1011 /// Apply a device instance "op" to all instances associated with this
1012 /// model
1013 ///
1014 /// @param[in] op Operator to apply to all instances.
1015 ///
1016 ///
1017 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1018 {
1019  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1020  op(*it);
1021 }
1022 
1023 
1024 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1025 {
1026 
1027  return new DeviceMaster<Traits>(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1028 }
1029 
1031 {
1033  .registerDevice("neuronpop", 1)
1034  .registerModelType("neuronpop", 1);
1035 }
1036 
1037 } // namespace NeuronPop1
1038 } // namespace Device
1039 } // namespace Xyce