MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SpineMesh.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 ** This program is part of 'MOOSE', the
3 ** Messaging Object Oriented Simulation Environment.
4 ** Copyright (C) 2013 Upinder S. Bhalla. and NCBS
5 ** It is made available under the terms of the
6 ** GNU Lesser General Public License version 2.1
7 ** See the file COPYING.LIB for the full notice.
8 **********************************************************************/
9 
10 #include <cctype>
11 #include "header.h"
12 #include "SparseMatrix.h"
13 #include "../utility/Vec.h"
14 
15 #include "ElementValueFinfo.h"
16 #include "Boundary.h"
17 #include "MeshEntry.h"
18 #include "ChemCompt.h"
19 #include "MeshCompt.h"
20 #include "CubeMesh.h"
21 #include "CylBase.h"
22 #include "NeuroNode.h"
23 #include "NeuroMesh.h"
24 #include "SpineEntry.h"
25 #include "SpineMesh.h"
26 #include "PsdMesh.h"
27 #include "../utility/numutil.h"
28 
29 /*
30 static SrcFinfo3< Id, vector< double >, vector< unsigned int > >*
31  psdListOut()
32 {
33  static SrcFinfo3< Id, vector< double >, vector< unsigned int > >
34  psdListOut(
35  "psdListOut",
36  "Tells PsdMesh to build a mesh. "
37  "Arguments: Coordinates of each psd, "
38  "index of matching parent voxels for each spine"
39  "The coordinates each have 8 entries:"
40  "xyz of centre of psd, xyz of vector perpendicular to psd, "
41  "psd diameter, "
42  " diffusion distance from parent compartment to PSD"
43  );
44  return &psdListOut;
45 }
46 */
47 
49 {
51  // Field Definitions
54  parentVoxel
55  (
56  "parentVoxel",
57  "Vector of indices of proximal voxels within this mesh."
58  "Spines are at present modeled with just one compartment,"
59  "so each entry in this vector is always set to EMPTY == -1U",
61  );
62 
64  neuronVoxel
65  (
66  "neuronVoxel",
67  "Vector of indices of voxels on parent NeuroMesh, from which "
68  "the respective spines emerge.",
70  );
71 
72  static ReadOnlyValueFinfo< SpineMesh, vector< Id > > elecComptMap(
73  "elecComptMap",
74  "Vector of Ids of electrical compartments that map to each "
75  "voxel. This is necessary because the order of the IDs may "
76  "differ from the ordering of the voxels. Note that there "
77  "is always just one voxel per spine head. ",
79  );
80  static ReadOnlyValueFinfo< SpineMesh, vector< Id > > elecComptList(
81  "elecComptList",
82  "Vector of Ids of all electrical compartments in this "
83  "SpineMesh. Ordering is as per the tree structure built in "
84  "the NeuroMesh, and may differ from Id order. Ordering "
85  "matches that used for startVoxelInCompt and endVoxelInCompt",
87  );
89  "startVoxelInCompt",
90  "Index of first voxel that maps to each electrical "
91  "compartment. This is a trivial function in the SpineMesh, as"
92  "we have a single voxel per spine. So just a vector of "
93  "its own indices.",
95  );
97  "endVoxelInCompt",
98  "Index of end voxel that maps to each electrical "
99  "compartment. Since there is just one voxel per electrical "
100  "compartment in the spine, this is just a vector of index+1",
102  );
103 
105  // MsgDest Definitions
107 
108  static DestFinfo spineList( "spineList",
109  "Specifies the list of electrical compartments for the spine,"
110  "and the associated parent voxel"
111  "Arguments: shaft compartments, "
112  "head compartments, parent voxel index ",
113  new EpFunc3< SpineMesh, vector< Id >, vector< Id >,
114  vector< unsigned int > >(
116  );
117 
119  // Field Elements
121 
122  static Finfo* spineMeshFinfos[] = {
123  &parentVoxel, // ReadOnlyValueFinfo
124  &neuronVoxel, // ReadOnlyValueFinfo
125  &elecComptMap, // ReadOnlyValueFinfo
126  &elecComptList, // ReadOnlyValueFinfo
127  &startVoxelInCompt, // ReadOnlyValueFinfo
128  &endVoxelInCompt, // ReadOnlyValueFinfo
129  &spineList, // DestFinfo
130  // psdListOut(), // SrcFinfo
131  };
132 
133  static Dinfo< SpineMesh > dinfo;
134  static Cinfo spineMeshCinfo (
135  "SpineMesh",
137  spineMeshFinfos,
138  sizeof( spineMeshFinfos ) / sizeof ( Finfo* ),
139  &dinfo
140  );
141 
142  return &spineMeshCinfo;
143 }
144 
146 // Basic class Definitions
148 
150 
152 // Class stuff.
155  :
156  spines_( 1 ),
157  surfaceGranularity_( 0.1 ),
158  vs_( 1, 1.0e-18 ),
159  area_( 1, 1.0e-12 ),
160  length_( 1, 1.0e-6 )
161 {;}
162 
164  :
165  spines_( other.spines_ ),
166  surfaceGranularity_( other.surfaceGranularity_ )
167 {;}
168 
170 {
171  ;
172 }
173 
175 // Field assignment stuff
177 
185 vector< unsigned int > SpineMesh::getParentVoxel() const
186 {
187  vector< unsigned int > ret( spines_.size(), -1U );
188  // for ( unsigned int i = 0; i < spines_.size(); ++i )
189  // ret[i] = spines_[i].parent(); // Wrong, returns voxel on NeuroMesh
190  return ret;
191 }
192 
196 vector< unsigned int > SpineMesh::getNeuronVoxel() const
197 {
198  vector< unsigned int > ret( spines_.size(), -1U );
199  for ( unsigned int i = 0; i < spines_.size(); ++i )
200  ret[i] = spines_[i].parent();
201  return ret;
202 }
203 
204 vector< Id > SpineMesh::getElecComptMap() const
205 {
206  vector< Id > ret( spines_.size() );
207  for ( unsigned int i = 0; i < spines_.size(); ++i )
208  ret[i] = spines_[i].headId();
209  return ret;
210 }
211 
212 vector< unsigned int > SpineMesh::getStartVoxelInCompt() const
213 {
214  vector< unsigned int > ret( spines_.size() );
215  for ( unsigned int i = 0; i < ret.size(); ++i )
216  ret[i] = i;
217  return ret;
218 }
219 
220 vector< unsigned int > SpineMesh::getEndVoxelInCompt() const
221 {
222  vector< unsigned int > ret( spines_.size() );
223  for ( unsigned int i = 0; i < ret.size(); ++i )
224  ret[i] = i+1;
225  return ret;
226 }
227 
229 
236 {
237  buildStencil();
238 }
239 
240 unsigned int SpineMesh::innerGetDimensions() const
241 {
242  return 3;
243 }
244 
245 // Here we set up the spines. We don't permit heads without shafts.
247  const Eref& e, vector< Id > shaft, vector< Id > head,
248  vector< unsigned int > parentVoxel )
249 {
250  double oldVol = getMeshEntryVolume( 0 );
251  assert( head.size() == parentVoxel.size() );
252  assert( head.size() == shaft.size() );
253  spines_.resize( head.size() );
254  vs_.resize( head.size() );
255  area_.resize( head.size() );
256  length_.resize( head.size() );
257 
258  vector< double > ret;
259  vector< double > psdCoords;
260  vector< unsigned int > index( head.size(), 0 );
261  for ( unsigned int i = 0; i < head.size(); ++i ) {
262  spines_[i] = SpineEntry( shaft[i], head[i], parentVoxel[i] );
263  // cout << i << " " << head[i] << ", pa = " << parentVoxel[i] << endl;
264  // ret = spines_[i].psdCoords();
265  // assert( ret.size() == 8 );
266  // psdCoords.insert( psdCoords.end(), ret.begin(), ret.end() );
267  // index[i] = i;
268  vs_[i] = spines_[i].volume();
269  area_[i] = spines_[i].rootArea();
270  length_[i] = spines_[i].diffusionLength();
271  }
272 
273  updateCoords();
274  Id meshEntry( e.id().value() + 1 );
275 
276  vector< unsigned int > localIndices( head.size() );
277  vector< double > vols( head.size() );
278  for ( unsigned int i = 0; i < head.size(); ++i ) {
279  localIndices[i] = i;
280  vols[i] = spines_[i].volume();
281  }
282  vector< vector< unsigned int > > outgoingEntries;
283  vector< vector< unsigned int > > incomingEntries;
284  // meshSplit()->send( e, oldVol, vols, localIndices, outgoingEntries, incomingEntries );
285  lookupEntry( 0 )->triggerRemesh( meshEntry.eref(),
286  oldVol, 0, localIndices, vols );
287 }
288 
290 // FieldElement assignment stuff for MeshEntries
292 
294 unsigned int SpineMesh::getMeshType( unsigned int fid ) const
295 {
296  assert( fid < spines_.size() );
297  return CYL;
298 }
299 
301 unsigned int SpineMesh::getMeshDimensions( unsigned int fid ) const
302 {
303  return 3;
304 }
305 
307 double SpineMesh::getMeshEntryVolume( unsigned int fid ) const
308 {
309  if ( spines_.size() == 0 )
310  return 1.0;
311  assert( fid < spines_.size() );
312  return spines_[ fid % spines_.size() ].volume();
313 }
315 void SpineMesh::setMeshEntryVolume( unsigned int fid, double volume )
316 {
317  if ( spines_.size() == 0 )
318  return;
319  assert( fid < spines_.size() );
320  spines_[ fid % spines_.size() ].setVolume( volume );
321 }
322 
325 vector< double > SpineMesh::getCoordinates( unsigned int fid ) const
326 {
327  vector< double > ret;
328  return ret;
329 }
330 
332 vector< double > SpineMesh::getDiffusionArea( unsigned int fid ) const
333 {
334  vector< double > ret;
335  return ret;
336 }
337 
340 // Regular points return vector( 2, 1.0 );
341 vector< double > SpineMesh::getDiffusionScaling( unsigned int fid ) const
342 {
343  return vector< double >( 2, 1.0 );
344 }
345 
348 double SpineMesh::extendedMeshEntryVolume( unsigned int fid ) const
349 {
350  if ( fid < spines_.size() ) {
351  return getMeshEntryVolume( fid );
352  } else {
353  return MeshCompt::extendedMeshEntryVolume( fid - spines_.size() );
354  }
355 }
356 
357 
358 
360 // Dest funcsl
362 
363 /*
366 void SpineMesh::innerHandleRequestMeshStats( const Eref& e,
367  const SrcFinfo2< unsigned int, vector< double > >* meshStatsFinfo
368  )
369 {
370  ;
371 }
372 */
373 
375  const Eref& e,
376  unsigned int numNodes, unsigned int numThreads )
377 {
378 
379 
380 }
382 // Inherited virtual funcs
384 
385 const vector< double >& SpineMesh::vGetVoxelVolume() const
386 {
387  return vs_;
388 }
389 
390 const vector< double >& SpineMesh::vGetVoxelMidpoint() const
391 {
392  static vector< double > midpoint;
393  midpoint.resize( spines_.size() * 3 );
394  for ( unsigned int i = 0; i < spines_.size(); ++i ) {
395  spines_[i].mid( midpoint[i],
396  midpoint[i + spines_.size() ],
397  midpoint[i + 2 * spines_.size() ]
398  );
399  }
400  return midpoint;
401 }
402 
403 const vector< double >& SpineMesh::getVoxelArea() const
404 {
405  return area_;
406 }
407 
408 const vector< double >& SpineMesh::getVoxelLength() const
409 {
410  return length_;
411 }
412 
414 {
415  double ret = 0.0;
416  for ( vector< double >::const_iterator i =
417  vs_.begin(); i != vs_.end(); ++i )
418  ret += *i;
419  return ret;
420 }
421 
422 bool SpineMesh::vSetVolumeNotRates( double volume )
423 {
424  double volscale = volume / vGetEntireVolume();
425  double linscale = pow( volscale, 1.0/3.0 );
426  assert( vs_.size() == spines_.size() );
427  assert( area_.size() == spines_.size() );
428  assert( length_.size() == spines_.size() );
429  for ( unsigned int i = 0; i < spines_.size(); ++i ) {
430  spines_[i].setVolume( volume );
431  vs_[i] *= volscale;
432  area_[i] *= linscale * linscale;
433  length_[i] *= linscale;
434  }
435  return true;
436 }
437 
439 
443 unsigned int SpineMesh::innerGetNumEntries() const
444 {
445  return spines_.size();
446 }
447 
452 void SpineMesh::innerSetNumEntries( unsigned int n )
453 {
454 }
455 
456 
461  double volume, unsigned int numEntries )
462 {
463  cout << "Warning: SpineMesh::innerBuildDefaultMesh: attempt to build a default spine: not permitted\n";
464 }
465 
467 const vector< SpineEntry >& SpineMesh::spines() const
468 {
469  return spines_;
470 }
471 
473 // Utility function to set up Stencil for diffusion
476 {
477 // stencil_[0] = new NeuroStencil( nodes_, nodeIndex_, vs_, area_);
478  setStencilSize( spines_.size(), spines_.size() );
480 }
481 
483 // Utility function for junctions
485 
487  vector< VoxelJunction >& ret ) const
488 {
489  const CubeMesh* cm = dynamic_cast< const CubeMesh* >( other );
490  if ( cm ) {
491  matchCubeMeshEntries( other, ret );
492  return;
493  }
494  const NeuroMesh* nm = dynamic_cast< const NeuroMesh* >( other );
495  if ( nm ) {
496  matchNeuroMeshEntries( other, ret );
497  return;
498  }
499  const PsdMesh* pm = dynamic_cast< const PsdMesh* >( other );
500  if ( pm ) {
501  pm->matchSpineMeshEntries( this, ret );
502  flipRet( ret );
503  return;
504  }
505  cout << "Warning: SpineMesh::matchMeshEntries: unknown class\n";
506 }
507 
508 void SpineMesh::indexToSpace( unsigned int index,
509  double& x, double& y, double& z ) const
510 {
511  if ( index >= innerGetNumEntries() )
512  return;
513  spines_[ index ].mid( x, y, z );
514 }
515 
516 double SpineMesh::nearest( double x, double y, double z,
517  unsigned int& index ) const
518 {
519  double best = 1e12;
520  index = 0;
521  for( unsigned int i = 0; i < spines_.size(); ++i ) {
522  const SpineEntry& se = spines_[i];
523  double a0, a1, a2;
524  se.mid( a0, a1, a2 );
525  Vec a( a0, a1, a2 );
526  Vec b( x, y, z );
527  double d = a.distance( b );
528  if ( best > d ) {
529  best = d;
530  index = i;
531  }
532  }
533  if ( best == 1e12 )
534  return -1;
535  return best;
536 }
537 
539  vector< VoxelJunction >& ret ) const
540 {
541 }
542 
544  vector< VoxelJunction >& ret ) const
545 {
546  const NeuroMesh* nm = dynamic_cast< const NeuroMesh* >( other );
547  assert( nm );
548  for ( unsigned int i = 0; i < spines_.size(); ++i ) {
549  double xda = spines_[i].rootArea() / spines_[i].diffusionLength();
550  ret.push_back( VoxelJunction( i, spines_[i].parent(), xda ) );
551  ret.back().firstVol = spines_[i].volume();
552  ret.back().secondVol =
553  nm->getMeshEntryVolume( spines_[i].parent() );
554  }
555 }
556 
558  vector< VoxelJunction >& ret ) const
559 {
560  for( unsigned int i = 0; i < spines_.size(); ++i ) {
561  const SpineEntry& se = spines_[i];
562  se.matchCubeMeshEntriesToHead( other, i, surfaceGranularity_, ret );
563  }
564 }
static const Cinfo * initCinfo()
Definition: ChemCompt.cpp:25
unsigned int innerGetNumEntries() const
Definition: SpineMesh.cpp:443
Id id() const
Definition: Eref.cpp:62
double getMeshEntryVolume(unsigned int fid) const
Virtual function to return volume of mesh Entry.
Definition: NeuroMesh.cpp:906
static const Cinfo * spineMeshCinfo
Definition: SpineMesh.cpp:149
void innerBuildDefaultMesh(const Eref &e, double volume, unsigned int numEntries)
Virtual func to make a mesh with specified Volume and numEntries.
Definition: SpineMesh.cpp:460
vector< double > area_
Definition: SpineMesh.h:203
void innerResetStencil()
virtual func implemented here.
Definition: MeshCompt.cpp:49
double getMeshEntryVolume(unsigned int fid) const
Virtual function to return volume of mesh Entry.
Definition: SpineMesh.cpp:307
const vector< double > & vGetVoxelVolume() const
Virtual func so that derived classes can pass voxel volume back.
Definition: SpineMesh.cpp:385
bool vSetVolumeNotRates(double volume)
Inherited virtual func.
Definition: SpineMesh.cpp:422
unsigned int value() const
Definition: Id.cpp:197
vector< unsigned int > getStartVoxelInCompt() const
Returns index of first voxel mapping to elec compt.
Definition: SpineMesh.cpp:212
Definition: Dinfo.h:60
MeshEntry * lookupEntry(unsigned int index)
Definition: ChemCompt.cpp:379
const vector< double > & vGetVoxelMidpoint() const
Virtual func so that derived classes can return voxel midpoint.
Definition: SpineMesh.cpp:390
double extendedMeshEntryVolume(unsigned int fid) const
Vol of all mesh Entries including abutting diff-coupled voxels.
Definition: SpineMesh.cpp:348
double extendedMeshEntryVolume(unsigned int fid) const
Virtual function to return volume of mesh Entry, including.
Definition: MeshCompt.cpp:36
vector< double > getCoordinates(unsigned int fid) const
Virtual function to return coords of mesh Entry.
Definition: SpineMesh.cpp:325
const vector< double > & getVoxelArea() const
Definition: SpineMesh.cpp:403
void indexToSpace(unsigned int index, double &x, double &y, double &z) const
Definition: SpineMesh.cpp:508
vector< double > getDiffusionArea(unsigned int fid) const
Virtual function to return diffusion X-section area.
Definition: SpineMesh.cpp:332
void matchMeshEntries(const ChemCompt *other, vector< VoxelJunction > &ret) const
Definition: SpineMesh.cpp:486
vector< SpineEntry > spines_
Definition: SpineMesh.h:183
const int numEntries
Definition: proc.cpp:60
const vector< SpineEntry > & spines() const
Definition: SpineMesh.cpp:467
void updateCoords()
Definition: SpineMesh.cpp:235
void mid(double &x, double &y, double &z) const
Return coords of centre of spine head.
Definition: SpineEntry.cpp:124
Definition: EpFunc.h:95
vector< Id > getElecComptMap() const
Definition: SpineMesh.cpp:204
unsigned int getMeshType(unsigned int fid) const
Virtual function to return MeshType of specified entry.
Definition: SpineMesh.cpp:294
double vGetEntireVolume() const
Inherited virtual func.
Definition: SpineMesh.cpp:413
const vector< double > & getVoxelLength() const
Definition: SpineMesh.cpp:408
vector< double > length_
Pre-calculation of length of each MeshEntry.
Definition: SpineMesh.h:206
Definition: Vec.h:13
vector< double > vs_
Definition: SpineMesh.h:197
Definition: MeshEntry.h:20
vector< unsigned int > getNeuronVoxel() const
Definition: SpineMesh.cpp:196
static const Cinfo * initCinfo()
Definition: SpineMesh.cpp:48
double surfaceGranularity_
Definition: SpineMesh.h:190
Definition: Eref.h:26
double distance(const Vec &other) const
Definition: Vec.cpp:81
void matchSpineMeshEntries(const ChemCompt *other, vector< VoxelJunction > &ret) const
Definition: PsdMesh.cpp:493
vector< double > getDiffusionScaling(unsigned int fid) const
Virtual function to return scale factor for diffusion. 1 here.
Definition: SpineMesh.cpp:341
void matchSpineMeshEntries(const ChemCompt *other, vector< VoxelJunction > &ret) const
Definition: SpineMesh.cpp:538
void innerSetNumEntries(unsigned int n)
Inherited virtual func.
Definition: SpineMesh.cpp:452
void innerHandleNodeInfo(const Eref &e, unsigned int numNodes, unsigned int numThreads)
Definition: SpineMesh.cpp:374
void triggerRemesh(const Eref &e, double oldvol, unsigned int startEntry, const vector< unsigned int > &localIndices, const vector< double > &vols)
Definition: MeshEntry.cpp:267
double nearest(double x, double y, double z, unsigned int &index) const
Definition: SpineMesh.cpp:516
static unsigned int numNodes
void matchNeuroMeshEntries(const ChemCompt *other, vector< VoxelJunction > &ret) const
Definition: SpineMesh.cpp:543
vector< unsigned int > getEndVoxelInCompt() const
Returns index of end voxel mapping to elec compt, just first+1.
Definition: SpineMesh.cpp:220
Definition: Id.h:17
void matchCubeMeshEntriesToHead(const ChemCompt *compt, unsigned int myIndex, double granularity, vector< VoxelJunction > &ret) const
Returns Id of head electrical compartment.
Definition: SpineEntry.cpp:145
void setStencilSize(unsigned int numRows, unsigned int numCols)
Definition: MeshCompt.cpp:106
void setMeshEntryVolume(unsigned int fid, double volume)
Virtual function to assign volume of mesh Entry.
Definition: SpineMesh.cpp:315
void buildStencil()
Definition: SpineMesh.cpp:475
void flipRet(vector< VoxelJunction > &ret) const
Utility function for swapping first and second in VoxelJunctions.
Definition: ChemCompt.cpp:406
void matchCubeMeshEntries(const ChemCompt *other, vector< VoxelJunction > &ret) const
Definition: SpineMesh.cpp:557
Definition: Cinfo.h:18
unsigned int getMeshDimensions(unsigned int fid) const
Virtual function to return dimensions of specified entry.
Definition: SpineMesh.cpp:301
unsigned int innerGetDimensions() const
Returns # of dimensions, always 3 here. Inherited pure virt func.
Definition: SpineMesh.cpp:240
vector< unsigned int > getParentVoxel() const
Definition: SpineMesh.cpp:185
Definition: Finfo.h:12
void handleSpineList(const Eref &e, vector< Id > shaft, vector< Id > head, vector< unsigned int > parentVoxel)
Definition: SpineMesh.cpp:246