// static function Id Neutral::child( const Eref& e, const string& name ) { static const Finfo* pf = neutralCinfo->findFinfo( "parentMsg" ); static const DestFinfo* pf2 = dynamic_cast< const DestFinfo* >( pf ); static const FuncId pafid = pf2->getFid(); static const Finfo* cf = neutralCinfo->findFinfo( "childOut" ); static const SrcFinfo* cf2 = dynamic_cast< const SrcFinfo* >( cf ); static const BindIndex bi = cf2->getBindIndex(); const vector< MsgFuncBinding >* bvec = e.element()->getMsgAndFunc( bi ); vector< Id > ret; for ( vector< MsgFuncBinding >::const_iterator i = bvec->begin(); i != bvec->end(); ++i ) { if ( i->fid == pafid ) { const Msg* m = Msg::getMsg( i->mid ); assert( m ); Element* e2 = m->e2(); if ( e2->getName() == name ) { if ( e.dataIndex() == ALLDATA ) {// Child of any index is OK return e2->id(); } else { ObjId parent = m->findOtherEnd( m->getE2() ); // If child is a fieldElement, then all parent indices // are permitted. Otherwise insist parent dataIndex OK. if ( e2->hasFields() || parent == e.objId() ) return e2->id(); } } } } return Id(); }
void Pool::vRemesh( const Eref& e, const Qinfo* q, double oldvol, unsigned int numTotalEntries, unsigned int startEntry, const vector< unsigned int >& localIndices, const vector< double >& vols ) { if ( e.index().value() != 0 ) return; /* if ( q->addToStructuralQ() ) return; */ Neutral* n = reinterpret_cast< Neutral* >( e.data() ); assert( vols.size() > 0 ); double concInit = nInit_ / ( NA * oldvol ); if ( vols.size() != e.element()->dataHandler()->localEntries() ) n->setLastDimension( e, q, vols.size() ); // Note that at this point the Pool pointer may be invalid! // But we need to update the concs anyway. assert( e.element()->dataHandler()->localEntries() == vols.size() ); Pool* pooldata = reinterpret_cast< Pool* >( e.data() ); for ( unsigned int i = 0; i < vols.size(); ++i ) { pooldata[i].nInit_ = pooldata[i].n_ = concInit * vols[i] * NA; } }
OneToAllMsg::OneToAllMsg( MsgId mid, Eref e1, Element* e2 ) : Msg( mid, e1.element(), e2, OneToAllMsg::managerId_ ), i1_( e1.index() ) { ; }
void HSolve::zombify( Eref hsolve ) const { vector< Id >::const_iterator i; vector< ObjId > temp; for ( i = compartmentId_.begin(); i != compartmentId_.end(); ++i ) temp.push_back( ObjId( *i, 0 ) ); for ( i = compartmentId_.begin(); i != compartmentId_.end(); ++i ) CompartmentBase::zombify( i->eref().element(), ZombieCompartment::initCinfo(), hsolve.id() ); temp.clear(); for ( i = caConcId_.begin(); i != caConcId_.end(); ++i ) temp.push_back( ObjId( *i, 0 ) ); // Shell::dropClockMsgs( temp, "process" ); for ( i = caConcId_.begin(); i != caConcId_.end(); ++i ) CaConcBase::zombify( i->eref().element(), ZombieCaConc::initCinfo(), hsolve.id() ); temp.clear(); for ( i = channelId_.begin(); i != channelId_.end(); ++i ) temp.push_back( ObjId( *i, 0 ) ); for ( i = channelId_.begin(); i != channelId_.end(); ++i ) HHChannelBase::zombify( i->eref().element(), ZombieHHChannel::initCinfo(), hsolve.id() ); }
unsigned int getReactantVols( const Eref& reac, const SrcFinfo* pools, vector< double >& vols ) { static const unsigned int meshIndex = 0; const vector< MsgFuncBinding >* mfb = reac.element()->getMsgAndFunc( pools->getBindIndex() ); unsigned int smallIndex = 0; vols.resize( 0 ); if ( mfb ) { for ( unsigned int i = 0; i < mfb->size(); ++i ) { double v = 1; Element* pool = Msg::getMsg( (*mfb)[i].mid )->e2(); if ( pool == reac.element() ) pool = Msg::getMsg( (*mfb)[i].mid )->e1(); assert( pool != reac.element() ); Eref pooler( pool, meshIndex ); if ( pool->cinfo()->isA( "PoolBase" ) ) { v = lookupVolumeFromMesh( pooler ); } else { cout << "Error: getReactantVols: pool is of unknown type\n"; assert( 0 ); } vols.push_back( v ); if ( v < vols[0] ) smallIndex = i; } } return smallIndex; }
/* Enzymatic Reaction */ void SbmlReader::setupEnzymaticReaction( const EnzymeInfo & einfo,string name ) { static const Cinfo* enzymeCinfo = initEnzymeCinfo(); static const Finfo* k1Finfo = enzymeCinfo->findFinfo( "k1" ); static const Finfo* k2Finfo = enzymeCinfo->findFinfo( "k2" ); static const Finfo* k3Finfo = enzymeCinfo->findFinfo( "k3" ); Eref E = ( einfo.enzyme )(); Element* enzyme_ = Neutral::create( "Enzyme",name,E.id(),Id::scratchId() );//create Enzyme Eref complx = einfo.complex(); Eref(enzyme_).add( "enz",E,"reac",ConnTainer::Default ); Eref(enzyme_).add( "cplx",complx,"reac",ConnTainer::Default ); vector< Id >::const_iterator sub_itr; for ( sub_itr = einfo.substrates.begin(); sub_itr != einfo.substrates.end(); sub_itr++ ) { Eref S = (*sub_itr)(); Eref( enzyme_ ).add( "sub",S,"reac",ConnTainer::Default ); } vector< Id >::const_iterator prd_itr; for ( prd_itr = einfo.products.begin(); prd_itr != einfo.products.end(); prd_itr++ ) { Eref P = (*prd_itr)(); Eref( enzyme_ ).add( "prd",P,"prd",ConnTainer::Default ); } ::set< double >( enzyme_, k1Finfo, einfo.k1 ); ::set< double >( enzyme_, k2Finfo, einfo.k2 ); ::set< double >( enzyme_, k3Finfo, einfo.k3 ); ::set< bool >( enzyme_,"mode",0 ); ::set( complx,"destroy" ); }
/* create COMPARTMENT */ map< string,Id > SbmlReader::createCompartment( Id location ) { static const Cinfo* kincomptCinfo = initKinComptCinfo(); static const Finfo* sizeFinfo = kincomptCinfo->findFinfo( "size" ); static const Finfo* dimensionFinfo = kincomptCinfo->findFinfo( "numDimensions" ); map< string,Id > idMap; //Id outcompt; //outside compartment map< Id,string > outsideMap; map< Id,string > ::iterator iter; double msize = 0.0,size=0.0; ::Compartment* compt; unsigned int num_compts = model_->getNumCompartments(); //cout << "num of compartments :" << num_compts <<endl; for ( unsigned int i = 0; i < num_compts; i++ ) { compt = model_->getCompartment(i); std::string id = ""; if ( compt->isSetId() ){ id = compt->getId(); } std::string name = ""; if ( compt->isSetName() ){ name = compt->getName(); } std::string outside = ""; if ( compt->isSetOutside() ){ outside = compt->getOutside (); } if ( compt->isSetSize() ){ msize = compt->getSize(); } UnitDefinition * ud = compt->getDerivedUnitDefinition(); size = transformUnits( msize,ud ); unsigned int dimension = compt->getSpatialDimensions(); comptEl_ = Neutral::create( "KinCompt",id, location, Id::scratchId() ); //create Compartment idMap[id] = comptEl_->id(); if ( outside != "" ) outsideMap[comptEl_->id()] = outside ; if ( size != 0.0 ) ::set< double >( comptEl_, sizeFinfo, size ); if ( dimension != 0 ) ::set< unsigned int >( comptEl_,dimensionFinfo,dimension ); } for ( iter = outsideMap.begin(); iter != outsideMap.end(); iter++ ) { Eref msid = iter->first(); string outside = iter->second; Id outcompt = idMap.find( outside )->second; static const Finfo* outsideFinfo = kincomptCinfo->findFinfo( "outside" ); static const Finfo* insideFinfo = kincomptCinfo->findFinfo( "inside" ); msid.dropAll("child"); //delete the connection with old parent ie, /kinetics Eref(outcompt() ).add("childSrc",msid,"child",ConnTainer::Default); //create connection with new parent ie.outside compartment Eref( msid ).add( outsideFinfo->msg(),outcompt(),insideFinfo->msg(),ConnTainer::Default ); } return idMap; }
double GslStoich::getNinit( const Eref& e ) const { unsigned int i = e.index().value(); unsigned int j = coreStoich()->convertIdToPoolIndex( e.id() ); assert( i < pools_.size() ); assert( j < pools_[i].size() ); return pools_[i].Sinit()[j]; }
Eref SingleMsg::firstTgt( const Eref& src ) const { if ( src.element() == e1_ ) return Eref( e2_, i2_, f2_ ); else if ( src.element() == e2_ ) return Eref( e1_, i1_ ); return Eref( 0, 0 ); }
void GslStoich::setNinit( const Eref& e, double v ) { unsigned int i = e.index().value(); unsigned int j = coreStoich()->convertIdToPoolIndex( e.id() ); assert( i < pools_.size() ); assert( j < pools_[i].size() ); pools_[i].varSinit()[j] = v; }
/// Utility function to find the size of a pool. We assume one-to-one /// match between pool indices and mesh indices: that is what they are for. double lookupVolumeFromMesh( const Eref& e ) { ObjId compt = getCompt( e.id() ); if ( compt == ObjId() ) return 1.0; return LookupField< unsigned int, double >:: get( compt, "oneVoxelVolume", e.dataIndex() ); }
Eref OneToAllMsg::firstTgt( const Eref& src ) const { if ( src.element() == e1_ ) return Eref( e2_, 0 ); else if ( src.element() == e2_ ) return Eref( e1_, i1_ ); return Eref( 0, 0 ); }
///////////////////////////////////////////////////////////////// // Now test 'get' across nodes. // Normally the 'get' call is invoked by the parser, which expects a // value to come back. Note that the return must be asynchronous: // the parser cannot block since we need to execute MPI polling // operations on either side. ///////////////////////////////////////////////////////////////// void testParGet( Id tnId, vector< Id >& testIds ) { unsigned int myNode = MuMPI::INTRA_COMM().Get_rank(); unsigned int numNodes = MuMPI::INTRA_COMM().Get_size(); Slot parGetSlot = initShellCinfo()->getSlot( "parallel.getSrc" ); char name[20]; string sname; if ( myNode == 0 ) { cout << "\ntesting parallel get" << flush; } else { sprintf( name, "foo%d", myNode * 2 ); sname = name; set< string >( tnId.eref(), "name", sname ); } MuMPI::INTRA_COMM().Barrier(); Eref e = Id::shellId().eref(); Shell* sh = static_cast< Shell* >( e.data() ); vector< unsigned int > rids( numNodes, 0 ); vector< string > ret( numNodes ); unsigned int origSize = sh->freeRidStack_.size(); ASSERT( origSize > 0 , "Stack initialized properly" ); if ( myNode == 0 ) { for ( unsigned int i = 1; i < numNodes; i++ ) { rids[i] = openOffNodeValueRequest< string >( sh, &ret[i], 1 ); ASSERT( sh->freeRidStack_.size() == origSize - i, "stack in use" ); sendTo3< Id, string, unsigned int >( Id::shellId().eref(), parGetSlot, i - 1, testIds[i - 1], "name", rids[i] ); } } // Here we explicitly do what the closeOffNodeValueRequest handles. MuMPI::INTRA_COMM().Barrier(); // Cycle a few times to make sure all data gets back to node 0 for ( unsigned int i = 0; i < 5; i++ ) { pollPostmaster(); MuMPI::INTRA_COMM().Barrier(); } // Now go through to check all values have come back. if ( myNode == 0 ) { ASSERT( sh->freeRidStack_.size() == 1 + origSize - numNodes, "Stack still waiting" ); for ( unsigned int i = 1; i < numNodes; i++ ) { sprintf( name, "foo%d", i * 2 ); sname = name; ASSERT( sh->offNodeData_[ rids[i] ].numPending == 0, "Pending requests cleared" ); ASSERT( sh->offNodeData_[ rids[i] ].data == static_cast< void* >( &ret[i] ), "Pointing to strings" ); ASSERT( ret[ i ] == sname, "All values returned correctly" ); // Clean up the debris sh->offNodeData_[ rids[i] ].data = 0; sh->freeRidStack_.push_back( rids[i] ); } } }
/** * This is a little tricky because we might be mapping between * data entries and field entries here. * May wish also to apply to exec operations. * At this point, the effect of trying to go between regular * data entries and field entries is undefined. */ Eref OneToOneDataIndexMsg::firstTgt( const Eref& src ) const { if ( src.element() == e1_ ) { return Eref( e2_, src.dataIndex(), 0 ); } else if ( src.element() == e2_ ) { return Eref( e1_, src.dataIndex() ); } return Eref( 0, 0 ); }
void Synapse::addSpike( const Eref& e, double time ) { static bool report = false; static unsigned int tgtDataIndex = 0; // static unsigned int tgtFieldIndex = 0; if ( report && e.dataIndex() == tgtDataIndex ) { cout << " " << time << "," << e.fieldIndex(); } handler_->addSpike( e.fieldIndex(), time + delay_, weight_ ); }
void GslStoich::setN( const Eref& e, double v ) { unsigned int i = e.index().value(); // Later: Handle node location. unsigned int j = coreStoich()->convertIdToPoolIndex( e.id() ); assert( i < pools_.size() ); assert( j < pools_[i].size() ); pools_[i].varS()[j] = v; assert( i < y_.size() ); assert( j < y_[i].size() ); y_[i][j] = v; }
vector< string > Neutral::getDestFields( const Eref& e ) const { unsigned int num = e.element()->cinfo()->getNumDestFinfo(); vector< string > ret( num ); for ( unsigned int i = 0; i < num; ++i ) { const Finfo *f = e.element()->cinfo()->getDestFinfo( i ); assert( f ); ret[i] = f->name(); } return ret; }
/** * setIsBuffered is a really nasty operation, made possible only because * BufPool is derived from Pool and has no other fields. * It uses a low-level replaceCinfo call to just change the * identity of the Cinfo used, leaving everything else as is. */ void Pool::vSetIsBuffered( const Eref& e, bool v ) { static const Cinfo* bufPoolCinfo = Cinfo::find( "BufPool" ); if (vGetIsBuffered( e ) == v) return; if (v) { e.element()->replaceCinfo( bufPoolCinfo ); } else { e.element()->replaceCinfo( poolCinfo ); } }
/** * This is a little tricky because we might be mapping between * data entries and field entries here. * May wish also to apply to exec operations. * At this point, the effect of trying to go between regular * data entries and field entries is undefined. */ Eref OneToOneMsg::firstTgt( const Eref& src ) const { if ( src.element() == e1_ ) { if ( e2_->hasFields() ) return Eref( e2_, i2_, src.dataIndex() ); else return Eref( e2_, src.dataIndex(), 0 ); } else if ( src.element() == e2_ ) { return Eref( e1_, src.dataIndex() ); } return Eref( 0, 0 ); }
vector< Id > Neutral::getNeighbors( const Eref& e, string field ) const { vector< Id > ret; const Finfo* finfo = e.element()->cinfo()->findFinfo( field ); if ( finfo ) e.element()->getNeighbors( ret, finfo ); else cout << "Warning: Neutral::getNeighbors: Id.Field '" << e.id().path() << "." << field << "' not found\n"; return ret; }
/* * get Assignment Rule */ void SbmlReader::getRules() { unsigned int nr = model_->getNumRules(); //cout<<"no of rules:"<<nr<<endl; for ( unsigned int r = 0;r < nr;r++ ) { Rule * rule = model_->getRule(r); //cout << "rule :" << rule->getFormula() << endl; bool assignRule = rule->isAssignment(); //cout << "is assignment :" << assignRule << endl; if ( assignRule ){ string rule_variable = rule->getVariable(); //cout << "variable :" << rule_variable << endl; map< string,Eref >::iterator v_iter; map< string,Eref >::iterator m_iter; v_iter = elmtMap_.find( rule_variable ); if ( v_iter != elmtMap_.end() ){ Eref rVariable = elmtMap_.find(rule_variable)->second; const ASTNode * ast = rule->getMath(); vector< string > ruleMembers; ruleMembers.clear(); printMembers( ast,ruleMembers ); for ( unsigned int rm = 0; rm < ruleMembers.size(); rm++ ) { m_iter = elmtMap_.find( ruleMembers[rm] ); if ( m_iter != elmtMap_.end() ){ Eref rMember = elmtMap_.find(ruleMembers[rm])->second; rMember.add( "nSrc",rVariable,"sumTotal",ConnTainer::Default ); } else{ cerr << "SbmlReader::getRules: Assignment rule member is not a species" << endl; errorFlag_ = true; } } } else{ cerr << "SbmlReader::getRules: for now Assignment rule for parameter/compartment is not handled" << endl; 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; } } }
vector< ObjId > Neutral::getIncomingMsgs( const Eref& e ) const { vector< ObjId > ret; const vector< ObjId >& msgIn = e.element()->msgIn(); for (unsigned int i = 0; i < msgIn.size(); ++i ) { const Msg* m = Msg::getMsg( msgIn[i] ); assert( m ); if ( m->e2() == e.element() ) ret.push_back( m->mid() ); } return ret; }
void HSolve::zombify( Eref hsolve ) const { vector< Id >::const_iterator i; for ( i = compartmentId_.begin(); i != compartmentId_.end(); ++i ) ZombieCompartment::zombify( hsolve.element(), i->eref().element() ); for ( i = caConcId_.begin(); i != caConcId_.end(); ++i ) ZombieCaConc::zombify( hsolve.element(), i->eref().element() ); for ( i = channelId_.begin(); i != channelId_.end(); ++i ) ZombieHHChannel::zombify( hsolve.element(), i->eref().element() ); }
unsigned int Neutral::buildTree( const Eref& e, vector< Id >& tree ) const { unsigned int ret = 1; Eref er( e.element(), ALLDATA ); vector< Id > kids = getChildren( er ); sort( kids.begin(), kids.end() ); kids.erase( unique( kids.begin(), kids.end() ), kids.end() ); for ( vector< Id >::iterator i = kids.begin(); i != kids.end(); ++i ) ret += buildTree( i->eref(), tree ); tree.push_back( e.element()->id() ); return ret; }
// vRemesh: All the work is done by the message from the compartment to the // Stoich. None of the ZPools is remeshed directly. However, their // DataHandlers need updating. void ZPool::vRemesh( const Eref& e, const Qinfo* q, double oldvol, unsigned int numTotalEntries, unsigned int startEntry, const vector< unsigned int >& localIndices, const vector< double >& vols ) { ; if ( e.index().value() != 0 ) return; Neutral* n = reinterpret_cast< Neutral* >( e.data() ); if ( vols.size() != e.element()->dataHandler()->localEntries() ) n->setLastDimension( e, q, vols.size() ); }
OneToOneDataIndexMsg::OneToOneDataIndexMsg( const Eref& e1, const Eref& e2, unsigned int msgIndex ) : Msg( ObjId( managerId_, (msgIndex != 0) ? msgIndex: msg_.size() ), e1.element(), e2.element() ) { if ( msgIndex == 0 ) { msg_.push_back( this ); } else { if ( msg_.size() <= msgIndex ) msg_.resize( msgIndex + 1 ); msg_[ msgIndex ] = this; } }
void HHGate::setTableA( const Eref& e, vector< double > v ) { if ( v.size() < 2 ) { cout << "Warning: HHGate::setTableA: size must be >= 2 entries on " << e.id().path() << endl; return; } if ( checkOriginal( e.id(), "tableA" ) ) { isDirectTable_ = 1; A_ = v; unsigned int xdivs = A_.size() - 1; invDx_ = static_cast< double >( xdivs ) / ( xmax_ - xmin_ ); } }
void HHGate::setMinfinity( const Eref& e, vector< double > val ) { if ( val.size() != 5 ) { cout << "Error: HHGate::setMinfinity on " << e.id().path() << ": Number of entries on argument vector should be 5, was " << val.size() << endl; return; } if ( checkOriginal( e.id(), "mInfinity" ) ) { mInfinity_ = val; updateAlphaBeta(); updateTables(); } }
void HHGate::setAlpha( const Eref& e, vector< double > val ) { if ( val.size() != 5 ) { cout << "Error: HHGate::setAlpha on " << e.id().path() << ": Number of entries on argument vector should be 5, was " << val.size() << endl; return; } if ( checkOriginal( e.id(), "alpha" ) ) { alpha_ = val; updateTauMinf(); updateTables(); } }
void HDF5DataWriter::reinit(const Eref & e, ProcPtr p) { steps_ = 0; for (unsigned int ii = 0; ii < data_.size(); ++ii){ H5Dclose(datasets_[ii]); } data_.clear(); src_.clear(); func_.clear(); datasets_.clear(); unsigned int numTgt = e.element()->getMsgTargetAndFunctions(e.dataIndex(), requestOut(), src_, func_); assert(numTgt == src_.size()); // TODO: what to do when reinit is called? Close the existing file // and open a new one in append mode? Or keep adding to the // current file? if (filename_.empty()){ filename_ = "moose_data.h5"; } if (filehandle_ > 0 ){ close(); } if (numTgt == 0){ return; } openFile(); for (unsigned int ii = 0; ii < src_.size(); ++ii){ string varname = func_[ii]; size_t found = varname.find("get"); if (found == 0){ varname = varname.substr(3); if (varname.length() == 0){ varname = func_[ii]; } else { // TODO: there is no way we can get back the original // field-name case. tolower will get the right name in // most cases as field names start with lower case by // convention in MOOSE. varname[0] = tolower(varname[0]); } } assert(varname.length() > 0); string path = src_[ii].path() + "/" + varname; hid_t dataset_id = getDataset(path); datasets_.push_back(dataset_id); } data_.resize(src_.size()); }