void Phase::addUniqueSpecies(const std::string& name_, const doublereal* comp, doublereal charge_, doublereal size_) { for (size_t k = 0; k < m_kk; k++) { if (m_speciesNames[k] == name_) { // We have found a match. Do some compatibility checks. for (size_t i = 0; i < m_mm; i++) { if (comp[i] != m_speciesComp[k * m_mm + i]) { throw CanteraError("addUniqueSpecies", "Duplicate species have different " "compositions: " + name_); } } if (charge_ != m_speciesCharge[k]) { throw CanteraError("addUniqueSpecies", "Duplicate species have different " "charges: " + name_); } if (size_ != m_speciesSize[k]) { throw CanteraError("addUniqueSpecies", "Duplicate species have different " "sizes: " + name_); } return; } } addSpecies(name_, comp, charge_, size_); }
/** Sets up the species and the source compartment. We use the pre-defined drift-diffusion method gpgmp::DT_ORNSTEIN_UHLENBECK and set the kernel parameters accordingly. \see setComputeDriftDiffusivityMethod \see setParameter */ OrnsteinUhlenbeckProblem::OrnsteinUhlenbeckProblem(Real length, int dx, int dy, Real diffusivityX, Real diffusivityY, Real gxx, Real gxy, Real gyx, Real gyy, int numMolecules) : DiffusionModel(length, dx, dy) { // one species Species *speciesA = addSpecies("A", 1.); // set boundary mask const cl_int4 boundaryMask = {{1, 1, 1, 1}}; const cl_int4 sourceMask = {{0, 0, 0, 0}}; setBoundaryMasks(boundaryMask, sourceMask); // add source compartment Compartment *compartmentSource = new Compartment("TrueSource", dx/4,dy/4, dx/4, dy/4); compartmentSource->setInitialAmount(speciesA, numMolecules, gpgmp::HomogeneousDistribution); addCompartment(compartmentSource); // add user parameters for kernel setParameter("diffX", diffusivityX); setParameter("diffY", diffusivityY); setParameter("gammaXX", gxx); setParameter("gammaXY", gxy); setParameter("gammaYX", gyx); setParameter("gammaYY", gyy); // set OU method setComputeDriftDiffusivityMethod(gpgmp::DT_ORNSTEIN_UHLENBECK); }
/* * * addUniqueSpecies(): * * Add a species to a Constituents object. This routine will * first check to see if the species is already part of the * phase. It does this via a string comparison with the * existing species in the phase. */ void Constituents:: addUniqueSpecies(const std::string& name, const doublereal* comp, doublereal charge, doublereal size) { vector<string>::const_iterator it = m_speciesNames.begin(); for (int k = 0; k < m_kk; k++) { if (*it == name) { /* * We have found a match. At this point we could do some * compatibility checks. However, let's just return for the * moment without specifying any error. */ int m_mm = m_Elements->nElements(); for (int i = 0; i < m_mm; i++) { if (comp[i] != m_speciesComp[m_kk * m_mm + i]) { throw CanteraError("addUniqueSpecies", "Duplicate species have different " "compositions: " + *it); } } if (charge != m_speciesCharge[m_kk]) { throw CanteraError("addUniqueSpecies", "Duplicate species have different " "charges: " + *it); } if (size != m_speciesSize[m_kk]) { throw CanteraError("addUniqueSpecies", "Duplicate species have different " "sizes: " + *it); } return; } ++it; } addSpecies(name, comp, charge, size); }
int PopDynSEGA::addSpecies(lua_State* luaState) { Species* species = (Species*)Orbit<PopDynSEGA>::pointer(luaState, 1); unsigned int id = addSpecies(species); lua_pushinteger(luaState, id); return 1; }
TEST(LatticeSolidPhase, fromScratch) { auto base = make_shared<StoichSubstance>(); base->setName("Li7Si3(S)"); base->setDensity(1390.0); auto sLi7Si3 = make_shomate2_species("Li7Si3(S)", "Li:7 Si:3", li7si3_shomate_coeffs); base->addSpecies(sLi7Si3); base->initThermo(); auto interstital = make_shared<LatticePhase>(); interstital->setName("Li7Si3_Interstitial"); auto sLii = make_const_cp_species("Li(i)", "Li:1", 298.15, 0, 2e4, 2e4); auto sVac = make_const_cp_species("V(i)", "", 298.15, 8.98e4, 0, 0); sLii->extra["molar_volume"] = 0.2; interstital->setSiteDensity(10.46344); interstital->addSpecies(sLii); interstital->addSpecies(sVac); interstital->initThermo(); interstital->setMoleFractionsByName("Li(i):0.01 V(i):0.99"); LatticeSolidPhase p; p.addLattice(base); p.addLattice(interstital); p.setLatticeStoichiometry(parseCompString("Li7Si3(S):1.0 Li7Si3_Interstitial:1.0")); p.initThermo(); p.setState_TP(725, 10 * OneAtm); // Regression test based on modified version of Li7Si3_ls.xml EXPECT_NEAR(p.enthalpy_mass(), -2077821.9295456698, 1e-6); double mu_ref[] = {-4.62717474e+08, -4.64248485e+07, 1.16370186e+05}; double vol_ref[] = {0.09557086, 0.2, 0.09557086}; vector_fp mu(p.nSpecies()); vector_fp vol(p.nSpecies()); p.getChemPotentials(mu.data()); p.getPartialMolarVolumes(vol.data()); for (size_t k = 0; k < p.nSpecies(); k++) { EXPECT_NEAR(mu[k], mu_ref[k], 1e-7*fabs(mu_ref[k])); EXPECT_NEAR(vol[k], vol_ref[k], 1e-7); } }
void LatticeSolidPhase::initThermo() { size_t kk = 0; size_t kstart = 0; lkstart_.resize(m_lattice.size() + 1); size_t loc = 0; for (size_t n = 0; n < m_lattice.size(); n++) { LatticePhase* lp = m_lattice[n]; vector_fp constArr(lp->nElements()); const vector_fp& aws = lp->atomicWeights(); for (size_t es = 0; es < lp->nElements(); es++) { addElement(lp->elementName(es), aws[es], lp->atomicNumber(es), lp->entropyElement298(es), lp->elementType(es)); } kstart = kk; for (size_t k = 0; k < lp->nSpecies(); k++) { addSpecies(lp->species(k)); kk++; } // Add in the lattice stoichiometry constraint if (n > 0) { string econ = fmt::format("LC_{}_{}", n, id()); size_t m = addElement(econ, 0.0, 0, 0.0, CT_ELEM_TYPE_LATTICERATIO); size_t mm = nElements(); size_t nsp0 = m_lattice[0]->nSpecies(); for (size_t k = 0; k < nsp0; k++) { m_speciesComp[k * mm + m] = -theta_[0]; } for (size_t k = 0; k < lp->nSpecies(); k++) { size_t ks = kstart + k; m_speciesComp[ks * mm + m] = theta_[n]; } } size_t nsp = m_lattice[n]->nSpecies(); lkstart_[n] = loc; for (size_t k = 0; k < nsp; k++) { m_x[loc] =m_lattice[n]->moleFraction(k) / (double) m_lattice.size(); loc++; } lkstart_[n+1] = loc; } setMoleFractions(m_x.data()); ThermoPhase::initThermo(); }
TEST(IonsFromNeutralConstructor, fromScratch) { auto neutral = make_shared<MargulesVPSSTP>(); auto sKCl = make_shomate_species("KCl(L)", "K:1 Cl:1", kcl_shomate_coeffs); neutral->addSpecies(sKCl); std::unique_ptr<PDSS_ConstVol> ssKCl(new PDSS_ConstVol()); ssKCl->setMolarVolume(0.03757); neutral->installPDSS(0, std::move(ssKCl)); neutral->initThermo(); IonsFromNeutralVPSSTP p; p.setNeutralMoleculePhase(neutral); auto sKp = make_shared<Species>("K+", parseCompString("K:1"), 1); auto sClm = make_shared<Species>("Cl-", parseCompString("Cl:1"), -1); sClm->extra["special_species"] = true; p.addSpecies(sKp); p.addSpecies(sClm); std::unique_ptr<PDSS_IonsFromNeutral> ssKp(new PDSS_IonsFromNeutral()); std::unique_ptr<PDSS_IonsFromNeutral> ssClm(new PDSS_IonsFromNeutral()); ssKp->setNeutralSpeciesMultiplier("KCl(L)", 1.2); ssClm->setNeutralSpeciesMultiplier("KCl(L)", 1.5); ssClm->setSpecialSpecies(); p.installPDSS(0, std::move(ssKp)); p.installPDSS(1, std::move(ssClm)); p.initThermo(); ASSERT_EQ((int) p.nSpecies(), 2); p.setState_TPX(500, 2e5, "K+:0.1, Cl-:0.1"); vector_fp mu(p.nSpecies()); p.getChemPotentials(mu.data()); // Values for regression testing only -- same as XML test EXPECT_NEAR(p.density(), 1984.3225978174073, 1e-6); EXPECT_NEAR(p.enthalpy_mass(), -8035317241137.971, 1e-1); EXPECT_NEAR(mu[0], -4.66404010e+08, 1e1); EXPECT_NEAR(mu[1], -2.88157298e+06, 1e-1); }
FixedChemPotSSTP::FixedChemPotSSTP(const std::string& Ename, doublereal val) : chemPot_(0.0) { std::string pname = Ename + "Fixed"; setID(pname); setName(pname); setNDim(3); addElement(Ename); auto sp = make_shared<Species>(pname, parseCompString(Ename + ":1.0")); double c[4] = {298.15, val, 0.0, 0.0}; shared_ptr<SpeciesThermoInterpType> stit( newSpeciesThermoInterpType("const_cp", 0.1, 1e30, OneAtm, c)); sp->thermo = stit; addSpecies(sp); initThermo(); m_p0 = OneAtm; m_tlast = 298.15; setChemicalPotential(val); // Create an XML_Node entry for this species XML_Node s("species", 0); s.addAttribute("name", pname); std::string aaS = Ename + ":1"; s.addChild("atomArray", aaS); XML_Node& tt = s.addChild("thermo"); XML_Node& ss = tt.addChild("Simple"); ss.addAttribute("Pref", "1 bar"); ss.addAttribute("Tmax", "5000."); ss.addAttribute("Tmin", "100."); ss.addChild("t0", "298.15"); ss.addChild("cp0", "0.0"); std::string sval = fp2str(val); ss.addChild("h", sval); ss.addChild("s", "0.0"); saveSpeciesData(0, &s); }
// this one sets up dx*dy majority vote problems without diffusion MajorityVoteProblem::MajorityVoteProblem(Real length, int dx, int dy, uint numMolecules, uint nReds, uint numEncounters, Real reactionProb, Real recognitionError, const std::string &initScriptsPath) : DiffusionModel(length, dx, dy), m_individual(false), m_isNonDiffusive(true) { if (numEncounters < 3) { std::cout <<"ERROR: Need at least three encounters!\n"; exit(1); } // this list will hold all red and green species // we need (i^2+i)/2 species per red and green // where i is the number of encounters after which the species "votes" uint maxSpecies = (numEncounters*numEncounters+numEncounters)/2; std::vector<gpgmp::Species *> speciesListRed(maxSpecies); std::vector<gpgmp::Species *> speciesListGreen(maxSpecies); // add species and reactions corresponding to scheme: // Rxy - red, has encountered x red and y green robots // Gxy - green, has encountered x red and y green robots uint c=0; for (uint i=0; i<numEncounters; i++) { for (uint j=0; j<numEncounters-i; j++) { // add species std::ostringstream snamered; snamered << "R"<<i<<j; speciesListRed[c] = addSpecies(snamered.str(), 0.); std::ostringstream snamegreen; snamegreen << "G"<<i<<j; speciesListGreen[c] = addSpecies(snamegreen.str(),0.); // print out std::cout <<"Added species "<<snamered.str()<<" and "<<snamegreen.str()<<".\n"; // increase counter; c++; } } // create species // set diffusivity and drift for species setParameter("diffX", 0.); setParameter("diffY", 0.); setParameter("driftX", 0.); setParameter("driftY", 0.); // set homogeneous diffusivity and drift setComputeDriftDiffusivityMethod(gpgmp::DT_HOMOGENEOUS); // these are the actual reaction probabilities for the correct reaction and the error reaction double kcorrect = reactionProb*(1.-2.*recognitionError-recognitionError*recognitionError); double kwrong1 = reactionProb*recognitionError; double kwrongb = reactionProb*recognitionError*recognitionError; // add reactions // Gxy+Rwz -> Gx+1y + Rwz+1 // Gxy+Rwz -> Gxy+1 + Rw+1z (for recognition error) uint cg = 0; uint totnreacts=0.; // just debug counter to count number of reactions for (uint x=0; x<numEncounters; x++) { for (uint y=0; y<numEncounters-x; y++) { // to name the reaction std::ostringstream snamers; std::ostringstream snamerd; std::ostringstream snamerdw; // find source and target species for green Species *Gxy = speciesListGreen[cg]; snamers << "G"<<x<<y<<"("<<Gxy->id()<<")"; Species *Txp1y; Species *Txyp1; if ((x+y)==(numEncounters-1)) { // target species is either G00 or R00 if (x>=y) { // turns red Txp1y = speciesListRed[0]; snamerd <<"R00"<<"("<<Txp1y->id()<<")"; // wrong decision if (x>y) { Txyp1 = speciesListRed[0]; snamerdw <<"R00"<<"("<<Txyp1->id()<<")"; } else { Txyp1 = speciesListGreen[0]; snamerdw <<"G00"<<"("<<Txyp1->id()<<")"; } } else { // stays green Txp1y = speciesListGreen[0]; snamerd <<"G00"<<"("<<Txp1y->id()<<")"; // and the wrong decision stays green too Txyp1 = speciesListGreen[0]; snamerdw <<"G00"<<"("<<Txyp1->id()<<")"; } } else { // target species is Gx+1y Txp1y = speciesListGreen[cg+(numEncounters-x)]; snamerd <<"G"<<x+1<<y<<"("<<Txp1y->id()<<")"; // or Gxy+1 Txyp1 = speciesListGreen[cg+1]; snamerdw <<"G"<<x<<y+1<<"("<<Txyp1->id()<<")"; } // now pair with all red robots uint cr=0; for (uint w=0; w<numEncounters; w++) { for (uint z=0; z<numEncounters-w; z++) { // find source and target species for red Species *Rxy = speciesListRed[cr]; std::ostringstream sss; std::ostringstream ssd; std::ostringstream ssdw; sss << "R"<<w<<z << "("<<Rxy->id()<<")"; Species *Twzp1; Species *Twp1z; if ((w+z)==(numEncounters-1)) { // target species is either G00 or R00 if (w>z) { // stays red Twzp1 = speciesListRed[0]; ssd <<"R00" << "("<<Twzp1->id()<<")"; // and the wrong decision .. stays red too Twp1z = speciesListRed[0]; ssdw <<"R00" << "("<<Twp1z->id()<<")"; } else { // stays green Twzp1 = speciesListGreen[0]; ssd <<"G00" << "("<<Twzp1->id()<<")"; if (w==z) { Twp1z = speciesListRed[0]; ssdw <<"R00" << "("<<Twp1z->id()<<")"; } else { Twp1z = speciesListGreen[0]; ssdw <<"G00" << "("<<Twp1z->id()<<")"; } } } else { // target species is Rw+1z Twzp1 = speciesListRed[cr+1]; ssd <<"R"<<w<<z+1<< "("<<Twzp1->id()<<")"; // and Rwzp1 Twp1z = speciesListRed[cr+(numEncounters-w)]; ssdw <<"R"<<w+1<<z<< "("<<Twp1z->id()<<")"; } std::ostringstream rname, rnamew; rname <<snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str()<<" + " << ssd.str(); std::cout <<"Adding reaction "<<rname.str()<<".\n"; totnreacts++; Reaction *r = addReaction (rname.str(), kcorrect, Gxy, Rxy); r->setProductStoichiometry(Txp1y, 1); if (Txp1y == Twzp1) r->setProductStoichiometry(Twzp1, 2); else r->setProductStoichiometry(Twzp1, 1); // and add wrong reaction if needed if (recognitionError > 0) { // both wrong rnamew <<snamers.str()<<" + "<<sss.str()<<" -> "<<snamerdw.str()<<" + " << ssdw.str(); std::cout <<"Adding errenous reaction "<<rnamew.str()<<".\n"<<std::flush; totnreacts++; r = addReaction(rnamew.str(), kwrongb, Gxy, Rxy); r->setProductStoichiometry(Txyp1, 1); if (Txyp1 == Twp1z) r->setProductStoichiometry(Twp1z, 2); else r->setProductStoichiometry(Twp1z, 1); std::ostringstream rnamew1, rnamew2; // first wrong rnamew1 <<snamers.str()<<" + "<<sss.str()<<" -> "<<snamerdw.str()<<" + " << ssd.str(); std::cout <<"Adding errenous reaction (first wrong) "<<rnamew1.str()<<".\n"<<std::flush; totnreacts++; r = addReaction(rnamew.str(), kwrong1, Gxy, Rxy); r->setProductStoichiometry(Txyp1, 1); if (Txyp1 == Twzp1) r->setProductStoichiometry(Twzp1, 2); else r->setProductStoichiometry(Twzp1, 1); // second wrong rnamew2 <<snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str()<<" + " << ssdw.str(); std::cout <<"Adding errenous reaction (second wrong) "<<rnamew2.str()<<".\n"<<std::flush; totnreacts++; r = addReaction(rnamew2.str(), kwrong1, Gxy, Rxy); r->setProductStoichiometry(Txp1y, 1); if (Txp1y == Twp1z) r->setProductStoichiometry(Twp1z, 2); else r->setProductStoichiometry(Twp1z, 1); } // increase counter cr++; } // pair with red robots z } // pair with red robots w // increase counter cg++; } // green robots y } // green robots x // Gxy+Gwz -> Gxy+1 + Gwz+1 for (uint x=0; x<maxSpecies; x++) { for (uint y=x; y<maxSpecies; y++) { // get source species Species *G1 = speciesListGreen[x]; Species *G2 = speciesListGreen[y]; // get target species 1 Species *T1; Species *T1wrong; // is it at marginal position? if (isMarginal(x, numEncounters)) { // check if over changeover limit (see notebook index_computations.nb) if (x > getChangeoverLimit(x, numEncounters)) { // change to red T1 = speciesListRed[0]; T1wrong = speciesListRed[0]; } else { T1 = speciesListGreen[0]; // wrong species if (x==getChangeoverLimit(x, numEncounters)) T1wrong = speciesListRed[0]; else T1wrong = speciesListGreen[0]; } } else { T1 = speciesListGreen[x+1]; T1wrong = speciesListGreen[getNextRedPosition(x, numEncounters)]; } // get target species 2 Species *T2; Species *T2wrong; // is it at marginal position? if (isMarginal(y, numEncounters)) { // check if over changeover limit (see notebook index_computations.nb) if (y > getChangeoverLimit(y, numEncounters)) { // change to red T2 = speciesListRed[0]; T2wrong = speciesListRed[0]; } else { T2 = speciesListGreen[0]; // wrong species if (y==getChangeoverLimit(y, numEncounters)) T2wrong = speciesListRed[0]; else T2wrong = speciesListGreen[0]; } } else { T2 = speciesListGreen[y+1]; T2wrong = speciesListGreen[getNextRedPosition(y, numEncounters)]; } // print reaction std::stringstream rname; rname <<G1->id()<<" + "<<G2->id()<<" -> "<< T1->id()<<" + "<<T2->id(); std::cout <<"Adding reaction "<<rname.str() <<"\n"<<std::flush; // and add it totnreacts++; Reaction *r = addReaction(rname.str(), kcorrect, G1, G2); r->setProductStoichiometry(T1, 1); if (T1 == T2) r->setProductStoichiometry(T2, 2); else r->setProductStoichiometry(T2, 1); // wrong reactions if (recognitionError > 0) { // first wrong std::stringstream rnamew1; rnamew1 << G1->id() << " + " << G2->id() <<" -> "<< T1wrong->id() << " + "<<T2->id(); std::cout <<"Adding erreneous (first wrong) reaction "<<rnamew1.str()<<"\n"<<std::flush; totnreacts++; r = addReaction(rnamew1.str(), kwrong1, G1, G2); r->setProductStoichiometry(T1wrong, 1); if (T1wrong == T2) r->setProductStoichiometry(T2, 2); else r->setProductStoichiometry(T2, 1); // second wrong std::stringstream rnamew2; rnamew2 << G1->id() << " + " << G2->id() <<" -> "<< T1->id() << " + "<<T2wrong->id(); std::cout <<"Adding erreneous (second wrong) reaction "<<rnamew2.str()<<"\n"<<std::flush; totnreacts++; r = addReaction(rnamew2.str(), kwrong1, G1, G2); r->setProductStoichiometry(T1, 1); if (T1== T2wrong) r->setProductStoichiometry(T2wrong, 2); else r->setProductStoichiometry(T2wrong, 1); // both wrong std::stringstream rnamewb; rnamewb << G1->id() << " + " << G2->id() <<" -> "<< T1wrong->id() << " + "<<T2wrong->id(); std::cout <<"Adding erreneous (both wrong) reaction "<<rnamewb.str()<<"\n"<<std::flush; totnreacts++; r = addReaction(rnamewb.str(), kwrongb, G1, G2); r->setProductStoichiometry(T1wrong, 1); if (T1wrong == T2wrong) r->setProductStoichiometry(T2wrong, 2); else r->setProductStoichiometry(T2wrong, 1); } } } // Rxy+Rwz -> Rxy+1 + Rwz+1 for (uint x=0; x<maxSpecies; x++) { for (uint y=x; y<maxSpecies; y++) { // get source species Species *R1 = speciesListRed[x]; Species *R2 = speciesListRed[y]; // get target species 1 Species *T1; Species *T1wrong; // is it at marginal position? if (isMarginal(x, numEncounters)) { // check if over changeover limit (see notebook index_computations.nb) if (x >= getChangeoverLimit(x, numEncounters)) { // change to red T1 = speciesListRed[0]; // wrong species if (x == getChangeoverLimit(x, numEncounters)) T1wrong = speciesListGreen[0]; else T1wrong = speciesListRed[0]; } else { T1 = speciesListGreen[0]; T1wrong = speciesListGreen[0]; } } else { T1 = speciesListRed[getNextRedPosition(x, numEncounters)]; T1wrong = speciesListRed[x+1]; } // get target species 2 Species *T2; Species *T2wrong; // is it at marginal position? if (isMarginal(y, numEncounters)) { // check if over changeover limit (see notebook index_computations.nb) if (y >= getChangeoverLimit(y, numEncounters)) { // change to red T2 = speciesListRed[0]; // wrong species if (y == getChangeoverLimit(y, numEncounters)) T2wrong = speciesListGreen[0]; else T2wrong = speciesListRed[0]; } else { T2 = speciesListGreen[0]; T2wrong = speciesListGreen[0]; } } else { T2 = speciesListRed[getNextRedPosition(y, numEncounters)]; T2wrong = speciesListRed[y+1]; } // print reaction std::stringstream rname; rname <<R1->id()<<" + "<<R2->id()<<" -> "<< T1->id()<<" + "<<T2->id(); std::cout <<"Adding reaction "<<rname.str() <<"\n"<<std::flush; // and add it totnreacts++; Reaction *r = addReaction(rname.str(), kcorrect, R1, R2); r->setProductStoichiometry(T1, 1); if (T1 == T2) r->setProductStoichiometry(T2, 2); else r->setProductStoichiometry(T2, 1); // wrong reactions if (recognitionError > 0) { // first wrong std::stringstream rnamew1; rnamew1 << R1->id() <<" + " << R2->id() <<" -> " << T1wrong->id() << " + " << T2->id(); std::cout <<"Adding erreneous (first wrong) reaction "<<rnamew1.str() << "\n" << std::flush; totnreacts++; r = addReaction(rnamew1.str(), kwrong1, R1, R2); r->setProductStoichiometry(T1wrong, 1); if (T1wrong == T2) r->setProductStoichiometry(T2, 2); else r->setProductStoichiometry(T2, 1); // second wrong std::stringstream rnamew2; rnamew2 << R1->id() <<" + " << R2->id() <<" -> " << T1->id() << " + " << T2wrong->id(); std::cout <<"Adding erreneous (second wrong) reaction "<<rnamew2.str() << "\n" << std::flush; totnreacts++; r = addReaction(rnamew2.str(), kwrong1, R1, R2); r->setProductStoichiometry(T1, 1); if (T1== T2wrong) r->setProductStoichiometry(T2wrong, 2); else r->setProductStoichiometry(T2wrong, 1); // both wrong std::stringstream rnamewb; rnamewb << R1->id() <<" + " << R2->id() <<" -> " << T1wrong->id() << " + " << T2wrong->id(); std::cout <<"Adding erreneous (both wrong) reaction "<<rnamewb.str() << "\n" << std::flush; totnreacts++; r = addReaction(rnamewb.str(), kwrongb, R1, R2); r->setProductStoichiometry(T1wrong, 1); if (T1wrong == T2wrong) r->setProductStoichiometry(T2wrong, 2); else r->setProductStoichiometry(T2wrong, 1); } } } std::cout <<"Added "<<totnreacts<<" reactions.\n"; std::cout <<"Reaction propensities: no error = "<<kcorrect<<", one wrong = "<< kwrong1 <<" both wrong = "<<kwrongb <<"Sum = "<<(kcorrect + 2. * kwrong1 + kwrongb)<<"\n"<<std::flush; /* // Gxy+Gwz -> Gxy+1 + Gwz+1 cg = 0; totnreacts=0; for (uint x=0; x<numEncounters; x++) { for (uint y=0; y<numEncounters-x; y++) { // to name the reaction std::ostringstream snamers; std::ostringstream snamerd; // find source and target species for green Species *Gxy = speciesListGreen[cg]; snamers << "G"<<x<<y<<"("<<Gxy->id()<<")"; Species *Txyp1; if ((x+y)==(numEncounters-1)) { // target species is either G00 or R00 if (x>y) { // turns red Txyp1 = speciesListRed[0]; snamerd <<"R00"<<"("<<Txyp1->id()<<")"; } else { // stays green Txyp1 = speciesListGreen[0]; snamerd <<"G00"<<"("<<Txyp1->id()<<")"; } } else { // target species is Gxyp1 Txyp1 = speciesListGreen[cg+1]; snamerd <<"G"<<x<<y+1<<"("<<Txyp1->id()<<")"; } // now pair with all other green robots for (uint w=x; w<numEncounters; w++) { for (uint z=x; z<numEncounters-w; z++) { // compute index to second source species // TODODODODO: you'll need to continue here .. // come up with a function to compute the speciesindex from w and z // and then assign cgg to it // and then compare to the notebook with nencounters=3 (mesoscopic_reactions.nb) // and then you need to adapt the HDF5 writer too // and then just do a couple of runs with this problem and see how it compares to spatial uint cgg=getSpeciesIndexFrom2D(w, z, numEncounters); // find source and target species for red Species *GGxy = speciesListGreen[cgg]; std::ostringstream sss; std::ostringstream ssd; sss << "G"<<w<<z<<"("<<GGxy->id()<<")"; Species *Twzp1; if ((w+z)==(numEncounters-1)) { // target species is either G00 or R00 if (w>z) { // turns red Twzp1 = speciesListRed[0]; ssd <<"R00"<<"("<<Twzp1->id()<<")"; } else { // stays green Twzp1 = speciesListGreen[0]; ssd <<"G00"<<"("<<Twzp1->id()<<")"; } } else { // target species is Gwzp1 Twzp1 = speciesListGreen[cgg+1]; ssd <<"G"<<w<<z+1<<"("<<Twzp1->id()<<")"; } std::stringstream rname; rname << snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str(); std::cout <<"Adding reaction "<< rname.str() <<" + " << ssd.str()<<".\n"<<std::flush; totnreacts++; Reaction *r = addReaction(rname.str(), reactionProb, Gxy, GGxy); r->setProductStoichiometry(Txyp1, 1); if (Twzp1 == Txyp1) r->setProductStoichiometry(Twzp1, 2); else r->setProductStoichiometry(Twzp1, 1); // increase counter cgg++; } // pair with other green robots z } // pair with other green robots w // increase counter cg++; } // green robots y } // green robots x std::cout <<"Added a total of "<<totnreacts<<" reactions in the green self-reaction part.\n"; exit(1); // Rxy+Rwz -> Rxy+1 + Rwz+1 uint cr = 0; for (uint x=0; x<numEncounters; x++) { for (uint y=0; y<numEncounters-x; y++) { // to name the reaction std::ostringstream snamers; std::ostringstream snamerd; // find source and target species for green Species *Rxy = speciesListRed[cr]; snamers << "R"<<x<<y<<"("<<Rxy->id()<<")"; Species *Txp1y; if ((x+y)==(numEncounters-1)) { // target species is either G00 or R00 if (x>=y) { // turns red Txp1y = speciesListRed[0]; snamerd <<"R00"<<"("<<Txp1y->id()<<")"; } else { // stays green Txp1y = speciesListGreen[0]; snamerd <<"G00"<<"("<<Txp1y->id()<<")"; } } else { // target species is Gxyp1 Txp1y = speciesListRed[cr+(numEncounters-x)]; snamerd <<"R"<<x+1<<y<<"("<<Txp1y->id()<<")"; } // now pair with all other red robots uint crr=0; for (uint w=0; w<numEncounters; w++) { for (uint z=0; z<numEncounters-w; z++) { // find source and target species for red Species *RRxy = speciesListRed[crr]; std::ostringstream sss; std::ostringstream ssd; sss << "R"<<w<<z<<"("<<RRxy->id()<<")"; Species *Twp1z; if ((w+z)==(numEncounters-1)) { // target species is either G00 or R00 if (w>=z) { // turns red Twp1z = speciesListRed[0]; ssd <<"R00"<<"("<<Twp1z->id()<<")"; } else { // stays green Twp1z = speciesListGreen[0]; ssd <<"G00"<<"("<<Twp1z->id()<<")"; } } else { // target species is Rwzp1 Twp1z = speciesListRed[crr+(numEncounters-w)]; ssd <<"R"<<w+1<<z<<"("<<Twp1z->id()<<")"; } std::stringstream rname; rname << snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str()<<" + " << ssd.str(); std::cout <<"Adding reaction "<< rname.str() <<".\n"; Reaction *r = addReaction(rname.str(), reactionProb, Rxy, RRxy); r->setProductStoichiometry(Txp1y, 1); if (Txp1y == Twp1z) r->setProductStoichiometry(Twp1z, 2); else r->setProductStoichiometry(Twp1z, 1); // increase counter crr++; } // pair with other red robots z } // pair with other red robots w // increase counter cr++; } // green robots y } // green robots x */ // distribute species randomly /* Compartment *source = addCompartment("Source", 0, 0, dx-1, dy-1); source->setInitialAmount(speciesListRed[0], nReds, gpgmp::RandomDistribution); source->setInitialAmount(speciesListGreen[0], numMolecules-nReds, gpgmp::RandomDistribution); */ // load init script loadInitScript((boost::filesystem::path(initScriptsPath) / "init_majority_no_diffusion.py").string()); // add script parameters setParameter("numMolecules", numMolecules); setParameter("p", static_cast<float>(nReds)/static_cast<float>(numMolecules)); setRegenerateInitStates(true); }
// sets up the toy model // MajorityVoteProblem::MajorityVoteProblem(Real length, int dx, int dy, uint numMolecules, uint nReds, Real reactionProb, const std::string &initScriptsPath) : DiffusionModel(length, dx, dy), m_individual(false), m_isNonDiffusive(true) { // add four species R_0, R_1, G_0, G_1 Species *R0 = addSpecies("R0", 0.); Species *R1 = addSpecies("R1", 0.); Species *G0 = addSpecies("G0", 0.); Species *G1 = addSpecies("G1", 0.); // set diffusivity and drift for species setParameter("diffX", 0.); setParameter("diffY", 0.); setParameter("driftX", 0.); setParameter("driftY", 0.); // set homogeneous diffusivity and drift setComputeDriftDiffusivityMethod(gpgmp::DT_HOMOGENEOUS); // add reactions // R0 + G0 -> R1 + G1 (i) Reaction *r1 = addReaction("R0 + G0 -> R1 + G1", reactionProb, R0, G0); r1 -> setProductStoichiometry(R1, 1); r1 -> setProductStoichiometry(G1, 1); // R0 + G1 -> R1 + R0 (ii) Reaction *r2 = addReaction("R0 + G1 -> R1 + R0", reactionProb, R0, G1); r2 -> setProductStoichiometry(R1, 1); r2 -> setProductStoichiometry(R0, 1); // R1 + G0 -> G0 + G1 (iii) Reaction *r3 = addReaction("R1 + G0 -> G0 + G1", reactionProb, R1, G0); r3 -> setProductStoichiometry(G1, 1); r3 -> setProductStoichiometry(G0, 1); // R1 + G1 -> G0 + R0 (iv) Reaction *r4 = addReaction("R1 + G1 -> G0 + R0", reactionProb, R1, G1); r4 -> setProductStoichiometry(G0, 1); r4 -> setProductStoichiometry(R0, 1); // R0 + R1 -> R0 + R0 (v) Reaction *r5 = addReaction("R0 + R1 -> R0 + R0", reactionProb, R0, R1); r5 -> setProductStoichiometry(R0, 2); // R1 + R1 -> R0 + R0 (vi) Reaction *r6 = addReaction("R1 + R1 -> R0 + R0", reactionProb, R1, R1); r6 -> setProductStoichiometry(R0, 2); // G0 + G1 -> G0 + G0 (vii) Reaction *r7 = addReaction("G0 + G1 -> G0 + G0", reactionProb, G0, G1); r7 -> setProductStoichiometry(G0, 2); // G1 + G1 -> G0 + G0 (viii) Reaction *r8 = addReaction("G1 + G1 -> G0 + G0", reactionProb, G1, G1); r8 -> setProductStoichiometry(G0, 2); // load init script loadInitScript((boost::filesystem::path(initScriptsPath) / "init_majority_no_diffusion.py").string()); // add script parameters setParameter("numMolecules", numMolecules); setParameter("p", static_cast<float>(nReds)/static_cast<float>(numMolecules)); setRegenerateInitStates(true); }
MajorityVoteProblem::MajorityVoteProblem(Real length, int dx, int dy, Real diffX, Real diffY, Real mux, Real muy, uint numMolecules, uint nReds, uint numEncounters, Real reactionProb,const std::string &initScriptsPath) : DiffusionModel(length, dx, dy), m_individual(false), m_isNonDiffusive(false) { // this list will hold all red and green species // we need (i^2+i)/2 species per red and green // where i is the number of encounters after which the species "votes" uint maxSpecies = (numEncounters*numEncounters+numEncounters)/2; std::vector<gpgmp::Species *> speciesListRed(maxSpecies); std::vector<gpgmp::Species *> speciesListGreen(maxSpecies); // add species and reactions corresponding to scheme: // Rxy - red, has encountered x red and y green robots // Gxy - green, has encountered x red and y green robots uint c=0; for (uint i=0; i<numEncounters; i++) { for (uint j=0; j<numEncounters-i; j++) { // add species std::ostringstream snamered; snamered << "R"<<i<<j; speciesListRed[c] = addSpecies(snamered.str(), diffX); std::ostringstream snamegreen; snamegreen << "G"<<i<<j; speciesListGreen[c] = addSpecies(snamegreen.str(),diffX); // print out std::cout <<"Added species "<<snamered.str()<<" and "<<snamegreen.str()<<".\n"; // increase counter; c++; } } // create species // set diffusivity and drift for species setParameter("diffX", diffX); setParameter("diffY", diffY); setParameter("driftX", mux); setParameter("driftY", muy); // set homogeneous diffusivity and drift setComputeDriftDiffusivityMethod(gpgmp::DT_HOMOGENEOUS); // add reactions // Gxy+Rwz -> Gx+1y + Rwz+1 uint cg = 0; for (uint x=0; x<numEncounters; x++) { for (uint y=0; y<numEncounters-x; y++) { // to name the reaction std::ostringstream snamers; std::ostringstream snamerd; // find source and target species for green Species *Gxy = speciesListGreen[cg]; snamers << "G"<<x<<y<<"("<<Gxy->id()<<")"; Species *Txp1y; if ((x+y)==(numEncounters-1)) { // target species is either G00 or R00 if (x>=y) { // turns red Txp1y = speciesListRed[0]; snamerd <<"R00"<<"("<<Txp1y->id()<<")"; } else { // stays greenstd::map<std::string, std::vector<Real> > &propertiesA = speciesA->getIndividualProperties(); Txp1y = speciesListGreen[0]; snamerd <<"G00"<<"("<<Txp1y->id()<<")"; } } else { // target species is Gx+1y Txp1y = speciesListGreen[cg+(numEncounters-x)]; snamerd <<"G"<<x+1<<y<<"("<<Txp1y->id()<<")"; } // now pair with all red robots uint cr=0; for (uint w=0; w<numEncounters; w++) { for (uint z=0; z<numEncounters-w; z++) { // find source and target species for red Species *Rxy = speciesListRed[cr]; std::ostringstream sss; std::ostringstream ssd; sss << "R"<<w<<z << "("<<Rxy->id()<<")"; Species *Twzp1; if ((w+z)==(numEncounters-1)) { // target species is either G00 or R00 if (w>z) { // turns red Twzp1 = speciesListRed[0]; ssd <<"R00" << "("<<Twzp1->id()<<")"; } else { // stays green Twzp1 = speciesListGreen[0]; ssd <<"G00" << "("<<Twzp1->id()<<")"; } } else { // target species is Rw+1z Twzp1 = speciesListRed[cr+1]; ssd <<"R"<<w<<z+1<< "("<<Twzp1->id()<<")"; } std::ostringstream rname; rname <<snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str()<<" + " << ssd.str(); std::cout <<"Adding reaction "<<rname.str()<<".\n"; Reaction *r = addReaction (rname.str(), reactionProb, Gxy, Rxy); r->setProductStoichiometry(Txp1y, 1); if (Txp1y == Twzp1) r->setProductStoichiometry(Twzp1, 2); else r->setProductStoichiometry(Twzp1, 1); // increase counter cr++; } // pair with red robots z } // pair with red robots w // increase counter cg++; } // green robots y } // green robots x // Gxy+Gwz -> Gxy+1 + Gwz+1 cg = 0; for (uint x=0; x<numEncounters; x++) { for (uint y=0; y<numEncounters-x; y++) { // to name the reaction std::ostringstream snamers; std::ostringstream snamerd; // find source and target species for green Species *Gxy = speciesListGreen[cg]; snamers << "G"<<x<<y<<"("<<Gxy->id()<<")"; Species *Txyp1; if ((x+y)==(numEncounters-1)) { // target species is either G00 or R00 if (x>y) { // turns red Txyp1 = speciesListRed[0]; snamerd <<"R00"<<"("<<Txyp1->id()<<")"; } else { // stays green Txyp1 = speciesListGreen[0]; snamerd <<"G00"<<"("<<Txyp1->id()<<")"; } } else { // target species is Gxyp1 Txyp1 = speciesListGreen[cg+1]; snamerd <<"G"<<x<<y+1<<"("<<Txyp1->id()<<")"; } // now pair with all other green robots uint cgg=0; for (uint w=0; w<numEncounters; w++) { for (uint z=0; z<numEncounters-w; z++) { // find source and target species for red Species *GGxy = speciesListGreen[cgg]; std::ostringstream sss; std::ostringstream ssd; sss << "G"<<w<<z<<"("<<GGxy->id()<<")"; Species *Twzp1; if ((w+z)==(numEncounters-1)) { // target species is either G00 or R00 if (w>z) { // turns red Twzp1 = speciesListRed[0]; ssd <<"R00"<<"("<<Twzp1->id()<<")"; } else { // stays green Twzp1 = speciesListGreen[0]; ssd <<"G00"<<"("<<Twzp1->id()<<")"; } } else { // target species is Gwzp1 Twzp1 = speciesListGreen[cgg+1]; ssd <<"G"<<w<<z+1<<"("<<Twzp1->id()<<")"; } std::stringstream rname; rname << snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str(); std::cout <<"Adding reaction "<< rname.str() <<" + " << ssd.str()<<".\n"; Reaction *r = addReaction(rname.str(), reactionProb, Gxy, GGxy); r->setProductStoichiometry(Txyp1, 1); if (Twzp1 == Txyp1) r->setProductStoichiometry(Twzp1, 2); else r->setProductStoichiometry(Twzp1, 1); // increase counter cgg++; } // pair with other green robots z } // pair with other green robots w // increase counter cg++; } // green robots y } // green robots x // Rxy+Rwz -> Rxy+1 + Rwz+1 uint cr = 0; for (uint x=0; x<numEncounters; x++) { for (uint y=0; y<numEncounters-x; y++) { // to name the reaction std::ostringstream snamers; std::ostringstream snamerd; // find source and target species for green Species *Rxy = speciesListRed[cr]; snamers << "R"<<x<<y<<"("<<Rxy->id()<<")"; Species *Txp1y; if ((x+y)==(numEncounters-1)) { // target species is either G00 or R00 if (x>=y) { // turns red Txp1y = speciesListRed[0]; snamerd <<"R00"<<"("<<Txp1y->id()<<")"; } else { // stays green Txp1y = speciesListGreen[0]; snamerd <<"G00"<<"("<<Txp1y->id()<<")"; } } else { // target species is Gxyp1 Txp1y = speciesListRed[cr+(numEncounters-x)]; snamerd <<"R"<<x+1<<y<<"("<<Txp1y->id()<<")"; } // now pair with all other red robots uint crr=0; for (uint w=0; w<numEncounters; w++) { for (uint z=0; z<numEncounters-w; z++) { // find source and target species for red Species *RRxy = speciesListRed[crr]; std::ostringstream sss; std::ostringstream ssd; sss << "R"<<w<<z<<"("<<RRxy->id()<<")"; Species *Twp1z; if ((w+z)==(numEncounters-1)) { // target species is either G00 or R00 if (w>=z) { // turns red Twp1z = speciesListRed[0]; ssd <<"R00"<<"("<<Twp1z->id()<<")"; } else { // stays green Twp1z = speciesListGreen[0]; ssd <<"G00"<<"("<<Twp1z->id()<<")"; } } else { // target species is Rwzp1 Twp1z = speciesListRed[crr+(numEncounters-w)]; ssd <<"R"<<w+1<<z<<"("<<Twp1z->id()<<")"; } std::stringstream rname; rname << snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str()<<" + " << ssd.str(); std::cout <<"Adding reaction "<< rname.str() <<".\n"; Reaction *r = addReaction(rname.str(), reactionProb, Rxy, RRxy); r->setProductStoichiometry(Txp1y, 1); if (Txp1y == Twp1z) r->setProductStoichiometry(Twp1z, 2); else r->setProductStoichiometry(Twp1z, 1); // increase counter crr++; } // pair with other red robots z } // pair with other red robots w // increase counter cr++; } // green robots y } // green robots x // distribute species randomly /* Compartment *source = addCompartment("Source", 0, 0, dx-1, dy-1); source->setInitialAmount(speciesListRed[0], nReds, gpgmp::RandomDistribution); source->setInitialAmount(speciesListGreen[0], numMolecules-nReds, gpgmp::RandomDistribution); */ // load init script loadInitScript((boost::filesystem::path(initScriptsPath) / "init_majority.py").string()); // add script parameters setParameter("numMolecules", numMolecules); setParameter("p", static_cast<float>(nReds)/static_cast<float>(numMolecules)); setRegenerateInitStates(true); }