| 1 | /*
 | 
|---|
| 2 |  * BondVectors.hpp
 | 
|---|
| 3 |  *
 | 
|---|
| 4 |  *  Created on: Jun 13, 2017
 | 
|---|
| 5 |  *      Author: heber
 | 
|---|
| 6 |  */
 | 
|---|
| 7 | 
 | 
|---|
| 8 | 
 | 
|---|
| 9 | #ifndef DYNAMICS_BONDVECTORS_HPP_
 | 
|---|
| 10 | #define DYNAMICS_BONDVECTORS_HPP_
 | 
|---|
| 11 | 
 | 
|---|
| 12 | // include config.h
 | 
|---|
| 13 | #ifdef HAVE_CONFIG_H
 | 
|---|
| 14 | #include <config.h>
 | 
|---|
| 15 | #endif
 | 
|---|
| 16 | 
 | 
|---|
| 17 | #include <map>
 | 
|---|
| 18 | #include <vector>
 | 
|---|
| 19 | 
 | 
|---|
| 20 | #include <boost/function.hpp>
 | 
|---|
| 21 | 
 | 
|---|
| 22 | #include "CodePatterns/Assert.hpp"
 | 
|---|
| 23 | 
 | 
|---|
| 24 | #include "LinearAlgebra/Vector.hpp"
 | 
|---|
| 25 | 
 | 
|---|
| 26 | #include "Bond/bond.hpp"
 | 
|---|
| 27 | 
 | 
|---|
| 28 | /** This class represents all bond vectors, i.e. the normalized direction
 | 
|---|
| 29 |  * along a list of bonds, and provides means to extract them from a set of
 | 
|---|
| 30 |  * atoms such that for an arbitrary bond the vector can be quickly retrieved.
 | 
|---|
| 31 |  */
 | 
|---|
| 32 | class BondVectors
 | 
