Changeset 6e5907
- Timestamp:
- Jul 5, 2017, 7:40:48 PM (8 years ago)
- Branches:
- ForceAnnealing_oldresults, IndependentFragmentGrids_IntegrationTest
- Children:
- 89235ea
- Parents:
- 6afd46
- git-author:
- Frederik Heber <frederik.heber@…> (05/18/17 17:45:47)
- git-committer:
- Frederik Heber <frederik.heber@…> (07/05/17 19:40:48)
- Location:
- src
- Files:
-
- 3 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Actions/MoleculeAction/StretchBondAction.cpp
r6afd46 r6e5907 33 33 #endif 34 34 35 #include <boost/graph/adjacency_list.hpp>36 #include <boost/graph/breadth_first_search.hpp>37 38 35 //#include "CodePatterns/MemDebug.hpp" 39 36 … … 52 49 #include "Descriptors/AtomIdDescriptor.hpp" 53 50 #include "Graph/BoostGraphCreator.hpp" 51 #include "Graph/BoostGraphHelpers.hpp" 52 #include "Graph/BreadthFirstSearchGatherer.hpp" 54 53 #include "molecule.hpp" 55 54 #include "World.hpp" … … 61 60 #include "Action_impl_pre.hpp" 62 61 63 64 /**65 * I have no idea why this is so complicated with BGL ...66 *67 * This is taken from the book "The Boost Graph Library: User Guide and Reference Manual, Portable Documents",68 * chapter "Basic Graph Algorithms", example on calculating the bacon number.69 */70 template <typename DistanceMap>71 class distance_recorder : public boost::default_bfs_visitor72 {73 public:74 distance_recorder(DistanceMap dist) : d(dist) {}75 76 template <typename Edge, typename Graph>77 void tree_edge(Edge e, const Graph &g) const {78 typename boost::graph_traits<Graph>::vertex_descriptor u = source(e,g), v = target(e,g);79 d[v] = d[u] + 1;80 }81 82 private:83 DistanceMap d;84 };85 86 template <typename DistanceMap>87 distance_recorder<DistanceMap> record_distance(DistanceMap d)88 {89 return distance_recorder<DistanceMap>(d);90 }91 62 92 63 static bool addEdgePredicate( … … 110 81 return Action::failure; 111 82 } 83 molecule *mol = World::getInstance(). 84 getMolecule(MoleculeById(atoms[0]->getMolecule()->getId())); 85 if (mol != atoms[1]->getMolecule()) { 86 STATUS("The two selected atoms must belong to the same molecule."); 87 return Action::failure; 88 } 89 90 // gather undo information 91 const double olddistance = atoms[0]->getPosition().distance(atoms[1]->getPosition()); 92 const double newdistance = params.bonddistance.get(); 93 LOG(1, "INFO: Old bond distance is " << olddistance << ", stretching to " << newdistance << "."); 94 95 // gather sorted ids 112 96 std::vector<atomId_t> atomids(2); 113 97 atomids[0] = atoms[0]->getId(); … … 115 99 std::sort(atomids.begin(), atomids.end()); 116 100 LOG(1, "DEBUG: Selected nodes are " << atomids); 117 molecule *mol = World::getInstance(). 118 getMolecule(MoleculeById(atoms[0]->getMolecule()->getId())); 119 if (mol != atoms[1]->getMolecule()) { 120 STATUS("The two selected atoms must belong to the same molecule."); 121 return Action::failure; 122 } 123 // gather undo information 124 const double olddistance = atoms[0]->getPosition().distance(atoms[1]->getPosition()); 125 const double newdistance = params.bonddistance.get(); 126 LOG(1, "INFO: Old bond distance is " << olddistance << ", stretching to " << newdistance << "."); 101 102 const Vector NormalVector = (atoms[0]->getPosition() - atoms[1]->getPosition())* (1./olddistance); 103 const double shift = 0.5*(newdistance - olddistance); 104 std::vector<Vector> Shift(2); 105 Shift[0] = shift * NormalVector; 106 Shift[1] = -shift * NormalVector; 107 Box &domain = World::getInstance().getDomain(); 127 108 128 109 // Assume the selected bond splits the molecule into two parts, each one on … … 133 114 // leaving the other positions untouched. 134 115 135 // convert BondGraph into boost::graph116 // get nodes on either side of selected bond via BFS discovery 136 117 BoostGraphCreator BGcreator; 137 118 BGcreator.createFromMolecule(*mol, 138 119 boost::bind(addEdgePredicate, _1, boost::ref(atomids))); 139 const BoostGraphCreator::UndirectedGraph &molgraph = BGcreator.get(); 140 141 const size_t num_vertices = BGcreator.getNumVertices(); 142 std::vector< std::vector<size_t> > distances; 143 for (size_t i=0;i<2;++i) { 144 distances.push_back(std::vector<size_t>(num_vertices, num_vertices+1)); // set distance to num+1 145 distances[i][atomids[i]] = 0; 146 boost::breadth_first_search( 147 molgraph, 148 boost::vertex(atomids[i], molgraph), 149 boost::visitor(record_distance(&(distances[i][0])))); 150 LOG(3, "DEBUG: From atom #" << atomids[i] 151 << " BFS discovered the following distances " << distances[i]); 152 } 153 154 const Vector NormalVector = (atoms[0]->getPosition() - atoms[1]->getPosition())* (1./olddistance); 155 const double shift = 0.5*(newdistance - olddistance); 156 std::vector<Vector> Shift(2); 157 Shift[0] = shift * NormalVector; 158 Shift[1] = -shift * NormalVector; 159 Box &domain = World::getInstance().getDomain(); 160 std::vector< std::vector<size_t> > bondside_sets(2); 161 162 // Check whether there are common nodes in each set of distances 163 for (size_t i=0;i<num_vertices;++i) 164 if ((distances[0][i] != (num_vertices+1)) && (distances[1][i] != (num_vertices+1))) { 165 ELOG(2, "Node #" << i << " is reachable from either side of bond, hence must by cyclic." 120 BreadthFirstSearchGatherer NodeGatherer(BGcreator); 121 std::vector< BoostGraphHelpers::Nodeset_t > bondside_sets(2); 122 for(size_t j=0;j<2;++j) { 123 bondside_sets[j] = NodeGatherer(atoms[j]->getId()); 124 std::sort(bondside_sets[j].begin(), bondside_sets[j].end()); 125 } 126 127 // simple test whether bond has split the system in two disjoint sets or not 128 bool isCyclic = false; 129 if ((bondside_sets[0].size() + bondside_sets[1].size()) > BGcreator.getNumVertices()) { 130 // Check whether there are common nodes in each set of distances 131 if (BoostGraphHelpers::isCommonNodeInVector(bondside_sets[0], bondside_sets[1])) { 132 ELOG(2, "Sets contain common node, hence bond must have been by cyclic." 166 133 << " Shifting only bond partners."); 167 134 for(size_t j=0;j<2;++j) { 168 bondside_sets[j].push_back(atoms[j]->getId()); 135 bondside_sets[j].clear(); 136 bondside_sets[j].push_back( atomids[j] ); 169 137 const Vector &position = atoms[j]->getPosition(); 170 138 atoms[j]->setPosition( domain.enforceBoundaryConditions(position+Shift[j]) ); 171 139 } 172 break; 173 } 140 isCyclic = true; 141 } 142 } 174 143 175 144 // go through the molecule and stretch each atom in either set of nodes 176 if (bondside_sets[0].empty()) { 177 const BoostGraphCreator::index_map_t index_map = BGcreator.getIndexMap(); 145 if (!isCyclic) { 178 146 for (molecule::iterator iter = mol->begin(); iter != mol->end(); ++iter) { 179 147 const Vector &position = (*iter)->getPosition(); 180 148 // for each atom determine in which set of nodes it is and shift accordingly 181 size_t i=0; 182 const size_t nodeindex = boost::get(index_map, boost::vertex((*iter)->getId(), molgraph)); 183 for (;i<2;++i) { 184 if (distances[i][nodeindex] != (num_vertices+1)) { 185 (*iter)->setPosition( domain.enforceBoundaryConditions(position+Shift[i]) ); 186 bondside_sets[i].push_back((*iter)->getId()); 187 break; 188 } 189 } 190 if (i==2) { 149 const atomId_t &atomid = (*iter)->getId(); 150 if (std::binary_search(bondside_sets[0].begin(), bondside_sets[0].end(), atomid)) { 151 (*iter)->setPosition( domain.enforceBoundaryConditions(position+Shift[0]) ); 152 } else if (std::binary_search(bondside_sets[1].begin(), bondside_sets[1].end(), atomid)) { 153 (*iter)->setPosition( domain.enforceBoundaryConditions(position+Shift[1]) ); 154 } else { 191 155 ELOG(1, "Atom " << *iter << " is not contained on either side of bond? Undoing done shifts"); 192 156 // Have to undo shifts 193 for ( i=0;i<2;++i) {194 for ( std::vector<size_t>::const_iterator iter = bondside_sets[i].begin();157 for (size_t i=0;i<2;++i) { 158 for (BoostGraphHelpers::Nodeset_t::const_iterator iter = bondside_sets[i].begin(); 195 159 iter != bondside_sets[i].end(); ++iter) { 196 160 atom &walker = *World::getInstance().getAtom(AtomById(*iter)); … … 214 178 Box &domain = World::getInstance().getDomain(); 215 179 for (size_t i=0;i<2;++i) { 216 for ( std::vector<size_t>::const_iterator iter = state->bondside_sets[i].begin();180 for (BoostGraphHelpers::Nodeset_t::const_iterator iter = state->bondside_sets[i].begin(); 217 181 iter != state->bondside_sets[i].end(); ++iter) { 218 182 atom &walker = *World::getInstance().getAtom(AtomById(*iter)); … … 230 194 Box &domain = World::getInstance().getDomain(); 231 195 for (size_t i=0;i<2;++i) { 232 for ( std::vector<size_t>::const_iterator iter = state->bondside_sets[i].begin();196 for (BoostGraphHelpers::Nodeset_t::const_iterator iter = state->bondside_sets[i].begin(); 233 197 iter != state->bondside_sets[i].end(); ++iter) { 234 198 atom &walker = *World::getInstance().getAtom(AtomById(*iter)); -
src/Actions/MoleculeAction/StretchBondAction.def
r6afd46 r6e5907 21 21 (RangeValidator< double >(0., 10.)) 22 22 23 #define statetypes (std::vector<Vector>)(std::vector< std::vector<size_t>>)(const molecule *)23 #define statetypes (std::vector<Vector>)(std::vector< BoostGraphHelpers::Nodeset_t >)(const molecule *) 24 24 #define statereferences (Shift)(bondside_sets)(mol) 25 25 -
src/Graph/BoostGraphCreator.cpp
r6afd46 r6e5907 85 85 std::back_inserter(atomids), getAtomId); 86 86 ASSERT( _atoms.size() == atomids.size(), 87 "BoostGraphCreator::createFromAtom() - atomids and atoms differ in size?"); 87 "BoostGraphCreator::createFromAtom() - atomids " 88 +toString(atomids.size())+" and atoms "+toString(_atoms.size()) 89 +" differ in size?"); 88 90 std::sort(atomids.begin(), atomids.end()); 89 91 const predicate_t predicate = boost::bind(inSetPredicate, boost::ref(atomids), _1); … … 95 97 } 96 98 99 BoostGraphCreator::nodeId_t BoostGraphCreator::getNodeId( 100 const atomId_t &_atomid) const 101 { 102 atomids_nodeids_t::const_iterator iter = 103 atomids_nodeids.find(_atomid); 104 return (iter == atomids_nodeids.end()) ? (nodeId_t)-1 : iter->second; 105 } 106 97 107 template <typename iterator> 98 108 void BoostGraphCreator::createFromRange( … … 101 111 const size_t &_no_nodes, 102 112 const predicate_t &_pred 103 ) { 104 // convert BondGraph into boost::graph 105 UndirectedGraph molgraph(_no_nodes); 113 ) 114 { 115 graph = UndirectedGraph(); 116 117 // add vertices 106 118 for(iterator iter = _begin; iter != _end; ++iter) { 107 LOG(2, "DEBUG: Looking at node " << (*iter)->getId()); 119 const atomId_t atomid = (*iter)->getId(); 120 Vertex v = boost::add_vertex(atomid, graph); 121 const atomId_t vertexname = boost::get(boost::get(boost::vertex_name, graph), v); 122 const nodeId_t vertexindex = boost::get(boost::get(boost::vertex_index, graph), v); 123 LOG(2, "DEBUG: Adding node " << vertexindex << " associated to atom #" << vertexname); 124 ASSERT( vertexname == atomid, 125 "BoostGraphCreator::createFromRange() - atomid "+toString(atomid) 126 +" is not name of vertex "+toString(vertexname)+"."); 127 atomids_nodeids.insert( std::make_pair(vertexname, vertexindex) ); 128 } 129 130 // add edges 131 for(iterator iter = _begin; iter != _end; ++iter) { 132 LOG(2, "DEBUG: Looking at atom " << (*iter)->getId()); 108 133 const BondList& ListOfBonds = (*iter)->getListOfBonds(); 109 134 for(BondList::const_iterator bonditer = ListOfBonds.begin(); 110 135 bonditer != ListOfBonds.end(); ++bonditer) { 136 LOG(2, "DEBUG: Looking at bond " << *(*bonditer)); 111 137 const atomId_t leftid = (*bonditer)->leftatom->getId(); 138 const nodeId_t leftnodeid = getNodeId(leftid); 112 139 const atomId_t rightid = (*bonditer)->rightatom->getId(); 140 const nodeId_t rightnodeid = getNodeId(rightid); 113 141 // only pick each bond once and evaluate predicate 114 142 if ((leftid == (*iter)->getId()) 115 143 && (_pred(**bonditer))) { 116 LOG(3, "DEBUG: ADDING edge " << left id << " <-> " << rightid);117 boost::add_edge(left id, rightid, graph);144 LOG(3, "DEBUG: ADDING edge " << leftnodeid << " <-> " << rightnodeid); 145 boost::add_edge(leftnodeid, rightnodeid, graph); 118 146 } else { 119 LOG(3, "DEBUG: Discarding edge " << left id << " <-> " << rightid);147 LOG(3, "DEBUG: Discarding edge " << leftnodeid << " <-> " << rightnodeid); 120 148 } 121 149 } -
src/Graph/BoostGraphCreator.hpp
r6afd46 r6e5907 15 15 #endif 16 16 17 #include <map> 17 18 #include <vector> 18 19 19 20 #include <boost/function.hpp> 20 21 #include <boost/graph/adjacency_list.hpp> 22 23 #include "types.hpp" 21 24 22 25 class atom; … … 32 35 //!> typedef for an undirected graph using boost::graph 33 36 typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS, 34 boost:: no_property, boost::no_property > UndirectedGraph;37 boost::property<boost::vertex_name_t, atomId_t>, boost::no_property > UndirectedGraph; 35 38 //!> typedef for a map of graph node indices 36 typedef boost::property_map < boost::adjacency_list <>, boost::vertex_index_t >::type index_map_t; 39 typedef boost::property_map < UndirectedGraph, boost::vertex_index_t >::type index_map_t; 40 typedef boost::property_map < UndirectedGraph, boost::vertex_index_t >::const_type const_index_map_t; 41 //!> typedef for a map of graph node indices 42 typedef boost::property_map < UndirectedGraph, boost::vertex_name_t >::type name_map_t; 43 typedef boost::property_map < UndirectedGraph, boost::vertex_name_t >::const_type const_name_map_t; 37 44 //!> typedef for the predicate to evaluate for adding the current edge or not 38 45 typedef boost::function<bool (const bond &)> predicate_t; 46 //!> typedef for a Vertex 47 typedef boost::graph_traits<UndirectedGraph>::vertex_descriptor Vertex; 48 //!> typedef for vertex iterator 49 typedef boost::graph_traits<UndirectedGraph>::vertex_iterator vertex_iter; 39 50 51 //!> typedef for a node id 52 typedef size_t nodeId_t; 53 //!> typedef for map converting between node id in graph and the associated atomic id 54 typedef std::map<atomId_t, nodeId_t> atomids_nodeids_t; 40 55 41 56 /** Creates the boost::graph using all atoms and bonds in the given \a _mol. … … 89 104 } 90 105 106 /** Returns the node id to a given atom id \a _atomid. 107 * 108 * \param _atomid atom id 109 * \return node id 110 */ 111 nodeId_t getNodeId(const atomId_t &_atomid) const; 112 91 113 private: 92 114 /** General purpose function that contains the internal logic of walking the … … 114 136 //!> internal graph that is created by creator functions 115 137 UndirectedGraph graph; 138 //!> external property map for all the atomic ids of each graph node 139 atomids_nodeids_t atomids_nodeids; 116 140 }; 117 141 -
src/Graph/Makefile.am
r6afd46 r6e5907 3 3 4 4 GRAPHSOURCE = \ 5 Graph/AdjacencyList.cpp \ 5 6 Graph/BondGraph.cpp \ 6 7 Graph/BoostGraphCreator.cpp \ 8 Graph/BreadthFirstSearchGatherer.cpp \ 7 9 Graph/BuildInducedSubgraph.cpp \ 8 Graph/AdjacencyList.cpp \9 10 Graph/ConnectedSubgraph.cpp \ 10 11 Graph/CyclicStructureAnalysis.cpp \ … … 12 13 13 14 GRAPHHEADER = \ 15 Graph/AdjacencyList.hpp \ 14 16 Graph/BondGraph.hpp \ 15 17 Graph/BoostGraphCreator.hpp \ 18 Graph/BoostGraphHelpers.hpp \ 19 Graph/BreadthFirstSearchGatherer.hpp \ 16 20 Graph/BuildInducedSubgraph.hpp \ 17 Graph/AdjacencyList.hpp \18 21 Graph/ConnectedSubgraph.hpp \ 19 22 Graph/CyclicStructureAnalysis.hpp \
Note:
See TracChangeset
for help on using the changeset viewer.