ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
angle_common.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 * Copyright (C) 2002-2010
4 * Max-Planck-Institute for Polymer Research, Theory Group
5 *
6 * This file is part of ESPResSo.
7 *
8 * ESPResSo is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * ESPResSo is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#pragma once
23
24/** \file
25 * Common code for functions calculating angle forces.
26 */
27
28#include "config/config.hpp"
29
30#include <utils/Vector.hpp>
31
32#include <algorithm>
33#include <cmath>
34#include <tuple>
35
36/** Compute the cosine of the angle between three particles.
37 *
38 * @param[in] vec1 Vector from central particle to left particle.
39 * @param[in] vec2 Vector from central particle to right particle.
40 * @param[in] sanitize_cosine Sanitize the cosine of the angle.
41 * @return @f$ \vec{r_{ij}} @f$, @f$ \vec{r_{kj}} @f$,
42 * @f$ \left\|\vec{r_{ij}}\right\|^{-1} @f$,
43 * @f$ \left\|\vec{r_{kj}}\right\|^{-1} @f$,
44 * @f$ \cos(\theta_{ijk}) @f$
45 */
46inline double calc_cosine(Utils::Vector3d const &vec1,
47 Utils::Vector3d const &vec2,
48 bool sanitize_cosine = false) {
49 /* cosine of the angle between vec1 and vec2 */
50 auto cos_phi = (vec1 * vec2) / std::sqrt(vec1.norm2() * vec2.norm2());
51 if (sanitize_cosine) {
52 cos_phi = std::clamp(cos_phi, -TINY_COS_VALUE, TINY_COS_VALUE);
53 }
54 return cos_phi;
55}
56
57/** Compute a three-body angle interaction force.
58 *
59 * See the details in @ref bondedIA_angle_force. The @f$ K(\theta_{ijk}) @f$
60 * term is provided as a lambda function in @p forceFactor.
61 *
62 * @param[in] vec1 Vector from central particle to left particle.
63 * @param[in] vec2 Vector from central particle to right particle.
64 * @param[in] forceFactor Angle force term.
65 * @param[in] sanitize_cosine Sanitize the cosine of the angle.
66 * @tparam ForceFactor Function evaluating the angle force term
67 * for a given angle.
68 * @return Forces on the second, first and third particles, in that order.
69 */
70template <typename ForceFactor>
71std::tuple<Utils::Vector3d, Utils::Vector3d, Utils::Vector3d>
73 ForceFactor forceFactor, bool sanitize_cosine) {
74 auto const d1 = vec1.norm();
75 auto const d2 = vec2.norm();
76 auto cos_phi = (vec1 * vec2) / (d1 * d2);
77 if (sanitize_cosine) {
78 cos_phi = std::clamp(cos_phi, -TINY_COS_VALUE, TINY_COS_VALUE);
79 }
80 /* force factor */
81 auto const fac = forceFactor(cos_phi);
82 /* distribute forces */
83 auto const v1 = vec1 / d1;
84 auto const v2 = vec2 / d2;
85 auto f_left = (fac / d1) * (v1 * cos_phi - v2);
86 auto f_right = (fac / d2) * (v2 * cos_phi - v1);
87 auto f_mid = -(f_left + f_right);
88 return std::make_tuple(f_mid, f_left, f_right);
89}
Vector implementation and trait types for boost qvm interoperability.
std::tuple< Utils::Vector3d, Utils::Vector3d, Utils::Vector3d > angle_generic_force(Utils::Vector3d const &vec1, Utils::Vector3d const &vec2, ForceFactor forceFactor, bool sanitize_cosine)
Compute a three-body angle interaction force.
double calc_cosine(Utils::Vector3d const &vec1, Utils::Vector3d const &vec2, bool sanitize_cosine=false)
Compute the cosine of the angle between three particles.
T norm2() const
Definition Vector.hpp:138
T norm() const
Definition Vector.hpp:139
This file contains the defaults for ESPResSo.
#define TINY_COS_VALUE
Tiny angle cutoff for cosine calculations.
Definition config.hpp:75