votca 2024.1-dev
Loading...
Searching...
No Matches
interaction.h
Go to the documentation of this file.
1/*
2 * Copyright 2009-2019 The VOTCA Development Team (http://www.votca.org)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18#pragma once
19#ifndef VOTCA_CSG_INTERACTION_H
20#define VOTCA_CSG_INTERACTION_H
21
22// Standard includes
23#include <sstream>
24#include <string>
25
26// Local VOTCA includes
27#include "bead.h"
28#include "topology.h"
29
30namespace votca {
31namespace csg {
32
41 public:
42 Interaction() = default;
43
44 virtual ~Interaction() = default;
45 virtual double EvaluateVar(const Topology &top) = 0;
46
47 std::string getName() const { return name_; }
48
49 void setGroup(const std::string &group) {
50 group_ = group;
52 }
53 const std::string &getGroup() const {
54 assert(group_.compare("") != 0);
55 return group_;
56 }
57
58 // the group id is set by topology, when interaction is added to it
59 // \todo if the group name is changed later, group id should be updated by
60 // topology
62 assert(group_id_ != -1);
63 return group_id_;
64 }
65 void setGroupId(Index id) { group_id_ = id; }
66
67 void setIndex(const Index &index) {
68 index_ = index;
70 }
71 const Index &getIndex() const {
72 assert(index_ != -1);
73 return index_;
74 }
75
76 void setMolecule(const Index &mol) {
77 mol_ = mol;
79 }
80 const Index &getMolecule() const {
81 assert(mol_ != -1);
82 return mol_;
83 }
84
85 virtual Eigen::Vector3d Grad(const Topology &top, Index bead) = 0;
86 Index BeadCount() const { return beads_.size(); }
87 Index getBeadId(Index bead) const {
88 assert(bead > -1 && boost::lexical_cast<size_t>(bead) < beads_.size());
89 return beads_[bead];
90 }
91
92 protected:
94 std::string group_ = "";
96 std::string name_ = "";
97 Index mol_ = -1;
98 std::vector<Index> beads_;
99
100 void RebuildName();
101};
102
104 std::stringstream s;
105 if (mol_ != -1) {
106 {
107 s << "molecule " << mol_;
108 }
109 }
110 if (!group_.empty()) {
111 s << ":" << group_;
112 if (group_id_ != -1) {
113 s << " " << group_id_;
114 }
115 }
116 if (index_ != -1) {
117 {
118 s << ":index " << index_;
119 }
120 }
121 name_ = s.str();
122}
123
127class IBond : public Interaction {
128 public:
129 IBond(Index bead1, Index bead2) {
130 beads_.resize(2);
131 beads_[0] = bead1;
132 beads_[1] = bead2;
133 }
134
135 IBond(std::list<Index> &beads) {
136 assert(beads.size() >= 2);
137 beads_.resize(2);
138 for (Index i = 0; i < 2; ++i) {
139 beads_[i] = beads.front();
140 beads.pop_front();
141 }
142 }
143 double EvaluateVar(const Topology &top) override;
144 Eigen::Vector3d Grad(const Topology &top, Index bead) override;
145
146 private:
147};
148
152class IAngle : public Interaction {
153 public:
154 IAngle(Index bead1, Index bead2, Index bead3) {
155 beads_.resize(3);
156 beads_[0] = bead1;
157 beads_[1] = bead2;
158 beads_[2] = bead3;
159 }
160 IAngle(std::list<Index> &beads) {
161 assert(beads.size() >= 3);
162 beads_.resize(3);
163 for (Index i = 0; i < 3; ++i) {
164 beads_[i] = beads.front();
165 beads.pop_front();
166 }
167 }
168
169 double EvaluateVar(const Topology &top) override;
170 Eigen::Vector3d Grad(const Topology &top, Index bead) override;
171
172 private:
173};
174
178class IDihedral : public Interaction {
179 public:
180 IDihedral(Index bead1, Index bead2, Index bead3, Index bead4) {
181 beads_.resize(4);
182 beads_[0] = bead1;
183 beads_[1] = bead2;
184 beads_[2] = bead3;
185 beads_[3] = bead4;
186 }
187 IDihedral(std::list<Index> &beads) {
188 assert(beads.size() >= 4);
189 beads_.resize(4);
190 for (Index i = 0; i < 4; ++i) {
191 beads_[i] = beads.front();
192 beads.pop_front();
193 }
194 }
195
196 double EvaluateVar(const Topology &top) override;
197 Eigen::Vector3d Grad(const Topology &top, Index bead) override;
198
199 private:
200};
201
202inline double IBond::EvaluateVar(const Topology &top) {
203 return top.getDist(beads_[0], beads_[1]).norm();
204}
205
206inline Eigen::Vector3d IBond::Grad(const Topology &top, Index bead) {
207 Eigen::Vector3d r = top.getDist(beads_[0], beads_[1]);
208 r.normalize();
209 return (bead == 0) ? -r : r;
210}
211
212inline double IAngle::EvaluateVar(const Topology &top) {
213 Eigen::Vector3d v1(top.getDist(beads_[1], beads_[0]));
214 Eigen::Vector3d v2(top.getDist(beads_[1], beads_[2]));
215 return std::acos(v1.dot(v2) / sqrt(v1.squaredNorm() * v2.squaredNorm()));
216}
217
218inline Eigen::Vector3d IAngle::Grad(const Topology &top, Index bead) {
219 Eigen::Vector3d v1(top.getDist(beads_[1], beads_[0]));
220 Eigen::Vector3d v2(top.getDist(beads_[1], beads_[2]));
221
222 double acos_prime =
223 1.0 / (sqrt(1 - std::pow(v1.dot(v2), 2) /
224 (v1.squaredNorm() * v2.squaredNorm())));
225 switch (bead) {
226 case (0):
227 return acos_prime *
228 (-v2 / (v1.norm() * v2.norm()) +
229 (v1.dot(v2) * v1) / (v1.squaredNorm() * v2.squaredNorm()));
230 break;
231 case (1):
232 return acos_prime *
233 ((v1 + v2) / (v1.norm() * v2.norm()) -
234 (v1.dot(v2)) * (v2.squaredNorm() * v1 + v1.squaredNorm() * v2) /
235 (std::pow(v1.norm(), 3) * std::pow(v2.norm(), 3)));
236 break;
237 case (2):
238 return acos_prime * (-v1 / (v1.norm() * v2.norm())) +
239 (v1.dot(v2) * v2 / (v1.norm() * std::pow(v2.norm(), 3)));
240 break;
241 }
242 // should never reach this
243 assert(false);
244 return Eigen::Vector3d::Zero();
245}
246
247inline double IDihedral::EvaluateVar(const Topology &top) {
248 Eigen::Vector3d v1(top.getDist(beads_[0], beads_[1]));
249 Eigen::Vector3d v2(top.getDist(beads_[1], beads_[2]));
250 Eigen::Vector3d v3(top.getDist(beads_[2], beads_[3]));
251 Eigen::Vector3d n1 = v1.cross(v2); // calculate the normal vector
252 Eigen::Vector3d n2 = v2.cross(v3); // calculate the normal vector
253 double sign = (v1.dot(n2) < 0) ? -1 : 1;
254 return sign *
255 std::acos(n1.dot(n2) / sqrt(n1.squaredNorm() * n2.squaredNorm()));
256}
257
258inline Eigen::Vector3d IDihedral::Grad(const Topology &top, Index bead) {
259 Eigen::Vector3d v1(top.getDist(beads_[0], beads_[1]));
260 Eigen::Vector3d v2(top.getDist(beads_[1], beads_[2]));
261 Eigen::Vector3d v3(top.getDist(beads_[2], beads_[3]));
262 Eigen::Vector3d n1, n2;
263 n1 = v1.cross(v2); // calculate the normal vector
264 n2 = v2.cross(v3); // calculate the normal vector
265 double sign = (v1.dot(n2) < 0) ? -1 : 1;
266 Eigen::Vector3d returnvec;
267
268 Eigen::Matrix3d e = Eigen::Matrix3d::Identity();
269
270 double acos_prime =
271 sign * (-1.0 / (sqrt(1 - std::pow(n1.dot(n2), 2) /
272 (n1.squaredNorm() * n2.squaredNorm()))));
273 switch (bead) {
274 case (0): {
275 for (Index i = 0; i < 3; i++) {
276 returnvec[i] = n2.dot(v2.cross(e.col(i))) / (n1.norm() * n2.norm()) -
277 n1.dot(n2) * n1.dot(v2.cross(e.col(i))) /
278 (n2.norm() * std::pow(n1.norm(), 3));
279 }
280 return acos_prime * returnvec;
281 break;
282 }
283 case (1): {
284 for (Index i = 0; i < 3; i++) {
285 returnvec[i] =
286 (n1.dot(v3.cross(e.col(i))) +
287 n2.dot(e.col(i).cross(v1) + e.col(i).cross(v2))) /
288 (n1.norm() * n2.norm()) -
289 n1.dot(n2) * ((n1.dot(e.col(i).cross(v1) + e.col(i).cross(v2))) /
290 (n2.norm() * std::pow(n1.norm(), 3)) +
291 n2.dot(v3.cross(e.col(i))) /
292 (n1.norm() * std::pow(n2.norm(), 3)));
293 }
294 return acos_prime * returnvec;
295 break;
296 };
297 case (2): {
298 for (Index i = 0; i < 3; i++) {
299 returnvec[i] =
300 (n1.dot(e.col(i).cross(v2) + e.col(i).cross(v3)) +
301 n2.dot(v1.cross(e.col(i)))) /
302 (n1.norm() * n2.norm()) -
303 n1.dot(n2) * (n1.dot(v1.cross(e.col(i))) /
304 (n2.norm() * std::pow(n1.norm(), 3)) +
305 (n2.dot(e.col(i).cross(v2) + e.col(i).cross(v3))) /
306 (n1.norm() * std::pow(n2.norm(), 3)));
307 }
308 return acos_prime * returnvec;
309 break;
310 };
311 case (3): { //
312 for (Index i = 0; i < 3; i++) {
313 returnvec[i] = n1.dot(v2.cross(e.col(i))) / (n1.norm() * n2.norm()) -
314 n1.dot(n2) * n2.dot(v2.cross(e.col(i))) /
315 (n1.norm() * std::pow(n2.norm(), 3));
316 }
317 return acos_prime * returnvec;
318 break;
319 };
320 }
321 // should never reach this
322 assert(false);
323 return Eigen::Vector3d::Zero();
324}
325} // namespace csg
326} // namespace votca
327
328#endif // VOTCA_CSG_INTERACTION_H
angle interaction
Eigen::Vector3d Grad(const Topology &top, Index bead) override
double EvaluateVar(const Topology &top) override
IAngle(Index bead1, Index bead2, Index bead3)
IAngle(std::list< Index > &beads)
bond interaction
IBond(Index bead1, Index bead2)
IBond(std::list< Index > &beads)
Eigen::Vector3d Grad(const Topology &top, Index bead) override
double EvaluateVar(const Topology &top) override
dihedral interaction
IDihedral(std::list< Index > &beads)
double EvaluateVar(const Topology &top) override
Eigen::Vector3d Grad(const Topology &top, Index bead) override
IDihedral(Index bead1, Index bead2, Index bead3, Index bead4)
base class for all interactions
Definition interaction.h:40
const std::string & getGroup() const
Definition interaction.h:53
const Index & getIndex() const
Definition interaction.h:71
Index BeadCount() const
Definition interaction.h:86
Index getBeadId(Index bead) const
Definition interaction.h:87
void setGroup(const std::string &group)
Definition interaction.h:49
const Index & getMolecule() const
Definition interaction.h:80
virtual Eigen::Vector3d Grad(const Topology &top, Index bead)=0
void setGroupId(Index id)
Definition interaction.h:65
virtual double EvaluateVar(const Topology &top)=0
void setIndex(const Index &index)
Definition interaction.h:67
std::vector< Index > beads_
Definition interaction.h:98
void setMolecule(const Index &mol)
Definition interaction.h:76
virtual ~Interaction()=default
std::string getName() const
Definition interaction.h:47
topology of the whole system
Definition topology.h:81
Eigen::Vector3d getDist(Index bead1, Index bead2) const
pbc correct distance of two beads
Definition topology.cc:243
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26