// PropDispatch.cpp #include "PropDispatch.h" #include #include #include "objstream/ObjData.hpp" #include "objstream/ObjTable.hpp" #include "trfutil/trfstream.h" #include "PropStat.h" #include "Surface.h" #include "ETrack.h" using trf::TrfObject; using trf::TrackDerivative; using trf::Surface; using trf::VTrack; using trf::ETrack; using trf::PropStat; using trf::Propagator; using trf::PropagatorPtr; using trf::PropDispatch; typedef std::vector PropList; PropagatorPtr prop_null(0); //********************************************************************** // Free functions. //********************************************************************** namespace { // Creator. // // We depend on creator returned by table to be the same as the // type used in TRF++ RTTI. ObjPtr create(const ObjData& data) { assert( data.get_object_type() == "PropDispatch" ); PropDispatch* pprop = new PropDispatch; #ifdef ObjData_supports_lists ObjData::StringList bsurfs; ObjData::StringList esurfs; PropList props; data.get_string_list( "begin_surfs", bsurfs ); data.get_string_list( "end_surfs", esurfs ); data.get_share_ptr_list( "propagators", props ); assert( bsurfs.size() == esurfs.size() ); assert( bsurfs.size() == props.size() ); if ( bsurfs.size() < props.size() || esurfs.size() < props.size() ) { return ObjPtr(pprop); } ObjData::StringList::const_iterator ibs = bsurfs.begin(); ObjData::StringList::const_iterator ies = esurfs.begin(); for ( PropList::const_iterator ipr = props.begin(); ipr!=props.end(); ++ipr ) { TrfObject::Type btype = ObjTable::get_creator(*ibs++); TrfObject::Type etype = ObjTable::get_creator(*ies++); pprop->add_propagator(btype,etype,*ipr); } #endif return ObjPtr(pprop); } } //********************************************************************** // output stream void PropDispatch::ostr(ostream& stream) const { stream << begin_object; stream << "Propagator Dispatcher:"; PropMap::const_iterator iprop; for ( iprop=_props.begin(); iprop!=_props.end(); ++iprop ) { stream << new_line; string bname = ObjTable::get_type_name(iprop->first.first); string ename = ObjTable::get_type_name(iprop->first.second); stream << bname << " " << ename << " " << *(*iprop).second; } stream << end_object; } //********************************************************************** // constructor PropDispatch::PropDispatch() { } //********************************************************************** // destructor PropDispatch::~PropDispatch() { } //********************************************************************** // Return the creator. ObjCreator PropDispatch::get_creator() { return create; } //********************************************************************** // Write object data. ObjData PropDispatch::write_data() const { ObjData data("PropDispatch"); #ifdef ObjData_supports_lists ObjData::StringList bsurfs; ObjData::StringList esurfs; PropList props; // Loop over registrants and write the two surface types and the // propagator object for each. for ( PropMap::const_iterator iprop=_props.begin(); iprop!=_props.end(); ++iprop ) { string bname = ObjTable::get_type_name(iprop->first.first); string ename = ObjTable::get_type_name(iprop->first.second); bsurfs.push_back( bname ); esurfs.push_back( ename ); props.push_back( iprop->second ); } data.add_string_list("begin_surfs", bsurfs); data.add_string_list("end_surfs", esurfs); data.add_share_ptr_list("propagators", props); #endif return data; } //********************************************************************** // Register a propagator. int PropDispatch:: add_propagator(Type stype1, Type stype2, const PropagatorPtr& pprop) { TypePair types(stype1,stype2); PropMap::const_iterator iprop = _props.find(types); if ( iprop != _props.end() ) return 1; _props[types] = pprop; return 0; } //********************************************************************** // Return the nuber of registrations. int PropDispatch::get_propagator_count() const { return _props.size(); } //********************************************************************** // Return the propagator fpr a specified pair of surfaces. const PropagatorPtr& PropDispatch::get_propagator(Type stype1, Type stype2) const { TypePair types(stype1,stype2); PropMap::const_iterator iprop = _props.find(types); if ( iprop == _props.end() ) return prop_null; return (*iprop).second; } //********************************************************************** // Clone, i.e. create a copy on the free store. Propagator* PropDispatch::new_propagator( ) const { return new PropDispatch(*this); } //********************************************************************** // propagate a track without error PropStat PropDispatch:: vec_prop(VTrack& trv, const Surface& srf, TrackDerivative* pder) const { Type stype1 = trv.get_surface()->get_pure_type(); Type stype2 = srf.get_pure_type(); TypePair types(stype1,stype2); PropMap::const_iterator iprop = _props.find(types); if ( iprop == _props.end() ) return PropStat(); return (*iprop).second->vec_prop(trv,srf,pder); } //********************************************************************** // propagate a track without error in the specified direction PropStat PropDispatch:: vec_dir_prop(VTrack& trv, const Surface& srf, PropDir dir, TrackDerivative* pder) const { Type stype1 = trv.get_surface()->get_pure_type(); Type stype2 = srf.get_pure_type(); TypePair types(stype1,stype2); PropMap::const_iterator iprop = _props.find(types); if ( iprop == _props.end() ) return PropStat(); return (*iprop).second->vec_dir_prop(trv,srf,dir,pder); } //********************************************************************** // propagate a track with error PropStat PropDispatch:: err_prop(ETrack& tre, const Surface& srf, TrackDerivative* pder) const { Type stype1 = tre.get_surface()->get_pure_type(); Type stype2 = srf.get_pure_type(); TypePair types(stype1,stype2); PropMap::const_iterator iprop = _props.find(types); if ( iprop == _props.end() ) return PropStat(); return (*iprop).second->err_prop(tre,srf, pder); } //********************************************************************** // propagate a track with error in a specified direction PropStat PropDispatch:: err_dir_prop(ETrack& tre, const Surface& srf, PropDir dir, TrackDerivative* pder) const { Type stype1 = tre.get_surface()->get_pure_type(); Type stype2 = srf.get_pure_type(); TypePair types(stype1,stype2); PropMap::const_iterator iprop = _props.find(types); if ( iprop == _props.end() ) return PropStat(); return (*iprop).second->err_dir_prop(tre,srf,dir,pder); } //**********************************************************************