Changeset 9f55b9
- Timestamp:
- Apr 23, 2021, 8:34:22 PM (5 years ago)
- Branches:
- Candidate_v1.7.0, stable
- Children:
- 4de4f6
- Parents:
- f3eb6a
- git-author:
- Frederik Heber <frederik.heber@…> (10/04/20 20:13:46)
- git-committer:
- Frederik Heber <frederik.heber@…> (04/23/21 20:34:22)
- Location:
- src
- Files:
-
- 2 added
- 3 edited
-
Actions/MoleculeAction/StretchBondAction.cpp (modified) (3 diffs)
-
Bond/StretchBond.cpp (added)
-
Bond/StretchBond.hpp (added)
-
Graph/BoostGraphHelpers.hpp (modified) (1 diff)
-
Makefile.am (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Actions/MoleculeAction/StretchBondAction.cpp
rf3eb6a r9f55b9 39 39 #include <boost/bind.hpp> 40 40 41 #include "CodePatterns/Assert.hpp"42 41 #include "CodePatterns/Log.hpp" 43 42 #include "CodePatterns/Verbose.hpp" … … 47 46 #include "Atom/atom.hpp" 48 47 #include "Bond/bond.hpp" 49 #include "Descriptors/AtomIdDescriptor.hpp" 50 #include "Graph/BoostGraphCreator.hpp" 48 #include "Bond/StretchBond.hpp" 51 49 #include "Graph/BoostGraphHelpers.hpp" 52 #include "Graph/BreadthFirstSearchGatherer.hpp"53 #include "molecule.hpp"54 50 #include "World.hpp" 55 51 … … 61 57 62 58 63 static bool addEdgePredicate(64 const bond &_bond,65 const std::vector<atomId_t> &_atomids)66 {67 ASSERT(_atomids.size() == (size_t)2,68 "addEdgePredicate() - atomids must contain exactly two ids.");69 // do not add selected edge70 return ((_bond.leftatom->getId() != _atomids[0])71 || (_bond.rightatom->getId() != _atomids[1]));72 }73 74 59 /** =========== define the function ====================== */ 75 60 ActionState::ptr MoleculeStretchBondAction::performCall() 76 61 { 77 // check preconditions78 62 const std::vector< atom *> atoms = World::getInstance().getSelectedAtoms(); 79 if (atoms.size() != 2) { 80 STATUS("Exactly two atoms must be selected."); 63 StretchBondUtil stretcher(atoms); 64 bool status = stretcher(params.bonddistance.get()); 65 66 if (status) { 67 MoleculeStretchBondState *UndoState = 68 new MoleculeStretchBondState( 69 stretcher.getShift(), 70 stretcher.getBondSides(), 71 &stretcher.getMolecule(), 72 params); 73 return ActionState::ptr(UndoState); 74 } else { 75 STATUS("Failed, exactly two atoms must be selected."); 81 76 return Action::failure; 82 77 } 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 information91 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 ids96 std::vector<atomId_t> atomids(2);97 atomids[0] = atoms[0]->getId();98 atomids[1] = atoms[1]->getId();99 std::sort(atomids.begin(), atomids.end());100 LOG(1, "DEBUG: Selected nodes are " << atomids);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();108 109 // Assume the selected bond splits the molecule into two parts, each one on110 // either side of the bond. We need to perform a BFS from each bond partner111 // not using the selected bond. Therefrom, we obtain two sets of atoms/nodes.112 // If both are disjoint, the bond is not contained in a cycle and we simply113 // shift either set as desired. If not, then we simply shift each atom,114 // leaving the other positions untouched.115 116 // get nodes on either side of selected bond via BFS discovery117 BoostGraphCreator BGcreator;118 BGcreator.createFromMolecule(*mol,119 boost::bind(addEdgePredicate, _1, boost::ref(atomids)));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 not128 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 distances131 if (BoostGraphHelpers::isCommonNodeInVector(bondside_sets[0], bondside_sets[1])) {132 ELOG(2, "Sets contain common node, hence bond must have been by cyclic."133 << " Shifting only bond partners.");134 for(size_t j=0;j<2;++j) {135 bondside_sets[j].clear();136 bondside_sets[j].push_back( atomids[j] );137 const Vector &position = atoms[j]->getPosition();138 atoms[j]->setPosition( domain.enforceBoundaryConditions(position+Shift[j]) );139 }140 isCyclic = true;141 }142 }143 144 // go through the molecule and stretch each atom in either set of nodes145 if (!isCyclic) {146 for (molecule::iterator iter = mol->begin(); iter != mol->end(); ++iter) {147 const Vector &position = (*iter)->getPosition();148 // for each atom determine in which set of nodes it is and shift accordingly149 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 {155 ELOG(1, "Atom " << *iter << " is not contained on either side of bond? Undoing done shifts");156 // Have to undo shifts157 for (size_t i=0;i<2;++i) {158 for (BoostGraphHelpers::Nodeset_t::const_iterator iter = bondside_sets[i].begin();159 iter != bondside_sets[i].end(); ++iter) {160 atom &walker = *World::getInstance().getAtom(AtomById(*iter));161 const Vector &position = walker.getPosition();162 walker.setPosition( domain.enforceBoundaryConditions(position-Shift[i]) );163 }164 }165 return Action::failure;166 }167 }168 }169 170 MoleculeStretchBondState *UndoState = new MoleculeStretchBondState(Shift, bondside_sets, mol, params);171 return ActionState::ptr(UndoState);172 78 } 173 79 -
src/Graph/BoostGraphHelpers.hpp
rf3eb6a r9f55b9 16 16 17 17 #include <vector> 18 19 #include "types.hpp" 18 20 19 21 namespace BoostGraphHelpers { -
src/Makefile.am
rf3eb6a r9f55b9 33 33 Bond/bond_observable.cpp \ 34 34 Bond/BondInfo.cpp \ 35 Bond/GraphEdge.cpp 35 Bond/GraphEdge.cpp \ 36 Bond/StretchBond.cpp 36 37 37 38 BONDHEADER = \ … … 39 40 Bond/bond_observable.hpp \ 40 41 Bond/BondInfo.hpp \ 41 Bond/GraphEdge.hpp 42 Bond/GraphEdge.hpp \ 43 Bond/StretchBond.hpp 42 44 43 45 DESCRIPTORSOURCE = \
Note:
See TracChangeset
for help on using the changeset viewer.
