-
Notifications
You must be signed in to change notification settings - Fork 2
/
reaction.cpp
117 lines (101 loc) · 3.85 KB
/
reaction.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "reaction.h"
Reaction::Reaction(std::string reactant0, int stoichiometry0, std::string reactant1, int stoichiometry1, PROPFLOAT rate){
addSpecie(reactant0, -1*stoichiometry0);
addSpecie(reactant1, -1*stoichiometry1);
m_rate = rate;
m_partialPropensity = -1.f;
}
std::ostream& operator<<(std::ostream& os, const Reaction& rc){
int i = 0;
for(auto itRec=rc.m_records.begin(); itRec != rc.m_records.end(); itRec++){
std::string s; //specie id
int st; //specie's stoichiometry
std::tie (s, st) = *itRec;
switch(i){//case is the position of the ?? in the reactions vector?? TODO
case 0:
os << (-1)*st << " of " << s;
break;
case 1:
os << " + " << (-1)*st << " of " << s << " -> " ;
break;
case 2:
os << st << " of " << s;
break;
default:
os << " + " << st << " of " << s;
break;
}
i++;
}
if( rc.m_partialPropensity < 0.f )
os << " (rate " << rc.m_rate << ", Pi has not been computed yet)";
else
os << " (rate " << rc.m_rate << ", Pi " << rc.m_partialPropensity << " w respect to " << rc.m_pPWRespectTo << ")";
return os;
}
void Reaction::computePartialPropensity(std::string wRespectToSp, MOLINT populationOfSp)
{
std::string s0, s1;
int st0, st1;
std::tie (s0, st0) = m_records[0];
std::tie (s1, st1) = m_records[1];
if( s0 != wRespectToSp && s1 != wRespectToSp ){
std::cout << "Reaction: Computation of partial propensity with respect to an unknown specie " << wRespectToSp << " attempted, exiting" << std::endl;
std::cout << "Reaction: " << (*this) << std::endl;
exit(EXIT_FAILURE);
}
// from here on we are sure that wRespectToSp is one of our reagents
m_pPWRespectTo = wRespectToSp;
// if both reagents are "vacuum", then the reaction is of source type, and Pi is the rate
if( s0 == "" && s1 == "" ){
m_partialPropensity = m_rate;
return;
}
// if the reagents are the same, we can have either unimolecular or bimolecular reaction
if( s0 == s1 ){
// for unimolecular reaction Pi is the rate
if( (st0 == 0 && st1 == -1) || (st1 == 0 && st0 == -1) ){
m_partialPropensity = m_rate;
return;
}
// for reactions involving two molecules of the same specie, Pi is computed using formula from RG-SS
if( st0 == -1 && st1 == -1 ){
m_partialPropensity = 0.5f*((PROPFLOAT) (populationOfSp - 1))*m_rate;
return;
}
}
// if the reagents are different, both stoichiometries must be -1: we do NOT handle trinary reactions
if( s0 != s1 && st0 == -1 && st1 == -1 ){
m_partialPropensity = ((PROPFLOAT) populationOfSp)*m_rate;
return;
}
// we do not like situations when none of the patterns above are matched
std::cout << "Reaction: Couldn't find a rule to compute partial propensity with respect to " << wRespectToSp << ", exiting" << std::endl;
std::cout << "Reaction: " << (*this) << std::endl;
exit(EXIT_FAILURE);
}
bool Reaction::isValid()
{
std::string s, s0, s1;
int st, st0, st1;
std::tie (s0, st0) = m_records[0];
std::tie (s1, st1) = m_records[1];
if( (st0 != -1 && st0 != 0) || (st1 != -1 && st1 != 0) )
return false;
if( s0 == "" && s1 == "" && (st0 != 0 || st1 != 0) )
return false;
if( ((st0 == 0 && st1 != 0) || (st0 != 0 && st1 == 0)) && ( s0 != s1 ) )
return false;
auto itRec = m_records.begin();
itRec++;
itRec++;
for(; itRec != m_records.end(); itRec++){
std::tie (s, st) = *itRec;
if(st <= 0)
return false;
}
return true;
}
void Reaction::addSpecie(std::string specie, int stoichiometry){
m_records.push_back(specieRecord_t(specie, stoichiometry));
}