|---|
| 33 | {
 | 
|---|
| 34 | public:
 | 
|---|
| 35 |   //!> typedef for the internal container of the bonds
 | 
|---|
| 36 |   typedef std::vector<bond::ptr> container_t;
 | 
|---|
| 37 | 
 | 
|---|
| 38 |   //!> typedef for the association of bonds to bond vectors
 | 
|---|
| 39 |   typedef std::map<bond::ptr, Vector> mapped_t;
 | 
|---|
| 40 | 
 | 
|---|
| 41 |   /** Default cstor for class BondVectors.
 | 
|---|
| 42 |    *
 | 
|---|
| 43 |    */
 | 
|---|
| 44 |   BondVectors();
 | 
|---|
| 45 | 
 | 
|---|
| 46 |   /** Prepares the internal container from the bonds of a range of atoms.
 | 
|---|
| 47 |    *
 | 
|---|
| 48 |    * \param _start start of range
 | 
|---|
| 49 |    * \param _end end of range
 | 
|---|
| 50 |    * \param _step time step to request bonds for
 | 
|---|
| 51 |    */
 | 
|---|
| 52 |   template <class T>
 | 
|---|
| 53 |   void setFromAtomRange(
 | 
|---|
| 54 |       typename T::iterator _start,
 | 
|---|
| 55 |       typename T::iterator _end,
 | 
|---|
| 56 |       const size_t &_step);
 | 
|---|
| 57 | 
 | 
|---|
| 58 |   /** Returns the number of bonds whose bond vectors have been registered.
 | 
|---|
| 59 |    *
 | 
|---|
| 60 |    * \param number of bonds
 | 
|---|
| 61 |    */
 | 
|---|
| 62 |   size_t size() const
 | 
|---|
| 63 |   { return container.size(); }
 | 
|---|
| 64 | 
 | 
|---|
| 65 |   /** Getter for the sorted bonds.
 | 
|---|
| 66 |    *
 | 
|---|
| 67 |    * \return const ref to internal container
 | 
|---|
| 68 |    */
 | 
|---|
| 69 |   const container_t& getSorted() const;
 | 
|---|
| 70 | 
 | 
|---|
| 71 |   /** Getter for the Bondvectors.
 | 
|---|
| 72 |    *
 | 
|---|
| 73 |    * \param _step time step for which the bond vector is request
 | 
|---|
| 74 |    * \return a map from bond to bond vector
 | 
|---|
| 75 |    */
 | 
|---|
| 76 |   const mapped_t& getBondVectorsAtStep(const size_t &_step) const;
 | 
|---|
| 77 | 
 | 
|---|
| 78 |   /** Get the position in the internal container for a specific bond.
 | 
|---|
| 79 |    *
 | 
|---|
| 80 |    * \param _bond given bond
 | 
|---|
| 81 |    * \return position in the vector, -1 if not present
 | 
|---|
| 82 |    */
 | 
|---|
| 83 |   size_t getIndexForBond(const bond::ptr &_bond) const;
 | 
|---|
| 84 | 
 | 
|---|
| 85 |   /** Gather the subset of BondVectors for the given atom.
 | 
|---|
| 86 |    *
 | 
|---|
| 87 |    * \param _walker atom to get BondVectors for
 | 
|---|
| 88 |    * \param _step time step for which the bond vector is request
 | 
|---|
| 89 |    */
 | 
|---|
| 90 |   std::vector<Vector> getAtomsBondVectorsAtStep(
 | 
|---|
| 91 |       const atom &_walker,
 | 
|---|
| 92 |       const size_t &_step) const;
 | 
|---|
| 93 | 
 | 
|---|
| 94 |   //!> typedef for the weights for the Bondvectors of a single atom
 | 
|---|
| 95 |   typedef std::deque<double> weights_t;
 | 
|---|
| 96 | 
 | 
|---|
| 97 |   /** Calculates the weights for a frame where each Bondvector of the
 | 
|---|
| 98 |    * given atom is a vector of the frame.
 | 
|---|
| 99 |    *
 | 
|---|
| 100 |    * The idea is that we can represent any vector by appropriate weights such
 | 
|---|
| 101 |    * that is still sums up to one.
 | 
|---|
| 102 |    *
 | 
|---|
| 103 |    * \param _walker atom to get BondVectors for
 | 
|---|
| 104 |    * \param _bondvectors precalculated bond vectors for given \a _walker
 | 
|---|
| 105 |    * \param _step time step for which the bond vector is request
 | 
|---|
| 106 |    */
 | 
|---|
| 107 |   weights_t getWeightsForAtomAtStep(
 | 
|---|
| 108 |       const atom &_walker,
 | 
|---|
| 109 |       const std::vector<Vector> &_bondvectors,
 | 
|---|
| 110 |       const size_t &_step) const;
 | 
|---|
| 111 | 
 | 
|---|
| 112 |   /** Calculates the weights for a frame where each Bondvector of the
 | 
|---|
| 113 |    * given atom is a vector of the frame.
 | 
|---|
| 114 |    *
 | 
|---|
| 115 |    * The idea is that we can represent any vector by appropriate weights such
 | 
|---|
| 116 |    * that is still sums up to one.
 | 
|---|
| 117 |    *
 | 
|---|
| 118 |    * \param _walker atom to get BondVectors for
 | 
|---|
| 119 |    * \param _step time step for which the bond vector is request
 | 
|---|
| 120 |    */
 | 
|---|
| 121 |   weights_t getWeightsForAtomAtStep(
 | 
|---|
| 122 |       const atom &_walker,
 | 
|---|
| 123 |       const size_t &_step) const;
 | 
|---|
| 124 | 
 | 
|---|
| 125 |   /** Function typedef to store the bond gradient into a specific container
 | 
|---|
| 126 |    * depending on the atom, its current bond and the time step.
 | 
|---|
| 127 |    */
 | 
|---|
| 128 |   typedef boost::function<void (
 | 
|---|
| 129 |       const atom &,
 | 
|---|
| 130 |       const bond::ptr &,
 | 
|---|
| 131 |       const size_t &,
 | 
|---|
| 132 |       const double)> forcestore_t;
 | 
|---|
| 133 | 
 | 
|---|
| 134 |   /** Function calculates the remaining part of the atomic gradient that is
 | 
|---|
| 135 |    * not captured by the sum of the force along the Bond Vectors.
 | 
|---|
| 136 |    *
 | 
|---|
| 137 |    * \param _walker atom to get BondVectors for
 | 
|---|
| 138 |    * \param _walkerGradient gradient of atom to get BondVectors for
 | 
|---|
| 139 |    * \param _BondVectors precalculated bond vectors for given \a _walker
 | 
|---|
| 140 |    * \param _weights weight per bond vector (as it is a frame, not a basis)
 | 
|---|
| 141 |    * \param _step time step for which the bond vector is request
 | 
|---|
| 142 |    * \param _forcestore additional function which may be used to store each
 | 
|---|
| 143 |    *        calculated bond force in a bound container
 | 
|---|
| 144 |    */
 | 
|---|
| 145 |   Vector getRemnantGradientForAtomAtStep(
 | 
|---|
| 146 |       const atom &_walker,
 | 
|---|
| 147 |       const Vector &_walkerGradient,
 | 
|---|
| 148 |       const std::vector<Vector> _BondVectors,
 | 
|---|
| 149 |       const BondVectors::weights_t &_weights,
 | 
|---|
| 150 |       const size_t &_step,
 | 
|---|
| 151 |       forcestore_t _forcestore) const;
 | 
|---|
| 152 | 
 | 
|---|
| 153 |   /** Calculates the \a _walkkerGradient projected onto the bond vector for
 | 
|---|
| 154 |    * every of \a _walker's bonds.
 | 
|---|
| 155 |    *
 | 
|---|
| 156 |    * \param _walker atom
 | 
|---|
| 157 |    * \param _walkerGradient atom's gradient
 | 
|---|
| 158 |    * \param _timestep time step
 | 
|---|
| 159 |    * \param _projected_forces list of forces for every \a whichatom_t and every bond
 | 
|---|
| 160 |    */
 | 
|---|
| 161 |   void getProjectedGradientsForAtomAtStep(
 | 
|---|
| 162 |       const atom &_walker,
 | 
|---|
| 163 |       const Vector &_walkerGradient,
 | 
|---|
| 164 |       const size_t _timestep,
 | 
|---|
| 165 |       std::vector< std::vector<double> > &_projected_forces) const;
 | 
|---|
| 166 | 
 | 
|---|
| 167 |   // knowing the number of bonds in total, we can setup the storage for the
 | 
|---|
| 168 |   // projected forces
 | 
|---|
| 169 |   enum whichatom_t {
 | 
|---|
| 170 |     leftside=0,
 | 
|---|
| 171 |     rightside=1,
 | 
|---|
| 172 |     MAX_sides
 | 
|---|
| 173 |   };
 | 
|---|
| 174 | 
 | 
|---|
| 175 | private:
 | 
|---|
| 176 |   /** Calculates the bond vector for each bond in the internal container.
 | 
|---|
| 177 |    *
 | 
|---|
| 178 |    * \param _step time step for which the bond vector is request
 | 
|---|
| 179 |    */
 | 
|---|
| 180 |   void recalculateBondVectorsAtStep(const size_t &_step) const;
 | 
|---|
| 181 | 
 | 
|---|
| 182 |   /** Helper function to check whether weights sum up to one for each
 | 
|---|
| 183 |    * Bond Vector.
 | 
|---|
| 184 |    *
 | 
|---|
| 185 |    * \param _walker atom to get BondVectors for
 | 
|---|
| 186 |    * \param _BondVectors precalculated bond vectors for given \a _walker
 | 
|---|
| 187 |    * \param _weights weight per bond vector (as it is a frame, not a basis)
 | 
|---|
| 188 |    * \param _step time step for which the bond vector is request
 | 
|---|
| 189 |    */
 | 
|---|
| 190 |   bool getCheckWeightSumForAtomAtStep(
 | 
|---|
| 191 |       const atom &_walker,
 | 
|---|
| 192 |       const std::vector<Vector> _BondVectors,
 | 
|---|
| 193 |       const BondVectors::weights_t &_weights,
 | 
|---|
| 194 |       const size_t &_step) const;
 | 
|---|
| 195 | 
 | 
|---|
| 196 | private:
 | 
|---|
| 197 |   //!> internal container for sorted bonds
 | 
|---|
| 198 |   container_t container;
 | 
|---|
| 199 | 
 | 
|---|
| 200 |   //!> states whether map needs update or not
 | 
|---|
| 201 |   mutable bool map_is_dirty;
 | 
|---|
| 202 | 
 | 
|---|
| 203 |   //!> contains the step for which the map was calculated
 | 
|---|
| 204 |   mutable size_t current_step_for_map;
 | 
|---|
| 205 | 
 | 
|---|
| 206 |   //!> internal map for bond Bondvector association
 | 
|---|
| 207 |   mutable mapped_t current_mapped_vectors;
 | 
|---|
| 208 | 
 | 
|---|
| 209 | };
 | 
|---|
| 210 | 
 | 
|---|
| 211 | #include "BondVectors_impl.hpp"
 | 
|---|
| 212 | 
 | 
|---|
| 213 | #endif /* DYNAMICS_BONDVECTORS_HPP_ */
 | 
|---|