MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Dsolve.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-2014 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"
12 #include "SparseMatrix.h"
13 #include "KinSparseMatrix.h"
14 #include "VoxelPoolsBase.h"
15 #include "../mesh/VoxelJunction.h"
16 #include "XferInfo.h"
17 #include "ZombiePoolInterface.h"
18 #include "../kinetics/ConcChan.h"
19 #include "DiffPoolVec.h"
20 #include "ConcChanInfo.h"
21 #include "FastMatrixElim.h"
22 #include "../mesh/VoxelJunction.h"
23 #include "DiffJunction.h"
24 #include "Dsolve.h"
25 #include "../mesh/Boundary.h"
26 #include "../mesh/MeshEntry.h"
27 #include "../mesh/ChemCompt.h"
28 #include "../mesh/MeshCompt.h"
29 #include "../shell/Wildcard.h"
30 #include "../kinetics/PoolBase.h"
31 #include "../kinetics/Pool.h"
32 #include "../kinetics/BufPool.h"
33 #include "../ksolve/ZombiePool.h"
34 #include "../ksolve/ZombieBufPool.h"
35 
37 {
39  // Field definitions
41 
42  static ValueFinfo< Dsolve, Id > stoich (
43  "stoich",
44  "Stoichiometry object for handling this reaction system.",
47  );
48 
50  "path",
51  "Path of reaction system. Must include all the pools that "
52  "are to be handled by the Dsolve, can also include other "
53  "random objects, which will be ignored.",
56  );
57 
59  "numVoxels",
60  "Number of voxels in the core reac-diff system, on the "
61  "current diffusion solver. ",
63  );
65  "numAllVoxels",
66  "Number of voxels in the core reac-diff system, on the "
67  "current diffusion solver. ",
69  );
70  static LookupValueFinfo<
71  Dsolve, unsigned int, vector< double > > nVec(
72  "nVec",
73  "vector of # of molecules along diffusion length, "
74  "looked up by pool index",
77  );
78 
79  static ValueFinfo< Dsolve, unsigned int > numPools(
80  "numPools",
81  "Number of molecular pools in the entire reac-diff system, "
82  "including variable, function and buffered.",
85  );
86 
87  static ValueFinfo< Dsolve, Id > compartment (
88  "compartment",
89  "Reac-diff compartment in which this diffusion system is "
90  "embedded.",
93  );
94 
96  "diffVol1",
97  "Volume used to set diffusion scaling: firstVol[ voxel# ] "
98  "Particularly relevant for diffusion between PSD and head.",
101  );
102 
104  "diffVol2",
105  "Volume used to set diffusion scaling: secondVol[ voxel# ] "
106  "Particularly relevant for diffusion between spine and dend.",
109  );
110 
112  "diffScale",
113  "Geometry term to set diffusion scaling: diffScale[ voxel# ] "
114  "Here the scaling term is given by cross-section area/length "
115  "Relevant for diffusion between spine head and dend, or PSD.",
118  );
119 
120 
122  // DestFinfo definitions
124 
125  static DestFinfo process( "process",
126  "Handles process call",
128  static DestFinfo reinit( "reinit",
129  "Handles reinit call",
131 
132  static DestFinfo buildMeshJunctions( "buildMeshJunctions",
133  "Builds junctions between mesh on current Dsolve, and another"
134  " Dsolve. The meshes have to be compatible. ",
137 
138  static DestFinfo buildNeuroMeshJunctions( "buildNeuroMeshJunctions",
139  "Builds junctions between NeuroMesh, SpineMesh and PsdMesh",
142 
144  // Shared definitions
146  static Finfo* procShared[] = {
147  &process, &reinit
148  };
149  static SharedFinfo proc( "proc",
150  "Shared message for process and reinit",
151  procShared, sizeof( procShared ) / sizeof( const Finfo* )
152  );
153 
154  static Finfo* dsolveFinfos[] =
155  {
156  &stoich, // ElementValue
157  &path, // ElementValue
158  &compartment, // Value
159  &numVoxels, // ReadOnlyValue
160  &numAllVoxels, // ReadOnlyValue
161  &nVec, // LookupValue
162  &numPools, // Value
163  &diffVol1, // LookupValue
164  &diffVol2, // LookupValue
165  &diffScale, // LookupValue
166  &buildMeshJunctions, // DestFinfo
167  &buildNeuroMeshJunctions, // DestFinfo
168  &proc, // SharedFinfo
169  };
170 
171  static Dinfo< Dsolve > dinfo;
172  static Cinfo dsolveCinfo(
173  "Dsolve",
175  dsolveFinfos,
176  sizeof(dsolveFinfos)/sizeof(Finfo *),
177  &dinfo
178  );
179 
180  return &dsolveCinfo;
181 }
182 
184 
186 // Class definitions
189  :
190  dt_( -1.0 ),
191  numTotPools_( 0 ),
192  numLocalPools_( 0 ),
193  poolStartIndex_( 0 ),
194  numVoxels_( 0 )
195 {;}
196 
198 {;}
199 
201 // Field access functions
203 
204 void Dsolve::setNvec( unsigned int pool, vector< double > vec )
205 {
206  if ( pool < pools_.size() ) {
207  if ( vec.size() != pools_[pool].getNumVoxels() ) {
208  cout << "Warning: Dsolve::setNvec: pool index out of range\n";
209  } else {
210  pools_[ pool ].setNvec( vec );
211  }
212  }
213 }
214 
215 vector< double > Dsolve::getNvec( unsigned int pool ) const
216 {
217  static vector< double > ret;
218  if ( pool < pools_.size() )
219  return pools_[pool].getNvec();
220 
221  cout << "Warning: Dsolve::setNvec: pool index out of range\n";
222  return ret;
223 }
224 
225 static bool checkJn( const vector< DiffJunction >& jn, unsigned int voxel,
226  const string& info )
227 {
228  if ( jn.size() < 1 ) {
229  cout << "Warning: Dsolve::" << info << ": junctions not defined.\n";
230  return false;
231  }
232  if ( jn[0].vj.size() < voxel + 1 ) {
233  cout << "Warning: Dsolve:: " << info << ": " << voxel <<
234  "out of range.\n";
235  return false;
236  }
237  return true;
238 }
239 
240 void Dsolve::setDiffVol1( unsigned int voxel, double vol )
241 {
242  if ( checkJn( junctions_, voxel, "setDiffVol1" ) ) {
243  VoxelJunction& vj = junctions_[0].vj[ voxel ];
244  vj.firstVol = vol;
245  }
246 }
247 
248 double Dsolve::getDiffVol1( unsigned int voxel ) const
249 {
250  if ( checkJn( junctions_, voxel, "getDiffVol1" ) ) {
251  const VoxelJunction& vj = junctions_[0].vj[ voxel ];
252  return vj.firstVol;
253  }
254  return 0.0;
255 }
256 
257 void Dsolve::setDiffVol2( unsigned int voxel, double vol )
258 {
259  if ( checkJn( junctions_, voxel, "setDiffVol2" ) ) {
260  VoxelJunction& vj = junctions_[0].vj[ voxel ];
261  vj.secondVol = vol;
262  }
263 }
264 
265 double Dsolve::getDiffVol2( unsigned int voxel ) const
266 {
267  if ( checkJn( junctions_, voxel, "getDiffVol2" ) ) {
268  const VoxelJunction& vj = junctions_[0].vj[ voxel ];
269  return vj.secondVol;
270  }
271  return 0.0;
272 }
273 
274 void Dsolve::setDiffScale( unsigned int voxel, double adx )
275 {
276  if ( checkJn( junctions_, voxel, "setDiffScale" ) ) {
277  VoxelJunction& vj = junctions_[0].vj[ voxel ];
278  vj.diffScale = adx;
279  }
280 }
281 
282 double Dsolve::getDiffScale( unsigned int voxel ) const
283 {
284  if ( checkJn( junctions_, voxel, "getDiffScale" ) ) {
285  const VoxelJunction& vj = junctions_[0].vj[ voxel ];
286  return vj.diffScale;
287  }
288  return 0.0;
289 }
290 
292 // Process operations.
294 
295 static double integ( double myN, double rf, double rb, double dt )
296 {
297  const double EPSILON = 1e-12;
298  if ( myN > EPSILON && rf > EPSILON ) {
299  double C = exp( -rf * dt / myN );
300  myN *= C + ( rb / rf ) * ( 1.0 - C );
301  } else {
302  myN += ( rb - rf ) * dt;
303  }
304  if ( myN < 0.0 )
305  return 0.0;
306  return myN;
307 }
308 
309 void Dsolve::calcJnDiff( const DiffJunction& jn, Dsolve* other, double dt)
310 {
311  const double EPSILON = 1e-16;
312  assert( jn.otherPools.size() == jn.myPools.size() );
313  for ( unsigned int i = 0; i < jn.myPools.size(); ++i ) {
314  DiffPoolVec& myDv = pools_[ jn.myPools[i] ];
315  if ( myDv.getDiffConst() < EPSILON )
316  continue;
317  DiffPoolVec& otherDv = other->pools_[ jn.otherPools[i] ];
318  if ( otherDv.getDiffConst() < EPSILON )
319  continue;
320  // This geom mean is used in case we have the odd situation of
321  // different diffusion constants.
322  double effectiveDiffConst =
323  sqrt( myDv.getDiffConst() * otherDv.getDiffConst() );
324  for ( vector< VoxelJunction >::const_iterator
325  j = jn.vj.begin(); j != jn.vj.end(); ++j ) {
326  double myN = myDv.getN( j->first );
327  double otherN = otherDv.getN( j->second );
328  // Here we do an exp Euler calculation
329  // rf is rate from self to other.
330  // double k = myDv.getDiffConst() * j->diffScale;
331  double k = effectiveDiffConst * j->diffScale;
332  double lastN = myN;
333  myN = integ( myN,
334  k * myN / j->firstVol,
335  k * otherN / j->secondVol,
336  dt
337  );
338  otherN += lastN - myN; // Simple mass conservation
339  if ( otherN < 0.0 ) { // Avoid negatives
340  myN += otherN;
341  otherN = 0.0;
342  }
343  myDv.setN( j->first, myN );
344  otherDv.setN( j->second, otherN );
345  }
346  }
347 }
348 
350  const vector< unsigned int >& srcXfer,
351  const vector< unsigned int >& destXfer,
352  Dsolve* srcDsolve, Dsolve* destDsolve )
353 {
354  assert( destXfer.size() == srcXfer.size() );
355  for ( unsigned int i = 0; i < srcXfer.size(); ++i ) {
356  DiffPoolVec& srcDv = srcDsolve->pools_[ srcXfer[i] ];
357  DiffPoolVec& destDv = destDsolve->pools_[ destXfer[i] ];
358  for ( vector< VoxelJunction >::const_iterator
359  j = jn.vj.begin(); j != jn.vj.end(); ++j ) {
360  double prevSrc = srcDv.getPrev( j->first );
361  double prevDest = destDv.getPrev( j->second );
362  double srcN = srcDv.getN( j->first );
363  double destN = destDv.getN( j->second );
364  // Consider delta as sum of local dN, and reference as prevDest
365  // newN = (srcN - prevSrc + destN - prevDest) + prevDest
366  double newN = srcN + destN - prevSrc;
367  srcDv.setN( j->first, newN );
368  destDv.setN( j->second, newN );
369  }
370  }
371 }
372 
373 void Dsolve::calcJnChan( const DiffJunction& jn, Dsolve* other, double dt )
374 {
375  // Each jn has some channels
376  // Each channel has a chanPool, an intPool and an extPool.
377  // chanPool and intPool must be on self, extPool is on other. In
378  // cases where the intPool is on other, it attempts to swap the
379  // int and ext pools, but this too could fail
380  // because the chanPool could be a third compartment, such as the memb
381  //
382  // Don't have a solution for this case as yet.
383  // Other alternative is to have a message to update the N of the chan,
384  // so it isn't in the domain of the solver at all except for here.
385  // In which case we will want to point to the Moose object for it.
386  //
387 
388  for ( unsigned int i = 0; i < jn.myChannels.size(); ++i ) {
389  ConcChanInfo& myChan = channels_[ jn.myChannels[i] ];
390  DiffPoolVec& myDv = pools_[ myChan.myPool ];
391  DiffPoolVec& otherDv = other->pools_[ myChan.otherPool ];
392  DiffPoolVec& chanDv = pools_[ myChan.chanPool ];
393  for ( vector< VoxelJunction >::const_iterator
394  j = jn.vj.begin(); j != jn.vj.end(); ++j ) {
395 
396  double myN = myDv.getN( j->first );
397  double lastN = myN;
398  double otherN = otherDv.getN( j->second );
399  double chanN = chanDv.getN( j->first );
400  double perm = myChan.permeability * chanN / NA;
401  myN = integ( myN, perm * myN/j->firstVol,
402  perm * otherN/j->secondVol, dt );
403  otherN += lastN - myN; // Mass consv
404  if ( otherN < 0.0 ) { // Avoid negatives
405  myN += otherN;
406  otherN = 0.0;
407  }
408  myDv.setN( j->first, myN );
409  otherDv.setN( j->second, otherN );
410  }
411  }
412 }
413 
414 // Same as above, but now go through channels on other Dsolve.
415 void Dsolve::calcOtherJnChan( const DiffJunction& jn, Dsolve* other, double dt )
416 {
417  for ( unsigned int i = 0; i < jn.otherChannels.size(); ++i ) {
418  ConcChanInfo& otherChan = other->channels_[ jn.otherChannels[i] ];
419  // This is the DiffPoolVec for the pools on the other Dsolve,
420  // the one with the channel.
421  // DiffPoolVec& otherDv = other->pools_[ jn.otherPools[otherChan.myPool] ];
422  DiffPoolVec& otherDv = other->pools_[ otherChan.myPool ];
423  // Local diffPoolVec.
424  // DiffPoolVec& myDv = pools_[ jn.myPools[otherChan.otherPool] ];
425  DiffPoolVec& myDv = pools_[ otherChan.otherPool ];
426  DiffPoolVec& chanDv = other->pools_[ otherChan.chanPool ];
427  for ( vector< VoxelJunction >::const_iterator
428  j = jn.vj.begin(); j != jn.vj.end(); ++j ) {
429 
430  double myN = myDv.getN( j->first );
431  double lastN = myN;
432  double otherN = otherDv.getN( j->second );
433  double chanN = chanDv.getN( j->second );
434  double perm = otherChan.permeability * chanN / NA;
435  myN = integ( myN, perm * myN/j->firstVol,
436  perm * otherN/j->secondVol, dt );
437  otherN += lastN - myN; // Mass consv
438  if ( otherN < 0.0 ) { // Avoid negatives
439  myN += otherN;
440  otherN = 0.0;
441  }
442  myDv.setN( j->first, myN );
443  otherDv.setN( j->second, otherN );
444  }
445  }
446 }
447 
457 void Dsolve::calcJunction( const DiffJunction& jn, double dt )
458 {
459  Id oid( jn.otherDsolve );
460  assert ( oid != Id() );
461  assert ( oid.element()->cinfo()->isA( "Dsolve" ) );
462 
463  Dsolve* other = reinterpret_cast< Dsolve* >( oid.eref().data() );
464  calcJnDiff( jn, other, dt/2.0 );
465 
466  calcJnChan( jn, other, dt/2.0 );
467  calcOtherJnChan( jn, other, dt/2.0 );
468 
469  calcJnXfer( jn, jn.myXferSrc, jn.otherXferDest, this, other );
470  calcJnXfer( jn, jn.otherXferSrc, jn.myXferDest, other, this );
471 
472  calcJnDiff( jn, other, dt/2.0 );
473 
474  calcJnChan( jn, other, dt/2.0 );
475  calcOtherJnChan( jn, other, dt/2.0 );
476 }
477 
478 void Dsolve::process( const Eref& e, ProcPtr p )
479 {
480  for ( vector< DiffPoolVec >::iterator
481  i = pools_.begin(); i != pools_.end(); ++i ) {
482  i->advance( p->dt );
483  }
484 }
485 
486 void Dsolve::reinit( const Eref& e, ProcPtr p )
487 {
488  build( p->dt );
489  for ( vector< DiffPoolVec >::iterator
490  i = pools_.begin(); i != pools_.end(); ++i ) {
491  i->reinit();
492  }
493 }
494 
495 void Dsolve::updateJunctions( double dt )
496 {
497  for ( vector< DiffJunction >::const_iterator
498  i = junctions_.begin(); i != junctions_.end(); ++i ) {
499  calcJunction( *i, dt );
500  }
501 }
503 // Solver coordination and setup functions
505 
507 {
508  if ( !id.element()->cinfo()->isA( "Stoich" ) ) {
509  cout << "Dsolve::setStoich::( " << id << " ): Error: provided Id is not a Stoich\n";
510  return;
511  }
512 
513  stoich_ = id;
514  poolMap_ = Field< vector< unsigned int > >::get( stoich_, "poolIdMap" );
515  poolMapStart_ = poolMap_.back();
516  poolMap_.pop_back();
517 
518  path_ = Field< string >::get( stoich_, "path" );
519  // cout << "Pool Info for stoich " << id.path() << endl;
520 
521  for ( unsigned int i = 0; i < poolMap_.size(); ++i ) {
522  unsigned int poolIndex = poolMap_[i];
523  if ( poolIndex != ~0U && poolIndex < pools_.size() ) {
524  // assert( poolIndex < pools_.size() );
525  Id pid( i + poolMapStart_ );
526  assert( pid.element()->cinfo()->isA( "PoolBase" ) );
527  PoolBase* pb =
528  reinterpret_cast< PoolBase* >( pid.eref().data());
529  double diffConst = pb->getDiffConst( pid.eref() );
530  double motorConst = pb->getMotorConst( pid.eref() );
531  pools_[ poolIndex ].setId( pid.value() );
532  pools_[ poolIndex ].setDiffConst( diffConst );
533  pools_[ poolIndex ].setMotorConst( motorConst );
534  /*
535  cout << i << " poolIndex=" << poolIndex <<
536  ", id=" << pid.value() <<
537  ", name=" << pid.element()->getName() << endl;
538  */
539  }
540  }
541  string chanpath = path_ + "[ISA=ConcChan]";
542  vector< ObjId > chans;
543  wildcardFind( chanpath, chans );
544  fillConcChans( chans );
545 }
546 
547 void Dsolve::fillConcChans( const vector< ObjId >& chans )
548 {
549  static const Cinfo* ccc = Cinfo::find( "ConcChan" );
550  static const Finfo* inPoolFinfo = ccc->findFinfo( "inPool" );
551  static const Finfo* outPoolFinfo = ccc->findFinfo( "outPool" );
552  static const Finfo* chanPoolFinfo = ccc->findFinfo( "setNumChan" );
553  FuncId fin = static_cast< const DestFinfo* >( inPoolFinfo )->getFid();
554  FuncId fout = static_cast< const DestFinfo* >(outPoolFinfo )->getFid();
555  FuncId fchan =
556  static_cast< const DestFinfo* >(chanPoolFinfo )->getFid();
557 
558  // Find the in pools and the chan pools on the current compt.
559  // Save the Id of the outPool as an integer.
560  // Use these and the permeability to create the ConcChanInfo.
561  for ( auto i = chans.begin(); i != chans.end(); ++i ) {
562  vector< Id > ret;
563  if (i->element()->getNeighbors( ret, inPoolFinfo ) == 0 ) return;
564  ObjId inPool( ret[0] );
565  ret.clear();
566  if (i->element()->getNeighbors( ret, outPoolFinfo ) == 0 ) return;
567  ObjId outPool( ret[0] );
568  ret.clear();
569  if (i->element()->getNeighbors( ret, chanPoolFinfo ) == 0 ) return;
570  ObjId chanPool( ret[0] );
571  ret.clear();
572  unsigned int outPoolValue = outPool.id.value();
573  bool swapped = false;
574  if ( !( inPool.bad() or chanPool.bad() ) ) {
575  unsigned int inPoolIndex = convertIdToPoolIndex( inPool.id );
576  unsigned int chanPoolIndex = convertIdToPoolIndex(chanPool.id);
577  if ( inPoolIndex == ~0U ) { // Swap in and out as chan is symm
578  inPoolIndex = convertIdToPoolIndex( outPool.id );
579  outPoolValue = inPool.id.value();
580  swapped = true;
581  }
582  if ( ( inPoolIndex != ~0U) && (chanPoolIndex != ~0U ) ) {
583  ConcChanInfo cci(
584  inPoolIndex, outPoolValue, chanPoolIndex,
585  Field< double >::get( *i, "permeability" ),
587  swapped
588  );
589  channels_.push_back( cci );
590  }
591  }
592  }
593 }
594 
596 {
597  return stoich_;
598 }
599 
601 void Dsolve::setDsolve( Id dsolve )
602 {;}
603 
605 {
606  const Cinfo* c = id.element()->cinfo();
607  compartment_ = id;
608  numVoxels_ = Field< unsigned int >::get( id, "numMesh" );
609  if ( c->isA( "CubeMesh" ) ) { // we do only linear diffusion for now
610  unsigned int nx = Field< unsigned int >::get( id, "nx" );
611  unsigned int ny = Field< unsigned int >::get( id, "nx" );
612  unsigned int nz = Field< unsigned int >::get( id, "nx" );
613  if ( !( nx*ny == 1 || nx*nz == 1 || ny*nz == 1 ) ) {
614  cout << "Warning: Dsolve::setCompartment:: Cube mesh: " <<
615  c->name() << " found with >1 dimension of voxels. " <<
616  "Only 1-D diffusion supported for now.\n";
617  return;
618  }
619  }
620 }
621 
622 void Dsolve::makePoolMapFromElist( const vector< ObjId >& elist,
623  vector< Id >& temp )
624 {
625  unsigned int minId = 0;
626  unsigned int maxId = 0;
627  temp.resize( 0 );
628  for ( vector< ObjId >::const_iterator
629  i = elist.begin(); i != elist.end(); ++i ) {
630  if ( i->element()->cinfo()->isA( "PoolBase" ) ) {
631  temp.push_back( i->id );
632  if ( minId == 0 )
633  maxId = minId = i->id.value();
634  else if ( i->id.value() < minId )
635  minId = i->id.value();
636  else if ( i->id.value() > maxId )
637  maxId = i->id.value();
638  }
639  }
640 
641  if ( temp.size() == 0 ) {
642  cout << "Dsolve::makePoolMapFromElist::( " << path_ <<
643  " ): Error: path is has no pools\n";
644  return;
645  }
646 
647  stoich_ = Id();
648  poolMapStart_ = minId;
649  poolMap_.resize( 1 + maxId - minId );
650  for ( auto i = poolMap_.begin(); i != poolMap_.end(); ++i )
651  *i = ~0U;
652  for ( unsigned int i = 0; i < temp.size(); ++i ) {
653  unsigned int idValue = temp[i].value();
654  assert( idValue >= minId );
655  assert( idValue - minId < poolMap_.size() );
656  poolMap_[ idValue - minId ] = i;
657  }
658 }
659 
660 void Dsolve::setPath( const Eref& e, string path )
661 {
662  vector< ObjId > elist;
663  simpleWildcardFind( path, elist );
664  if ( elist.size() == 0 ) {
665  cout << "Dsolve::setPath::( " << path << " ): Error: path is empty\n";
666  return;
667  }
668  vector< Id > temp;
669  makePoolMapFromElist( elist, temp );
670 
671  setNumPools( temp.size() );
672  for ( unsigned int i = 0; i < temp.size(); ++i ) {
673  Id id = temp[i];
674  double diffConst = Field< double >::get( id, "diffConst" );
675  double motorConst = Field< double >::get( id, "motorConst" );
676  const Cinfo* c = id.element()->cinfo();
677  if ( c == Pool::initCinfo() ) {
678  PoolBase::zombify( id.element(), ZombiePool::initCinfo(), Id(), e.id() );
679  } else if ( c == BufPool::initCinfo() ) {
680  PoolBase::zombify( id.element(), ZombieBufPool::initCinfo(), Id(), e.id() );
681  // Any Functions will have to continue to manage the BufPools.
682  // This needs them to be replicated, and for their messages
683  // to be copied over. Not really set up here.
684  } else {
685  cout << "Error: Dsolve::setPath( " << path << " ): unknown pool class:" << c->name() << endl;
686  }
687  id.element()->resize( numVoxels_ );
688 
689  unsigned int j = temp[i].value() - poolMapStart_;
690  assert( j < poolMap_.size() );
691  pools_[ poolMap_[i] ].setId( id.value() );
692  pools_[ poolMap_[j] ].setDiffConst( diffConst );
693  pools_[ poolMap_[j] ].setMotorConst( motorConst );
694  }
695 }
696 
697 string Dsolve::getPath( const Eref& e ) const
698 {
699  return path_;
700 }
701 
703 // Solver building
705 
723 void Dsolve::build( double dt )
724 {
725  if ( doubleEq( dt, dt_ ) )
726  return;
727  if ( compartment_ == Id() ) {
728  cout << "Dsolve::build: Warning: No compartment defined. \n"
729  "Did you forget to assign 'stoich.dsolve = this' ?\n";
730  return;
731  }
732  dt_ = dt;
733  const MeshCompt* m = reinterpret_cast< const MeshCompt* >(
734  compartment_.eref().data() );
735  unsigned int numVoxels = m->getNumEntries();
736 
737  for ( unsigned int i = 0; i < numLocalPools_; ++i ) {
738  bool debugFlag = false;
739  vector< unsigned int > diagIndex;
740  vector< double > diagVal;
741  vector< Triplet< double > > fops;
742  FastMatrixElim elim( numVoxels, numVoxels );
743  if ( elim.buildForDiffusion(
744  m->getParentVoxel(), m->getVoxelVolume(),
745  m->getVoxelArea(), m->getVoxelLength(),
746  pools_[i].getDiffConst(), pools_[i].getMotorConst(), dt ) )
747  {
748  vector< unsigned int > parentVoxel = m->getParentVoxel();
749  assert( elim.checkSymmetricShape() );
750  vector< unsigned int > lookupOldRowsFromNew;
751  elim.hinesReorder( parentVoxel, lookupOldRowsFromNew );
752  assert( elim.checkSymmetricShape() );
753  pools_[i].setNumVoxels( numVoxels_ );
754  elim.buildForwardElim( diagIndex, fops );
755  elim.buildBackwardSub( diagIndex, fops, diagVal );
756  elim.opsReorder( lookupOldRowsFromNew, fops, diagVal );
757  if (debugFlag )
758  elim.print();
759  }
760  pools_[i].setOps( fops, diagVal );
761  }
762 }
763 
767 // Would like to permit vectors of spines and psd compartments.
768 void Dsolve::buildNeuroMeshJunctions( const Eref& e, Id spineD, Id psdD )
769 {
770  if ( !compartment_.element()->cinfo()->isA( "NeuroMesh" ) ) {
771  cout << "Warning: Dsolve::buildNeuroMeshJunction: Compartment '" <<
772  compartment_.path() << "' is not a NeuroMesh\n";
773  return;
774  }
775  Id spineMesh = Field< Id >::get( spineD, "compartment" );
776  if ( !spineMesh.element()->cinfo()->isA( "SpineMesh" ) ) {
777  cout << "Warning: Dsolve::buildNeuroMeshJunction: Compartment '" <<
778  spineMesh.path() << "' is not a SpineMesh\n";
779  return;
780  }
781  Id psdMesh = Field< Id >::get( psdD, "compartment" );
782  if ( !psdMesh.element()->cinfo()->isA( "PsdMesh" ) ) {
783  cout << "Warning: Dsolve::buildNeuroMeshJunction: Compartment '" <<
784  psdMesh.path() << "' is not a PsdMesh\n";
785  return;
786  }
787 
788  innerBuildMeshJunctions( spineD, e.id(), false );
789  innerBuildMeshJunctions( psdD, spineD, false );
790 }
791 
792 void Dsolve::buildMeshJunctions( const Eref& e, Id other )
793 {
794  Id otherMesh;
795  if ( other.element()->cinfo()->isA( "Dsolve" ) ) {
796  otherMesh = Field< Id >::get( other, "compartment" );
797  if ( compartment_.element()->cinfo()->isA( "ChemCompt" ) &&
798  otherMesh.element()->cinfo()->isA( "ChemCompt" ) ) {
799  bool isMembraneBound =
800  Field< bool >::get( compartment_, "isMembraneBound" );
801  innerBuildMeshJunctions( e.id(), other, isMembraneBound );
802  return;
803  }
804  }
805  cout << "Warning: Dsolve::buildMeshJunctions: one of '" <<
806  compartment_.path() << ", " << otherMesh.path() <<
807  "' is not a Mesh\n";
808 }
809 
810 void printJunction( Id self, Id other, const DiffJunction& jn )
811 {
812  cout << "Junction between " << self.path() << ", " << other.path() << endl;
813  cout << "Pool indices: myPools, otherPools\n";
814  for ( unsigned int i = 0; i < jn.myPools.size(); ++i )
815  cout << i << " " << jn.myPools[i] << " " << jn.otherPools[i] << endl;
816  cout << "Voxel junctions: first second firstVol secondVol diffScale\n";
817  for ( unsigned int i = 0; i < jn.vj.size(); ++i ) {
818  cout << i << " " << jn.vj[i].first << " " << jn.vj[i].second <<
819  " " << jn.vj[i].firstVol << " " << jn.vj[i].secondVol <<
820  " " << jn.vj[i].diffScale << endl;
821  }
822 }
823 
825  Id self, Id other)
826 {
827  Dsolve* mySolve = reinterpret_cast< Dsolve* >( self.eref().data() );
828  unordered_map< string, unsigned int > myPools;
829  for ( unsigned int i = 0; i < mySolve->pools_.size(); ++i ) {
830  Id pool( mySolve->pools_[i].getId() );
831  assert( pool != Id() );
832  myPools[ pool.element()->getName() ] = i;
833  }
834 
835  const Dsolve* otherSolve = reinterpret_cast< const Dsolve* >(
836  other.eref().data() );
837  for ( unsigned int i = 0; i < otherSolve->pools_.size(); ++i ) {
838  Id otherPool( otherSolve->pools_[i].getId() );
839  unordered_map< string, unsigned int >::iterator p =
840  myPools.find( otherPool.element()->getName() );
841  if ( p != myPools.end() ) {
842  jn.otherPools.push_back( i );
843  jn.myPools.push_back( p->second );
844  }
845  }
846 }
847 
859  vector< unsigned int >& srcPools, vector< unsigned int >& destPools,
860  Id src, Id dest )
861 {
862  Id destMesh = Field< Id >::get( dest, "compartment" );
863  string xferPost( string( "_xfer_" ) + destMesh.element()->getName() );
864  size_t xlen = xferPost.length();
865 
866  Dsolve* srcSolve = reinterpret_cast< Dsolve* >( src.eref().data() );
867  unordered_map< string, unsigned int > srcMap;
868  for ( unsigned int i = 0; i < srcSolve->pools_.size(); ++i ) {
869  Id pool( srcSolve->pools_[i].getId() );
870  assert( pool != Id() );
871  string poolName = pool.element()->getName();
872  if ( poolName.length() > xlen ) {
873  size_t prefixLen = poolName.length() - xlen;
874  if ( poolName.rfind( xferPost ) == prefixLen )
875  srcMap[ poolName.substr( 0, prefixLen) ] = i;
876  }
877  }
878 
879  const Dsolve* destSolve = reinterpret_cast< const Dsolve* >(
880  dest.eref().data() );
881  for ( unsigned int i = 0; i < destSolve->pools_.size(); ++i ) {
882  Id destPool( destSolve->pools_[i].getId() );
883  unordered_map< string, unsigned int >::iterator p =
884  srcMap.find( destPool.element()->getName() );
885  if ( p != srcMap.end() ) {
886  destPools.push_back( i );
887  srcPools.push_back( p->second );
888  }
889  }
890 }
891 
893 {
894  Dsolve* otherSolve = reinterpret_cast< Dsolve* >(
895  other.eref().data() );
896  Dsolve* selfSolve = reinterpret_cast< Dsolve* >( self.eref().data() );
897  vector< ConcChanInfo >& ch = selfSolve->channels_;
898  unsigned int outIndex;
899  for ( unsigned int i = 0; i < ch.size(); ++i ) {
900  unsigned int chanIndex = ch[i].chanPool;
901  outIndex = otherSolve->convertIdToPoolIndex( ch[i].otherPool );
902  if ( (outIndex != ~0U) && (chanIndex != ~0U ) ) {
903  jn.myChannels.push_back(i);
904  ch[i].otherPool = outIndex; // replace the Id with the index.
905  ch[i].chanPool = chanIndex; //chanIndex may be on either Dsolve
906  }
907  }
908  // Now set up the other Dsolve.
909  vector< ConcChanInfo >& ch2 = otherSolve->channels_;
910  for ( unsigned int i = 0; i < ch2.size(); ++i ) {
911  unsigned int chanIndex = ch2[i].chanPool;
912  outIndex = selfSolve->convertIdToPoolIndex( ch2[i].otherPool );
913  if ( (outIndex != ~0U) && (chanIndex != ~0U) ) {
914  jn.otherChannels.push_back(i);
915  ch2[i].otherPool = outIndex; // replace the Id with the index
916  ch2[i].chanPool = chanIndex; //chanIndex may be on either Dsolve
917  }
918  }
919 }
920 
921 static void mapVoxelsBetweenMeshes( DiffJunction& jn, Id self, Id other)
922 {
923  Id myMesh = Field< Id >::get( self, "compartment" );
924  Id otherMesh = Field< Id >::get( other, "compartment" );
925 
926  const ChemCompt* myCompt = reinterpret_cast< const ChemCompt* >(
927  myMesh.eref().data() );
928  const ChemCompt* otherCompt = reinterpret_cast< const ChemCompt* >(
929  otherMesh.eref().data() );
930  myCompt->matchMeshEntries( otherCompt, jn.vj );
931  vector< double > myVols = myCompt->getVoxelVolume();
932  vector< double > otherVols = otherCompt->getVoxelVolume();
933  for ( vector< VoxelJunction >::iterator
934  i = jn.vj.begin(); i != jn.vj.end(); ++i ) {
935  i->firstVol = myVols[i->first];
936  i->secondVol = otherVols[i->second];
937  }
938 }
939 
940 // Static utility func for building junctions
941 void Dsolve::innerBuildMeshJunctions( Id self, Id other, bool selfIsMembraneBound )
942 {
943  DiffJunction jn; // This is based on the Spine Dsolver.
944  jn.otherDsolve = other.value();
945  Dsolve* dself = reinterpret_cast< Dsolve* >( self.eref().data() );
946  if ( selfIsMembraneBound ) {
947  mapChansBetweenDsolves( jn, self, other );
948  } else {
949  mapDiffPoolsBetweenDsolves( jn, self, other );
950  }
951  mapXfersBetweenDsolves( jn.myXferSrc, jn.otherXferDest, self, other );
952  mapXfersBetweenDsolves( jn.otherXferSrc, jn.myXferDest, other, self );
953 
954  mapVoxelsBetweenMeshes( jn, self, other );
955 
956 
957  // printJunction( self, other, jn );
958  dself->junctions_.push_back( jn );
959 }
960 
962 // Zombie Pool Access functions
964 //
965 unsigned int Dsolve::getNumVarPools() const
966 {
967  return 0;
968 }
969 
970 unsigned int Dsolve::getNumVoxels() const
971 {
972  return numVoxels_;
973 }
974 
975 void Dsolve::setNumAllVoxels( unsigned int num )
976 {
977  numVoxels_ = num;
978  for ( unsigned int i = 0 ; i < numLocalPools_; ++i )
979  pools_[i].setNumVoxels( numVoxels_ );
980 }
981 
982 unsigned int Dsolve::convertIdToPoolIndex( const Id id ) const
983 {
984  unsigned int i = id.value() - poolMapStart_;
985  if ( i < poolMap_.size() ) {
986  return poolMap_[i];
987  }
988  cout << "Warning: Dsolve::convertIdToPoollndex: Id out of range, (" <<
989  poolMapStart_ << ", " << id << ", " << id.path() << ", " <<
990  poolMap_.size() + poolMapStart_ << "\n";
991  return 0;
992 }
993 
994 unsigned int Dsolve::convertIdToPoolIndex( const Eref& e ) const
995 {
996  return convertIdToPoolIndex( e.id() );
997 }
998 
999 void Dsolve::setN( const Eref& e, double v )
1000 {
1001  unsigned int pid = convertIdToPoolIndex( e );
1002  // Ignore silently, as this may be a valid pid for the ksolve to use.
1003  if ( pid >= pools_.size() )
1004  return;
1005  unsigned int vox = e.dataIndex();
1006  if ( vox < numVoxels_ ) {
1007  pools_[ pid ].setN( vox, v );
1008  return;
1009  }
1010  cout << "Warning: Dsolve::setN: Eref " << e << " out of range " <<
1011  pools_.size() << ", " << numVoxels_ << "\n";
1012 }
1013 
1014 double Dsolve::getN( const Eref& e ) const
1015 {
1016  unsigned int pid = convertIdToPoolIndex( e );
1017  if ( pid >= pools_.size() ) return 0.0; // ignore silently
1018  unsigned int vox = e.dataIndex();
1019  if ( vox < numVoxels_ ) {
1020  return pools_[ pid ].getN( vox );
1021  }
1022  cout << "Warning: Dsolve::setN: Eref " << e << " out of range " <<
1023  pools_.size() << ", " << numVoxels_ << "\n";
1024  return 0.0;
1025 }
1026 
1027 void Dsolve::setNinit( const Eref& e, double v )
1028 {
1029  unsigned int pid = convertIdToPoolIndex( e );
1030  if ( pid >= pools_.size() ) // Ignore silently
1031  return;
1032  unsigned int vox = e.dataIndex();
1033  if ( vox < numVoxels_ ) {
1034  pools_[ pid ].setNinit( vox, v );
1035  return;
1036  }
1037  cout << "Warning: Dsolve::setNinit: Eref " << e << " out of range " <<
1038  pools_.size() << ", " << numVoxels_ << "\n";
1039 }
1040 
1041 double Dsolve::getNinit( const Eref& e ) const
1042 {
1043  unsigned int pid = convertIdToPoolIndex( e );
1044  if ( pid >= pools_.size() ) return 0.0; // ignore silently
1045  unsigned int vox = e.dataIndex();
1046  if ( vox < numVoxels_ ) {
1047  return pools_[ pid ].getNinit( vox );
1048  }
1049  cout << "Warning: Dsolve::setNinit: Eref " << e << " out of range " <<
1050  pools_.size() << ", " << numVoxels_ << "\n";
1051  return 0.0;
1052 }
1053 
1054 void Dsolve::setDiffConst( const Eref& e, double v )
1055 {
1056  unsigned int pid = convertIdToPoolIndex( e );
1057  if ( pid >= pools_.size() ) // Ignore silently, out of range.
1058  return;
1059  pools_[ convertIdToPoolIndex( e ) ].setDiffConst( v );
1060 }
1061 
1062 double Dsolve::getDiffConst( const Eref& e ) const
1063 {
1064  unsigned int pid = convertIdToPoolIndex( e );
1065  if ( pid >= pools_.size() ) // Ignore silently, out of range.
1066  return 0.0;
1067  return pools_[ convertIdToPoolIndex( e ) ].getDiffConst();
1068 }
1069 
1070 void Dsolve::setMotorConst( const Eref& e, double v )
1071 {
1072  unsigned int pid = convertIdToPoolIndex( e );
1073  if ( pid >= pools_.size() ) // Ignore silently, out of range.
1074  return;
1075  pools_[ convertIdToPoolIndex( e ) ].setMotorConst( v );
1076 }
1077 
1078 void Dsolve::setNumPools( unsigned int numPoolSpecies )
1079 {
1080  // Decompose numPoolSpecies here, assigning some to each node.
1081  numTotPools_ = numPoolSpecies;
1082  numLocalPools_ = numPoolSpecies;
1083  poolStartIndex_ = 0;
1084 
1085  pools_.resize( numLocalPools_ );
1086  for ( unsigned int i = 0 ; i < numLocalPools_; ++i ) {
1087  pools_[i].setNumVoxels( numVoxels_ );
1088  // pools_[i].setId( reversePoolMap_[i] );
1089  // pools_[i].setParent( me );
1090  }
1091 }
1092 
1093 unsigned int Dsolve::getNumPools() const
1094 {
1095  return numTotPools_;
1096 }
1097 
1098 // July 2014: This is half-baked wrt the startPool.
1099 void Dsolve::getBlock( vector< double >& values ) const
1100 {
1101  unsigned int startVoxel = values[0];
1102  unsigned int numVoxels = values[1];
1103  unsigned int startPool = values[2];
1104  unsigned int numPools = values[3];
1105 
1106  assert( startVoxel + numVoxels <= numVoxels_ );
1107  assert( startPool >= poolStartIndex_ );
1108  assert( numPools + startPool <= numLocalPools_ );
1109  values.resize( 4 );
1110 
1111  for ( unsigned int i = 0; i < numPools; ++i ) {
1112  unsigned int j = i + startPool;
1113  if ( j >= poolStartIndex_ && j < poolStartIndex_ + numLocalPools_ ){
1114  vector< double >::const_iterator q =
1115  pools_[ j - poolStartIndex_ ].getNvec().begin();
1116 
1117  values.insert( values.end(),
1118  q + startVoxel, q + startVoxel + numVoxels );
1119  }
1120  }
1121 }
1122 
1123 // Inefficient but easy to set up. Optimize later.
1125 {
1126  for ( auto i = pools_.begin(); i != pools_.end(); ++i ) {
1127  // if (i->getDiffConst() > 0.0 )
1128  i->setPrevVec();
1129  }
1130 }
1131 
1132 void Dsolve::setBlock( const vector< double >& values )
1133 {
1134  unsigned int startVoxel = values[0];
1135  unsigned int numVoxels = values[1];
1136  unsigned int startPool = values[2];
1137  unsigned int numPools = values[3];
1138 
1139  assert( startVoxel + numVoxels <= numVoxels_ );
1140  assert( startPool >= poolStartIndex_ );
1141  assert( numPools + startPool <= numLocalPools_ );
1142  assert( values.size() == 4 + numVoxels * numPools );
1143 
1144  for ( unsigned int i = 0; i < numPools; ++i ) {
1145  unsigned int j = i + startPool;
1146  if ( j >= poolStartIndex_ && j < poolStartIndex_ + numLocalPools_ ){
1147  vector< double >::const_iterator
1148  q = values.begin() + 4 + i * numVoxels;
1149  pools_[ j - poolStartIndex_ ].setNvec( startVoxel, numVoxels, q );
1150  }
1151  }
1152 }
1153 
1155 // Inherited virtual
1156 
1157 void Dsolve::updateRateTerms( unsigned int index )
1158 {
1159  ;
1160 }
1161 
1162 unsigned int Dsolve::getPoolIndex( const Eref& e ) const
1163 {
1164  return convertIdToPoolIndex( e );
1165 }
1166 
1167 unsigned int Dsolve::getNumLocalVoxels() const
1168 {
1169  return numVoxels_;
1170 }
1171 
1172 VoxelPoolsBase* Dsolve::pools( unsigned int i )
1173 {
1174  return 0;
1175 }
1176 
1177 double Dsolve::volume( unsigned int i ) const
1178 {
1179  return 1.0;
1180 }
void setNumAllVoxels(unsigned int numVoxels)
Inherited virtual.
Definition: Dsolve.cpp:975
int wildcardFind(const string &path, vector< ObjId > &ret)
Definition: Wildcard.cpp:169
Id id() const
Definition: Eref.cpp:62
void fillConcChans(const vector< ObjId > &chans)
Definition: Dsolve.cpp:547
char * data() const
Definition: Eref.cpp:41
uint32_t value
Definition: moosemodule.h:42
void calcJunction(const DiffJunction &jn, double dt)
Definition: Dsolve.cpp:457
string getPath(const Eref &e) const
Definition: Dsolve.cpp:697
double getDiffScale(unsigned int voxel) const
Definition: Dsolve.cpp:282
void setDiffScale(unsigned int voxel, double scale)
Definition: Dsolve.cpp:274
string path_
Path of pools managed by Dsolve, may include other classes too.
Definition: Dsolve.h:196
unsigned int poolMapStart_
smallest Id value for poolMap_
Definition: Dsolve.h:212
unsigned int numVoxels_
Definition: Dsolve.h:204
void setN(unsigned int vox, double value)
Definition: DiffPoolVec.cpp:50
const double NA
Definition: consts.cpp:15
unsigned int getNumVoxels() const
Definition: Dsolve.cpp:970
Element * element() const
Synonym for Id::operator()()
Definition: Id.cpp:113
void setPath(const Eref &e, string path)
Dummy, inherited but not used.
Definition: Dsolve.cpp:660
void buildBackwardSub(vector< unsigned int > &diag, vector< Triplet< double > > &bops, vector< double > &diagVal)
static const Cinfo * initCinfo()
Definition: ZombiePool.cpp:21
static void innerBuildMeshJunctions(Id self, Id other, bool isMembraneBound)
Definition: Dsolve.cpp:941
unsigned int getNumLocalVoxels() const
Number of voxels here. pools_.size() == getNumLocalVoxels.
Definition: Dsolve.cpp:1167
bool bad() const
Definition: ObjId.cpp:18
std::string path(const std::string &separator="/") const
Definition: Id.cpp:76
void setNumPools(unsigned int num)
Specifies number of pools (species) handled by system.
Definition: Dsolve.cpp:1078
unsigned int value() const
Definition: Id.cpp:197
Definition: Dinfo.h:60
double diffScale
Definition: VoxelJunction.h:44
Definition: SetGet.h:236
Definition: EpFunc.h:64
vector< double > getVoxelVolume() const
Returns vector of all voxel volumes in compartment.
Definition: ChemCompt.cpp:313
Id id
Definition: ObjId.h:98
unsigned int dataIndex() const
Definition: Eref.h:50
double getNinit(const Eref &e) const
get initial # of molecules in given pool and voxel. Bdry cond.
Definition: Dsolve.cpp:1041
unsigned int numTotPools_
Definition: Dsolve.h:201
static const Cinfo * find(const std::string &name)
Definition: Cinfo.cpp:200
vector< unsigned int > otherPools
Definition: DiffJunction.h:38
unsigned int chanPool
Definition: ConcChanInfo.h:28
Definition: Dsolve.h:29
int simpleWildcardFind(const string &path, vector< ObjId > &ret)
Definition: Wildcard.cpp:137
vector< DiffJunction > junctions_
Definition: Dsolve.h:222
Definition: ObjId.h:20
double getDiffVol2(unsigned int voxel) const
Definition: Dsolve.cpp:265
bool hinesReorder(const vector< unsigned int > &parentVoxel, vector< unsigned int > &lookupOldRowsFromNew)
unsigned int otherPool
Definition: ConcChanInfo.h:27
Eref eref() const
Definition: Id.cpp:125
static void mapChansBetweenDsolves(DiffJunction &jn, Id self, Id other)
Definition: Dsolve.cpp:892
void calcJnDiff(const DiffJunction &jn, Dsolve *other, double dt)
Definition: Dsolve.cpp:309
double dt_
Timestep used by diffusion calculations.
Definition: Dsolve.h:199
vector< unsigned int > otherXferSrc
Definition: DiffJunction.h:44
Id getStoich() const
Definition: Dsolve.cpp:595
virtual vector< unsigned int > getParentVoxel() const =0
unsigned int otherDsolve
Definition: DiffJunction.h:36
void setStoich(Id id)
Definition: Dsolve.cpp:506
void setMotorConst(const Eref &e, double value)
Definition: Dsolve.cpp:1070
static void zombify(Element *original, const Cinfo *zClass, Id ksolve, Id dsolve)
Definition: PoolBase.cpp:430
unsigned int getNumEntries() const
Definition: ChemCompt.cpp:390
double getDiffConst() const
Definition: DiffPoolVec.cpp:87
vector< double > getNvec(unsigned int pool) const
Definition: Dsolve.cpp:215
bool doubleEq(double x, double y)
Definition: doubleEq.cpp:16
const std::string & name() const
Definition: Cinfo.cpp:260
void setNinit(const Eref &e, double value)
Set initial # of molecules in given pool and voxel. Bdry cond.
Definition: Dsolve.cpp:1027
void setNvec(unsigned int pool, vector< double > vec)
Definition: Dsolve.cpp:204
static double integ(double myN, double rf, double rb, double dt)
Definition: Dsolve.cpp:295
static const Cinfo * initCinfo()
double volume(unsigned int i) const
Return volume of voxel i.
Definition: Dsolve.cpp:1177
static const Cinfo * initCinfo()
Definition: BufPool.cpp:18
void printJunction(Id self, Id other, const DiffJunction &jn)
Definition: Dsolve.cpp:810
void calcJnChan(const DiffJunction &jn, Dsolve *other, double dt)
Definition: Dsolve.cpp:373
vector< ConcChanInfo > channels_
Internal vector, one for each ConcChan managed by Dsolve.
Definition: Dsolve.h:209
void setDiffConst(const Eref &e, double value)
Diffusion constant: Only one per pool, voxel number is ignored.
Definition: Dsolve.cpp:1054
static const Cinfo * dsolveCinfo
Definition: Dsolve.cpp:183
void setPrev()
Used to tell Dsolver to assign 'prev' values.
Definition: Dsolve.cpp:1124
static const Cinfo * initCinfo()
Definition: Dsolve.cpp:36
static const Cinfo * initCinfo()
Definition: Pool.cpp:18
double dt
Definition: ProcInfo.h:18
vector< unsigned int > myPools
Definition: DiffJunction.h:37
void getBlock(vector< double > &values) const
Definition: Dsolve.cpp:1099
vector< unsigned int > myChannels
Definition: DiffJunction.h:46
void buildMeshJunctions(const Eref &e, Id other)
Definition: Dsolve.cpp:792
static void mapVoxelsBetweenMeshes(DiffJunction &jn, Id self, Id other)
Definition: Dsolve.cpp:921
double permeability
Definition: ConcChanInfo.h:32
unsigned int myPool
Definition: ConcChanInfo.h:26
void setDsolve(Id id)
Inherited, defining dummy function here.
Definition: Dsolve.cpp:601
static void opsReorder(const vector< unsigned int > &lookupOldRowsFromNew, vector< Triplet< double > > &ops, vector< double > &diagVal)
vector< unsigned int > myXferSrc
Definition: DiffJunction.h:40
void makePoolMapFromElist(const vector< ObjId > &elist, vector< Id > &temp)
Definition: Dsolve.cpp:622
Definition: Eref.h:26
bool isA(const string &ancestor) const
Definition: Cinfo.cpp:280
double secondVol
Definition: VoxelJunction.h:43
bool checkSymmetricShape() const
const Cinfo * cinfo() const
Definition: Element.cpp:66
vector< unsigned int > otherXferDest
Definition: DiffJunction.h:41
static void mapXfersBetweenDsolves(vector< unsigned int > &srcPools, vector< unsigned int > &destPools, Id src, Id dest)
Definition: Dsolve.cpp:858
void calcJnXfer(const DiffJunction &jn, const vector< unsigned int > &srcXfer, const vector< unsigned int > &destXfer, Dsolve *srcDsolve, Dsolve *destDsolve)
Definition: Dsolve.cpp:349
unsigned int numLocalPools_
Definition: Dsolve.h:202
double firstVol
MeshIndex for second compartment.
Definition: VoxelJunction.h:42
void setBlock(const vector< double > &values)
Definition: Dsolve.cpp:1132
vector< unsigned int > myXferDest
Definition: DiffJunction.h:43
void print() const
Definition: SparseMatrix.h:650
vector< DiffPoolVec > pools_
Internal vector, one for each pool species managed by Dsolve.
Definition: Dsolve.h:207
virtual const vector< double > & getVoxelArea() const =0
unsigned int getPoolIndex(const Eref &e) const
Return pool index, using Stoich ptr to do lookup.
Definition: Dsolve.cpp:1162
unsigned int getNumVarPools() const
Definition: Dsolve.cpp:965
void setDiffVol2(unsigned int voxel, double vol)
Definition: Dsolve.cpp:257
void updateJunctions(double dt)
Used for telling Dsolver to handle all ops across Junctions.
Definition: Dsolve.cpp:495
double getDiffVol1(unsigned int voxel) const
LookupFied for examining cross-solver diffusion terms.
Definition: Dsolve.cpp:248
void setN(const Eref &e, double value)
Set # of molecules in given pool and voxel. Varies with time.
Definition: Dsolve.cpp:999
static void mapDiffPoolsBetweenDsolves(DiffJunction &jn, Id self, Id other)
Sets up map of matching pools for diffusion.
Definition: Dsolve.cpp:824
void setCompartment(Id id)
Assigns compartment.
Definition: Dsolve.cpp:604
~Dsolve()
Definition: Dsolve.cpp:197
static bool checkJn(const vector< DiffJunction > &jn, unsigned int voxel, const string &info)
Definition: Dsolve.cpp:225
virtual const vector< double > & getVoxelLength() const =0
Id compartment_
Id of Chem compartment used to figure out volumes of voxels.
Dsolve()
Definition: Dsolve.cpp:188
unsigned int getNumPools() const
gets number of pools (species) handled by system.
Definition: Dsolve.cpp:1093
void calcOtherJnChan(const DiffJunction &jn, Dsolve *other, double dt)
Definition: Dsolve.cpp:415
bool buildForDiffusion(const vector< unsigned int > &parentVoxel, const vector< double > &volume, const vector< double > &area, const vector< double > &length, double diffConst, double motorConst, double dt)
This function makes the diffusion matrix.
Definition: Id.h:17
virtual void matchMeshEntries(const ChemCompt *other, vector< VoxelJunction > &ret) const =0
void reinit(const Eref &e, ProcPtr p)
Definition: Dsolve.cpp:486
vector< VoxelJunction > vj
Definition: DiffJunction.h:49
static A get(const ObjId &dest, const string &field)
Definition: SetGet.h:284
void build(double dt)
Definition: Dsolve.cpp:723
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
VoxelPoolsBase * pools(unsigned int i)
Return a pointer to the specified VoxelPool.
Definition: Dsolve.cpp:1172
void setDiffVol1(unsigned int voxel, double vol)
Definition: Dsolve.cpp:240
void process(const Eref &e, ProcPtr p)
Definition: Dsolve.cpp:478
static char id[]
Definition: mfield.cpp:404
unsigned int FuncId
Definition: header.h:42
#define EPSILON
Definition: MatrixOps.h:28
double getDiffConst(const Eref &e) const
Definition: PoolBase.cpp:358
double getN(const Eref &e) const
Get # of molecules in given pool and voxel. Varies with time.
Definition: Dsolve.cpp:1014
const string & getName() const
Definition: Element.cpp:56
double getDiffConst(const Eref &e) const
Diffusion constant: Only one per pool, voxel number is ignored.
Definition: Dsolve.cpp:1062
void buildNeuroMeshJunctions(const Eref &e, Id spineD, Id psdD)
Definition: Dsolve.cpp:768
void updateRateTerms(unsigned int index)
Definition: Dsolve.cpp:1157
Definition: Cinfo.h:18
static char path[]
Definition: mfield.cpp:403
void buildForwardElim(vector< unsigned int > &diag, vector< Triplet< double > > &fops)
vector< unsigned int > poolMap_
Looks up pool# from pool Id, using poolMapStart_ as offset.
Definition: Dsolve.h:215
unsigned int convertIdToPoolIndex(Id id) const
Definition: Dsolve.cpp:982
vector< unsigned int > otherChannels
Definition: DiffJunction.h:47
Definition: EpFunc.h:79
double getN(unsigned int vox) const
Definition: DiffPoolVec.cpp:44
double getPrev(unsigned int vox) const
Definition: DiffPoolVec.cpp:56
const Finfo * findFinfo(const string &name) const
Definition: Cinfo.cpp:224
unsigned int poolStartIndex_
Definition: Dsolve.h:203
Definition: Finfo.h:12