Merge branch release-2016
[gromacs/AngularHB.git] / src / gromacs / tables / forcetable.cpp
blobcfd20340b9e391bdabf9fdc4e7d3d32a19a4a94c
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team.
6 * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
37 #include "gmxpre.h"
39 #include "forcetable.h"
41 #include <cmath>
43 #include <algorithm>
45 #include "gromacs/fileio/xvgr.h"
46 #include "gromacs/math/functions.h"
47 #include "gromacs/math/units.h"
48 #include "gromacs/math/utilities.h"
49 #include "gromacs/math/vec.h"
50 #include "gromacs/mdtypes/fcdata.h"
51 #include "gromacs/mdtypes/md_enums.h"
52 #include "gromacs/mdtypes/nblist.h"
53 #include "gromacs/utility/cstringutil.h"
54 #include "gromacs/utility/fatalerror.h"
55 #include "gromacs/utility/futil.h"
56 #include "gromacs/utility/smalloc.h"
58 /* All the possible (implemented) table functions */
59 enum {
60 etabLJ6,
61 etabLJ12,
62 etabLJ6Shift,
63 etabLJ12Shift,
64 etabShift,
65 etabRF,
66 etabRF_ZERO,
67 etabCOUL,
68 etabEwald,
69 etabEwaldSwitch,
70 etabEwaldUser,
71 etabEwaldUserSwitch,
72 etabLJ6Ewald,
73 etabLJ6Switch,
74 etabLJ12Switch,
75 etabCOULSwitch,
76 etabLJ6Encad,
77 etabLJ12Encad,
78 etabCOULEncad,
79 etabEXPMIN,
80 etabUSER,
81 etabNR
84 /** Evaluates to true if the table type contains user data. */
85 #define ETAB_USER(e) ((e) == etabUSER || \
86 (e) == etabEwaldUser || (e) == etabEwaldUserSwitch)
88 typedef struct {
89 const char *name;
90 gmx_bool bCoulomb;
91 } t_tab_props;
93 /* This structure holds name and a flag that tells whether
94 this is a Coulomb type funtion */
95 static const t_tab_props tprops[etabNR] = {
96 { "LJ6", FALSE },
97 { "LJ12", FALSE },
98 { "LJ6Shift", FALSE },
99 { "LJ12Shift", FALSE },
100 { "Shift", TRUE },
101 { "RF", TRUE },
102 { "RF-zero", TRUE },
103 { "COUL", TRUE },
104 { "Ewald", TRUE },
105 { "Ewald-Switch", TRUE },
106 { "Ewald-User", TRUE },
107 { "Ewald-User-Switch", TRUE },
108 { "LJ6Ewald", FALSE },
109 { "LJ6Switch", FALSE },
110 { "LJ12Switch", FALSE },
111 { "COULSwitch", TRUE },
112 { "LJ6-Encad shift", FALSE },
113 { "LJ12-Encad shift", FALSE },
114 { "COUL-Encad shift", TRUE },
115 { "EXPMIN", FALSE },
116 { "USER", FALSE },
119 typedef struct {
120 int nx, nx0;
121 double tabscale;
122 double *x, *v, *f;
123 } t_tabledata;
125 double v_q_ewald_lr(double beta, double r)
127 if (r == 0)
129 return beta*2/sqrt(M_PI);
131 else
133 return std::erf(beta*r)/r;
137 double v_lj_ewald_lr(double beta, double r)
139 double br, br2, br4, r6, factor;
140 if (r == 0)
142 return gmx::power6(beta)/6;
144 else
146 br = beta*r;
147 br2 = br*br;
148 br4 = br2*br2;
149 r6 = gmx::power6(r);
150 factor = (1.0 - std::exp(-br2)*(1 + br2 + 0.5*br4))/r6;
151 return factor;
155 void table_spline3_fill_ewald_lr(real *table_f,
156 real *table_v,
157 real *table_fdv0,
158 int ntab,
159 double dx,
160 real beta,
161 real_space_grid_contribution_computer v_lr)
163 real tab_max;
164 int i, i_inrange;
165 double dc, dc_new;
166 gmx_bool bOutOfRange;
167 double v_r0, v_r1, v_inrange, vi, a0, a1, a2dx;
168 double x_r0;
170 /* This function is called using either v_ewald_lr or v_lj_ewald_lr as a function argument
171 * depending on wether we should create electrostatic or Lennard-Jones Ewald tables.
174 if (ntab < 2)
176 gmx_fatal(FARGS, "Can not make a spline table with less than 2 points");
179 /* We need some margin to be able to divide table values by r
180 * in the kernel and also to do the integration arithmetics
181 * without going out of range. Furthemore, we divide by dx below.
183 tab_max = GMX_REAL_MAX*0.0001;
185 /* This function produces a table with:
186 * maximum energy error: V'''/(6*12*sqrt(3))*dx^3
187 * maximum force error: V'''/(6*4)*dx^2
188 * The rms force error is the max error times 1/sqrt(5)=0.45.
191 bOutOfRange = FALSE;
192 i_inrange = ntab;
193 v_inrange = 0;
194 dc = 0;
195 for (i = ntab-1; i >= 0; i--)
197 x_r0 = i*dx;
199 v_r0 = (*v_lr)(beta, x_r0);
201 if (!bOutOfRange)
203 i_inrange = i;
204 v_inrange = v_r0;
206 vi = v_r0;
208 else
210 /* Linear continuation for the last point in range */
211 vi = v_inrange - dc*(i - i_inrange)*dx;
214 if (table_v != nullptr)
216 table_v[i] = vi;
219 if (i == 0)
221 continue;
224 /* Get the potential at table point i-1 */
225 v_r1 = (*v_lr)(beta, (i-1)*dx);
227 if (v_r1 != v_r1 || v_r1 < -tab_max || v_r1 > tab_max)
229 bOutOfRange = TRUE;
232 if (!bOutOfRange)
234 /* Calculate the average second derivative times dx over interval i-1 to i.
235 * Using the function values at the end points and in the middle.
237 a2dx = (v_r0 + v_r1 - 2*(*v_lr)(beta, x_r0-0.5*dx))/(0.25*dx);
238 /* Set the derivative of the spline to match the difference in potential
239 * over the interval plus the average effect of the quadratic term.
240 * This is the essential step for minimizing the error in the force.
242 dc = (v_r0 - v_r1)/dx + 0.5*a2dx;
245 if (i == ntab - 1)
247 /* Fill the table with the force, minus the derivative of the spline */
248 table_f[i] = -dc;
250 else
252 /* tab[i] will contain the average of the splines over the two intervals */
253 table_f[i] += -0.5*dc;
256 if (!bOutOfRange)
258 /* Make spline s(x) = a0 + a1*(x - xr) + 0.5*a2*(x - xr)^2
259 * matching the potential at the two end points
260 * and the derivative dc at the end point xr.
262 a0 = v_r0;
263 a1 = dc;
264 a2dx = (a1*dx + v_r1 - a0)*2/dx;
266 /* Set dc to the derivative at the next point */
267 dc_new = a1 - a2dx;
269 if (dc_new != dc_new || dc_new < -tab_max || dc_new > tab_max)
271 bOutOfRange = TRUE;
273 else
275 dc = dc_new;
279 table_f[(i-1)] = -0.5*dc;
281 /* Currently the last value only contains half the force: double it */
282 table_f[0] *= 2;
284 if (table_v != nullptr && table_fdv0 != nullptr)
286 /* Copy to FDV0 table too. Allocation occurs in forcerec.c,
287 * init_ewald_f_table().
289 for (i = 0; i < ntab-1; i++)
291 table_fdv0[4*i] = table_f[i];
292 table_fdv0[4*i+1] = table_f[i+1]-table_f[i];
293 table_fdv0[4*i+2] = table_v[i];
294 table_fdv0[4*i+3] = 0.0;
296 table_fdv0[4*(ntab-1)] = table_f[(ntab-1)];
297 table_fdv0[4*(ntab-1)+1] = -table_f[(ntab-1)];
298 table_fdv0[4*(ntab-1)+2] = table_v[(ntab-1)];
299 table_fdv0[4*(ntab-1)+3] = 0.0;
303 /* Returns the spacing for a function using the maximum of
304 * the third derivative, x_scale (unit 1/length)
305 * and function tolerance.
307 static double spline3_table_scale(double third_deriv_max,
308 double x_scale,
309 double func_tol)
311 double deriv_tol;
312 double sc_deriv, sc_func;
314 /* Force tolerance: single precision accuracy */
315 deriv_tol = GMX_FLOAT_EPS;
316 sc_deriv = sqrt(third_deriv_max/(6*4*deriv_tol*x_scale))*x_scale;
318 /* Don't try to be more accurate on energy than the precision */
319 func_tol = std::max(func_tol, static_cast<double>(GMX_REAL_EPS));
320 sc_func = std::cbrt(third_deriv_max/(6*12*std::sqrt(3.0)*func_tol))*x_scale;
322 return std::max(sc_deriv, sc_func);
325 /* The scale (1/spacing) for third order spline interpolation
326 * of the Ewald mesh contribution which needs to be subtracted
327 * from the non-bonded interactions.
328 * Since there is currently only one spacing for Coulomb and LJ,
329 * the finest spacing is used if both Ewald types are present.
331 * Note that we could also implement completely separate tables
332 * for Coulomb and LJ Ewald, each with their own spacing.
333 * The current setup with the same spacing can provide slightly
334 * faster kernels with both Coulomb and LJ Ewald, especially
335 * when interleaving both tables (currently not implemented).
337 real ewald_spline3_table_scale(const interaction_const_t *ic)
339 real sc;
341 sc = 0;
343 if (ic->eeltype == eelEWALD || EEL_PME(ic->eeltype))
345 double erf_x_d3 = 1.0522; /* max of (erf(x)/x)''' */
346 double etol;
347 real sc_q;
349 /* Energy tolerance: 0.1 times the cut-off jump */
350 etol = 0.1*std::erfc(ic->ewaldcoeff_q*ic->rcoulomb);
352 sc_q = spline3_table_scale(erf_x_d3, ic->ewaldcoeff_q, etol);
354 if (debug)
356 fprintf(debug, "Ewald Coulomb quadratic spline table spacing: %f 1/nm\n", 1/sc_q);
359 sc = std::max(sc, sc_q);
362 if (EVDW_PME(ic->vdwtype))
364 double func_d3 = 0.42888; /* max of (x^-6 (1 - exp(-x^2)(1+x^2+x^4/2)))''' */
365 double xrc2, etol;
366 real sc_lj;
368 /* Energy tolerance: 0.1 times the cut-off jump */
369 xrc2 = gmx::square(ic->ewaldcoeff_lj*ic->rvdw);
370 etol = 0.1*std::exp(-xrc2)*(1 + xrc2 + xrc2*xrc2/2.0);
372 sc_lj = spline3_table_scale(func_d3, ic->ewaldcoeff_lj, etol);
374 if (debug)
376 fprintf(debug, "Ewald LJ quadratic spline table spacing: %f 1/nm\n", 1/sc_lj);
379 sc = std::max(sc, sc_lj);
382 return sc;
385 static void copy2table(int n, int offset, int stride,
386 double x[], double Vtab[], double Ftab[], real scalefactor,
387 real dest[])
389 /* Use double prec. for the intermediary variables
390 * and temporary x/vtab/vtab2 data to avoid unnecessary
391 * loss of precision.
393 int i, nn0;
394 double F, G, H, h;
396 h = 0;
397 for (i = 0; (i < n); i++)
399 if (i < n-1)
401 h = x[i+1] - x[i];
402 F = -Ftab[i]*h;
403 G = 3*(Vtab[i+1] - Vtab[i]) + (Ftab[i+1] + 2*Ftab[i])*h;
404 H = -2*(Vtab[i+1] - Vtab[i]) - (Ftab[i+1] + Ftab[i])*h;
406 else
408 /* Fill the last entry with a linear potential,
409 * this is mainly for rounding issues with angle and dihedral potentials.
411 F = -Ftab[i]*h;
412 G = 0;
413 H = 0;
415 nn0 = offset + i*stride;
416 dest[nn0] = scalefactor*Vtab[i];
417 dest[nn0+1] = scalefactor*F;
418 dest[nn0+2] = scalefactor*G;
419 dest[nn0+3] = scalefactor*H;
423 static void init_table(int n, int nx0,
424 double tabscale, t_tabledata *td, gmx_bool bAlloc)
426 td->nx = n;
427 td->nx0 = nx0;
428 td->tabscale = tabscale;
429 if (bAlloc)
431 snew(td->x, td->nx);
432 snew(td->v, td->nx);
433 snew(td->f, td->nx);
437 static void spline_forces(int nx, double h, double v[], gmx_bool bS3, gmx_bool bE3,
438 double f[])
440 int start, end, i;
441 double v3, b_s, b_e, b;
442 double beta, *gamma;
444 /* Formulas can be found in:
445 * H.J.C. Berendsen, Simulating the Physical World, Cambridge 2007
448 if (nx < 4 && (bS3 || bE3))
450 gmx_fatal(FARGS, "Can not generate splines with third derivative boundary conditions with less than 4 (%d) points", nx);
453 /* To make life easy we initially set the spacing to 1
454 * and correct for this at the end.
456 if (bS3)
458 /* Fit V''' at the start */
459 v3 = v[3] - 3*v[2] + 3*v[1] - v[0];
460 if (debug)
462 fprintf(debug, "The left third derivative is %g\n", v3/(h*h*h));
464 b_s = 2*(v[1] - v[0]) + v3/6;
465 start = 0;
467 if (FALSE)
469 /* Fit V'' at the start */
470 real v2;
472 v2 = -v[3] + 4*v[2] - 5*v[1] + 2*v[0];
473 /* v2 = v[2] - 2*v[1] + v[0]; */
474 if (debug)
476 fprintf(debug, "The left second derivative is %g\n", v2/(h*h));
478 b_s = 3*(v[1] - v[0]) - v2/2;
479 start = 0;
482 else
484 b_s = 3*(v[2] - v[0]) + f[0]*h;
485 start = 1;
487 if (bE3)
489 /* Fit V''' at the end */
490 v3 = v[nx-1] - 3*v[nx-2] + 3*v[nx-3] - v[nx-4];
491 if (debug)
493 fprintf(debug, "The right third derivative is %g\n", v3/(h*h*h));
495 b_e = 2*(v[nx-1] - v[nx-2]) + v3/6;
496 end = nx;
498 else
500 /* V'=0 at the end */
501 b_e = 3*(v[nx-1] - v[nx-3]) + f[nx-1]*h;
502 end = nx - 1;
505 snew(gamma, nx);
506 beta = (bS3 ? 1 : 4);
508 /* For V'' fitting */
509 /* beta = (bS3 ? 2 : 4); */
511 f[start] = b_s/beta;
512 for (i = start+1; i < end; i++)
514 gamma[i] = 1/beta;
515 beta = 4 - gamma[i];
516 b = 3*(v[i+1] - v[i-1]);
517 f[i] = (b - f[i-1])/beta;
519 gamma[end-1] = 1/beta;
520 beta = (bE3 ? 1 : 4) - gamma[end-1];
521 f[end-1] = (b_e - f[end-2])/beta;
523 for (i = end-2; i >= start; i--)
525 f[i] -= gamma[i+1]*f[i+1];
527 sfree(gamma);
529 /* Correct for the minus sign and the spacing */
530 for (i = start; i < end; i++)
532 f[i] = -f[i]/h;
536 static void set_forces(FILE *fp, int angle,
537 int nx, double h, double v[], double f[],
538 int table)
540 int start, end;
542 if (angle == 2)
544 gmx_fatal(FARGS,
545 "Force generation for dihedral tables is not (yet) implemented");
548 start = 0;
549 while (v[start] == 0)
551 start++;
554 end = nx;
555 while (v[end-1] == 0)
557 end--;
559 if (end > nx - 2)
561 end = nx;
563 else
565 end++;
568 if (fp)
570 fprintf(fp, "Generating forces for table %d, boundary conditions: V''' at %g, %s at %g\n",
571 table+1, start*h, end == nx ? "V'''" : "V'=0", (end-1)*h);
573 spline_forces(end-start, h, v+start, TRUE, end == nx, f+start);
576 static void read_tables(FILE *fp, const char *fn,
577 int ntab, int angle, t_tabledata td[])
579 char *libfn;
580 char buf[STRLEN];
581 double **yy = nullptr, start, end, dx0, dx1, ssd, vm, vp, f, numf;
582 int k, i, nx, nx0 = 0, ny, nny, ns;
583 gmx_bool bAllZero, bZeroV, bZeroF;
584 double tabscale;
586 nny = 2*ntab+1;
587 libfn = gmxlibfn(fn);
588 nx = read_xvg(libfn, &yy, &ny);
589 if (ny != nny)
591 gmx_fatal(FARGS, "Trying to read file %s, but nr columns = %d, should be %d",
592 libfn, ny, nny);
594 if (angle == 0)
596 if (yy[0][0] != 0.0)
598 gmx_fatal(FARGS,
599 "The first distance in file %s is %f nm instead of %f nm",
600 libfn, yy[0][0], 0.0);
603 else
605 if (angle == 1)
607 start = 0.0;
609 else
611 start = -180.0;
613 end = 180.0;
614 if (yy[0][0] != start || yy[0][nx-1] != end)
616 gmx_fatal(FARGS, "The angles in file %s should go from %f to %f instead of %f to %f\n",
617 libfn, start, end, yy[0][0], yy[0][nx-1]);
621 tabscale = (nx-1)/(yy[0][nx-1] - yy[0][0]);
623 if (fp)
625 fprintf(fp, "Read user tables from %s with %d data points.\n", libfn, nx);
626 if (angle == 0)
628 fprintf(fp, "Tabscale = %g points/nm\n", tabscale);
632 bAllZero = TRUE;
633 for (k = 0; k < ntab; k++)
635 bZeroV = TRUE;
636 bZeroF = TRUE;
637 for (i = 0; (i < nx); i++)
639 if (i >= 2)
641 dx0 = yy[0][i-1] - yy[0][i-2];
642 dx1 = yy[0][i] - yy[0][i-1];
643 /* Check for 1% deviation in spacing */
644 if (fabs(dx1 - dx0) >= 0.005*(fabs(dx0) + fabs(dx1)))
646 gmx_fatal(FARGS, "In table file '%s' the x values are not equally spaced: %f %f %f", fn, yy[0][i-2], yy[0][i-1], yy[0][i]);
649 if (yy[1+k*2][i] != 0)
651 bZeroV = FALSE;
652 if (bAllZero)
654 bAllZero = FALSE;
655 nx0 = i;
657 if (yy[1+k*2][i] > 0.01*GMX_REAL_MAX ||
658 yy[1+k*2][i] < -0.01*GMX_REAL_MAX)
660 gmx_fatal(FARGS, "Out of range potential value %g in file '%s'",
661 yy[1+k*2][i], fn);
664 if (yy[1+k*2+1][i] != 0)
666 bZeroF = FALSE;
667 if (bAllZero)
669 bAllZero = FALSE;
670 nx0 = i;
672 if (yy[1+k*2+1][i] > 0.01*GMX_REAL_MAX ||
673 yy[1+k*2+1][i] < -0.01*GMX_REAL_MAX)
675 gmx_fatal(FARGS, "Out of range force value %g in file '%s'",
676 yy[1+k*2+1][i], fn);
681 if (!bZeroV && bZeroF)
683 set_forces(fp, angle, nx, 1/tabscale, yy[1+k*2], yy[1+k*2+1], k);
685 else
687 /* Check if the second column is close to minus the numerical
688 * derivative of the first column.
690 ssd = 0;
691 ns = 0;
692 for (i = 1; (i < nx-1); i++)
694 vm = yy[1+2*k][i-1];
695 vp = yy[1+2*k][i+1];
696 f = yy[1+2*k+1][i];
697 if (vm != 0 && vp != 0 && f != 0)
699 /* Take the centered difference */
700 numf = -(vp - vm)*0.5*tabscale;
701 if (f + numf != 0)
703 ssd += fabs(2*(f - numf)/(f + numf));
705 ns++;
708 if (ns > 0)
710 ssd /= ns;
711 sprintf(buf, "For the %d non-zero entries for table %d in %s the forces deviate on average %lld%% from minus the numerical derivative of the potential\n", ns, k, libfn, (long long int)(100*ssd+0.5));
712 if (debug)
714 fprintf(debug, "%s", buf);
716 if (ssd > 0.2)
718 if (fp)
720 fprintf(fp, "\nWARNING: %s\n", buf);
722 fprintf(stderr, "\nWARNING: %s\n", buf);
727 if (bAllZero && fp)
729 fprintf(fp, "\nNOTE: All elements in table %s are zero\n\n", libfn);
732 for (k = 0; (k < ntab); k++)
734 init_table(nx, nx0, tabscale, &(td[k]), TRUE);
735 for (i = 0; (i < nx); i++)
737 td[k].x[i] = yy[0][i];
738 td[k].v[i] = yy[2*k+1][i];
739 td[k].f[i] = yy[2*k+2][i];
742 for (i = 0; (i < ny); i++)
744 sfree(yy[i]);
746 sfree(yy);
747 sfree(libfn);
750 static void done_tabledata(t_tabledata *td)
752 if (!td)
754 return;
757 sfree(td->x);
758 sfree(td->v);
759 sfree(td->f);
762 static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic,
763 gmx_bool b14only)
765 /* Fill the table according to the formulas in the manual.
766 * In principle, we only need the potential and the second
767 * derivative, but then we would have to do lots of calculations
768 * in the inner loop. By precalculating some terms (see manual)
769 * we get better eventual performance, despite a larger table.
771 * Since some of these higher-order terms are very small,
772 * we always use double precision to calculate them here, in order
773 * to avoid unnecessary loss of precision.
775 int i;
776 double reppow, p;
777 double r1, rc, r12, r13;
778 double r, r2, r6, rc2, rc6, rc12;
779 double expr, Vtab, Ftab;
780 /* Parameters for David's function */
781 double A = 0, B = 0, C = 0, A_3 = 0, B_4 = 0;
782 /* Parameters for the switching function */
783 double ksw, swi, swi1;
784 /* Temporary parameters */
785 gmx_bool bPotentialSwitch, bForceSwitch, bPotentialShift;
786 double ewc = ic->ewaldcoeff_q;
787 double ewclj = ic->ewaldcoeff_lj;
788 double Vcut = 0;
790 if (b14only)
792 bPotentialSwitch = FALSE;
793 bForceSwitch = FALSE;
794 bPotentialShift = FALSE;
796 else
798 bPotentialSwitch = ((tp == etabLJ6Switch) || (tp == etabLJ12Switch) ||
799 (tp == etabCOULSwitch) ||
800 (tp == etabEwaldSwitch) || (tp == etabEwaldUserSwitch) ||
801 (tprops[tp].bCoulomb && (ic->coulomb_modifier == eintmodPOTSWITCH)) ||
802 (!tprops[tp].bCoulomb && (ic->vdw_modifier == eintmodPOTSWITCH)));
803 bForceSwitch = ((tp == etabLJ6Shift) || (tp == etabLJ12Shift) ||
804 (tp == etabShift) ||
805 (tprops[tp].bCoulomb && (ic->coulomb_modifier == eintmodFORCESWITCH)) ||
806 (!tprops[tp].bCoulomb && (ic->vdw_modifier == eintmodFORCESWITCH)));
807 bPotentialShift = ((tprops[tp].bCoulomb && (ic->coulomb_modifier == eintmodPOTSHIFT)) ||
808 (!tprops[tp].bCoulomb && (ic->vdw_modifier == eintmodPOTSHIFT)));
811 reppow = ic->reppow;
813 if (tprops[tp].bCoulomb)
815 r1 = ic->rcoulomb_switch;
816 rc = ic->rcoulomb;
818 else
820 r1 = ic->rvdw_switch;
821 rc = ic->rvdw;
823 if (bPotentialSwitch)
825 ksw = 1.0/(gmx::power5(rc-r1));
827 else
829 ksw = 0.0;
831 if (bForceSwitch)
833 if (tp == etabShift)
835 p = 1;
837 else if (tp == etabLJ6Shift)
839 p = 6;
841 else
843 p = reppow;
846 A = p * ((p+1)*r1-(p+4)*rc)/(std::pow(rc, p+2)*gmx::square(rc-r1));
847 B = -p * ((p+1)*r1-(p+3)*rc)/(std::pow(rc, p+2)*gmx::power3(rc-r1));
848 C = 1.0/std::pow(rc, p)-A/3.0*gmx::power3(rc-r1)-B/4.0*gmx::power4(rc-r1);
849 if (tp == etabLJ6Shift)
851 A = -A;
852 B = -B;
853 C = -C;
855 A_3 = A/3.0;
856 B_4 = B/4.0;
858 if (debug)
860 fprintf(debug, "Setting up tables\n"); fflush(debug);
863 if (bPotentialShift)
865 rc2 = rc*rc;
866 rc6 = 1.0/(rc2*rc2*rc2);
867 if (gmx_within_tol(reppow, 12.0, 10*GMX_DOUBLE_EPS))
869 rc12 = rc6*rc6;
871 else
873 rc12 = std::pow(rc, -reppow);
876 switch (tp)
878 case etabLJ6:
879 /* Dispersion */
880 Vcut = -rc6;
881 break;
882 case etabLJ6Ewald:
883 Vcut = -rc6*exp(-ewclj*ewclj*rc2)*(1 + ewclj*ewclj*rc2 + gmx::power4(ewclj)*rc2*rc2/2);
884 break;
885 case etabLJ12:
886 /* Repulsion */
887 Vcut = rc12;
888 break;
889 case etabCOUL:
890 Vcut = 1.0/rc;
891 break;
892 case etabEwald:
893 case etabEwaldSwitch:
894 Vcut = std::erfc(ewc*rc)/rc;
895 break;
896 case etabEwaldUser:
897 /* Only calculate minus the reciprocal space contribution */
898 Vcut = -std::erf(ewc*rc)/rc;
899 break;
900 case etabRF:
901 case etabRF_ZERO:
902 /* No need for preventing the usage of modifiers with RF */
903 Vcut = 0.0;
904 break;
905 case etabEXPMIN:
906 Vcut = exp(-rc);
907 break;
908 default:
909 gmx_fatal(FARGS, "Cannot apply new potential-shift modifier to interaction type '%s' yet. (%s,%d)",
910 tprops[tp].name, __FILE__, __LINE__);
914 for (i = 0; (i < td->nx); i++)
916 td->x[i] = i/td->tabscale;
918 for (i = td->nx0; (i < td->nx); i++)
920 r = td->x[i];
921 r2 = r*r;
922 r6 = 1.0/(r2*r2*r2);
923 if (gmx_within_tol(reppow, 12.0, 10*GMX_DOUBLE_EPS))
925 r12 = r6*r6;
927 else
929 r12 = std::pow(r, -reppow);
931 Vtab = 0.0;
932 Ftab = 0.0;
933 if (bPotentialSwitch)
935 /* swi is function, swi1 1st derivative and swi2 2nd derivative */
936 /* The switch function is 1 for r<r1, 0 for r>rc, and smooth for
937 * r1<=r<=rc. The 1st and 2nd derivatives are both zero at
938 * r1 and rc.
939 * ksw is just the constant 1/(rc-r1)^5, to save some calculations...
941 if (r <= r1)
943 swi = 1.0;
944 swi1 = 0.0;
946 else if (r >= rc)
948 swi = 0.0;
949 swi1 = 0.0;
951 else
953 swi = 1 - 10*gmx::power3(r-r1)*ksw*gmx::square(rc-r1)
954 + 15*gmx::power4(r-r1)*ksw*(rc-r1) - 6*gmx::power5(r-r1)*ksw;
955 swi1 = -30*gmx::square(r-r1)*ksw*gmx::square(rc-r1)
956 + 60*gmx::power3(r-r1)*ksw*(rc-r1) - 30*gmx::power4(r-r1)*ksw;
959 else /* not really needed, but avoids compiler warnings... */
961 swi = 1.0;
962 swi1 = 0.0;
965 rc6 = rc*rc*rc;
966 rc6 = 1.0/(rc6*rc6);
968 switch (tp)
970 case etabLJ6:
971 /* Dispersion */
972 Vtab = -r6;
973 Ftab = 6.0*Vtab/r;
974 break;
975 case etabLJ6Switch:
976 case etabLJ6Shift:
977 /* Dispersion */
978 if (r < rc)
980 Vtab = -r6;
981 Ftab = 6.0*Vtab/r;
982 break;
984 break;
985 case etabLJ12:
986 /* Repulsion */
987 Vtab = r12;
988 Ftab = reppow*Vtab/r;
989 break;
990 case etabLJ12Switch:
991 case etabLJ12Shift:
992 /* Repulsion */
993 if (r < rc)
995 Vtab = r12;
996 Ftab = reppow*Vtab/r;
998 break;
999 case etabLJ6Encad:
1000 if (r < rc)
1002 Vtab = -(r6-6.0*(rc-r)*rc6/rc-rc6);
1003 Ftab = -(6.0*r6/r-6.0*rc6/rc);
1005 else /* r>rc */
1007 Vtab = 0;
1008 Ftab = 0;
1010 break;
1011 case etabLJ12Encad:
1012 if (r < rc)
1014 Vtab = -(r6-6.0*(rc-r)*rc6/rc-rc6);
1015 Ftab = -(6.0*r6/r-6.0*rc6/rc);
1017 else /* r>rc */
1019 Vtab = 0;
1020 Ftab = 0;
1022 break;
1023 case etabCOUL:
1024 Vtab = 1.0/r;
1025 Ftab = 1.0/r2;
1026 break;
1027 case etabCOULSwitch:
1028 case etabShift:
1029 if (r < rc)
1031 Vtab = 1.0/r;
1032 Ftab = 1.0/r2;
1034 break;
1035 case etabEwald:
1036 case etabEwaldSwitch:
1037 Vtab = std::erfc(ewc*r)/r;
1038 Ftab = std::erfc(ewc*r)/r2+exp(-(ewc*ewc*r2))*ewc*M_2_SQRTPI/r;
1039 break;
1040 case etabEwaldUser:
1041 case etabEwaldUserSwitch:
1042 /* Only calculate the negative of the reciprocal space contribution */
1043 Vtab = -std::erf(ewc*r)/r;
1044 Ftab = -std::erf(ewc*r)/r2+exp(-(ewc*ewc*r2))*ewc*M_2_SQRTPI/r;
1045 break;
1046 case etabLJ6Ewald:
1047 Vtab = -r6*exp(-ewclj*ewclj*r2)*(1 + ewclj*ewclj*r2 + gmx::power4(ewclj)*r2*r2/2);
1048 Ftab = 6.0*Vtab/r - r6*exp(-ewclj*ewclj*r2)*gmx::power5(ewclj)*ewclj*r2*r2*r;
1049 break;
1050 case etabRF:
1051 case etabRF_ZERO:
1052 Vtab = 1.0/r + ic->k_rf*r2 - ic->c_rf;
1053 Ftab = 1.0/r2 - 2*ic->k_rf*r;
1054 if (tp == etabRF_ZERO && r >= rc)
1056 Vtab = 0;
1057 Ftab = 0;
1059 break;
1060 case etabEXPMIN:
1061 expr = exp(-r);
1062 Vtab = expr;
1063 Ftab = expr;
1064 break;
1065 case etabCOULEncad:
1066 if (r < rc)
1068 Vtab = 1.0/r-(rc-r)/(rc*rc)-1.0/rc;
1069 Ftab = 1.0/r2-1.0/(rc*rc);
1071 else /* r>rc */
1073 Vtab = 0;
1074 Ftab = 0;
1076 break;
1077 default:
1078 gmx_fatal(FARGS, "Table type %d not implemented yet. (%s,%d)",
1079 tp, __FILE__, __LINE__);
1081 if (bForceSwitch)
1083 /* Normal coulomb with cut-off correction for potential */
1084 if (r < rc)
1086 Vtab -= C;
1087 /* If in Shifting range add something to it */
1088 if (r > r1)
1090 r12 = (r-r1)*(r-r1);
1091 r13 = (r-r1)*r12;
1092 Vtab += -A_3*r13 - B_4*r12*r12;
1093 Ftab += A*r12 + B*r13;
1096 else
1098 /* Make sure interactions are zero outside cutoff with modifiers */
1099 Vtab = 0;
1100 Ftab = 0;
1103 if (bPotentialShift)
1105 if (r < rc)
1107 Vtab -= Vcut;
1109 else
1111 /* Make sure interactions are zero outside cutoff with modifiers */
1112 Vtab = 0;
1113 Ftab = 0;
1117 if (ETAB_USER(tp))
1119 Vtab += td->v[i];
1120 Ftab += td->f[i];
1123 if (bPotentialSwitch)
1125 if (r >= rc)
1127 /* Make sure interactions are zero outside cutoff with modifiers */
1128 Vtab = 0;
1129 Ftab = 0;
1131 else if (r > r1)
1133 Ftab = Ftab*swi - Vtab*swi1;
1134 Vtab = Vtab*swi;
1137 /* Convert to single precision when we store to mem */
1138 td->v[i] = Vtab;
1139 td->f[i] = Ftab;
1142 /* Continue the table linearly from nx0 to 0.
1143 * These values are only required for energy minimization with overlap or TPI.
1145 for (i = td->nx0-1; i >= 0; i--)
1147 td->v[i] = td->v[i+1] + td->f[i+1]*(td->x[i+1] - td->x[i]);
1148 td->f[i] = td->f[i+1];
1152 static void set_table_type(int tabsel[], const interaction_const_t *ic, gmx_bool b14only)
1154 int eltype, vdwtype;
1156 /* Set the different table indices.
1157 * Coulomb first.
1161 if (b14only)
1163 switch (ic->eeltype)
1165 case eelUSER:
1166 case eelPMEUSER:
1167 case eelPMEUSERSWITCH:
1168 eltype = eelUSER;
1169 break;
1170 default:
1171 eltype = eelCUT;
1174 else
1176 eltype = ic->eeltype;
1179 switch (eltype)
1181 case eelCUT:
1182 tabsel[etiCOUL] = etabCOUL;
1183 break;
1184 case eelPOISSON:
1185 tabsel[etiCOUL] = etabShift;
1186 break;
1187 case eelSHIFT:
1188 if (ic->rcoulomb > ic->rcoulomb_switch)
1190 tabsel[etiCOUL] = etabShift;
1192 else
1194 tabsel[etiCOUL] = etabCOUL;
1196 break;
1197 case eelEWALD:
1198 case eelPME:
1199 case eelP3M_AD:
1200 tabsel[etiCOUL] = etabEwald;
1201 break;
1202 case eelPMESWITCH:
1203 tabsel[etiCOUL] = etabEwaldSwitch;
1204 break;
1205 case eelPMEUSER:
1206 tabsel[etiCOUL] = etabEwaldUser;
1207 break;
1208 case eelPMEUSERSWITCH:
1209 tabsel[etiCOUL] = etabEwaldUserSwitch;
1210 break;
1211 case eelRF:
1212 case eelGRF:
1213 case eelRF_ZERO:
1214 tabsel[etiCOUL] = etabRF_ZERO;
1215 break;
1216 case eelSWITCH:
1217 tabsel[etiCOUL] = etabCOULSwitch;
1218 break;
1219 case eelUSER:
1220 tabsel[etiCOUL] = etabUSER;
1221 break;
1222 case eelENCADSHIFT:
1223 tabsel[etiCOUL] = etabCOULEncad;
1224 break;
1225 default:
1226 gmx_fatal(FARGS, "Invalid eeltype %d", eltype);
1229 /* Van der Waals time */
1230 if (ic->useBuckingham && !b14only)
1232 tabsel[etiLJ6] = etabLJ6;
1233 tabsel[etiLJ12] = etabEXPMIN;
1235 else
1237 if (b14only && ic->vdwtype != evdwUSER)
1239 vdwtype = evdwCUT;
1241 else
1243 vdwtype = ic->vdwtype;
1246 switch (vdwtype)
1248 case evdwSWITCH:
1249 tabsel[etiLJ6] = etabLJ6Switch;
1250 tabsel[etiLJ12] = etabLJ12Switch;
1251 break;
1252 case evdwSHIFT:
1253 tabsel[etiLJ6] = etabLJ6Shift;
1254 tabsel[etiLJ12] = etabLJ12Shift;
1255 break;
1256 case evdwUSER:
1257 tabsel[etiLJ6] = etabUSER;
1258 tabsel[etiLJ12] = etabUSER;
1259 break;
1260 case evdwCUT:
1261 tabsel[etiLJ6] = etabLJ6;
1262 tabsel[etiLJ12] = etabLJ12;
1263 break;
1264 case evdwENCADSHIFT:
1265 tabsel[etiLJ6] = etabLJ6Encad;
1266 tabsel[etiLJ12] = etabLJ12Encad;
1267 break;
1268 case evdwPME:
1269 tabsel[etiLJ6] = etabLJ6Ewald;
1270 tabsel[etiLJ12] = etabLJ12;
1271 break;
1272 default:
1273 gmx_fatal(FARGS, "Invalid vdwtype %d in %s line %d", vdwtype,
1274 __FILE__, __LINE__);
1277 if (!b14only && ic->vdw_modifier != eintmodNONE)
1279 if (ic->vdw_modifier != eintmodPOTSHIFT &&
1280 ic->vdwtype != evdwCUT)
1282 gmx_incons("Potential modifiers other than potential-shift are only implemented for LJ cut-off");
1285 /* LJ-PME and other (shift-only) modifiers are handled by applying the modifiers
1286 * to the original interaction forms when we fill the table, so we only check cutoffs here.
1288 if (ic->vdwtype == evdwCUT)
1290 switch (ic->vdw_modifier)
1292 case eintmodNONE:
1293 case eintmodPOTSHIFT:
1294 case eintmodEXACTCUTOFF:
1295 /* No modification */
1296 break;
1297 case eintmodPOTSWITCH:
1298 tabsel[etiLJ6] = etabLJ6Switch;
1299 tabsel[etiLJ12] = etabLJ12Switch;
1300 break;
1301 case eintmodFORCESWITCH:
1302 tabsel[etiLJ6] = etabLJ6Shift;
1303 tabsel[etiLJ12] = etabLJ12Shift;
1304 break;
1305 default:
1306 gmx_incons("Unsupported vdw_modifier");
1313 t_forcetable *make_tables(FILE *out,
1314 const interaction_const_t *ic,
1315 const char *fn,
1316 real rtab, int flags)
1318 t_tabledata *td;
1319 gmx_bool b14only, useUserTable;
1320 int nx0, tabsel[etiNR];
1321 real scalefactor;
1323 t_forcetable *table;
1325 snew(table, 1);
1326 b14only = (flags & GMX_MAKETABLES_14ONLY);
1328 if (flags & GMX_MAKETABLES_FORCEUSER)
1330 tabsel[etiCOUL] = etabUSER;
1331 tabsel[etiLJ6] = etabUSER;
1332 tabsel[etiLJ12] = etabUSER;
1334 else
1336 set_table_type(tabsel, ic, b14only);
1338 snew(td, etiNR);
1339 table->r = rtab;
1340 table->scale = 0;
1341 table->n = 0;
1343 table->interaction = GMX_TABLE_INTERACTION_ELEC_VDWREP_VDWDISP;
1344 table->format = GMX_TABLE_FORMAT_CUBICSPLINE_YFGH;
1345 table->formatsize = 4;
1346 table->ninteractions = etiNR;
1347 table->stride = table->formatsize*table->ninteractions;
1349 /* Check whether we have to read or generate */
1350 useUserTable = FALSE;
1351 for (unsigned int i = 0; (i < etiNR); i++)
1353 if (ETAB_USER(tabsel[i]))
1355 useUserTable = TRUE;
1358 if (useUserTable)
1360 read_tables(out, fn, etiNR, 0, td);
1361 if (rtab == 0 || (flags & GMX_MAKETABLES_14ONLY))
1363 table->n = td[0].nx;
1365 else
1367 if (td[0].x[td[0].nx-1] < rtab)
1369 gmx_fatal(FARGS, "Tables in file %s not long enough for cut-off:\n"
1370 "\tshould be at least %f nm\n", fn, rtab);
1372 table->n = (int)(rtab*td[0].tabscale + 0.5);
1374 table->scale = td[0].tabscale;
1375 nx0 = td[0].nx0;
1377 else
1379 // No tables are read
1380 #if GMX_DOUBLE
1381 table->scale = 2000.0;
1382 #else
1383 table->scale = 500.0;
1384 #endif
1385 table->n = static_cast<int>(rtab*table->scale);
1386 nx0 = 10;
1389 /* Each table type (e.g. coul,lj6,lj12) requires four
1390 * numbers per table->n+1 data points. For performance reasons we want
1391 * the table data to be aligned to a 32-byte boundary.
1393 snew_aligned(table->data, table->stride*(table->n+1)*sizeof(real), 32);
1395 for (int k = 0; (k < etiNR); k++)
1397 /* Now fill data for tables that have not been read
1398 * or add the Ewald long-range correction for Ewald user tables.
1400 if (tabsel[k] != etabUSER)
1402 real scale = table->scale;
1403 if (ic->useBuckingham &&
1404 (ic->buckinghamBMax != 0) &&
1405 tabsel[k] == etabEXPMIN)
1407 scale /= ic->buckinghamBMax;
1409 init_table(table->n, nx0, scale, &(td[k]), !useUserTable);
1411 fill_table(&(td[k]), tabsel[k], ic, b14only);
1412 if (out)
1414 fprintf(out, "Generated table with %d data points for %s%s.\n"
1415 "Tabscale = %g points/nm\n",
1416 td[k].nx, b14only ? "1-4 " : "", tprops[tabsel[k]].name,
1417 td[k].tabscale);
1421 /* Set scalefactor for c6/c12 tables. This is because we save flops in the non-table kernels
1422 * by including the derivative constants (6.0 or 12.0) in the parameters, since
1423 * we no longer calculate force in most steps. This means the c6/c12 parameters
1424 * have been scaled up, so we need to scale down the table interactions too.
1425 * It comes here since we need to scale user tables too.
1427 if (k == etiLJ6)
1429 scalefactor = 1.0/6.0;
1431 else if (k == etiLJ12 && tabsel[k] != etabEXPMIN)
1433 scalefactor = 1.0/12.0;
1435 else
1437 scalefactor = 1.0;
1440 copy2table(table->n, k*table->formatsize, table->stride, td[k].x, td[k].v, td[k].f, scalefactor, table->data);
1442 done_tabledata(&(td[k]));
1444 sfree(td);
1446 return table;
1449 t_forcetable *make_gb_table(const t_forcerec *fr)
1451 t_tabledata *td;
1452 int nx0;
1453 double r, r2, Vtab, Ftab, expterm;
1455 t_forcetable *table;
1457 /* Set the table dimensions for GB, not really necessary to
1458 * use etiNR (since we only have one table, but ...)
1460 snew(table, 1);
1461 snew(td, 1);
1462 table->interaction = GMX_TABLE_INTERACTION_ELEC;
1463 table->format = GMX_TABLE_FORMAT_CUBICSPLINE_YFGH;
1464 table->r = fr->gbtabr;
1465 table->scale = fr->gbtabscale;
1466 table->n = static_cast<int>(table->scale*table->r);
1467 table->formatsize = 4;
1468 table->ninteractions = 1;
1469 table->stride = table->formatsize*table->ninteractions;
1470 nx0 = 0;
1472 /* Each table type (e.g. coul,lj6,lj12) requires four numbers per
1473 * datapoint. For performance reasons we want the table data to be
1474 * aligned on a 32-byte boundary. This new pointer must not be
1475 * used in a free() call, but thankfully we're sloppy enough not
1476 * to do this :-)
1479 snew_aligned(table->data, table->stride*table->n, 32);
1481 init_table(table->n, nx0, table->scale, &(td[0]), TRUE);
1483 /* Local implementation so we don't have to use the etabGB
1484 * enum above, which will cause problems later when
1485 * making the other tables (right now even though we are using
1486 * GB, the normal Coulomb tables will be created, but this
1487 * will cause a problem since fr->eeltype==etabGB which will not
1488 * be defined in fill_table and set_table_type
1491 for (int i = nx0; i < table->n; i++)
1493 r = td->x[i];
1494 r2 = r*r;
1495 expterm = exp(-0.25*r2);
1497 Vtab = 1/sqrt(r2+expterm);
1498 Ftab = (r-0.25*r*expterm)/((r2+expterm)*sqrt(r2+expterm));
1500 /* Convert to single precision when we store to mem */
1501 td->x[i] = i/table->scale;
1502 td->v[i] = Vtab;
1503 td->f[i] = Ftab;
1507 copy2table(table->n, 0, table->stride, td[0].x, td[0].v, td[0].f, 1.0, table->data);
1509 done_tabledata(&(td[0]));
1510 sfree(td);
1512 return table;
1517 bondedtable_t make_bonded_table(FILE *fplog, const char *fn, int angle)
1519 t_tabledata td;
1520 int i;
1521 bondedtable_t tab;
1522 int stride = 4;
1524 read_tables(fplog, fn, 1, angle, &td);
1525 if (angle > 0)
1527 /* Convert the table from degrees to radians */
1528 for (i = 0; i < td.nx; i++)
1530 td.x[i] *= DEG2RAD;
1531 td.f[i] *= RAD2DEG;
1533 td.tabscale *= RAD2DEG;
1535 tab.n = td.nx;
1536 tab.scale = td.tabscale;
1537 snew(tab.data, tab.n*stride);
1538 copy2table(tab.n, 0, stride, td.x, td.v, td.f, 1.0, tab.data);
1539 done_tabledata(&td);
1541 return tab;
1544 t_forcetable *makeDispersionCorrectionTable(FILE *fp,
1545 const interaction_const_t *ic,
1546 real rtab,
1547 const char *tabfn)
1549 t_forcetable *dispersionCorrectionTable = nullptr;
1551 if (tabfn == nullptr)
1553 if (debug)
1555 fprintf(debug, "No table file name passed, can not read table, can not do non-bonded interactions\n");
1557 return dispersionCorrectionTable;
1560 t_forcetable *fullTable = make_tables(fp, ic, tabfn, rtab, 0);
1561 /* Copy the contents of the table to one that has just dispersion
1562 * and repulsion, to improve cache performance. We want the table
1563 * data to be aligned to 32-byte boundaries. The pointers could be
1564 * freed but currently aren't. */
1565 snew(dispersionCorrectionTable, 1);
1566 dispersionCorrectionTable->interaction = GMX_TABLE_INTERACTION_VDWREP_VDWDISP;
1567 dispersionCorrectionTable->format = fullTable->format;
1568 dispersionCorrectionTable->r = fullTable->r;
1569 dispersionCorrectionTable->n = fullTable->n;
1570 dispersionCorrectionTable->scale = fullTable->scale;
1571 dispersionCorrectionTable->formatsize = fullTable->formatsize;
1572 dispersionCorrectionTable->ninteractions = 2;
1573 dispersionCorrectionTable->stride = dispersionCorrectionTable->formatsize * dispersionCorrectionTable->ninteractions;
1574 snew_aligned(dispersionCorrectionTable->data, dispersionCorrectionTable->stride*(dispersionCorrectionTable->n+1), 32);
1576 for (int i = 0; i <= fullTable->n; i++)
1578 for (int j = 0; j < 8; j++)
1580 dispersionCorrectionTable->data[8*i+j] = fullTable->data[12*i+4+j];
1583 sfree_aligned(fullTable->data);
1584 sfree(fullTable);
1586 return dispersionCorrectionTable;