9 #include "../basecode/header.h"
10 #include "../basecode/global.h"
12 #include "../mesh/VoxelJunction.h"
33 #define SIMPLE_ROUNDING 0
45 "Stoichiometry object for handling this reaction system.",
52 "Compartment that contains this reaction system.",
59 "Number of voxels in the core reac-diff system, on the "
64 Gsolve,
unsigned int, vector< double > > nVec(
66 "vector of pool counts",
72 "Number of voxels in the entire reac-diff system, "
73 "including proxy voxels to represent abutting compartments.",
80 "Number of molecular pools in the entire reac-diff system, "
81 "including variable, function and buffered.",
88 "Flag: True when using probabilistic (random) rounding.\n "
90 "When initializing the mol# from floating-point Sinit values, "
91 "we have two options. One is to look at each Sinit, and round "
92 "to the nearest integer. The other is to look at each Sinit, "
93 "and probabilistically round up or down depending on the "
94 "value. For example, if we had a Sinit value of 1.49, "
95 "this would always be rounded to 1.0 if the flag is false, "
96 "and would be rounded to 1.0 and 2.0 in the ratio 51:49 if "
104 "Flag: True to cause all reaction propensities to be updated "
105 "on every clock tick.\n"
107 "This flag should be set when the reaction system "
108 "includes a function with a dependency on time or on external "
109 "events. It has a significant speed penalty so the flag "
110 "should not be set unless there are such functions. " ,
115 Gsolve,
unsigned int, vector< unsigned int > > numFire(
117 "Vector of the number of times each reaction has fired."
118 "Indexed by the voxel number."
119 "Zeroed out at reinit.",
128 "Handles process call",
131 "Handles reinit call",
135 "Handles updates to all voxels. Comes from parent "
137 new OpFunc1< Gsolve, vector< double > >(
142 "Handles initProc call from Clock",
145 "Handles initReinit call from Clock",
151 static Finfo* procShared[] =
156 "Shared message for process and reinit",
157 procShared,
sizeof( procShared ) /
sizeof(
const Finfo* )
160 static Finfo* initShared[] =
165 "Shared message for initProc and initReinit. This is used"
166 " when the system has cross-compartment reactions. ",
167 initShared,
sizeof( initShared ) /
sizeof(
const Finfo* )
172 static Finfo* gsolveFinfos[] =
193 sizeof(gsolveFinfos)/
sizeof(
Finfo *),
207 #if PARALLELIZE_GSOLVE_WITH_CPP11_ASYNC
214 useClockedUpdate_( false )
243 vector< double > vols =
245 if ( vols.size() > 0 )
247 pools_.resize( vols.size() );
248 for (
unsigned int i = 0; i < vols.size(); ++i )
250 pools_[i].setVolume( vols[i] );
274 for (
unsigned int i = 0; i <
pools_.size(); ++i )
291 if ( numVoxels == 0 )
295 pools_.resize( numVoxels );
301 static vector< double >
dummy;
302 if ( voxel <
pools_.size() )
311 if ( voxel <
pools_.size() )
313 if ( nVec.size() !=
pools_[voxel].size() )
315 cout <<
"Warning: Gsolve::setNvec: size mismatch ( " <<
316 nVec.size() <<
", " <<
pools_[voxel].size() <<
")\n";
319 double* s =
pools_[voxel].varS();
320 for (
unsigned int i = 0; i < nVec.size(); ++i )
322 s[i] = round( nVec[i] );
333 static vector< unsigned int >
dummy;
334 if ( voxel <
pools_.size() )
363 #if PARALLELIZE_GSOLVE_WITH_CPP11_ASYNC
375 std::atomic<int> idx( begin );
376 for (
size_t cpu = 0; cpu != nWorkers; ++cpu)
378 std::async( std::launch::async,
379 [
this, &idx, end, p, sys]()
386 pools_[i].advance( p, sys);
408 vector< double > dvalues( 4 );
419 vector< double >::iterator i = dvalues.begin() + 4;
421 for ( ; i != dvalues.end(); ++i )
427 double base = floor( *i );
443 for ( vector< GssaVoxelPools >::iterator
446 i->refreshAtot( &
sys_ );
451 size_t nvPools =
pools_.size( );
453 #if PARALLELIZE_GSOLVE_WITH_CPP11_ASYNC
456 if( 1 == getNumThreads( ) || 1 == nvPools )
458 for (
size_t i = 0; i < nvPools; i++ )
467 size_t grainSize = min( nvPools, 1 + (nvPools / numThreads_ ) );
468 size_t nWorkers = nvPools / grainSize;
470 for (
size_t i = 0; i < nWorkers; i++)
475 for (
size_t i = 0; i < nvPools; i++ )
488 vector< double > kvalues( 4 );
510 for ( vector< GssaVoxelPools >::iterator
516 for ( vector< GssaVoxelPools >::iterator
519 i->refreshAtot( &
sys_ );
522 #if PARALLELIZE_GSOLVE_WITH_CPP11_ASYNC
523 if( 1 < getNumThreads( ) )
524 cout <<
"Info: Using threaded gsolve: " << getNumThreads( )
525 <<
" threads. " << endl;
539 for (
unsigned int i = 0 ; i <
pools_.size(); ++i )
564 for ( vector< GssaVoxelPools >::iterator
583 vector< unsigned int > indices;
587 map< unsigned int, unsigned int > enzMolMap;
588 for (
unsigned int i = 0; i < numRates; ++i )
594 vector< unsigned int > reactants;
596 if ( reactants.size() > 1 )
597 enzMolMap[ reactants.front() ] = i;
602 for (
unsigned int i = 0; i < numRates; ++i )
606 const unsigned int* colIndex;
608 unsigned int numInRow =
610 for(
unsigned int j = 0; j < numInRow; ++j )
612 map< unsigned int, unsigned int >::iterator pos =
613 enzMolMap.find( colIndex[j] );
614 if ( pos != enzMolMap.end() )
634 vector< vector< unsigned int > > funcMap(
637 for (
unsigned int i = 0; i < numFuncs; ++i )
641 for (
unsigned int j = 0; j < molIndex.size(); ++j )
642 funcMap[ molIndex[j] ].push_back( i );
648 vector< unsigned int > indices;
649 for (
unsigned int i = 0; i < numRates; ++i )
655 const unsigned int* colIndex;
656 unsigned int numInRow =
658 for (
unsigned int j = 0; j < numInRow; ++j )
660 unsigned int molIndex = colIndex[j];
661 vector< unsigned int >& funcs = funcMap[ molIndex ];
662 dep.insert( dep.end(), funcs.begin(), funcs.end() );
663 for (
unsigned int k = 0; k < funcs.size(); ++k )
669 vector< unsigned int > c;
671 getRow( outputMol, e, c );
674 rdep.insert( rdep.end(), c.begin(), c.end() );
697 vector< vector< unsigned int > > funcMap(
700 vector< FuncRate* > incrementRates;
701 vector< unsigned int > incrementRateIndex;
702 const vector< RateTerm* >::const_iterator q;
703 for (
unsigned int i = 0; i < rates.size(); ++i )
706 dynamic_cast< FuncRate*
>( rates[i] );
709 incrementRates.push_back( term );
710 incrementRateIndex.push_back( i );
714 for (
unsigned int k = 0; k < incrementRates.size(); ++k )
716 const vector< unsigned int >& molIndex =
717 incrementRates[k]->getFuncArgIndex();
718 for (
unsigned int j = 0; j < molIndex.size(); ++j )
719 funcMap[ molIndex[j] ].push_back( incrementRateIndex[k] );
724 vector< unsigned int > indices;
725 for (
unsigned int i = 0; i < numRates; ++i )
734 const unsigned int* colIndex;
735 unsigned int numInRow =
739 for (
unsigned int j = 0; j < numInRow; ++j )
741 unsigned int molIndex = colIndex[j];
744 vector< unsigned int >& funcs = funcMap[ molIndex ];
747 rdep.insert( rdep.end(), funcs.begin(), funcs.end() );
806 unsigned int firedReac )
825 for (
unsigned int i = 0; i < numRates; ++i )
829 sort( dep.begin(), dep.end() );
830 vector< unsigned int >::iterator k = dep.begin();
833 vector< unsigned int >::iterator pos =
834 unique( dep.begin(), dep.end() );
835 dep.resize( pos - dep.begin() );
859 if ( dsolve ==
Id () )
872 cout <<
"Warning: Gsolve::setDsolve: Object '" << dsolve.
path() <<
873 "' should be class Dsolve, is: " <<
956 unsigned int numVoxels =
pools_.size();
957 for (
unsigned int i = 0 ; i < numVoxels; ++i )
959 pools_[i].resizeArrays( numPoolSpecies );
972 unsigned int startVoxel = values[0];
973 unsigned int numVoxels = values[1];
974 unsigned int startPool = values[2];
975 unsigned int numPools = values[3];
978 assert( numVoxels <=
pools_.size() );
979 assert(
pools_.size() > 0 );
980 assert( numPools + startPool <=
pools_[0].size() );
981 values.resize( 4 + numVoxels * numPools );
983 for (
unsigned int i = 0; i < numVoxels; ++i )
985 const double* v =
pools_[ startVoxel + i ].S();
986 for (
unsigned int j = 0; j < numPools; ++j )
988 values[ 4 + j * numVoxels + i] = v[ j + startPool ];
995 unsigned int startVoxel = values[0];
996 unsigned int numVoxels = values[1];
997 unsigned int startPool = values[2];
998 unsigned int numPools = values[3];
1001 assert( numVoxels <=
pools_.size() );
1002 assert(
pools_.size() > 0 );
1003 assert( numPools + startPool <=
pools_[0].size() );
1005 for (
unsigned int i = 0; i < numVoxels; ++i )
1007 double* v =
pools_[ startVoxel + i ].varS();
1008 for (
unsigned int j = 0; j < numPools; ++j )
1010 v[ j + startPool ] = values[ 4 + j * numVoxels + i ];
1021 if ( vols.size() ==
pools_.size() )
1023 for (
unsigned int i = 0; i < vols.size(); ++i )
1025 pools_[i].setVolumeAndDependencies( vols[i] );
1036 for (
unsigned int i = 0 ; i <
pools_.size(); ++i )
1042 else if ( index < stoichPtr_->getNumRates() )
1044 for (
unsigned int i = 0 ; i <
pools_.size(); ++i )
1062 return pools_[i].getVolume();
1066 #if PARALLELIZE_GSOLVE_WITH_CPP11_ASYNC
1067 unsigned int Gsolve::getNumThreads( )
const
1072 void Gsolve::setNumThreads(
unsigned int x )
unsigned int getNumAllVoxels() const
void fillIncrementFuncDep()
Id init(int argc, char **argv, bool &doUnitTests, bool &doRegressionTests, unsigned int &benchmark)
bool getRandInit() const
Flag: returns true if randomized round to integers is done.
double getN(const Eref &e) const
Get # of molecules in given pool and voxel. Varies with time.
Id getCompartment() const
Inherited from ZombiePoolInterface.
void updateVoxelVol(vector< double > vols)
virtual unsigned int getReactants(vector< unsigned int > &molIndex) const =0
Gsolve & operator=(const Gsolve &)
const unsigned int getTarget() const
Element * element() const
Synonym for Id::operator()()
unsigned int getVoxelIndex(const Eref &e) const
vector< vector< unsigned int > > dependency
std::string path(const std::string &separator="/") const
void process(const Eref &e, ProcPtr p)
unsigned int getRow(unsigned int row, const T **entry, const unsigned int **colIndex) const
static DestFinfo dummy("dummy","This Finfo is a dummy. If you are reading this you have used an invalid index", 0)
void setStoich(Id stoich)
void setRandInit(bool val)
Flag: set true if randomized round to integers is to be done.
static const Cinfo * initCinfo()
const unsigned int OFFNODE
void setNvec(unsigned int voxel, vector< double > vec)
unsigned int startVoxel_
First voxel indexed on the current node.
unsigned int dataIndex() const
unsigned int getPoolIndex(const Eref &e) const
Return pool index, using Stoich ptr to do lookup.
const KinSparseMatrix & getStoichiometryMatrix() const
Updates the rates for cross-compartment reactions.
Stoich * stoichPtr_
Utility ptr used to help Pool Id lookups by the Ksolve.
void initReinit(const Eref &e, ProcPtr p)
virtual void updateJunctions(double dt)
Used for telling Dsolver to handle all ops across Junctions.
Element * element() const
vector< vector< unsigned int > > dependentMathExpn
double getDiffConst(const Eref &e) const
Diffusion constant: Only one per pool, voxel number is ignored.
static const Cinfo * gsolveCinfo
void setN(const Eref &e, double v)
Set # of molecules in given pool and voxel. Varies with time.
void updateRateTerms(unsigned int index)
void advance(vector< double > &y, const vector< Triplet< double > > &ops, const vector< double > &diagVal)
void setClockedUpdate(bool val)
Flag: set true if randomized round to integers is to be done.
double getNinit(const Eref &e) const
get initial # of molecules in given pool and voxel. Bdry cond.
unsigned int getNumPools() const
Inherited.
vector< double > & Svec()
Returns a handle to the mol # vector.
void getGillespieDependence(unsigned int row, vector< unsigned int > &cols) const
const std::string & name() const
unsigned int convertIdToPoolIndex(Id id) const
VoxelPoolsBase * pools(unsigned int i)
Inherited.
vector< GssaVoxelPools > pools_
unsigned int getNumLocalVoxels() const
Number of voxels here. pools_.size() == getNumLocalVoxels.
unsigned int getNumFuncs() const
KinSparseMatrix transposeN
Transpose of stoichiometry matrix.
const FuncTerm * funcs(unsigned int i) const
void getBlock(vector< double > &values) const
void setCompartment(Id compt)
Assigns compartment.
void insertMathDepReacs(unsigned int mathDepIndex, unsigned int firedReac)
bool isA(const string &ancestor) const
bool useClockedUpdate_
Flag: True if atot should be updated every clock tick.
void setDsolve(Id dsolve)
virtual void setPrev()
Used to tell Dsolver to assign 'prev' values.
const Cinfo * cinfo() const
void truncateRow(unsigned int maxColumnIndex)
unsigned int getNumRates() const
unsigned int getNumVarPools() const
Returns number of local pools that are updated by solver.
vector< unsigned int > numFire() const
void setBlock(const vector< double > &values)
bool getClockedUpdate() const
Flag: returns true if randomized round to integers is done.
ZombiePoolInterface * dsolvePtr_
Pointer to diffusion solver.
const vector< unsigned int > & getReactantIndex() const
void setDiffConst(const Eref &e, double v)
Diffusion constant: Only one per pool, voxel number is ignored.
virtual void setBlock(const vector< double > &values)=0
void convertRatesToStochasticForm()
const RateTerm * rates(unsigned int i) const
Utility function to return a rates_ entry.
Id compartment_
Id of Chem compartment used to figure out volumes of voxels.
void initProc(const Eref &e, ProcPtr p)
vector< unsigned int > getNumFire(unsigned int voxel) const
double mtrand(void)
Generate a random double between 0 and 1.
void setNinit(const Eref &e, double v)
Set initial # of molecules in given pool and voxel. Bdry cond.
unsigned int getNumCoreRates() const
Number of rate terms for reactions purely on this compartment.
unsigned int getNumAllPools() const
const vector< RateTerm * > & getRateTerms() const
Returns a reference to the entire rates_ vector.
static const Cinfo * initCinfo()
void makeReacDepsUnique()
void setNumAllVoxels(unsigned int num)
unsigned int getNumProxyPools() const
vector< double > getNvec(unsigned int voxel) const
Returns the vector of pool Num at the specified voxel.
void parallel_advance(int begin, int end, size_t nWorkers, ProcPtr p, const GssaSystem *sys)
double volume(unsigned int i) const
Inherited.
void reinit(const Eref &e, ProcPtr p)
virtual void getBlock(vector< double > &values) const =0
void setNumPools(unsigned int num)