ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
mmm-modpsi.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 "config/config.hpp"
23
24#include "mmm-modpsi.hpp"
25#include "specfunc.hpp"
26
27#include <utils/constants.hpp>
28
29#include <cmath>
30#include <vector>
31
32std::vector<std::vector<double>> modPsi;
33
34static void preparePolygammaEven(int n, double binom,
35 std::vector<double> &series) {
36 /* (-0.5 n) psi^2n/2n! (-0.5 n) and psi^(2n+1)/(2n)! series expansions
37 note that BOTH carry 2n! */
38 auto const deriv = static_cast<double>(2 * n);
39 if (n == 0) {
40 // psi^0 has a slightly different series expansion
41 double maxx = 0.25;
42 series.resize(1);
43 series[0] = 2 * (1 - Utils::gamma());
44 for (int order = 1;; order += 1) {
45 auto const x_order = static_cast<double>(2 * order);
46 auto const coeff = -2 * hzeta(x_order + 1, 2);
47 if (fabs(maxx * coeff) * (4.0 / 3.0) < ROUND_ERROR_PREC)
48 break;
49 series.push_back(coeff);
50
51 maxx *= 0.25;
52 }
53 } else {
54 // even, n > 0
55 double maxx = 1;
56 double pref = 2;
57
58 for (int order = 0;; order++) {
59 // only even exponents of x
60 auto const x_order = static_cast<double>(2 * order);
61 auto const coeff = pref * hzeta(1 + deriv + x_order, 2);
62 if ((fabs(maxx * coeff) * (4.0 / 3.0) < ROUND_ERROR_PREC) &&
63 (x_order > deriv))
64 break;
65 series.push_back(-binom * coeff);
66
67 maxx *= 0.25;
68 pref *= (1.0 + deriv / (x_order + 1));
69 pref *= (1.0 + deriv / (x_order + 2));
70 }
71 }
72}
73
74static void preparePolygammaOdd(int n, double binom,
75 std::vector<double> &series) {
76 auto const deriv = static_cast<double>(2 * n + 1);
77 auto maxx = 0.5;
78 // to get 1/(2n)! instead of 1/(2n+1)!
79 auto pref = 2 * deriv * (1 + deriv);
80
81 for (int order = 0;; order++) {
82 // only odd exponents of x
83 auto const x_order = static_cast<double>(2 * order + 1);
84 auto const coeff = pref * hzeta(1 + deriv + x_order, 2);
85 if ((fabs(maxx * coeff) * (4.0 / 3.0) < ROUND_ERROR_PREC) &&
86 (x_order > deriv))
87 break;
88
89 series.push_back(-binom * coeff);
90 maxx *= 0.25;
91 pref *= (1.0 + deriv / (x_order + 1));
92 pref *= (1.0 + deriv / (x_order + 2));
93 }
94}
95
96void create_mod_psi_up_to(int new_n) {
97 auto const old_n = static_cast<int>(modPsi.size() >> 1);
98 if (new_n > old_n) {
99 modPsi.resize(2 * new_n);
100
101 double binom = 1.0;
102 for (int n = 0; n < old_n; n++)
103 binom *= (-0.5 - n) / static_cast<double>(n + 1);
104
105 for (int n = old_n; n < new_n; n++) {
106 preparePolygammaEven(n, binom, modPsi[2 * n]);
107 preparePolygammaOdd(n, binom, modPsi[2 * n + 1]);
108 binom *= (-0.5 - n) / static_cast<double>(n + 1);
109 }
110 }
111}
This file contains the defaults for ESPResSo.
#define ROUND_ERROR_PREC
Precision for capture of round off errors.
Definition config.hpp:66
std::vector< std::vector< double > > modPsi
Table of the Taylor expansions of the modified polygamma functions.
static void preparePolygammaOdd(int n, double binom, std::vector< double > &series)
static void preparePolygammaEven(int n, double binom, std::vector< double > &series)
void create_mod_psi_up_to(int new_n)
Create both the even and odd polygamma functions up to order 2*new_n
Common parts of the MMM family of methods for the electrostatic interaction: MMM1D and ELC.
DEVICE_QUALIFIER constexpr T gamma()
Euler-Mascheroni constant.
Definition constants.hpp:50
double hzeta(double s, double q)
Hurwitz zeta function.
Definition specfunc.cpp:215
This file contains implementations for some special functions which are needed by the MMM family of a...