void testRunKsolve() { double simDt = 0.1; // double plotDt = 0.1; Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); Id kin = makeReacTest(); Id ksolve = s->doCreate( "Ksolve", kin, "ksolve", 1 ); Id stoich = s->doCreate( "Stoich", ksolve, "stoich", 1 ); Field< Id >::set( stoich, "compartment", kin ); Field< Id >::set( stoich, "ksolve", ksolve ); Field< string >::set( stoich, "path", "/kinetics/##" ); s->doUseClock( "/kinetics/ksolve", "process", 4 ); s->doSetClock( 4, simDt ); s->doReinit(); s->doStart( 20.0 ); Id plots( "/kinetics/plots" ); for ( unsigned int i = 0; i < 7; ++i ) { stringstream ss; ss << "plot." << i; SetGet2< string, string >::set( ObjId( plots, i ), "xplot", "tsr2.plot", ss.str() ); } s->doDelete( kin ); cout << "." << flush; }
void testReacVolumeScaling() { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); Id comptId = shell->doCreate( "CubeMesh", Id(), "cube", 1 ); Id meshId( comptId.value() + 1 ); Id subId = shell->doCreate( "Pool", comptId, "sub", 1 ); Id prdId = shell->doCreate( "Pool", comptId, "prd", 1 ); Id reacId = shell->doCreate( "Reac", comptId, "reac", 1 ); double vol1 = 1e-15; ObjId mid = shell->doAddMsg( "OneToOne", subId, "requestVolume", meshId, "get_volume" ); assert( mid != ObjId() ); mid = shell->doAddMsg( "OneToOne", prdId, "requestVolume", meshId, "get_volume" ); assert( mid != ObjId() ); vector< double > coords( 9, 10.0e-6 ); coords[0] = coords[1] = coords[2] = 0; Field< vector< double > >::set( comptId, "coords", coords ); double volume = Field< double >::get( comptId, "volume" ); assert( doubleEq( volume, vol1 ) ); ObjId ret = shell->doAddMsg( "Single", reacId, "sub", subId, "reac" ); assert( ret != ObjId() ); ret = shell->doAddMsg( "Single", reacId, "prd", prdId, "reac" ); assert( ret != ObjId() ); Field< double >::set( reacId, "Kf", 2 ); Field< double >::set( reacId, "Kb", 3 ); double x = Field< double >::get( reacId, "kf" ); assert( doubleEq( x, 2 ) ); x = Field< double >::get( reacId, "kb" ); assert( doubleEq( x, 3 ) ); ret = shell->doAddMsg( "Single", reacId, "sub", subId, "reac" ); assert( ret != ObjId() ); double conv = 1.0 / ( NA * vol1 ); x = Field< double >::get( reacId, "kf" ); assert( doubleEq( x, 2 * conv ) ); x = Field< double >::get( reacId, "kb" ); assert( doubleEq( x, 3 ) ); ret = shell->doAddMsg( "Single", reacId, "sub", subId, "reac" ); assert( ret != ObjId() ); ret = shell->doAddMsg( "Single", reacId, "prd", prdId, "reac" ); assert( ret != ObjId() ); x = Field< double >::get( reacId, "kf" ); assert( doubleEq( x, 2 * conv * conv ) ); x = Field< double >::get( reacId, "kb" ); assert( doubleEq( x, 3 * conv ) ); shell->doDelete( comptId ); cout << "." << flush; }
void testMMenzProcess() { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); ////////////////////////////////////////////////////////////////////// // This set is the test kinetic calculation using MathFunc ////////////////////////////////////////////////////////////////////// Id nid = shell->doCreate( "Neutral", Id(), "n", 1 ); ////////////////////////////////////////////////////////////////////// // This set is the reference kinetic calculation using MMEnz ////////////////////////////////////////////////////////////////////// Id pid = shell->doCreate( "Pool", nid, "p", 1 ); // substrate Id qid = shell->doCreate( "Pool", nid, "q", 1 ); // enz mol Id rid = shell->doCreate( "Pool", nid, "r", 1 ); // product Id mmid = shell->doCreate( "MMenz", nid, "mm", 1 ); // mmenz Id tabid2 = shell->doCreate( "Table", nid, "tab2", 1 ); //output plot Field< double >::set( mmid, "Km", 1.0 ); Field< double >::set( mmid, "kcat", 1.0 ); Field< double >::set( pid, "nInit", 1.0 ); Field< double >::set( qid, "nInit", 1.0 ); Field< double >::set( rid, "nInit", 0.0 ); shell->doAddMsg( "Single", ObjId( mmid ), "sub", ObjId( pid ), "reac" ); shell->doAddMsg( "Single", ObjId( mmid ), "prd", ObjId( rid ), "reac" ); shell->doAddMsg( "Single", ObjId( qid ), "nOut", ObjId( mmid ), "enzDest" ); shell->doAddMsg( "Single", ObjId( pid ), "nOut", ObjId( tabid2 ), "input" ); shell->doSetClock( 0, 0.01 ); shell->doSetClock( 1, 0.01 ); shell->doUseClock( "/n/mm,/n/tab2", "process", 0 ); shell->doUseClock( "/n/#[ISA=Pool]", "process", 1 ); ////////////////////////////////////////////////////////////////////// // Now run models and compare outputs ////////////////////////////////////////////////////////////////////// shell->doReinit(); shell->doStart( 10 ); vector< double > vec = Field< vector< double > >::get( tabid2, "vec" ); assert( vec.size() == 1001 ); for ( unsigned int i = 0; i < vec.size(); ++i ) { double t = 0.01 * i; double et = estT( vec[i] ); assert( doubleApprox( t, et ) ); } shell->doDelete( nid ); cout << "." << flush; }
void testTaperingCylDiffn() { Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); double len = 25e-6; double r0 = 2e-6; double r1 = 1e-6; double diffLength = 1e-6; // 1e-6 is the highest dx for which error is OK double runtime = 10.0; double dt = 0.1; // 0.2 is the highest dt for which the error is in bounds double diffConst = 1.0e-12; // Should set explicitly, currently during creation of DiffPoolVec //double diffConst = 1.0e-12; Id model = s->doCreate( "Neutral", Id(), "model", 1 ); Id cyl = s->doCreate( "CylMesh", model, "cyl", 1 ); Field< double >::set( cyl, "r0", r0 ); Field< double >::set( cyl, "r1", r1 ); Field< double >::set( cyl, "x0", 0 ); Field< double >::set( cyl, "x1", len ); Field< double >::set( cyl, "diffLength", diffLength ); unsigned int ndc = Field< unsigned int >::get( cyl, "numMesh" ); assert( ndc == static_cast< unsigned int >( round( len / diffLength ))); Id pool = s->doCreate( "Pool", cyl, "pool", 1 ); Field< double >::set( pool, "diffConst", diffConst ); Id dsolve = s->doCreate( "Dsolve", model, "dsolve", 1 ); Field< Id >::set( dsolve, "compartment", cyl ); s->doUseClock( "/model/dsolve", "process", 1 ); s->doSetClock( 1, dt ); // Next: build by setting the path of the dsolve. Field< string >::set( dsolve, "path", "/model/cyl/pool" ); // Then find a way to test it. assert( pool.element()->numData() == ndc ); Field< double >::set( ObjId( pool, 0 ), "nInit", 1.0 ); s->doReinit(); s->doStart( runtime ); double myTot = 0.0; vector< double > poolVec; Field< double >::getVec( pool, "n", poolVec ); for ( unsigned int i = 0; i < poolVec.size(); ++i ) { myTot += poolVec[i]; } assert( doubleEq( myTot, 1.0 ) ); s->doDelete( model ); cout << "." << flush; }
/// crate test object and push it into the container vector Id create_testobject(vector<Id> & container, string classname, Id parent, string name, vector<int> dims) { Shell * shell = reinterpret_cast< Shell* >( ObjId( Id(), 0 ).data() ); Id nid = shell->doCreate( classname, parent, name, dims ); container.push_back(nid); return nid; }
/* Enzymatic Reaction */ void SbmlReader::setupEnzymaticReaction( const EnzymeInfo & einfo,string enzname, const map< string, Id > &molSidcmptMIdMap,string name1) { string enzPool = einfo.enzyme; Id comptRef = molSidcmptMIdMap.find(enzPool)->second; //gives compartment of sp Id meshEntry = Neutral::child( comptRef.eref(), "mesh" ); Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); //Creating enz pool to enzyme site Id enzPoolId = molSidMIdMap_.find(enzPool)->second; Id enzyme_ = shell->doCreate("Enz", enzPoolId, name1, 1); //shell->doAddMsg( "Single", meshEntry, "remeshReacs", enzyme_, "remesh"); Id complex = einfo.complex; //Moving enzyme site under enzyme shell->doMove(complex,enzyme_); shell->doAddMsg("OneToAll",enzyme_,"cplx",complex,"reac"); shell->doAddMsg("OneToOne",enzyme_,"enz",enzPoolId,"reac"); vector< Id >::const_iterator sub_itr; for ( sub_itr = einfo.substrates.begin(); sub_itr != einfo.substrates.end(); sub_itr++ ) { Id S = (*sub_itr); Id b = shell->doAddMsg( "OneToOne", enzyme_, "sub" ,S , "reac" ); } vector< Id >::const_iterator prd_itr; for ( prd_itr = einfo.products.begin(); prd_itr != einfo.products.end(); prd_itr++ ) { Id P = (*prd_itr); shell->doAddMsg ("OneToOne",enzyme_,"prd", P,"reac"); } // populate k3,k2,k1 in this order only. Field < double > :: set( enzyme_, "k3", einfo.k3 ); Field < double > :: set( enzyme_, "k2", einfo.k2 ); Field < double > :: set( enzyme_, "k1", einfo.k1 ); }
void testPoolVolumeScaling() { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); Id comptId = shell->doCreate( "CylMesh", Id(), "cyl", 1 ); Id meshId( comptId.value() + 1 ); Id poolId = shell->doCreate( "Pool", comptId, "pool", 1 ); ObjId mid = shell->doAddMsg( "OneToOne", ObjId( poolId, 0 ), "requestVolume", ObjId( meshId, 0 ), "get_volume" ); assert( mid != ObjId() ); vector< double > coords( 9, 0.0 ); double x1 = 100e-6; double r0 = 10e-6; double r1 = 5e-6; double lambda = x1; coords[3] = x1; coords[6] = r0; coords[7] = r1; coords[8] = lambda; Field< vector< double > >::set( comptId, "coords", coords ); double volume = Field< double >::get( poolId, "volume" ); assert( doubleEq( volume, PI * x1 * (r0+r1) * (r0+r1) / 4.0 ) ); Field< double >::set( poolId, "n", 400 ); double volscale = 1 / ( NA * volume ); double conc = Field< double >::get( poolId, "conc" ); assert( doubleEq( conc, 400 * volscale ) ); Field< double >::set( poolId, "conc", 500 * volscale ); double n = Field< double >::get( poolId, "n" ); assert( doubleEq( n, 500 ) ); Field< double >::set( poolId, "nInit", 650 ); double concInit = Field< double >::get( poolId, "concInit" ); assert( doubleEq( concInit, 650 * volscale ) ); Field< double >::set( poolId, "concInit", 10 * volscale ); n = Field< double >::get( poolId, "nInit" ); assert( doubleEq( n, 10 ) ); shell->doDelete( comptId ); cout << "." << flush; }
void SbmlReader::getRules() { unsigned int nr = model_->getNumRules(); //if (nr > 0) // cout << "\n ##### Need to populate funcpool and sumtotal which is pending due to equations \n"; Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); for ( unsigned int r = 0; r < nr; r++ ) { Rule * rule = model_->getRule(r); bool assignRule = rule->isAssignment(); if ( assignRule ) { string rule_variable = rule->getVariable(); map< string,Id >::iterator v_iter; map< string,Id >::iterator m_iter; v_iter = molSidMIdMap_.find( rule_variable ); if (v_iter != molSidMIdMap_.end()) { Id rVariable = molSidMIdMap_.find(rule_variable)->second; string rstring =molSidMIdMap_.find(rule_variable)->first; Id sumId = shell->doCreate( "SumFunc", rVariable, "func", 1 ); rVariable.element()->zombieSwap( FuncPool::initCinfo() ); ObjId ret = shell->doAddMsg( "single", ObjId( sumId, 0 ), "output", ObjId( rVariable, 0 ), "input" ); assert( ret != ObjId() ); const ASTNode * ast = rule->getMath(); vector< string > ruleMembers; ruleMembers.clear(); printMembers( ast,ruleMembers ); for ( unsigned int rm = 0; rm < ruleMembers.size(); rm++ ) { m_iter = molSidMIdMap_.find( ruleMembers[rm] ); if ( m_iter != molSidMIdMap_.end() ) { Id rMember = molSidMIdMap_.find(ruleMembers[rm])->second; ObjId ret = shell->doAddMsg( "single", ObjId( rMember, 0 ), "nOut", ObjId( sumId, 0 ), "input" ); string test = molSidMIdMap_.find(ruleMembers[rm])->first; } else { cerr << "SbmlReader::getRules: Assignment rule member is not a species" << endl; // In assignment rule there are constants instead of molecule which is yet to deal in moose. errorFlag_ = true; } } } } bool rateRule = rule->isRate(); if ( rateRule ) { cout << "warning : for now Rate Rule is not handled " << endl; errorFlag_ = true; } bool algebRule = rule->isAlgebraic(); if ( algebRule ) { cout << "warning: for now Algebraic Rule is not handled" << endl; errorFlag_ = true; } } }
void testRunGsolve() { double simDt = 0.1; // double plotDt = 0.1; Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); Id kin = makeReacTest(); double volume = 1e-21; Field< double >::set( kin, "volume", volume ); Field< double >::set( ObjId( "/kinetics/A" ), "concInit", 2 ); Field< double >::set( ObjId( "/kinetics/e1Pool" ), "concInit", 1 ); Field< double >::set( ObjId( "/kinetics/e2Pool" ), "concInit", 1 ); Id e1( "/kinetics/e1Pool/e1" ); Field< double >::set( e1, "Km", 5 ); Field< double >::set( e1, "kcat", 1 ); vector< double > stim( 100, 0.0 ); for ( unsigned int i = 0; i< 100; ++i ) { stim[i] = volume * NA * (1.0 + sin( i * 2.0 * PI / 100.0 ) ); } Field< vector< double > >::set( ObjId( "/kinetics/tab" ), "vector", stim ); Id gsolve = s->doCreate( "Gsolve", kin, "gsolve", 1 ); Id stoich = s->doCreate( "Stoich", gsolve, "stoich", 1 ); Field< Id >::set( stoich, "compartment", kin ); Field< Id >::set( stoich, "ksolve", gsolve ); Field< string >::set( stoich, "path", "/kinetics/##" ); s->doUseClock( "/kinetics/gsolve", "process", 4 ); s->doSetClock( 4, simDt ); s->doReinit(); s->doStart( 20.0 ); Id plots( "/kinetics/plots" ); for ( unsigned int i = 0; i < 7; ++i ) { stringstream ss; ss << "plot." << i; SetGet2< string, string >::set( ObjId( plots, i ), "xplot", "tsr3.plot", ss.str() ); } s->doDelete( kin ); cout << "." << flush; }
// See what Element::getNeighbors does with 2 sub <----> prd. void testTwoReacGetNeighbors() { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); Id comptId = shell->doCreate( "CubeMesh", Id(), "cube", 1 ); Id meshId( comptId.value() + 1 ); Id subId = shell->doCreate( "Pool", comptId, "sub", 1 ); Id prdId = shell->doCreate( "Pool", comptId, "prd", 1 ); Id reacId = shell->doCreate( "Reac", comptId, "reac", 1 ); ObjId mid = shell->doAddMsg( "OneToOne", subId, "requestVolume", meshId, "get_volume" ); assert( mid != ObjId() ); mid = shell->doAddMsg( "OneToOne", prdId, "requestVolume", meshId, "get_volume" ); assert( mid != ObjId() ); ObjId ret = shell->doAddMsg( "Single", reacId, "sub", subId, "reac" ); assert( ret != ObjId() ); ret = shell->doAddMsg( "Single", reacId, "sub", subId, "reac" ); assert( ret != ObjId() ); ret = shell->doAddMsg( "Single", reacId, "prd", prdId, "reac" ); assert( ret != ObjId() ); vector< Id > pools; unsigned int num = reacId.element()->getNeighbors( pools, Reac::initCinfo()->findFinfo( "toSub" ) ); assert( num == 2 ); assert( pools[0] == subId ); assert( pools[1] == subId ); pools.clear(); num = reacId.element()->getNeighbors( pools, Reac::initCinfo()->findFinfo( "sub" ) ); assert( num == 2 ); assert( pools[0] == subId ); assert( pools[1] == subId ); shell->doDelete( comptId ); cout << "." << flush; }
////////////////////////////////////////////////////////////////// // The read functions. ////////////////////////////////////////////////////////////////// Id makeStandardElements( Id pa, const string& modelname ) { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); //cout << " kkit read " << pa << " " << modelname << " "<< MooseGlobal; string modelPath = pa.path() + "/" + modelname; if ( pa == Id() ) modelPath = "/" + modelname; Id mgr( modelPath ); if ( mgr == Id() ) mgr = shell->doCreate( "Neutral", pa, modelname, 1, MooseGlobal ); Id kinetics( modelPath + "/kinetics" ); if ( kinetics == Id() ) { kinetics = shell->doCreate( "CubeMesh", mgr, "kinetics", 1, MooseGlobal ); SetGet2< double, unsigned int >::set( kinetics, "buildDefaultMesh", 1e-15, 1 ); } assert( kinetics != Id() ); Id graphs = shell->doCreate( "Neutral", mgr, "graphs", 1, MooseGlobal); assert( graphs != Id() ); Id moregraphs = shell->doCreate( "Neutral", mgr, "moregraphs", 1, MooseGlobal ); Id geometry = shell->doCreate( "Neutral", mgr, "geometry", 1, MooseGlobal ); assert( geometry != Id() ); Id groups = shell->doCreate( "Neutral", mgr, "groups", 1, MooseGlobal ); assert( groups != Id() ); return mgr; }
void testSpikeGen() { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); Id sid = shell->doCreate( "SpikeGen", Id(), "spike", 1, MooseGlobal ); SpikeGen& sg = *( reinterpret_cast< SpikeGen* >( sid.eref().data() ) ); Eref er( sid.eref() ); ProcInfo p; p.dt = 0.001; p.currTime = 0.0; sg.setThreshold( 1.0 ); sg.setRefractT( 0.005 ); sg.reinit( er, &p ); sg.handleVm( 0.5 ); sg.process( er, &p ); assert( !sg.getFired() ); p.currTime += p.dt; sg.handleVm( 0.999 ); sg.process( er, &p ); assert( !sg.getFired() ); p.currTime += p.dt; sg.handleVm( 1.001 ); sg.process( er, &p ); assert( sg.getFired() ); p.currTime += p.dt; sg.handleVm( 0.999 ); sg.process( er, &p ); assert( !sg.getFired() ); p.currTime += p.dt; sg.handleVm( 2.0 ); // Too soon, refractory sg.process( er, &p ); assert( !sg.getFired() ); p.currTime += 0.005; // Now post-refractory sg.handleVm( 2.0 ); // Now not refractory sg.process( er, &p ); assert( sg.getFired() ); sid.destroy(); cout << "." << flush; }
/* set up Michalies Menten reaction */ void SbmlReader::setupMMEnzymeReaction( Reaction * reac,string rid,string rname,const map< string, Id > &molSidcmptMIdMap ) { string::size_type loc = rid.find( "_MM_Reaction_" ); if( loc != string::npos ) { int strlen = rid.length(); rid.erase( loc,strlen-loc ); } unsigned int num_modifr = reac->getNumModifiers(); for ( unsigned int m = 0; m < num_modifr; m++ ) { const ModifierSpeciesReference* modifr=reac->getModifier( m ); std::string sp = modifr->getSpecies(); Id enzyme_; Id E = molSidMIdMap_.find(sp)->second; Id comptRef = molSidcmptMIdMap.find(sp)->second; //gives compartment of sp Id meshEntry = Neutral::child( comptRef.eref(), "mesh" ); Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); enzyme_ = shell->doCreate("MMenz",E,rname,1); //shell->doAddMsg( "Single", meshEntry, "remeshReacs", enzyme_, "remesh"); shell->doAddMsg("Single",E,"nOut",enzyme_,"enzDest"); KineticLaw * klaw=reac->getKineticLaw(); vector< double > rate; rate.clear(); getKLaw( klaw,true,rate ); if ( errorFlag_ ) return; else if ( !errorFlag_ ) { for ( unsigned int rt = 0; rt < reac->getNumReactants(); rt++ ) { const SpeciesReference* rct = reac->getReactant( rt ); sp=rct->getSpecies(); Id S = molSidMIdMap_.find(sp)->second; shell->doAddMsg( "OneToOne", enzyme_, "sub" ,S , "reac" ); } for ( unsigned int pt = 0; pt < reac->getNumProducts(); pt++ ) { const SpeciesReference* pdt = reac->getProduct(pt); sp = pdt->getSpecies(); Id P = molSidMIdMap_.find(sp)->second; shell->doAddMsg( "OneToOne", enzyme_, "prd" ,P, "reac" ); } Field < double > :: set( enzyme_, "kcat", rate[0] ); Field < double > :: set( enzyme_, "numKm", rate[1] ); } } }
static Id makeCompt( Id parent, const SwcSegment& seg, const SwcSegment& pa, double RM, double RA, double CM, unsigned int i, unsigned int j ) { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); double len = seg.radius() * 2.0; string name = "soma"; Id compt; double x0, y0, z0; if ( seg.parent() != ~0U ) { len = seg.distance( pa ); stringstream ss; ss << SwcSegment::typeName[ seg.type() ] << "_" << i << "_" << j; name = ss.str(); x0 = pa.vec().a0(); y0 = pa.vec().a1(); z0 = pa.vec().a2(); } else { x0 = seg.vec().a0() - len; y0 = seg.vec().a1(); z0 = seg.vec().a2(); } assert( len > 0.0 ); compt = shell->doCreate( "Compartment", parent, name, 1 ); Eref er = compt.eref(); moose::CompartmentBase *cptr = reinterpret_cast< moose::CompartmentBase* >( compt.eref().data() ); double xa = seg.radius() * seg.radius() * PI * 1e-12; len *= 1e-6; double dia = seg.radius() * 2.0e-6; cptr->setRm( er, RM / ( len * dia * PI ) ); cptr->setRa( er, RA * len / xa ); cptr->setCm( er, CM * ( len * dia * PI ) ); cptr->setDiameter( dia ); cptr->setLength( len ); cptr->setX0( x0 * 1e-6 ); cptr->setY0( y0 * 1e-6 ); cptr->setZ0( z0 * 1e-6 ); cptr->setX( seg.vec().a0() * 1e-6 ); cptr->setY( seg.vec().a1() * 1e-6 ); cptr->setZ( seg.vec().a2() * 1e-6 ); return compt; }
void testMMenz() { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); Id mmid = shell->doCreate( "MMenz", Id(), "mm", 1 ); // mmenz MMenz m; ProcInfo p; m.vSetKm( mmid.eref(), 5.0 ); m.vSetKcat( mmid.eref(), 4.0 ); m.vReinit( mmid.eref(), &p ); m.vSub( 2 ); m.vEnz( 3 ); assert( doubleEq( m.vGetKm( mmid.eref() ), 5.0 ) ); assert( doubleEq( m.vGetKcat( mmid.eref() ), 4.0 ) ); m.vProcess( mmid.eref(), &p ); shell->doDelete( mmid ); cout << "." << flush; }
void testCompartment() { unsigned int size = 1; Eref sheller( Id().eref() ); Shell* shell = reinterpret_cast< Shell* >( sheller.data() ); Id comptId = shell->doCreate("Compartment", Id(), "compt", size); assert( Id::isValid(comptId)); Eref compter = comptId.eref(); Compartment* c = reinterpret_cast< Compartment* >( comptId.eref().data() ); ProcInfo p; p.dt = 0.002; c->setInject( compter, 1.0 ); c->setRm( compter, 1.0 ); c->setRa( compter, 0.0025 ); c->setCm( compter, 1.0 ); c->setEm( compter, 0.0 ); c->setVm( compter, 0.0 ); // First, test charging curve for a single compartment // We want our charging curve to be a nice simple exponential // Vm = 1.0 - 1.0 * exp( - t / 1.0 ); double delta = 0.0; double Vm = 0.0; double tau = 1.0; double Vmax = 1.0; for ( p.currTime = 0.0; p.currTime < 2.0; p.currTime += p.dt ) { Vm = c->getVm( compter ); double x = Vmax - Vmax * exp( -p.currTime / tau ); delta += ( Vm - x ) * ( Vm - x ); c->process( compter, &p ); } assert( delta < 1.0e-6 ); shell->doDelete(comptId); cout << "." << flush; }
void testCylDiffnWithStoich() { Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); double len = 25e-6; double r0 = 1e-6; double r1 = 1e-6; double diffLength = 1e-6; // 1e-6 is the highest dx for which error is OK double runtime = 10.0; double dt0 = 0.1; // Used for diffusion. 0.2 is the highest dt for which the error is in bounds double dt1 = 1; // Used for chem. double diffConst = 1.0e-12; Id model = s->doCreate( "Neutral", Id(), "model", 1 ); Id cyl = s->doCreate( "CylMesh", model, "cyl", 1 ); Field< double >::set( cyl, "r0", r0 ); Field< double >::set( cyl, "r1", r1 ); Field< double >::set( cyl, "x0", 0 ); Field< double >::set( cyl, "x1", len ); Field< double >::set( cyl, "diffLength", diffLength ); unsigned int ndc = Field< unsigned int >::get( cyl, "numMesh" ); assert( ndc == static_cast< unsigned int >( round( len / diffLength ))); Id pool1 = s->doCreate( "Pool", cyl, "pool1", 1 ); Id pool2 = s->doCreate( "Pool", cyl, "pool2", 1 ); Field< double >::set( pool1, "diffConst", diffConst ); Field< double >::set( pool2, "diffConst", diffConst/2 ); Id stoich = s->doCreate( "Stoich", model, "stoich", 1 ); Id ksolve = s->doCreate( "Ksolve", model, "ksolve", 1 ); Id dsolve = s->doCreate( "Dsolve", model, "dsolve", 1 ); Field< Id >::set( stoich, "compartment", cyl ); Field< Id >::set( stoich, "ksolve", ksolve ); Field< Id >::set( stoich, "dsolve", dsolve ); Field< string >::set( stoich, "path", "/model/cyl/#" ); assert( pool1.element()->numData() == ndc ); // Then find a way to test it. vector< double > poolVec; Field< double >::set( ObjId( pool1, 0 ), "nInit", 1.0 ); Field< double >::set( ObjId( pool2, 0 ), "nInit", 1.0 ); Field< double >::getVec( pool1, "nInit", poolVec ); assert( poolVec.size() == ndc ); assert( doubleEq( poolVec[0], 1.0 ) ); assert( doubleEq( poolVec[1], 0.0 ) ); vector< double > nvec = LookupField< unsigned int, vector< double > >::get( dsolve, "nVec", 0); assert( nvec.size() == ndc ); // Next: build by doing reinit s->doUseClock( "/model/dsolve", "process", 0 ); s->doUseClock( "/model/ksolve", "process", 1 ); s->doSetClock( 0, dt0 ); s->doSetClock( 1, dt1 ); s->doReinit(); s->doStart( runtime ); nvec = LookupField< unsigned int, vector< double > >::get( dsolve, "nVec", 0); Field< double >::getVec( pool1, "n", poolVec ); assert( nvec.size() == poolVec.size() ); for ( unsigned int i = 0; i < nvec.size(); ++i ) assert( doubleEq( nvec[i], poolVec[i] ) ); /* cout << endl; for ( unsigned int i = 0; i < nvec.size(); ++i ) cout << nvec[i] << " "; cout << endl; */ double dx = diffLength; double err = 0.0; double analyticTot = 0.0; double myTot = 0.0; for ( unsigned int i = 0; i < nvec.size(); ++i ) { double x = i * dx + dx * 0.5; // This part is the solution as a func of x,t. double y = dx * // This part represents the init n of 1 in dx ( 1.0 / sqrt( PI * diffConst * runtime ) ) * exp( -x * x / ( 4 * diffConst * runtime ) ); err += ( y - nvec[i] ) * ( y - nvec[i] ); //cout << i << " " << x << " " << y << " " << conc[i] << endl; analyticTot += y; myTot += nvec[i]; } assert( doubleEq( myTot, 1.0 ) ); // cout << "analyticTot= " << analyticTot << ", myTot= " << myTot << endl; assert( err < 1.0e-5 ); s->doDelete( model ); cout << "." << flush; }
void SbmlReader::createReaction(const map< string, Id > &molSidcmptMIdMap ) { Reaction* reac; map< string,double > rctMap; map< string,double >::iterator rctMap_iter; map< string,double >prdMap; map< string,double >::iterator prdMap_iter; map< string,EnzymeInfo >enzInfoMap; for ( unsigned int r = 0; r < model_->getNumReactions(); r++ ) { Id reaction_; reac = model_->getReaction( r ); noOfsub_ = 0; noOfprd_ = 0; std:: string id; //=reac->getId(); if ( reac->isSetId() ) id = reac->getId(); std::string name; if ( reac->isSetName() ) { name = reac->getName(); name = nameString(name); } if (name.empty()) { if (id.empty()) assert("Reaction id and name is empty"); else name = id; } string grpname = getAnnotation( reac,enzInfoMap ); if ( (grpname != "") && (enzInfoMap[grpname].stage == 3) ) { setupEnzymaticReaction( enzInfoMap[grpname],grpname ,molSidcmptMIdMap,name); } //if (grpname != "") // { //cout << "\n enz matic reaction " << enzInfoMap[grpname].stage; //setupEnzymaticReaction( enzInfoMap[grpname],grpname ,molSidcmptMIdMap); //} else if ( grpname == "" ) { if (reac->getNumModifiers() > 0) setupMMEnzymeReaction( reac,id,name ,molSidcmptMIdMap); else { bool rev=reac->getReversible(); bool fast=reac->getFast(); if ( fast ) { cout<<"warning: for now fast attribute is not handled"<<endl; errorFlag_ = true; } int numRcts = reac->getNumReactants(); int numPdts = reac->getNumProducts(); if ( numRcts == 0 && numPdts != 0 ) { cout << "Reaction with zero Substrate is not possible but exist in this model"; const SpeciesReference* pdt = reac->getProduct( 0 ); std::string spName = pdt->getSpecies(); Id parent = molSidcmptMIdMap.find( spName )->second; //gives compartment of spName cout << " \n \t ################################# Sub = 0 and prd != 0 need to the reac ############### "; const SpeciesReference* rect=reac->getReactant(0); std::string sp=rect->getSpecies(); Id comptRef = molSidcmptMIdMap.find(sp)->second; //gives compartment of sp Id meshEntry = Neutral::child( comptRef.eref(), "mesh" ); Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); reaction_ = shell->doCreate("Reac", meshEntry, name, 1); //shell->doAddMsg( "Single", meshEntry, "remeshReacs", reaction_, "remesh"); //Get Substrate addSubPrd(reac,reaction_,"prd"); } //if numRcts == 0 else { const SpeciesReference* rect=reac->getReactant(0); std::string sp=rect->getSpecies(); Id comptRef = molSidcmptMIdMap.find(sp)->second; //gives compartment of sp Id meshEntry = Neutral::child( comptRef.eref(), "mesh" ); Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); reaction_ = shell->doCreate("Reac", comptRef, name, 1); //shell->doAddMsg( "Single", meshEntry, "remeshReacs", reaction_, "remesh"); //Get Substrate addSubPrd(reac,reaction_,"sub"); //Get Product addSubPrd(reac,reaction_,"prd"); } if ( reac->isSetKineticLaw() ) { KineticLaw * klaw=reac->getKineticLaw(); //vector< double > rate = getKLaw( klaw,rev ); vector< double > rate; rate.clear(); getKLaw( klaw,rev,rate ); if ( errorFlag_ ) return; else if ( !errorFlag_ ) { //cout << " Reaction name " << name << " kf " << rate[0] << " kb " << rate[1]<<endl; Field < double > :: set( reaction_, "Kf", rate[0] ); Field < double > :: set( reaction_, "Kb", rate[1] ); /*if (numRcts > 1) rate[0] = rate[0]*pow(1e3,1.0); cout << "Reaction " << id << " " << name << " " << rate[0] << " " << rate[1]<<endl; Field < double > :: set( reaction_, "Kf", rate[0] ); Field < double > :: set( reaction_, "Kb", rate[1] ); */ } } //issetKineticLaw } //else } // else grpname == "" }//for unsigned } //reaction
/** * @brief Reads a given SBML file and loads it into MOOSE. * * @param filename Name of file, std::string. * @param location * @param solverClass * * @return Id on success. Some expcetion on failure. */ Id SbmlReader::read( string filename, string location, string solverClass) { FILE * fp = fopen( filename.c_str(), "r" ); if ( fp == NULL) { stringstream ss; ss << "File " << filename << " does not exist." << endl; throw runtime_error(ss.str()); } document_ = readSBML( filename.c_str() ); unsigned num_errors = document_->getNumErrors(); if ( num_errors > 0 ) { cerr << "Errors encountered while reading" << endl; document_->printErrors( cerr ); errorFlag_ = true; return baseId; } model_= document_->getModel(); if ( model_ == 0 ) { cout << "SBML: Error: No model present." << endl; errorFlag_ = true; return baseId; } if ( !errorFlag_ ) getGlobalParameter(); if ( !errorFlag_ ) { string modelName; Id parentId; findModelParent ( Id(), location, parentId, modelName ) ; Id parentId2 = parentId; Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); /* As a policy model is created under /model and all the graphs are created under /data, if this file is invoke from Gui the /model is already created and path is passed, but if readSbml is called then only modelName is taken so making sure /model is the model path */ //Id modelPath_ = s->doCreate("Neutral",parentId,"model",1,MooseGlobal); if (parentId == Id()) { Id parentId1 = s->doCreate("Neutral",parentId,"model",1,MooseGlobal); parentId = parentId1; } Id base_ = s->doCreate( "Neutral", parentId, modelName, 1, MooseGlobal); //Id base_ = s->doCreate( "SimManager", parentId, modelName, dims, true ); assert( base_ != Id() ); //Map Compartment's SBML id to Moose ID map< string,Id > comptSidMIdMap; // Map between Molecule's SBML id to which it belongs compartment Moose Id map< string, Id > molSidcmptMIdMap; if ( !errorFlag_ ) comptSidMIdMap = createCompartment(location, parentId, modelName, base_); if ( !errorFlag_ ) molSidcmptMIdMap = createMolecule( comptSidMIdMap); if ( !errorFlag_ ) getRules(); if ( !errorFlag_ ) createReaction( molSidcmptMIdMap ); // or we get //createReaction (result); if ( errorFlag_ ) return baseId; else { // SimManager* sm = reinterpret_cast< SimManager* >(baseId.eref().data()); //Shell* s = reinterpret_cast< Shell* >(baseId.eref().data()); XMLNode * annotationNode = model_->getAnnotation(); if( annotationNode != NULL ) { unsigned int num_children = annotationNode->getNumChildren(); for( unsigned int child_no = 0; child_no < num_children; child_no++ ) { XMLNode childNode = annotationNode->getChild( child_no ); if ( childNode.getPrefix() == "moose" && childNode.getName() == "ModelAnnotation" ) { unsigned int num_gchildren = childNode.getNumChildren(); for( unsigned int gchild_no = 0; gchild_no < num_gchildren; gchild_no++ ) { XMLNode &grandChildNode = childNode.getChild( gchild_no ); string nodeName = grandChildNode.getName(); if (grandChildNode.getNumChildren() == 1 ) { string plotValue; //double nodeValue; if(nodeName == "plots") { // if plots exist then will be placing at "/data" Id graphs; //Id dataId; Id dataIdTest; if (parentId2 == Id()) graphs = s->doCreate( "Neutral", parentId2, "data", 1); else // need to check how to put / while coming from gui as the path is /model/modelName??? 27 jun 2014 findModelParent ( Id(), modelName, dataIdTest, modelName ) ; string test = "/data"; Id tgraphs(test); graphs=tgraphs; //graphs = s->doCreate("Neutral",parentId,"data",1); //Id dataId; //if (dataId == Id()) // cout << "Id " << dataId; // graphs = s->doCreate( "Neutral",dataId, "data", 1); assert( graphs != Id() ); plotValue = (grandChildNode.getChild(0).toXMLString()).c_str(); istringstream pltVal(plotValue); string pltClean; while (getline(pltVal,pltClean, ';')) { pltClean.erase( remove( pltClean.begin(), pltClean.end(), ' ' ), pltClean.end() ); //string plotPath = location+pltClean; string plotPath = base_.path()+pltClean; Id plotSId(plotPath); unsigned pos = pltClean.find('/'); if (pos != std::string::npos) pltClean = pltClean.substr(pos+1,pltClean.length()); replace(pltClean.begin(),pltClean.end(),'/','_'); string plotName = pltClean + ".conc"; Id pltPath(graphs.path()); Id tab = s->doCreate( "Table", pltPath, plotName, 1 ); if (tab != Id()) s->doAddMsg("Single",tab,"requestOut",plotSId,"getConc"); }//while /* passing /model and /data */ string comptPath =base_.path()+"/##"; s->doUseClock(comptPath,"process",4); string tablePath = graphs.path()+"/##[TYPE=Table]"; s->doUseClock( tablePath, "process",8 ); }//plots /*else nodeValue = atof ((grandChildNode.getChild(0).toXMLString()).c_str()); if (nodeName == "runTime") sm->setRunTime(nodeValue); else if (nodeName == "simdt") sm->setSimDt(nodeValue); else if(nodeName == "plotdt") sm->setPlotDt(nodeValue); */ } //grandChild else cout << "Warning: expected exactly ONE child of " << nodeName << " but none found "<<endl; } //gchild } //moose and modelAnnotation } }//annotation Node else { //4 for simdt and 8 for plotdt s->doUseClock(base_.path()+"/##","process",4); s->doUseClock(+"/data/##[TYPE=Table]","process",8); s->doSetClock(4,0.1); s->doSetClock(8,0.1); } vector< ObjId > compts; string comptpath = base_.path()+"/##[ISA=ChemCompt]"; wildcardFind( comptpath, compts ); vector< ObjId >::iterator i = compts.begin(); string comptName = nameString(Field<string> :: get(ObjId(*i),"name")); string simpath = base_.path() + "/##"; s->doUseClock( simpath, "process", 4 ); //wildcardFind( plotpath, plots ); //Id pathexist(base_.path()+"/kinetics"); /* if (solverClass.empty()) { if( pathexist != Id()) sm->build(base_.eref(),&q,"rk5"); else sm->buildForSBML(base_.eref(),&q,"rk5"); } else { if(pathexist != Id()) sm->build(base_.eref(),&q,solverClass); else sm->buildForSBML(base_.eref(),&q,solverClass); } */ return base_; } } else return baseId; }
void testHSolveUtils( ) { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); bool success; Id n = shell->doCreate( "Neutral", Id(), "n" ); /** * First we test the functions which return the compartments linked to a * given compartment: adjacent(), and children(). * * A small tree is created for this: * * c0 * L c1 * L c2 * L c3 * L c4 * L c5 * * (c0 is the parent of c1. c1 is the parent of c2, c3, c4, c5.) */ Id c[ 6 ]; c[ 0 ] = shell->doCreate( "Compartment", n, "c0" ); c[ 1 ] = shell->doCreate( "Compartment", n, "c1" ); c[ 2 ] = shell->doCreate( "Compartment", n, "c2" ); c[ 3 ] = shell->doCreate( "Compartment", n, "c3" ); c[ 4 ] = shell->doCreate( "Compartment", n, "c4" ); c[ 5 ] = shell->doCreate( "Compartment", n, "c5" ); MsgId mid; mid = shell->doAddMsg( "Single", c[ 0 ], "axial", c[ 1 ], "raxial" ); ASSERT( mid != Msg::bad, "Linking compartments" ); mid = shell->doAddMsg( "Single", c[ 1 ], "axial", c[ 2 ], "raxial" ); ASSERT( mid != Msg::bad, "Linking compartments" ); mid = shell->doAddMsg( "Single", c[ 1 ], "axial", c[ 3 ], "raxial" ); ASSERT( mid != Msg::bad, "Linking compartments" ); mid = shell->doAddMsg( "Single", c[ 1 ], "axial", c[ 4 ], "raxial" ); ASSERT( mid != Msg::bad, "Linking compartments" ); mid = shell->doAddMsg( "Single", c[ 1 ], "axial", c[ 5 ], "raxial" ); ASSERT( mid != Msg::bad, "Linking compartments" ); vector< Id > found; unsigned int nFound; /* * Testing version 1 of HSolveUtils::adjacent. * It finds all neighbours of given compartment. */ // Neighbours of c0 nFound = HSolveUtils::adjacent( c[ 0 ], found ); ASSERT( nFound == found.size(), "Finding adjacent compartments" ); // c1 is adjacent ASSERT( nFound == 1, "Finding adjacent compartments" ); ASSERT( found[ 0 ] == c[ 1 ], "Finding adjacent compartments" ); // Neighbours of c1 found.clear(); nFound = HSolveUtils::adjacent( c[ 1 ], found ); ASSERT( nFound == 5, "Finding adjacent compartments" ); // c0 is adjacent success = find( found.begin(), found.end(), c[ 0 ] ) != found.end(); ASSERT( success, "Finding adjacent compartments" ); // c2 - c5 are adjacent for ( int i = 2; i < 6; i++ ) { success = find( found.begin(), found.end(), c[ i ] ) != found.end(); ASSERT( success, "Finding adjacent compartments" ); } // Neighbours of c2 found.clear(); nFound = HSolveUtils::adjacent( c[ 2 ], found ); // c1 is adjacent ASSERT( nFound == 1, "Finding adjacent compartments" ); ASSERT( found[ 0 ] == c[ 1 ], "Finding adjacent compartments" ); /* * Testing version 2 of HSolveUtils::adjacent. * It finds all but one neighbours of given compartment. * The the second argument to 'adjacent' is the one that is excluded. */ // Neighbours of c1 (excluding c0) found.clear(); nFound = HSolveUtils::adjacent( c[ 1 ], c[ 0 ], found ); ASSERT( nFound == 4, "Finding adjacent compartments" ); // c2 - c5 are adjacent for ( int i = 2; i < 6; i++ ) { success = find( found.begin(), found.end(), c[ i ] ) != found.end(); ASSERT( success, "Finding adjacent compartments" ); } // Neighbours of c1 (excluding c2) found.clear(); nFound = HSolveUtils::adjacent( c[ 1 ], c[ 2 ], found ); ASSERT( nFound == 4, "Finding adjacent compartments" ); // c0 is adjacent success = find( found.begin(), found.end(), c[ 0 ] ) != found.end(); ASSERT( success, "Finding adjacent compartments" ); // c3 - c5 are adjacent for ( int i = 3; i < 6; i++ ) { success = find( found.begin(), found.end(), c[ i ] ) != found.end(); ASSERT( success, "Finding adjacent compartments" ); } // Neighbours of c2 (excluding c1) found.clear(); nFound = HSolveUtils::adjacent( c[ 2 ], c[ 1 ], found ); // None adjacent, if c1 is excluded ASSERT( nFound == 0, "Finding adjacent compartments" ); // Neighbours of c2 (excluding c3) found.clear(); nFound = HSolveUtils::adjacent( c[ 2 ], c[ 3 ], found ); // c1 is adjacent, while c3 is not even connected ASSERT( nFound == 1, "Finding adjacent compartments" ); ASSERT( found[ 0 ] == c[ 1 ], "Finding adjacent compartments" ); /* * Testing HSolveUtils::children. * It finds all compartments which are dests for the "axial" message. */ // Children of c0 found.clear(); nFound = HSolveUtils::children( c[ 0 ], found ); ASSERT( nFound == 1, "Finding child compartments" ); // c1 is a child ASSERT( found[ 0 ] == c[ 1 ], "Finding child compartments" ); // Children of c1 found.clear(); nFound = HSolveUtils::children( c[ 1 ], found ); ASSERT( nFound == 4, "Finding child compartments" ); // c2 - c5 are c1's children for ( int i = 2; i < 6; i++ ) { success = find( found.begin(), found.end(), c[ i ] ) != found.end(); ASSERT( success, "Finding child compartments" ); } // Children of c2 found.clear(); nFound = HSolveUtils::children( c[ 2 ], found ); // c2 has no children ASSERT( nFound == 0, "Finding child compartments" ); // Clean up shell->doDelete( n ); cout << "." << flush; }
/** * Tab controlled by table * A + Tab <===> B * A + B -sumtot--> tot1 * 2B <===> C * * C ---e1Pool ---> D * D ---e2Pool ----> E * * All these are created on /kinetics, a cube compartment of vol 1e-18 m^3 * */ Id makeReacTest() { double simDt = 0.1; double plotDt = 0.1; Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); Id pools[10]; unsigned int i = 0; // Make the objects. Id kin = s->doCreate( "CubeMesh", Id(), "kinetics", 1 ); Id tab = s->doCreate( "StimulusTable", kin, "tab", 1 ); Id T = pools[i++] = s->doCreate( "BufPool", kin, "T", 1 ); Id A = pools[i++] = s->doCreate( "Pool", kin, "A", 1 ); Id B = pools[i++] = s->doCreate( "Pool", kin, "B", 1 ); Id C = pools[i++] = s->doCreate( "Pool", kin, "C", 1 ); Id D = pools[i++] = s->doCreate( "Pool", kin, "D", 1 ); Id E = pools[i++] = s->doCreate( "Pool", kin, "E", 1 ); Id tot1 = pools[i++] = s->doCreate( "BufPool", kin, "tot1", 1 ); Id sum = s->doCreate( "Function", tot1, "func", 1 ); // Silly that it has to have this name. Id sumInput( sum.value() + 1 ); Id e1Pool = s->doCreate( "Pool", kin, "e1Pool", 1 ); Id e2Pool = s->doCreate( "Pool", kin, "e2Pool", 1 ); Id e1 = s->doCreate( "Enz", e1Pool, "e1", 1 ); Id cplx = s->doCreate( "Pool", e1, "cplx", 1 ); Id e2 = s->doCreate( "MMenz", e2Pool, "e2", 1 ); Id r1 = s->doCreate( "Reac", kin, "r1", 1 ); Id r2 = s->doCreate( "Reac", kin, "r2", 1 ); Id plots = s->doCreate( "Table2", kin, "plots", 7 ); // Connect them up s->doAddMsg( "Single", tab, "output", T, "setN" ); s->doAddMsg( "Single", r1, "sub", T, "reac" ); s->doAddMsg( "Single", r1, "sub", A, "reac" ); s->doAddMsg( "Single", r1, "prd", B, "reac" ); Field< unsigned int >::set( sum, "numVars", 2 ); s->doAddMsg( "Single", A, "nOut", ObjId( sumInput, 0, 0 ), "input" ); s->doAddMsg( "Single", B, "nOut", ObjId( sumInput, 0, 1 ), "input" ); s->doAddMsg( "Single", sum, "valueOut", tot1, "setN" ); s->doAddMsg( "Single", r2, "sub", B, "reac" ); s->doAddMsg( "Single", r2, "sub", B, "reac" ); s->doAddMsg( "Single", r2, "prd", C, "reac" ); s->doAddMsg( "Single", e1, "sub", C, "reac" ); s->doAddMsg( "Single", e1, "enz", e1Pool, "reac" ); s->doAddMsg( "Single", e1, "cplx", cplx, "reac" ); s->doAddMsg( "Single", e1, "prd", D, "reac" ); s->doAddMsg( "Single", e2, "sub", D, "reac" ); s->doAddMsg( "Single", e2Pool, "nOut", e2, "enzDest" ); s->doAddMsg( "Single", e2, "prd", E, "reac" ); // Set parameters. Field< double >::set( A, "concInit", 2 ); Field< double >::set( e1Pool, "concInit", 1 ); Field< double >::set( e2Pool, "concInit", 1 ); Field< string >::set( sum, "expr", "x0+x1" ); Field< double >::set( r1, "Kf", 0.2 ); Field< double >::set( r1, "Kb", 0.1 ); Field< double >::set( r2, "Kf", 0.1 ); Field< double >::set( r2, "Kb", 0.0 ); Field< double >::set( e1, "Km", 5 ); Field< double >::set( e1, "kcat", 1 ); Field< double >::set( e1, "ratio", 4 ); Field< double >::set( e2, "Km", 5 ); Field< double >::set( e2, "kcat", 1 ); vector< double > stim( 100, 0.0 ); double vol = Field< double >::get( kin, "volume" ); for ( unsigned int i = 0; i< 100; ++i ) { stim[i] = vol * NA * (1.0 + sin( i * 2.0 * PI / 100.0 ) ); } Field< vector< double > >::set( tab, "vector", stim ); Field< double >::set( tab, "stepSize", 0.0 ); Field< double >::set( tab, "stopTime", 10.0 ); Field< double >::set( tab, "loopTime", 10.0 ); Field< bool >::set( tab, "doLoop", true ); // Connect outputs for ( unsigned int i = 0; i < 7; ++i ) s->doAddMsg( "Single", ObjId( plots,i), "requestOut", pools[i], "getConc" ); // Schedule it. for ( unsigned int i = 11; i < 18; ++i ) s->doSetClock( i, simDt ); s->doSetClock( 18, plotDt ); /* s->doUseClock( "/kinetics/##[ISA=Reac],/kinetics/##[ISA=EnzBase],/kinetics/##[ISA=SumFunc]", "process", 4 ); s->doUseClock( "/kinetics/##[ISA=PoolBase]", "process", 5 ); s->doUseClock( "/kinetics/##[ISA=StimulusTable]", "process", 4 ); s->doUseClock( "/kinetics/##[ISA=Table]", "process", 8 ); s->doSetClock( 4, simDt ); s->doSetClock( 5, simDt ); s->doSetClock( 8, plotDt ); */ return kin; }
void testAssortedMsg() { Eref sheller = Id().eref(); Shell* shell = reinterpret_cast< Shell* >( sheller.data() ); ObjId pa = shell->doCreate( "Neutral", ObjId(), "pa", 1 ); unsigned int numData = 5; /////////////////////////////////////////////////////////// // Set up the objects. /////////////////////////////////////////////////////////// Id a1 = shell->doCreate( "Arith", pa, "a1", numData ); Id a2 = shell->doCreate( "Arith", pa, "a2", numData ); Id b1 = shell->doCreate( "Arith", pa, "b1", numData ); Id b2 = shell->doCreate( "Arith", pa, "b2", numData ); Id c1 = shell->doCreate( "Arith", pa, "c1", numData ); Id c2 = shell->doCreate( "Arith", pa, "c2", numData ); Id d1 = shell->doCreate( "Arith", pa, "d1", numData ); Id d2 = shell->doCreate( "Arith", pa, "d2", numData ); Id e1 = shell->doCreate( "Arith", pa, "e1", numData ); Id e2 = shell->doCreate( "Arith", pa, "e2", numData ); /////////////////////////////////////////////////////////// // Set up initial conditions /////////////////////////////////////////////////////////// bool ret = 0; vector< double > init; // 12345 for ( unsigned int i = 1; i < 6; ++i ) init.push_back( i ); ret = SetGet1< double >::setVec( a1, "arg1", init ); // 12345 assert( ret ); ret = SetGet1< double >::setVec( b1, "arg1", init ); // 12345 assert( ret ); ret = SetGet1< double >::setVec( c1, "arg1", init ); // 12345 assert( ret ); ret = SetGet1< double >::setVec( d1, "arg1", init ); // 12345 assert( ret ); ret = SetGet1< double >::setVec( e1, "arg1", init ); // 12345 assert( ret ); /////////////////////////////////////////////////////////// // Set up messaging /////////////////////////////////////////////////////////// // Should give 04000 ObjId m1 = shell->doAddMsg( "Single", ObjId( a1, 3 ), "output", ObjId( a2, 1 ), "arg1" ); assert( !m1.bad() ); // Should give 33333 ObjId m2 = shell->doAddMsg( "OneToAll", ObjId( b1, 2 ), "output", ObjId( b2, 0 ), "arg1" ); assert( !m2.bad() ); // Should give 12345 ObjId m3 = shell->doAddMsg( "OneToOne", ObjId( c1, 0 ), "output", ObjId( c2, 0 ), "arg1" ); assert( !m3.bad() ); // Should give 01234 ObjId m4 = shell->doAddMsg( "Diagonal", ObjId( d1, 0 ), "output", ObjId( d2, 0 ), "arg1" ); assert( !m4.bad() ); // Should give 54321 ObjId m5 = shell->doAddMsg( "Sparse", ObjId( e1, 0 ), "output", ObjId( e2, 0 ), "arg1" ); assert( !m5.bad() ); ret = SetGet3< unsigned int, unsigned int, unsigned int >::set( m5, "setEntry", 0, 4, 0 ); assert( ret ); ret = SetGet3< unsigned int, unsigned int, unsigned int >::set( m5, "setEntry", 1, 3, 0 ); assert( ret ); ret = SetGet3< unsigned int, unsigned int, unsigned int >::set( m5, "setEntry", 2, 2, 0 ); assert( ret ); ret = SetGet3< unsigned int, unsigned int, unsigned int >::set( m5, "setEntry", 3, 1, 0 ); assert( ret ); ret = SetGet3< unsigned int, unsigned int, unsigned int >::set( m5, "setEntry", 4, 0, 0 ); assert( ret ); assert( ret ); /////////////////////////////////////////////////////////// // Test traversal /////////////////////////////////////////////////////////// // Single ObjId f = Msg::getMsg( m1 )->findOtherEnd( ObjId( a1, 3 ) ); assert( f == ObjId( a2, 1 ) ); f = Msg::getMsg( m1 )->findOtherEnd( ObjId( a2, 1 ) ); assert( f == ObjId( a1, 3 ) ); f = Msg::getMsg( m1 )->findOtherEnd( ObjId( a1, 0 ) ); assert( f.bad() ); f = Msg::getMsg( m1 )->findOtherEnd( ObjId( a2, 0 ) ); assert( f.bad() ); f = Msg::getMsg( m1 )->findOtherEnd( ObjId( b2, 1 ) ); assert( f.bad() ); // OneToAll f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b1, 2 ) ); assert( f == ObjId( b2, 0 ) ); f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 0 ) ); assert( f == ObjId( b1, 2 ) ); f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 1 ) ); assert( f == ObjId( b1, 2 ) ); f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 2 ) ); assert( f == ObjId( b1, 2 ) ); f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 3 ) ); assert( f == ObjId( b1, 2 ) ); f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 4 ) ); assert( f == ObjId( b1, 2 ) ); f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b1, 0 ) ); assert( f.bad() ); f = Msg::getMsg( m2 )->findOtherEnd( ObjId( a2, 1 ) ); assert( f.bad() ); // OneToOne for ( unsigned int i = 0; i < 5; ++i ) { f = Msg::getMsg( m3 )->findOtherEnd( ObjId( c1, i ) ); assert( f == ObjId( c2, i ) ); f = Msg::getMsg( m3 )->findOtherEnd( ObjId( c2, i ) ); assert( f == ObjId( c1, i ) ); } f = Msg::getMsg( m3 )->findOtherEnd( ObjId( a2, 1 ) ); assert( f.bad() ); // Diagonal for ( unsigned int i = 0; i < 4; ++i ) { f = Msg::getMsg( m4 )->findOtherEnd( ObjId( d1, i ) ); assert( f == ObjId( d2, i + 1 ) ); f = Msg::getMsg( m4 )->findOtherEnd( ObjId( d2, i + 1 ) ); assert( f == ObjId( d1, i ) ); } f = Msg::getMsg( m4 )->findOtherEnd( ObjId( d1, 4 ) ); assert( f.bad() ); f = Msg::getMsg( m4 )->findOtherEnd( ObjId( d2, 0 ) ); assert( f.bad() ); f = Msg::getMsg( m4 )->findOtherEnd( ObjId( a2, 1 ) ); assert( f.bad() ); // Sparse for ( unsigned int i = 0; i < 5; ++i ) { f = Msg::getMsg( m5 )->findOtherEnd( ObjId( e1, i ) ); assert( f == ObjId( e2, 4 - i ) ); f = Msg::getMsg( m5 )->findOtherEnd( ObjId( e2, i ) ); assert( f == ObjId( e1, 4 - i ) ); } f = Msg::getMsg( m5 )->findOtherEnd( ObjId( a2, 1 ) ); assert( f.bad() ); cout << "." << flush; /////////////////////////////////////////////////////////// // Check lookup by funcId. /////////////////////////////////////////////////////////// const Finfo* aFinfo = Arith::initCinfo()->findFinfo( "arg1" ); FuncId afid = dynamic_cast< const DestFinfo* >( aFinfo )->getFid(); ObjId m = a2.element()->findCaller( afid ); assert ( m == m1 ); m = b2.element()->findCaller( afid ); assert ( m == m2 ); m = c2.element()->findCaller( afid ); assert ( m == m3 ); m = d2.element()->findCaller( afid ); assert ( m == m4 ); m = e2.element()->findCaller( afid ); assert ( m == m5 ); /////////////////////////////////////////////////////////// // Clean up. /////////////////////////////////////////////////////////// shell->doDelete( pa ); cout << "." << flush; }
// Reported as a bug by Subha 22 Feb 2012. void testMsgElementListing() { Eref sheller = Id().eref(); Shell* shell = reinterpret_cast< Shell* >( sheller.data() ); unsigned int numData = 1; Id pa = shell->doCreate( "Neutral", Id(), "pa", numData ); numData = 5; /////////////////////////////////////////////////////////// // Set up the objects. /////////////////////////////////////////////////////////// Id a1 = shell->doCreate( "Arith", pa, "a1", numData ); Id a2 = shell->doCreate( "Arith", pa, "a2", numData ); Id b1 = shell->doCreate( "Arith", pa, "b1", numData ); Id b2 = shell->doCreate( "Arith", pa, "b2", numData ); Id c1 = shell->doCreate( "Arith", pa, "c1", numData ); Id c2 = shell->doCreate( "Arith", pa, "c2", numData ); Id d1 = shell->doCreate( "Arith", pa, "d1", numData ); Id d2 = shell->doCreate( "Arith", pa, "d2", numData ); Id e1 = shell->doCreate( "Arith", pa, "e1", numData ); Id e2 = shell->doCreate( "Arith", pa, "e2", numData ); /////////////////////////////////////////////////////////// // Set up messaging /////////////////////////////////////////////////////////// ObjId m1 = shell->doAddMsg( "Single", ObjId( a1, 3 ), "output", ObjId( a2, 1 ), "arg1" ); assert( !m1.bad() ); ObjId m2 = shell->doAddMsg( "OneToAll", ObjId( b1, 2 ), "output", ObjId( b2, 0 ), "arg1" ); assert( !m2.bad() ); ObjId m3 = shell->doAddMsg( "OneToOne", ObjId( c1, 0 ), "output", ObjId( c2, 0 ), "arg1" ); assert( !m3.bad() ); ObjId m4 = shell->doAddMsg( "Diagonal", ObjId( d1, 0 ), "output", ObjId( d2, 0 ), "arg1" ); assert( !m4.bad() ); ObjId m5 = shell->doAddMsg( "Sparse", ObjId( e1, 0 ), "output", ObjId( e2, 0 ), "arg1" ); assert( !m5.bad() ); /////////////////////////////////////////////////////////// // List messages /////////////////////////////////////////////////////////// Id manager( "/Msgs" ); assert( manager != Id() ); vector< Id > children = Field< vector< Id > >::get( manager, "children" ); assert( children.size() == 5 ); assert( children[0].element()->getName() == "singleMsg" ); assert( children[1].element()->getName() == "oneToOneMsg" ); assert( children[2].element()->getName() == "oneToAllMsg" ); assert( children[3].element()->getName() == "diagonalMsg" ); assert( children[4].element()->getName() == "sparseMsg" ); /* // A remarkably large number of some message classes, including 645 // OneToAll which are used by parent-child messages. I thought they // were cleaned out as the tests proceed. for ( unsigned int i = 0; i < children.size(); ++i ) { cout << "\nlocalEntries[" << i << "] = " << children[i].element()->dataHandler()->localEntries() << endl; } */ /* string path = children[0].path(); cout << "\nlocalEntries = " << children[0].element()->dataHandler()->localEntries() << endl; assert( path == "/Msgs/singleMsg[0]" ); */ assert( children[0].path() == "/Msgs[0]/singleMsg" ); assert( children[1].path() == "/Msgs[0]/oneToOneMsg" ); assert( children[2].path() == "/Msgs[0]/oneToAllMsg" ); assert( children[3].path() == "/Msgs[0]/diagonalMsg" ); assert( children[4].path() == "/Msgs[0]/sparseMsg" ); /////////////////////////////////////////////////////////// // Next: check that the child messages have the appropriate number // and indices of entries. /////////////////////////////////////////////////////////// shell->doDelete( pa ); cout << "." << flush; }
void testBuildStoich() { // Matrix looks like: // Reac Name R1 R2 e1a e1b e2 // MolName // D -1 0 0 0 0 // A -1 0 0 0 0 // B +1 -2 0 0 0 // C 0 +1 -1 0 0 // enz1 0 0 -1 +1 0 // e1cplx 0 0 +1 -1 0 // E 0 0 0 +1 -1 // F 0 0 0 0 +1 // enz2 0 0 0 0 0 // tot1 0 0 0 0 0 // // This has been shuffled to: // A -1 0 0 0 0 // B +1 -2 0 0 0 // C 0 +1 -1 0 0 // E 0 0 0 +1 -1 // F 0 0 0 0 +1 // enz1 0 0 -1 +1 0 // enz2 0 0 0 0 0 // e1cplx 0 0 +1 -1 0 // D -1 0 0 0 0 // tot1 0 0 0 0 0 // // But the reacs have also been reordered: // Reac Name e1a e1b e2 R1 R2 // A 0 0 0 -1 0 // B 0 0 0 1 -2 // C -1 0 0 0 1 // E 0 1 -1 0 0 // F 0 0 1 0 0 // enz1 -1 1 0 0 0 // enz2 0 0 0 0 0 // e1cplx 1 -1 0 0 0 // D 0 0 0 -1 0 // tot1 0 0 0 0 0 // // (This is the output of the print command on the sparse matrix.) // Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); Id kin = makeReacTest(); Id ksolve = s->doCreate( "Ksolve", kin, "ksolve", 1 ); Id stoich = s->doCreate( "Stoich", ksolve, "stoich", 1 ); Field< Id >::set( stoich, "compartment", kin ); Field< Id >::set( stoich, "ksolve", ksolve ); // Used to get at the stoich matrix from gdb. // Stoich* stoichPtr = reinterpret_cast< Stoich* >( stoich.eref().data() ); Field< string >::set( stoich, "path", "/kinetics/##" ); unsigned int n = Field< unsigned int >::get( stoich, "numAllPools" ); assert( n == 10 ); unsigned int r = Field< unsigned int >::get( stoich, "numRates" ); assert( r == 5 ); // One each for reacs and MMenz, two for Enz. vector< int > entries = Field< vector< int > >::get( stoich, "matrixEntry" ); vector< unsigned int > colIndex = Field< vector< unsigned int > >::get( stoich, "columnIndex" ); vector< unsigned int > rowStart = Field< vector< unsigned int > >::get( stoich, "rowStart" ); assert( rowStart.size() == n + 1 ); assert( entries.size() == colIndex.size() ); assert( entries.size() == 13 ); assert( entries[0] == -1 ); assert( entries[1] == 1 ); assert( entries[2] == -2 ); assert( entries[3] == -1 ); assert( entries[4] == 1 ); assert( entries[5] == 1 ); assert( entries[6] == -1 ); assert( entries[7] == 1 ); assert( entries[8] == -1 ); assert( entries[9] == 1 ); assert( entries[10] == 1 ); assert( entries[11] == -1 ); assert( entries[12] == -1 ); s->doDelete( kin ); cout << "." << flush; }
void testHSolvePassive() { // TEST_BEGIN; Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); vector< int* > childArray; vector< unsigned int > childArraySize; /** * We test passive-cable solver for the following cell: * * Soma---> 15 - 14 - 13 - 12 * | | * | L 11 - 10 * | * L 16 - 17 - 18 - 19 * | * L 9 - 8 - 7 - 6 - 5 * | | * | L 4 - 3 * | * L 2 - 1 - 0 * * The numbers are the hines indices of compartments. Compartment X is the * child of compartment Y if X is one level further away from the soma (#15) * than Y. So #17 is the parent of #'s 2, 9 and 18. */ int childArray_1[ ] = { /* c0 */ -1, /* c1 */ -1, 0, /* c2 */ -1, 1, /* c3 */ -1, /* c4 */ -1, 3, /* c5 */ -1, /* c6 */ -1, 5, /* c7 */ -1, 4, 6, /* c8 */ -1, 7, /* c9 */ -1, 8, /* c10 */ -1, /* c11 */ -1, 10, /* c12 */ -1, /* c13 */ -1, 12, /* c14 */ -1, 11, 13, /* c15 */ -1, 14, 16, /* c16 */ -1, 17, /* c17 */ -1, 2, 9, 18, /* c18 */ -1, 19, /* c19 */ -1, }; childArray.push_back( childArray_1 ); childArraySize.push_back( sizeof( childArray_1 ) / sizeof( int ) ); /** * Cell 2: * * 3 * | * Soma---> 2 * / \ * / \ * 1 0 * */ int childArray_2[ ] = { /* c0 */ -1, /* c1 */ -1, /* c2 */ -1, 0, 1, 3, /* c3 */ -1, }; childArray.push_back( childArray_2 ); childArraySize.push_back( sizeof( childArray_2 ) / sizeof( int ) ); /** * Cell 3: * * 3 * | * 2 * / \ * / \ * 1 0 <--- Soma * */ int childArray_3[ ] = { /* c0 */ -1, 2, /* c1 */ -1, /* c2 */ -1, 1, 3, /* c3 */ -1, }; childArray.push_back( childArray_3 ); childArraySize.push_back( sizeof( childArray_3 ) / sizeof( int ) ); /** * Cell 4: * * 3 <--- Soma * | * 2 * / \ * / \ * 1 0 * */ int childArray_4[ ] = { /* c0 */ -1, /* c1 */ -1, /* c2 */ -1, 0, 1, /* c3 */ -1, 2, }; childArray.push_back( childArray_4 ); childArraySize.push_back( sizeof( childArray_4 ) / sizeof( int ) ); /** * Cell 5: * * 1 <--- Soma * | * 2 * / \ * 4 0 * / \ * 3 5 * */ int childArray_5[ ] = { /* c0 */ -1, /* c1 */ -1, 2, /* c2 */ -1, 0, 4, /* c3 */ -1, /* c4 */ -1, 3, 5, /* c5 */ -1, }; childArray.push_back( childArray_5 ); childArraySize.push_back( sizeof( childArray_5 ) / sizeof( int ) ); /** * Cell 6: * * 3 <--- Soma * L 4 * L 6 * L 5 * L 2 * L 1 * L 0 * */ int childArray_6[ ] = { /* c0 */ -1, /* c1 */ -1, /* c2 */ -1, /* c3 */ -1, 4, /* c4 */ -1, 0, 1, 2, 5, 6, /* c5 */ -1, /* c6 */ -1, }; childArray.push_back( childArray_6 ); childArraySize.push_back( sizeof( childArray_6 ) / sizeof( int ) ); /** * Cell 7: Single compartment */ int childArray_7[ ] = { /* c0 */ -1, }; childArray.push_back( childArray_7 ); childArraySize.push_back( sizeof( childArray_7 ) / sizeof( int ) ); /** * Cell 8: 3 compartments; soma is in the middle. */ int childArray_8[ ] = { /* c0 */ -1, /* c1 */ -1, 0, 2, /* c2 */ -1, }; childArray.push_back( childArray_8 ); childArraySize.push_back( sizeof( childArray_8 ) / sizeof( int ) ); /** * Cell 9: 3 compartments; first compartment is soma. */ int childArray_9[ ] = { /* c0 */ -1, 1, /* c1 */ -1, 2, /* c2 */ -1, }; childArray.push_back( childArray_9 ); childArraySize.push_back( sizeof( childArray_9 ) / sizeof( int ) ); //////////////////////////////////////////////////////////////////////////// // Run tests //////////////////////////////////////////////////////////////////////////// /* * Solver instance. */ HSolvePassive HP; /* * This is the full reference matrix which will be compared to its sparse * implementation. */ vector< vector< double > > matrix; /* * Model details. */ double dt = 1.0; vector< TreeNodeStruct > tree; vector< double > Em; vector< double > B; vector< double > V; vector< double > VMid; /* * Loop over cells. */ int i; int j; //~ bool success; int nCompt; int* array; unsigned int arraySize; for ( unsigned int cell = 0; cell < childArray.size(); cell++ ) { array = childArray[ cell ]; arraySize = childArraySize[ cell ]; nCompt = count( array, array + arraySize, -1 ); ////////////////////////////////////////// // Prepare local information on cell ////////////////////////////////////////// tree.clear(); tree.resize( nCompt ); Em.clear(); V.clear(); for ( i = 0; i < nCompt; i++ ) { tree[ i ].Ra = 15.0 + 3.0 * i; tree[ i ].Rm = 45.0 + 15.0 * i; tree[ i ].Cm = 500.0 + 200.0 * i * i; Em.push_back( -0.06 ); V.push_back( -0.06 + 0.01 * i ); } int count = -1; for ( unsigned int a = 0; a < arraySize; a++ ) if ( array[ a ] == -1 ) count++; else tree[ count ].children.push_back( array[ a ] ); ////////////////////////////////////////// // Create cell inside moose; setup solver. ////////////////////////////////////////// Id n = shell->doCreate( "Neutral", Id(), "n", 1 ); vector< Id > c( nCompt ); for ( i = 0; i < nCompt; i++ ) { ostringstream name; name << "c" << i; c[ i ] = shell->doCreate( "Compartment", n, name.str() , 1); Field< double >::set( c[ i ], "Ra", tree[ i ].Ra ); Field< double >::set( c[ i ], "Rm", tree[ i ].Rm ); Field< double >::set( c[ i ], "Cm", tree[ i ].Cm ); Field< double >::set( c[ i ], "Em", Em[ i ] ); Field< double >::set( c[ i ], "initVm", V[ i ] ); Field< double >::set( c[ i ], "Vm", V[ i ] ); } for ( i = 0; i < nCompt; i++ ) { vector< unsigned int >& child = tree[ i ].children; for ( j = 0; j < ( int )( child.size() ); j++ ) { ObjId mid = shell->doAddMsg( "Single", c[ i ], "axial", c[ child[ j ] ], "raxial" ); ASSERT( ! mid.bad(), "Creating test model" ); } } HP.setup( c[ 0 ], dt ); /* * Here we check if the cell was read in correctly by the solver. * This test only checks if all the created compartments were read in. * It doesn't check if they have been assigned hines' indices correctly. */ vector< Id >& hc = HP.compartmentId_; ASSERT( ( int )( hc.size() ) == nCompt, "Tree traversal" ); for ( i = 0; i < nCompt; i++ ) ASSERT( find( hc.begin(), hc.end(), c[ i ] ) != hc.end(), "Tree traversal" ); ////////////////////////////////////////// // Setup local matrix ////////////////////////////////////////// /* * First we need to ensure that the hines' indices for the local model * and those inside the solver match. If the numbering is different, * then the matrices will not agree. * * In the following, we find out the indices assigned by the solver, * and impose them on the local data structures. */ // Figure out new indices vector< unsigned int > permutation( nCompt ); for ( i = 0; i < nCompt; i++ ) { unsigned int newIndex = find( hc.begin(), hc.end(), c[ i ] ) - hc.begin(); permutation[ i ] = newIndex; } // Shuffle compartment properties according to new order permute< TreeNodeStruct >( tree, permutation ); permute< double >( Em, permutation ); permute< double >( V, permutation ); // Update indices of children for ( i = 0; i < nCompt; i++ ) { vector< unsigned int >& child = tree[ i ].children; for ( j = 0; j < ( int )( child.size() ); j++ ) child[ j ] = permutation[ child[ j ] ]; } // Create local reference matrix makeFullMatrix( tree, dt, matrix ); VMid.resize( nCompt ); B.resize( nCompt ); vector< vector< double > > matrixCopy; matrixCopy.assign( matrix.begin(), matrix.end() ); ////////////////////////////////////////// // Run comparisons ////////////////////////////////////////// double tolerance; /* * Compare initial matrices */ tolerance = 2.0; for ( i = 0; i < nCompt; ++i ) for ( j = 0; j < nCompt; ++j ) { ostringstream error; error << "Testing matrix construction:" << " Cell# " << cell + 1 << " A(" << i << ", " << j << ")"; ASSERT ( isClose< double >( HP.getA( i, j ), matrix[ i ][ j ], tolerance ), error.str() ); } /* * * Gaussian elimination * */ tolerance = 4.0; // ratio to machine epsilon for ( int pass = 0; pass < 2; pass++ ) { /* * First update terms in the equation. This involves setting up the B * in Ax = B, using the latest voltage values. Also, the coefficients * stored in A have to be restored to their original values, since * the matrix is modified at the end of every pass of gaussian * elimination. */ // Do so in the solver.. HP.updateMatrix(); // ..locally.. matrix.assign( matrixCopy.begin(), matrixCopy.end() ); for ( i = 0; i < nCompt; i++ ) B[ i ] = V[ i ] * tree[ i ].Cm / ( dt / 2.0 ) + Em[ i ] / tree[ i ].Rm; // ..and compare B. for ( i = 0; i < nCompt; ++i ) { ostringstream error; error << "Updating right-hand side values:" << " Pass " << pass << " Cell# " << cell + 1 << " B(" << i << ")"; ASSERT ( isClose< double >( HP.getB( i ), B[ i ], tolerance ), error.str() ); } /* * Forward elimination.. */ // ..in solver.. HP.forwardEliminate(); // ..and locally.. int k; for ( i = 0; i < nCompt - 1; i++ ) for ( j = i + 1; j < nCompt; j++ ) { double div = matrix[ j ][ i ] / matrix[ i ][ i ]; for ( k = 0; k < nCompt; k++ ) matrix[ j ][ k ] -= div * matrix[ i ][ k ]; B[ j ] -= div * B[ i ]; } // ..then compare A.. for ( i = 0; i < nCompt; ++i ) for ( j = 0; j < nCompt; ++j ) { ostringstream error; error << "Forward elimination:" << " Pass " << pass << " Cell# " << cell + 1 << " A(" << i << ", " << j << ")"; ASSERT ( isClose< double >( HP.getA( i, j ), matrix[ i ][ j ], tolerance ), error.str() ); } // ..and also B. for ( i = 0; i < nCompt; ++i ) { ostringstream error; error << "Forward elimination:" << " Pass " << pass << " Cell# " << cell + 1 << " B(" << i << ")"; ASSERT ( isClose< double >( HP.getB( i ), B[ i ], tolerance ), error.str() ); } /* * Backward substitution.. */ // ..in solver.. HP.backwardSubstitute(); // ..and full back-sub on local matrix equation.. for ( i = nCompt - 1; i >= 0; i-- ) { VMid[ i ] = B[ i ]; for ( j = nCompt - 1; j > i; j-- ) VMid[ i ] -= VMid[ j ] * matrix[ i ][ j ]; VMid[ i ] /= matrix[ i ][ i ]; V[ i ] = 2 * VMid[ i ] - V[ i ]; } // ..and then compare VMid. for ( i = nCompt - 1; i >= 0; i-- ) { ostringstream error; error << "Back substitution:" << " Pass " << pass << " Cell# " << cell + 1 << " VMid(" << i << ")"; ASSERT ( isClose< double >( HP.getVMid( i ), VMid[ i ], tolerance ), error.str() ); } for ( i = nCompt - 1; i >= 0; i-- ) { ostringstream error; error << "Back substitution:" << " Pass " << pass << " Cell# " << cell + 1 << " V(" << i << ")"; ASSERT ( isClose< double >( HP.getV( i ), V[ i ], tolerance ), error.str() ); } } // cleanup shell->doDelete( n ); } // TEST_END; }
/** * In all cases we set up the same amount of data transfer by the msgs, that * is, equivalent to a fully recurrently connected network. * Used in regressionTests/benchmarkTests.cpp */ void benchmarkMsg( unsigned int n, string msgType ) { Eref sheller = Id().eref(); Shell* shell = reinterpret_cast< Shell* >( sheller.data() ); vector< double > init( n ); for ( unsigned int i = 0; i < n; ++i ) init[i] = (i + 1) * 1e6; Id a1 = shell->doCreate( "Arith", Id(), "a1", n ); if ( msgType == "Single" ) { for ( unsigned int i = 0; i < n; ++i ) { for ( unsigned int j = 0; j < n; ++j ) { ObjId m1 = shell->doAddMsg( "Single", ObjId( a1, i ), "output", ObjId( a1, j ), "arg3" ); assert( !m1.bad() ); } } } else if ( msgType == "OneToAll" ) { for ( unsigned int i = 0; i < n; ++i ) { ObjId m1 = shell->doAddMsg( "OneToAll", ObjId( a1, i ), "output", ObjId( a1, 0 ), "arg3" ); assert( !m1.bad() ); } } else if ( msgType == "OneToOne" ) { for ( unsigned int i = 0; i < n; ++i ) { // just repeat it n times ObjId m1 = shell->doAddMsg( "OneToOne", ObjId( a1, 0 ), "output", ObjId( a1, 0 ), "arg3" ); assert( !m1.bad() ); } } else if ( msgType == "Diagonal" ) { for ( unsigned int i = 0; i < 2 * n; ++i ) { // Set up all offsets ObjId m1 = shell->doAddMsg( "Diagonal", ObjId( a1, 0 ), "output", ObjId( a1, 0 ), "arg3" ); Field< int >::set( m1, "stride", n - i ); } } else if ( msgType == "Sparse" ) { ObjId m1 = shell->doAddMsg( "Sparse", ObjId( a1, 0 ), "output", ObjId( a1, 0 ), "arg3" ); SetGet2< double, long >::set( m1, "setRandomConnectivity", 1.0, 1234 ); } shell->doUseClock( "/a1", "proc", 0 ); for ( unsigned int i = 0; i < 10; ++i ) shell->doSetClock( i, 0 ); shell->doSetClock( 0, 1 ); shell->doReinit(); SetGet1< double >::setVec( a1, "arg1", init ); shell->doStart( 100 ); for ( unsigned int i = 0; i < n; ++i ) init[i] = 0; // be sure we don't retain old info. init.clear(); Field< double >::getVec( a1, "outputValue", init ); cout << endl; for ( unsigned int i = 0; i < n; ++i ) { cout << i << " " << init[i] << " "; if ( i % 5 == 4 ) cout << endl; } shell->doDelete( a1 ); }
void testCellDiffn() { Id makeCompt( Id parentCompt, Id parentObj, string name, double len, double dia, double theta ); Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); double len = 40e-6; double dia = 10e-6; double diffLength = 1e-6; double dt = 1.0e-1; double runtime = 100.0; double diffConst = 1.0e-12; Id model = s->doCreate( "Neutral", Id(), "model", 1 ); Id soma = makeCompt( Id(), model, "soma", dia, dia, 90 ); Id dend = makeCompt( soma, model, "dend", len, 3e-6, 0 ); Id branch1 = makeCompt( dend, model, "branch1", len, 2e-6, 45.0 ); Id branch2 = makeCompt( dend, model, "branch2", len, 2e-6, -45.0 ); Id twig1 = makeCompt( branch1, model, "twig1", len, 1.5e-6, 90.0 ); Id twig2 = makeCompt( branch1, model, "twig2", len, 1.5e-6, 0.0 ); Id nm = s->doCreate( "NeuroMesh", model, "neuromesh", 1 ); Field< double >::set( nm, "diffLength", diffLength ); Field< string >::set( nm, "geometryPolicy", "cylinder" ); Field< Id >::set( nm, "cell", model ); unsigned int ns = Field< unsigned int >::get( nm, "numSegments" ); assert( ns == 6 ); unsigned int ndc = Field< unsigned int >::get( nm, "numDiffCompts" ); assert( ndc == 210 ); Id pool1 = s->doCreate( "Pool", nm, "pool1", 1 ); Field< double >::set( pool1, "diffConst", diffConst ); Id pool2 = s->doCreate( "Pool", nm, "pool2", 1 ); Field< double >::set( pool2, "diffConst", diffConst ); Id dsolve = s->doCreate( "Dsolve", model, "dsolve", 1 ); Field< Id >::set( dsolve, "compartment", nm ); s->doUseClock( "/model/dsolve", "process", 1 ); s->doSetClock( 1, dt ); // Next: build by setting path Field< string >::set( dsolve, "path", "/model/neuromesh/pool#" ); vector< double > nvec = LookupField< unsigned int, vector< double > >::get( dsolve, "nVec", 0); assert( nvec.size() == ndc ); assert( pool1.element()->numData() == ndc ); Field< double >::set( ObjId( pool1, 0 ), "nInit", 1.0 ); Field< double >::set( ObjId( pool2, ndc - 1 ), "nInit", 2.0 ); s->doReinit(); s->doStart( runtime ); nvec = LookupField< unsigned int, vector< double > >::get( dsolve, "nVec", 0); vector< double > pool1Vec; Field< double >::getVec( pool1, "n", pool1Vec ); assert( pool1Vec.size() == ndc ); vector< double > pool2Vec; Field< double >::getVec( pool2, "n", pool2Vec ); assert( pool2Vec.size() == ndc ); double myTot1 = 0; double myTot2 = 0; for ( unsigned int i = 0; i < nvec.size(); ++i ) { assert( doubleEq( pool1Vec[i], nvec[i] ) ); myTot1 += nvec[i]; myTot2 += pool2Vec[i]; } assert( doubleEq( myTot1, 1.0 ) ); assert( doubleEq( myTot2, 2.0 ) ); /* cout << endl; cout << "Big cell: " << endl; for ( unsigned int i = 0; i < nvec.size(); ++i ) cout << nvec[i] << ", " << pool2Vec[i] << endl; cout << endl; */ s->doDelete( model ); cout << "." << flush; }
void testCompartmentProcess() { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); unsigned int size = 100; double Rm = 1.0; double Ra = 0.01; double Cm = 1.0; double dt = 0.01; double runtime = 10; double lambda = sqrt( Rm / Ra ); Id cid = shell->doCreate( "Compartment", Id(), "compt", size ); assert( Id::isValid(cid)); assert( cid.eref().element()->numData() == size ); bool ret = Field< double >::setRepeat( cid, "initVm", 0.0 ); assert( ret ); Field< double >::setRepeat( cid, "inject", 0 ); // Only apply current injection in first compartment Field< double >::set( ObjId( cid, 0 ), "inject", 1.0 ); Field< double >::setRepeat( cid, "Rm", Rm ); Field< double >::setRepeat( cid, "Ra", Ra ); Field< double >::setRepeat( cid, "Cm", Cm ); Field< double >::setRepeat( cid, "Em", 0 ); Field< double >::setRepeat( cid, "Vm", 0 ); // The diagonal message has a default stride of 1, so it connects // successive compartments. // Note that the src and dest elements here are identical, so we cannot // use a shared message. The messaging system will get confused about // direction to send data. So we split up the shared message that we // might have used, below, into two individual messages. // MsgId mid = shell->doAddMsg( "Diagonal", ObjId( cid ), "raxial", ObjId( cid ), "axial" ); ObjId mid = shell->doAddMsg( "Diagonal", ObjId( cid ), "axialOut", ObjId( cid ), "handleAxial" ); assert( !mid.bad()); // mid = shell->doAddMsg( "Diagonal", ObjId( cid ), "handleRaxial", ObjId( cid ), "raxialOut" ); mid = shell->doAddMsg( "Diagonal", ObjId( cid ), "raxialOut", ObjId( cid ), "handleRaxial" ); assert( !mid.bad() ); // ObjId managerId = Msg::getMsg( mid )->manager().objId(); // Make the raxial data go from high to lower index compartments. Field< int >::set( mid, "stride", -1 ); #ifdef DO_SPATIAL_TESTS shell->doSetClock( 0, dt ); shell->doSetClock( 1, dt ); // Ensure that the inter_compt msgs go between nodes once every dt. shell->doSetClock( 9, dt ); shell->doUseClock( "/compt", "init", 0 ); shell->doUseClock( "/compt", "process", 1 ); shell->doReinit(); shell->doStart( runtime ); double Vmax = Field< double >::get( ObjId( cid, 0 ), "Vm" ); double delta = 0.0; // We measure only the first 50 compartments as later we // run into end effects because it is not an infinite cable for ( unsigned int i = 0; i < size; i++ ) { double Vm = Field< double >::get( ObjId( cid, i ), "Vm" ); double x = Vmax * exp( - static_cast< double >( i ) / lambda ); delta += ( Vm - x ) * ( Vm - x ); // cout << i << " (x, Vm) = ( " << x << ", " << Vm << " )\n"; } assert( delta < 1.0e-5 ); #endif // DO_SPATIAL_TESTS shell->doDelete( cid ); cout << "." << flush; }
void testCalcJunction() { Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); // Make a neuron with same-size dend and spine. PSD is tiny. // Put a, b, c in dend, b, c, d in spine, c, d, f in psd. No reacs. // See settling of all concs by diffusion, pairwise. Id model = s->doCreate( "Neutral", Id(), "model", 1 ); Id dend = s->doCreate( "Compartment", model, "dend", 1 ); Id neck = s->doCreate( "Compartment", model, "spine_neck", 1 ); Id head = s->doCreate( "Compartment", model, "spine_head", 1 ); Field< double >::set( dend, "x", 10e-6 ); Field< double >::set( dend, "diameter", 2e-6 ); Field< double >::set( dend, "length", 10e-6 ); Field< double >::set( neck, "x0", 9e-6 ); Field< double >::set( neck, "x", 9e-6 ); Field< double >::set( neck, "y", 1e-6 ); Field< double >::set( neck, "diameter", 0.5e-6 ); Field< double >::set( neck, "length", 1.0e-6 ); Field< double >::set( head, "x0", 9e-6 ); Field< double >::set( head, "x", 9e-6 ); Field< double >::set( head, "y0", 1e-6 ); Field< double >::set( head, "y", 11e-6 ); Field< double >::set( head, "diameter", 2e-6 ); Field< double >::set( head, "length", 10e-6 ); s->doAddMsg( "Single", ObjId( dend ), "raxial", ObjId( neck ), "axial"); s->doAddMsg( "Single", ObjId( neck ), "raxial", ObjId( head ), "axial"); Id nm = s->doCreate( "NeuroMesh", model, "nm", 1 ); Field< double >::set( nm, "diffLength", 10e-6 ); Field< bool >::set( nm, "separateSpines", true ); Id sm = s->doCreate( "SpineMesh", model, "sm", 1 ); Id pm = s->doCreate( "PsdMesh", model, "pm", 1 ); ObjId mid = s->doAddMsg( "Single", ObjId( nm ), "spineListOut", ObjId( sm ), "spineList" ); assert( !mid.bad() ); mid = s->doAddMsg( "Single", ObjId( nm ), "psdListOut", ObjId( pm ), "psdList" ); Field< Id >::set( nm, "cell", model ); vector< Id > pools( 9 ); static string names[] = {"a", "b", "c", "b", "c", "d", "c", "d", "e" }; static Id parents[] = {nm, nm, nm, sm, sm, sm, pm, pm, pm}; for ( unsigned int i = 0; i < 9; ++i ) { pools[i] = s->doCreate( "Pool", parents[i], names[i], 1 ); assert( pools[i] != Id() ); Field< double >::set( pools[i], "concInit", 1.0 + 1.0 * i ); Field< double >::set( pools[i], "diffConst", 1e-11 ); if ( i < 6 ) { double vol = Field< double >::get( pools[i], "volume" ); assert( doubleEq( vol, 10e-6 * 1e-12 * PI ) ); } } Id dendsolve = s->doCreate( "Dsolve", model, "dendsolve", 1 ); Id spinesolve = s->doCreate( "Dsolve", model, "spinesolve", 1 ); Id psdsolve = s->doCreate( "Dsolve", model, "psdsolve", 1 ); Field< Id >::set( dendsolve, "compartment", nm ); Field< Id >::set( spinesolve, "compartment", sm ); Field< Id >::set( psdsolve, "compartment", pm ); Field< string >::set( dendsolve, "path", "/model/nm/#" ); Field< string >::set( spinesolve, "path", "/model/sm/#" ); Field< string >::set( psdsolve, "path", "/model/pm/#" ); assert( Field< unsigned int >::get( dendsolve, "numAllVoxels" ) == 1 ); assert( Field< unsigned int >::get( spinesolve, "numAllVoxels" ) == 1 ); assert( Field< unsigned int >::get( psdsolve, "numAllVoxels" ) == 1 ); assert( Field< unsigned int >::get( dendsolve, "numPools" ) == 3 ); assert( Field< unsigned int >::get( spinesolve, "numPools" ) == 3 ); assert( Field< unsigned int >::get( psdsolve, "numPools" ) == 3 ); SetGet2< Id, Id >::set( dendsolve, "buildNeuroMeshJunctions", spinesolve, psdsolve ); s->doSetClock( 0, 0.01 ); s->doUseClock( "/model/#solve", "process", 0 ); s->doReinit(); s->doStart( 100 ); for ( unsigned int i = 0; i < 9; ++i ) { double c = Field< double >::get( pools[i], "conc" ); double n = Field< double >::get( pools[i], "n" ); double v = Field< double >::get( pools[i], "volume" ); cout << pools[i].path() << ": " << c << ", " << n << ", " << n / v << ", " << v << endl; } s->doDelete( model ); cout << "." << flush; }
/* create MOLECULE */ const SbmlReader::sbmlStr_mooseId SbmlReader::createMolecule( map< string,Id > &comptSidMIdMap) { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); map< string, Id >molSidcmptMIdMap; double transvalue = 0.0; int num_species = model_->getNumSpecies(); if (num_species == 0) { baseId = Id(); errorFlag_ = true; return molSidcmptMIdMap; } for ( int sindex = 0; sindex < num_species; sindex++ ) { Species* spe = model_->getSpecies(sindex); if (!spe) { continue; } std::string compt = ""; if ( spe->isSetCompartment() ) { compt = spe->getCompartment(); } if (compt.length()< 1) { //cout << "compt is empty for species "<< sindex << endl; continue; } string id = spe->getId(); if (id.length() < 1) { continue; } std::string name = ""; if ( spe->isSetName() ) { name = spe->getName(); name = nameString(name); } if (name.empty()) name = id; double initvalue =0.0; if ( spe->isSetInitialConcentration() ) initvalue = spe->getInitialConcentration(); else if ( spe->isSetInitialAmount() ) initvalue = spe->getInitialAmount() ; else { unsigned int nr = model_->getNumRules(); bool found = false; for ( unsigned int r = 0; r < nr; r++ ) { Rule * rule = model_->getRule(r); bool assignRule = rule->isAssignment(); if ( assignRule ) { string rule_variable = rule->getVariable(); if (rule_variable.compare(id) == 0) { found = true; break; } } } if (found == false) { cout << "Invalid SBML: Either initialConcentration or initialAmount must be set or it should be found in assignmentRule but non happening for " << spe->getName() <<endl; return molSidcmptMIdMap; } } Id comptEl = comptSidMIdMap[compt]; Id meshEntry = Neutral::child( comptEl.eref(), "mesh" ); bool constant = spe->getConstant(); bool boundaryCondition = spe->getBoundaryCondition(); if (boundaryCondition == true) cout << "Pools having BoundaryCondition true " << name <<endl; Id pool; //If constant is true then its equivalent to BuffPool in moose if (constant == true) //if( (boundaryCondition == true) && (constant==false)) pool = shell->doCreate("BufPool",comptEl,name,1); else pool = shell->doCreate("Pool", comptEl, name ,1); molSidcmptMIdMap[id] = comptEl; //Map to Molecule SBML id to Moose Id molSidMIdMap_[id] = pool; //shell->doAddMsg( "OneToOne",pool, "mesh", meshEntry, "mesh" ); bool bcondition = spe->getBoundaryCondition(); if ( constant == true && bcondition == false) cout <<"The species "<< name << " should not appear in reactant or product as per sbml Rules"<< endl; unsigned int spatialDimen =Field< unsigned int >::get( comptEl, "numDimensions"); UnitDefinition * ud = spe->getDerivedUnitDefinition(); assert(ud != NULL); bool hasonlySubUnit = spe->getHasOnlySubstanceUnits(); //double v = Field< double >::get( comptEl.path(), "volume" ); transvalue = transformUnits(1,ud,"substance",hasonlySubUnit); if (hasonlySubUnit) { // In Moose, no. of molecules (nInit) and unit is "item" if (spatialDimen > 0 && spe->isSetInitialAmount() ) { //transvalue *= initvalue; initvalue *=transvalue; Field < double> :: set( pool, "nInit", initvalue); } } else { //transvalue *=initvalue; initvalue *=transvalue; Field <double> :: set(pool, "concInit",initvalue); } //cout << " poolMap_ "<< name << " " <<transvalue << " "<< hasonlySubUnit; //poolMap_.insert(make_pair(id,make_tuple(name,transvalue,hasonlySubUnit))); } return molSidcmptMIdMap; }