ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
Ellipsoid.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,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#include <shapes/Ellipsoid.hpp>
23
24#include <utils/Vector.hpp>
25#include <utils/math/sqr.hpp>
26
27#include <algorithm>
28
29namespace Shapes {
30void Ellipsoid::calculate_dist(const Utils::Vector3d &pos, double &dist,
31 Utils::Vector3d &vec) const {
32
33 /* get particle position in reference frame of ellipsoid */
34 Utils::Vector3d const ppos_e = pos - m_center;
35
36 /* set appropriate initial point for Newton's method */
37 double l = 0.;
38 int distance_prefactor = -1;
39 if (not inside_ellipsoid(ppos_e)) {
40 l = *std::max_element(m_semiaxes.begin(), m_semiaxes.end()) * ppos_e.norm();
41 distance_prefactor = 1;
42 }
43
44 /* find root via Newton's method */
45 double eps = 10.;
46 int step = 0;
47 while ((eps >= 1e-12) and (step < 100)) {
48 auto const l0 = l;
49 l -= newton_term(ppos_e, l0);
50 eps = std::abs(l - l0);
51 step++;
52 }
53
54 /* calculate dist and vec */
55 for (unsigned int i = 0; i < 3; i++) {
56 auto const semi_sq = Utils::sqr(m_semiaxes[i]);
57 vec[i] = (ppos_e[i] - semi_sq * ppos_e[i] / (l + semi_sq));
58 }
59
60 dist = distance_prefactor * m_direction * vec.norm();
61}
62
63bool Ellipsoid::inside_ellipsoid(const Utils::Vector3d &ppos) const {
64 return Utils::hadamard_division(ppos, m_semiaxes).norm2() <= 1;
65}
66
67double Ellipsoid::newton_term(const Utils::Vector3d &ppos,
68 const double &l) const {
69 Utils::Vector3d axpos, lax, lax2;
70 for (unsigned int i = 0; i < 3; i++) {
71 axpos[i] = Utils::sqr(m_semiaxes[i]) * Utils::sqr(ppos[i]);
72 lax[i] = l + Utils::sqr(m_semiaxes[i]);
73 lax2[i] = Utils::sqr(lax[i]);
74 }
75
76 return (axpos[0] * lax2[1] * lax2[2] + axpos[1] * lax2[2] * lax2[0] +
77 axpos[2] * lax2[0] * lax2[1] - lax2[0] * lax2[1] * lax2[2]) /
78 (2 * (axpos[0] * lax[1] * lax2[2] + axpos[1] * lax[2] * lax2[0] +
79 axpos[2] * lax[0] * lax2[1] + axpos[0] * lax2[1] * lax[2] +
80 axpos[1] * lax2[2] * lax[0] + axpos[2] * lax2[0] * lax[1] -
81 lax[0] * lax2[1] * lax2[2] - lax2[0] * lax[1] * lax2[2] -
82 lax2[0] * lax2[1] * lax[2]));
83}
84
85} // namespace Shapes
Vector implementation and trait types for boost qvm interoperability.
void calculate_dist(const Utils::Vector3d &pos, double &dist, Utils::Vector3d &vec) const override
Definition Ellipsoid.cpp:30
T norm() const
Definition Vector.hpp:138
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
Definition sqr.hpp:28
auto hadamard_division(Vector< T, N > const &a, Vector< U, N > const &b)
Definition Vector.hpp:422
DEVICE_QUALIFIER constexpr iterator begin() noexcept
Definition Array.hpp:128
DEVICE_QUALIFIER constexpr iterator end() noexcept
Definition Array.hpp:140