MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ChemCompt.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) 2003-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 "header.h"
11 #include "ElementValueFinfo.h"
13 #include "Boundary.h"
14 #include "MeshEntry.h"
15 #include "ChemCompt.h"
16 
18  static SrcFinfo1< vector< double > > voxelVolOut( "voxelVolOut",
19  "Sends updated voxel volume out to Ksolve, Gsolve, and Dsolve."
20  "Used to request a recalculation of rates and of initial numbers."
21  );
22  return &voxelVolOut;
23 }
24 
26 {
28  // Field Definitions
31  "volume",
32  "Volume of entire chemical domain."
33  "Assigning this only works if the chemical compartment has"
34  "only a single voxel. Otherwise ignored."
35  "This function goes through all objects below this on the"
36  "tree, and rescales their molecule #s and rates as per the"
37  "volume change. This keeps concentration the same, and also"
38  "maintains rates as expressed in volume units.",
41  );
42 
44  voxelVolume(
45  "voxelVolume",
46  "Vector of volumes of each of the voxels.",
48  );
49 
51  voxelMidpoint(
52  "voxelMidpoint",
53  "Vector of midpoint coordinates of each of the voxels. The "
54  "size of this vector is 3N, where N is the number of voxels. "
55  "The first N entries are for x, next N for y, last N are z. ",
57  );
58 
60  ChemCompt, unsigned int, double >
61  oneVoxelVolume(
62  "oneVoxelVolume",
63  "Volume of specified voxel.",
66  );
67 
69  "numDimensions",
70  "Number of spatial dimensions of this compartment. Usually 3 or 2",
72  );
73 
75  "stencilRate",
76  "vector of diffusion rates in the stencil for specified voxel."
77  "The identity of the coupled voxels is given by the partner "
78  "field 'stencilIndex'."
79  "Returns an empty vector for non-voxelized compartments.",
81  );
82 
84  "stencilIndex",
85  "vector of voxels diffusively coupled to the specified voxel."
86  "The diffusion rates into the coupled voxels is given by the "
87  "partner field 'stencilRate'."
88  "Returns an empty vector for non-voxelized compartments.",
90  );
91 
92  static ValueFinfo< ChemCompt, bool > isMembraneBound(
93  "isMembraneBound",
94  "Flag, set to True for meshes where each voxel is membrane "
95  "bound. \n"
96  "NeuroMesh and SpineMesh are false. \n"
97  "CubeMesh, CylMesh, and EndoMesh can be either. If they are "
98  "membrane bound they can still interact via channels and "
99  "cross-compartment reactions. ",
102  );
103 
105  // MsgDest Definitions
107 
108  static DestFinfo buildDefaultMesh( "buildDefaultMesh",
109  "Tells ChemCompt derived class to build a default mesh with the"
110  "specified volume and number of meshEntries.",
113  );
114 
115  static DestFinfo setVolumeNotRates( "setVolumeNotRates",
116  "Changes volume but does not notify any child objects."
117  "Only works if the ChemCompt has just one voxel."
118  "This function will invalidate any concentration term in"
119  "the model. If you don't know why you would want to do this,"
120  "then you shouldn't use this function.",
123  );
124 
125  static DestFinfo handleNodeInfo( "handleNodeInfo",
126  "Tells ChemCompt how many nodes and threads per node it is "
127  "allowed to use. Triggers a return meshSplitOut message.",
130  );
131 
132  static DestFinfo resetStencil( "resetStencil",
133  "Resets the diffusion stencil to the core stencil that only "
134  "includes the within-mesh diffusion. This is needed prior to "
135  "building up the cross-mesh diffusion through junctions.",
138  );
139 
140 
142  // Field Elements
144 
146  "mesh",
147  "Field Element for mesh entries",
152  false
153  );
154 
155  static Finfo* chemMeshFinfos[] = {
156  &volume, // Value
157  &voxelVolume, // ReadOnlyLookupValue
158  &voxelMidpoint, // ReadOnlyLookupValue
159  &oneVoxelVolume, // ReadOnlyLookupValue
160  &numDimensions, // ReadOnlyValue
161  &stencilRate, // ReadOnlyLookupValue
162  &stencilIndex, // ReadOnlyLookupValue
163  &isMembraneBound, // Value
164  voxelVolOut(), // SrcFinfo
165  &buildDefaultMesh, // DestFinfo
166  &setVolumeNotRates, // DestFinfo
167  &resetStencil, // DestFinfo
168  &entryFinfo, // FieldElementFinfo
169  };
170 
171  static string doc[] = {
172  "Name", "ChemCompt",
173  "Author", "Upi Bhalla",
174  "Description", "Pure virtual base class for chemical compartments"
175 
176  };
177  static Dinfo< short > dinfo;
178  static Cinfo chemMeshCinfo (
179  "ChemCompt",
181  chemMeshFinfos,
182  sizeof( chemMeshFinfos ) / sizeof ( Finfo* ),
183  &dinfo,
184  doc,
185  sizeof(doc)/sizeof( string ),
186  true // This is a base class, not be be created directly.
187  );
188 
189  return &chemMeshCinfo;
190 }
191 
193 // Basic class Definitions
195 
197 
199  :
200  entry_( this ),
201  isMembraneBound_( false )
202 {
203  ;
204 }
205 
207 {
208  /*
209  for ( unsigned int i = 0; i < stencil_.size(); ++i ) {
210  if ( stencil_[i] )
211  delete stencil_[i];
212  }
213  */
214 }
215 
217 // MsgDest Definitions
219 
221  double volume, unsigned int numEntries )
222 {
223  this->innerBuildDefaultMesh( e, volume, numEntries );
224 }
225 
227  unsigned int numNodes, unsigned int numThreads )
228 {
229  // Pass it down to derived classes along with the SrcFinfo
230  innerHandleNodeInfo( e, numNodes, numThreads );
231 }
232 
234 {
235  this->innerResetStencil();
236 }
237 
239 // Field Definitions
241 
242 void ChemCompt::setEntireVolume( const Eref& e, double volume )
243 {
244  // If the reac system is not solved, then explicitly do scaling
245  vector< ObjId > tgtVec =
247  if ( tgtVec.size() == 0 ) {
248  vector< double > childConcs;
249  getChildConcs( e, childConcs );
250  if ( vSetVolumeNotRates( volume ) ) {
251  setChildConcs( e, childConcs, 0 );
252  }
253  } else {
254  vSetVolumeNotRates( volume );
255  voxelVolOut()->send( e, this->vGetVoxelVolume() );
256  }
257 }
258 
259 double ChemCompt::getEntireVolume( const Eref& e ) const
260 {
261  return vGetEntireVolume();
262 }
263 
264 void ChemCompt::getChildConcs( const Eref& e, vector< double >& childConcs )
265  const
266 {
267  vector< Id > kids;
268  Neutral::children( e, kids );
269  for ( vector < Id >::iterator i = kids.begin(); i != kids.end(); ++i )
270  {
271  if ( i->element()->cinfo()->isA( "PoolBase" ) ) {
272  childConcs.push_back( Field< double >::get( *i, "conc" ) );
273  childConcs.push_back( Field< double >::get( *i, "concInit" ) );
274  } else if ( i->element()->cinfo()->isA( "ReacBase" ) ) {
275  childConcs.push_back( Field< double >::get( *i, "Kf" ) );
276  childConcs.push_back( Field< double >::get( *i, "Kb" ) );
277  } else if ( i->element()->cinfo()->isA( "EnzBase" ) ) {
278  childConcs.push_back( Field< double >::get( *i, "Km" ) );
279  } else if ( i->element()->cinfo()->isA( "ChemCompt" ) ) {
280  // Do NOT traverse into child ChemCompts, they look after their
281  // own volumes.
282  continue;
283  }
284  getChildConcs( i->eref(), childConcs );
285  }
286 }
287 
288 unsigned int ChemCompt::setChildConcs( const Eref& e,
289  const vector< double >& conc, unsigned int start ) const
290 {
291  vector< Id > kids;
292  Neutral::children( e, kids );
293  for ( vector < Id >::iterator i = kids.begin(); i != kids.end(); ++i )
294  {
295  if ( i->element()->cinfo()->isA( "PoolBase" ) ) {
296  Field< double >::set( *i, "conc", conc[ start++ ] );
297  Field< double >::set( *i, "concInit", conc[start++] );
298  } else if ( i->element()->cinfo()->isA( "ReacBase" ) ) {
299  Field< double >::set( *i, "Kf", conc[ start++ ] );
300  Field< double >::set( *i, "Kb", conc[ start++ ] );
301  } else if ( i->element()->cinfo()->isA( "EnzBase" ) ) {
302  Field< double >::set( *i, "Km", conc[ start++ ] );
303  } else if ( i->element()->cinfo()->isA( "ChemCompt" ) ) {
304  // Do NOT traverse into child ChemCompts, they look after their
305  // own volumes.
306  continue;
307  }
308  start = setChildConcs( i->eref(), conc, start );
309  }
310  return start;
311 }
312 
313 vector< double > ChemCompt::getVoxelVolume() const
314 {
315  return this->vGetVoxelVolume();
316 }
317 
318 vector< double > ChemCompt::getVoxelMidpoint() const
319 {
320  return this->vGetVoxelMidpoint();
321 }
322 
323 double ChemCompt::getOneVoxelVolume( const Eref& e, unsigned int dataIndex ) const
324 {
325  return this->getMeshEntryVolume( dataIndex );
326 }
327 
328 void ChemCompt::setOneVoxelVolume( const Eref& e, unsigned int dataIndex,
329  double volume )
330 {
331  this->setMeshEntryVolume( dataIndex, volume );
332 }
333 
334 // A virtual function, meant to be overridden.
335 void ChemCompt::setMeshEntryVolume( unsigned int dataIndex, double volume )
336 {
337  cout << "Warning: ChemCompt::setMeshEntryVolume: Undefined except for PSD and spine mesh.\n";
338 }
339 
340 unsigned int ChemCompt::getDimensions() const
341 {
342  return this->innerGetDimensions();
343 }
344 
345 vector< double > ChemCompt::getStencilRate( unsigned int row ) const
346 {
347  return this->innerGetStencilRate( row );
348 }
349 
350 vector< unsigned int > ChemCompt::getStencilIndex( unsigned int row ) const
351 {
352  return this->getNeighbors( row );
353 }
354 
356 {
357  return isMembraneBound_;
358 }
359 
361 {
362  isMembraneBound_ = v;
363 }
364 
365 
367 // Dest Definitions
369 
370 void ChemCompt::setVolumeNotRates( double volume )
371 {
372  vSetVolumeNotRates( volume ); // Pass on to derived classes.
373 }
374 
376 // Element Field Definitions
378 
379 MeshEntry* ChemCompt::lookupEntry( unsigned int index )
380 {
381  return &entry_;
382 }
383 
384 void ChemCompt::setNumEntries( unsigned int num )
385 {
386  this->innerSetNumEntries( num );
387  // cout << "Warning: ChemCompt::setNumEntries: No effect. Use subclass-specific functions\nto build or resize mesh.\n";
388 }
389 
390 unsigned int ChemCompt::getNumEntries() const
391 {
392  return this->innerGetNumEntries();
393 }
394 
395 
397 // Build the junction between this and another ChemCompt.
398 // This one function does the work for both meshes.
400 void ChemCompt::buildJunction( ChemCompt* other, vector< VoxelJunction >& ret)
401 {
402  matchMeshEntries( other, ret );
403  extendStencil( other, ret );
404 }
405 
406 void ChemCompt::flipRet( vector< VoxelJunction >& ret ) const
407 {
408  vector< VoxelJunction >::iterator i;
409  for ( i = ret.begin(); i != ret.end(); ++i ) {
410  unsigned int temp = i->first;
411  i->first = i->second;
412  i->second = temp;
413  double vol = i->firstVol;
414  i->firstVol = i->secondVol;
415  i->secondVol = vol;
416  }
417 }
418 
420 // Utility function
421 
422 double ChemCompt::distance( double x, double y, double z )
423 {
424  return sqrt( x * x + y * y + z * z );
425 }
void resetStencil()
Definition: ChemCompt.cpp:233
static const Cinfo * initCinfo()
Definition: ChemCompt.cpp:25
void setIsMembraneBound(bool v)
Definition: ChemCompt.cpp:360
vector< double > getVoxelMidpoint() const
Returns vector of all voxel midpoints in compartment.
Definition: ChemCompt.cpp:318
vector< ObjId > getMsgTargets(DataId srcDataId, const SrcFinfo *finfo) const
Definition: Element.cpp:856
virtual bool vSetVolumeNotRates(double volume)=0
Virtual function for actually doing this.
virtual ~ChemCompt()
Definition: ChemCompt.cpp:206
Definition: Dinfo.h:60
virtual void innerHandleNodeInfo(const Eref &e, unsigned int numNodes, unsigned int numThreads)=0
Definition: SetGet.h:236
void setVolumeNotRates(double volume)
Definition: ChemCompt.cpp:370
MeshEntry * lookupEntry(unsigned int index)
Definition: ChemCompt.cpp:379
vector< double > getVoxelVolume() const
Returns vector of all voxel volumes in compartment.
Definition: ChemCompt.cpp:313
vector< double > getStencilRate(unsigned int row) const
Definition: ChemCompt.cpp:345
unsigned int dataIndex() const
Definition: Eref.h:50
vector< unsigned int > getStencilIndex(unsigned int row) const
Definition: ChemCompt.cpp:350
void setEntireVolume(const Eref &e, double volume)
Definition: ChemCompt.cpp:242
void setOneVoxelVolume(const Eref &e, unsigned int voxel, double volume)
Definition: ChemCompt.cpp:328
double getEntireVolume(const Eref &e) const
Definition: ChemCompt.cpp:259
double getOneVoxelVolume(const Eref &e, unsigned int voxel) const
Definition: ChemCompt.cpp:323
void buildJunction(ChemCompt *other, vector< VoxelJunction > &ret)
Definition: ChemCompt.cpp:400
const int numEntries
Definition: proc.cpp:60
static void children(const Eref &e, vector< Id > &ret)
Definition: Neutral.cpp:342
Element * element() const
Definition: Eref.h:42
static bool set(const ObjId &dest, const string &field, A arg)
Definition: SetGet.h:245
bool isMembraneBound_
Definition: ChemCompt.h:363
virtual void innerResetStencil()=0
static SrcFinfo1< vector< double > > * voxelVolOut()
Definition: ChemCompt.cpp:17
unsigned int getNumEntries() const
Definition: ChemCompt.cpp:390
unsigned int getDimensions() const
Definition: ChemCompt.cpp:340
virtual vector< double > innerGetStencilRate(unsigned int row) const =0
Virtual func for getting stencil rates for the derived classes.
virtual vector< unsigned int > getNeighbors(unsigned int fid) const =0
Virtual function to return info on Entries connected to this one.
virtual unsigned int innerGetDimensions() const =0
virtual double vGetEntireVolume() const =0
static double distance(double x, double y, double z)
Definition: ChemCompt.cpp:422
static char dataIndex[]
Definition: mfield.cpp:406
void getChildConcs(const Eref &e, vector< double > &childConcs) const
Definition: ChemCompt.cpp:264
virtual const vector< double > & vGetVoxelVolume() const =0
Virtual func so that derived classes can pass voxel volume back.
virtual unsigned int innerGetNumEntries() const =0
bool getIsMembraneBound() const
Definition: ChemCompt.cpp:355
void buildDefaultMesh(const Eref &e, double volume, unsigned int numEntries)
Definition: ChemCompt.cpp:220
Definition: OpFunc.h:27
Definition: Eref.h:26
virtual void extendStencil(const ChemCompt *other, const vector< VoxelJunction > &vj)=0
unsigned int setChildConcs(const Eref &e, const vector< double > &childConcs, unsigned int start) const
Definition: ChemCompt.cpp:288
void setNumEntries(unsigned int num)
Definition: ChemCompt.cpp:384
static unsigned int numNodes
virtual void setMeshEntryVolume(unsigned int fid, double volume)
Definition: ChemCompt.cpp:335
virtual const vector< double > & vGetVoxelMidpoint() const =0
Virtual func so that derived classes can return voxel midpoint.
Definition: OpFunc.h:13
virtual void matchMeshEntries(const ChemCompt *other, vector< VoxelJunction > &ret) const =0
MeshEntry entry_
Definition: ChemCompt.h:333
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
void handleNodeInfo(const Eref &e, unsigned int numNodes, unsigned int numThreads)
Definition: ChemCompt.cpp:226
static const Cinfo * initCinfo()
Definition: MeshEntry.cpp:47
virtual double getMeshEntryVolume(unsigned int fid) const =0
Virtual function to return volume of mesh Entry.
void flipRet(vector< VoxelJunction > &ret) const
Utility function for swapping first and second in VoxelJunctions.
Definition: ChemCompt.cpp:406
virtual void innerSetNumEntries(unsigned int n)=0
static const Cinfo * chemMeshCinfo
Definition: ChemCompt.cpp:196
Definition: Cinfo.h:18
virtual void innerBuildDefaultMesh(const Eref &e, double volume, unsigned int numEntries)=0
Definition: EpFunc.h:79
Definition: Finfo.h:12