3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * GROwing Monsters And Cloning Shrimps
44 #include "gmx_fatal.h"
54 /* All the possible (implemented) table functions */
84 /* This structure holds name and a flag that tells whether
85 this is a Coulomb type funtion */
86 static const t_tab_props tprops
[etabNR
] = {
89 { "LJ6Shift", FALSE
},
90 { "LJ12Shift", FALSE
},
96 { "Ewald-Switch", TRUE
},
97 { "Ewald-User", TRUE
},
98 { "Ewald-User-Switch", TRUE
},
99 { "LJ6Switch", FALSE
},
100 { "LJ12Switch", FALSE
},
101 { "COULSwitch", TRUE
},
102 { "LJ6-Encad shift", FALSE
},
103 { "LJ12-Encad shift", FALSE
},
104 { "COUL-Encad shift", TRUE
},
109 /* Index in the table that says which function to use */
110 enum { etiCOUL
, etiLJ6
, etiLJ12
, etiNR
};
118 #define pow2(x) ((x)*(x))
119 #define pow3(x) ((x)*(x)*(x))
120 #define pow4(x) ((x)*(x)*(x)*(x))
121 #define pow5(x) ((x)*(x)*(x)*(x)*(x))
123 /* Calculate the potential and force for an r value
124 * in exactly the same way it is done in the inner loop.
125 * VFtab is a pointer to the table data, offset is
126 * the point where we should begin and stride is
127 * 4 if we have a buckingham table, 3 otherwise.
128 * If you want to evaluate table no N, set offset to 4*N.
130 * We use normal precision here, since that is what we
131 * will use in the inner loops.
133 static void evaluate_table(real VFtab
[], int offset
, int stride
,
134 real tabscale
, real r
, real
*y
, real
*yp
)
138 real Y
,F
,Geps
,Heps2
,Fp
;
147 Geps
= eps
*VFtab
[n
+2];
148 Heps2
= eps2
*VFtab
[n
+3];
151 *yp
= (Fp
+Geps
+2.0*Heps2
)*tabscale
;
155 static void splint(real xa
[],real ya
[],real y2a
[],
156 int n
,real x
,real
*y
,real
*yp
)
165 while ((khi
-klo
) > 1) {
174 gmx_fatal(FARGS
,"Bad XA input to function splint");
177 *y
= a
*ya
[klo
]+b
*ya
[khi
]+((a
*a
*a
-a
)*y2a
[klo
]+(b
*b
*b
-b
)*y2a
[khi
])*(h
*h
)/6.0;
178 *yp
= (ya
[khi
]-ya
[klo
])/h
+((3*a
*a
-1)*y2a
[klo
]-(3*b
*b
-1)*y2a
[khi
])*h
/6.0;
181 F
= (ya
[khi
]-ya
[klo
]-(h
*h
/6.0)*(2*y2a
[klo
]+y2a
[khi
]));
182 G
= (h
*h
/2.0)*y2a
[klo
];
183 H
= (h
*h
/6.0)*(y2a
[khi
]-y2a
[klo
]);
184 *y
= ya
[klo
] + eps
*F
+ eps
*eps
*G
+ eps
*eps
*eps
*H
;
185 *yp
= (F
+ 2*eps
*G
+ 3*eps
*eps
*H
)/h
;
189 static void copy2table(int n
,int offset
,int stride
,
190 double x
[],double Vtab
[],double Ftab
[],
193 /* Use double prec. for the intermediary variables
194 * and temporary x/vtab/vtab2 data to avoid unnecessary
201 for(i
=0; (i
<n
); i
++) {
205 G
= 3*(Vtab
[i
+1] - Vtab
[i
]) + (Ftab
[i
+1] + 2*Ftab
[i
])*h
;
206 H
= -2*(Vtab
[i
+1] - Vtab
[i
]) - (Ftab
[i
+1] + Ftab
[i
])*h
;
208 /* Fill the last entry with a linear potential,
209 * this is mainly for rounding issues with angle and dihedral potentials.
215 nn0
= offset
+ i
*stride
;
223 static void init_table(FILE *fp
,int n
,int nx0
,
224 double tabscale
,t_tabledata
*td
,bool bAlloc
)
230 td
->tabscale
= tabscale
;
236 for(i
=td
->nx0
; (i
<td
->nx
); i
++)
237 td
->x
[i
] = i
/tabscale
;
240 static void spline_forces(int nx
,double h
,double v
[],bool bS3
,bool bE3
,
247 /* Formulas can be found in:
248 * H.J.C. Berendsen, Simulating the Physical World, Cambridge 2007
251 if (nx
< 4 && (bS3
|| bE3
))
252 gmx_fatal(FARGS
,"Can not generate splines with third derivative boundary conditions with less than 4 (%d) points",nx
);
254 /* To make life easy we initially set the spacing to 1
255 * and correct for this at the end.
259 /* Fit V''' at the start */
260 v3
= v
[3] - 3*v
[2] + 3*v
[1] - v
[0];
262 fprintf(debug
,"The left third derivative is %g\n",v3
/(h
*h
*h
));
263 b_s
= 2*(v
[1] - v
[0]) + v3
/6;
267 /* Fit V'' at the start */
270 v2
= -v
[3] + 4*v
[2] - 5*v
[1] + 2*v
[0];
271 /* v2 = v[2] - 2*v[1] + v[0]; */
273 fprintf(debug
,"The left second derivative is %g\n",v2
/(h
*h
));
274 b_s
= 3*(v
[1] - v
[0]) - v2
/2;
278 b_s
= 3*(v
[2] - v
[0]) + f
[0]*h
;
282 /* Fit V''' at the end */
283 v3
= v
[nx
-1] - 3*v
[nx
-2] + 3*v
[nx
-3] - v
[nx
-4];
285 fprintf(debug
,"The right third derivative is %g\n",v3
/(h
*h
*h
));
286 b_e
= 2*(v
[nx
-1] - v
[nx
-2]) + v3
/6;
289 /* V'=0 at the end */
290 b_e
= 3*(v
[nx
-1] - v
[nx
-3]) + f
[nx
-1]*h
;
295 beta
= (bS3
? 1 : 4);
297 /* For V'' fitting */
298 /* beta = (bS3 ? 2 : 4); */
301 for(i
=start
+1; i
<end
; i
++) {
304 b
= 3*(v
[i
+1] - v
[i
-1]);
305 f
[i
] = (b
- f
[i
-1])/beta
;
307 gamma
[end
-1] = 1/beta
;
308 beta
= (bE3
? 1 : 4) - gamma
[end
-1];
309 f
[end
-1] = (b_e
- f
[end
-2])/beta
;
311 for(i
=end
-2; i
>=start
; i
--)
312 f
[i
] -= gamma
[i
+1]*f
[i
+1];
315 /* Correct for the minus sign and the spacing */
316 for(i
=start
; i
<end
; i
++)
320 static void set_forces(FILE *fp
,int angle
,
321 int nx
,double h
,double v
[],double f
[],
328 "Force generation for dihedral tables is not (yet) implemented");
331 while (v
[start
] == 0)
343 fprintf(fp
,"Generating forces for table %d, boundary conditions: V''' at %g, %s at %g\n",
344 table
+1,start
*h
,end
==nx
? "V'''" : "V'=0",(end
-1)*h
);
345 spline_forces(end
-start
,h
,v
+start
,TRUE
,end
==nx
,f
+start
);
348 static void read_tables(FILE *fp
,const char *fn
,
349 int ntab
,int angle
,t_tabledata td
[])
353 double **yy
=NULL
,start
,end
,dx0
,dx1
,ssd
,vm
,vp
,f
,numf
;
354 int k
,i
,nx
,nx0
=0,ny
,nny
,ns
;
355 bool bAllZero
,bZeroV
,bZeroF
;
359 libfn
= gmxlibfn(fn
);
360 nx
= read_xvg(libfn
,&yy
,&ny
);
362 gmx_fatal(FARGS
,"Trying to read file %s, but nr columns = %d, should be %d",
367 "The first distance in file %s is %f nm instead of %f nm",
375 if (yy
[0][0] != start
|| yy
[0][nx
-1] != end
)
376 gmx_fatal(FARGS
,"The angles in file %s should go from %f to %f instead of %f to %f\n",
377 libfn
,start
,end
,yy
[0][0],yy
[0][nx
-1]);
380 tabscale
= (nx
-1)/(yy
[0][nx
-1] - yy
[0][0]);
383 fprintf(fp
,"Read user tables from %s with %d data points.\n",libfn
,nx
);
385 fprintf(fp
,"Tabscale = %g points/nm\n",tabscale
);
389 for(k
=0; k
<ntab
; k
++) {
392 for(i
=0; (i
< nx
); i
++) {
394 dx0
= yy
[0][i
-1] - yy
[0][i
-2];
395 dx1
= yy
[0][i
] - yy
[0][i
-1];
396 /* Check for 1% deviation in spacing */
397 if (fabs(dx1
- dx0
) >= 0.005*(fabs(dx0
) + fabs(dx1
))) {
398 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
]);
401 if (yy
[1+k
*2][i
] != 0) {
407 if (yy
[1+k
*2][i
] > 0.01*GMX_REAL_MAX
||
408 yy
[1+k
*2][i
] < -0.01*GMX_REAL_MAX
) {
409 gmx_fatal(FARGS
,"Out of range potential value %g in file '%s'",
413 if (yy
[1+k
*2+1][i
] != 0) {
419 if (yy
[1+k
*2+1][i
] > 0.01*GMX_REAL_MAX
||
420 yy
[1+k
*2+1][i
] < -0.01*GMX_REAL_MAX
) {
421 gmx_fatal(FARGS
,"Out of range force value %g in file '%s'",
427 if (!bZeroV
&& bZeroF
) {
428 set_forces(fp
,angle
,nx
,1/tabscale
,yy
[1+k
*2],yy
[1+k
*2+1],k
);
430 /* Check if the second column is close to minus the numerical
431 * derivative of the first column.
435 for(i
=1; (i
< nx
-1); i
++) {
439 if (vm
!= 0 && vp
!= 0 && f
!= 0) {
440 /* Take the centered difference */
441 numf
= -(vp
- vm
)*0.5*tabscale
;
442 ssd
+= fabs(2*(f
- numf
)/(f
+ numf
));
448 sprintf(buf
,"For the %d non-zero entries for table %d in %s the forces deviate on average %d%% from minus the numerical derivative of the potential\n",ns
,k
,libfn
,(int)(100*ssd
+0.5));
450 fprintf(debug
,"%s",buf
);
453 fprintf(fp
,"\nWARNING: %s\n",buf
);
454 fprintf(stderr
,"\nWARNING: %s\n",buf
);
459 if (bAllZero
&& fp
) {
460 fprintf(fp
,"\nNOTE: All elements in table %s are zero\n\n",libfn
);
463 for(k
=0; (k
<ntab
); k
++) {
464 init_table(fp
,nx
,nx0
,tabscale
,&(td
[k
]),TRUE
);
465 for(i
=0; (i
<nx
); i
++) {
466 td
[k
].x
[i
] = yy
[0][i
];
467 td
[k
].v
[i
] = yy
[2*k
+1][i
];
468 td
[k
].f
[i
] = yy
[2*k
+2][i
];
471 for(i
=0; (i
<ny
); i
++)
477 static void done_tabledata(t_tabledata
*td
)
489 static void fill_table(t_tabledata
*td
,int tp
,const t_forcerec
*fr
)
491 /* Fill the table according to the formulas in the manual.
492 * In principle, we only need the potential and the second
493 * derivative, but then we would have to do lots of calculations
494 * in the inner loop. By precalculating some terms (see manual)
495 * we get better eventual performance, despite a larger table.
497 * Since some of these higher-order terms are very small,
498 * we always use double precision to calculate them here, in order
499 * to avoid unnecessary loss of precision.
506 double r1
,rc
,r12
,r13
;
508 double expr
,Vtab
,Ftab
;
509 /* Parameters for David's function */
510 double A
=0,B
=0,C
=0,A_3
=0,B_4
=0;
511 /* Parameters for the switching function */
513 /* Temporary parameters */
515 double ewc
=fr
->ewaldcoeff
;
516 double isp
= 0.564189583547756;
518 bSwitch
= ((tp
== etabLJ6Switch
) || (tp
== etabLJ12Switch
) ||
519 (tp
== etabCOULSwitch
) ||
520 (tp
== etabEwaldSwitch
) || (tp
== etabEwaldUserSwitch
));
521 bShift
= ((tp
== etabLJ6Shift
) || (tp
== etabLJ12Shift
) ||
526 if (tprops
[tp
].bCoulomb
) {
527 r1
= fr
->rcoulomb_switch
;
531 r1
= fr
->rvdw_switch
;
535 ksw
= 1.0/(pow5(rc
-r1
));
541 else if (tp
== etabLJ6Shift
)
546 A
= p
* ((p
+1)*r1
-(p
+4)*rc
)/(pow(rc
,p
+2)*pow2(rc
-r1
));
547 B
= -p
* ((p
+1)*r1
-(p
+3)*rc
)/(pow(rc
,p
+2)*pow3(rc
-r1
));
548 C
= 1.0/pow(rc
,p
)-A
/3.0*pow3(rc
-r1
)-B
/4.0*pow4(rc
-r1
);
549 if (tp
== etabLJ6Shift
) {
557 if (debug
) { fprintf(debug
,"Setting up tables\n"); fflush(debug
); }
560 fp
=xvgropen("switch.xvg","switch","r","s");
563 for(i
=td
->nx0
; (i
<td
->nx
); i
++) {
571 /* swi is function, swi1 1st derivative and swi2 2nd derivative */
572 /* The switch function is 1 for r<r1, 0 for r>rc, and smooth for
573 * r1<=r<=rc. The 1st and 2nd derivatives are both zero at
575 * ksw is just the constant 1/(rc-r1)^5, to save some calculations...
584 swi
= 1 - 10*pow3(r
-r1
)*ksw
*pow2(rc
-r1
)
585 + 15*pow4(r
-r1
)*ksw
*(rc
-r1
) - 6*pow5(r
-r1
)*ksw
;
586 swi1
= -30*pow2(r
-r1
)*ksw
*pow2(rc
-r1
)
587 + 60*pow3(r
-r1
)*ksw
*(rc
-r1
) - 30*pow4(r
-r1
)*ksw
;
590 else { /* not really needed, but avoids compiler warnings... */
595 fprintf(fp
,"%10g %10g %10g %10g\n",r
,swi
,swi1
,swi2
);
618 Ftab
= reppow
*Vtab
/r
;
625 Ftab
= reppow
*Vtab
/r
;
630 Vtab
= -(r6
-6.0*(rc
-r
)*rc6
/rc
-rc6
);
631 Ftab
= -(6.0*r6
/r
-6.0*rc6
/rc
);
639 Vtab
= r12
-12.0*(rc
-r
)*rc6
*rc6
/rc
-1.0*rc6
*rc6
;
640 Ftab
= 12.0*r12
/r
-12.0*rc6
*rc6
/rc
;
658 case etabEwaldSwitch
:
659 Vtab
= gmx_erfc(ewc
*r
)/r
;
660 Ftab
= gmx_erfc(ewc
*r
)/r2
+2*exp(-(ewc
*ewc
*r2
))*ewc
*isp
/r
;
663 case etabEwaldUserSwitch
:
664 /* Only calculate minus the reciprocal space contribution */
665 Vtab
= -gmx_erf(ewc
*r
)/r
;
666 Ftab
= -gmx_erf(ewc
*r
)/r2
+2*exp(-(ewc
*ewc
*r2
))*ewc
*isp
/r
;
670 Vtab
= 1.0/r
+ fr
->k_rf
*r2
- fr
->c_rf
;
671 Ftab
= 1.0/r2
- 2*fr
->k_rf
*r
;
672 if (tp
== etabRF_ZERO
&& r
>= rc
) {
684 Vtab
= 1.0/r
-(rc
-r
)/(rc
*rc
)-1.0/rc
;
685 Ftab
= 1.0/r2
-1.0/(rc
*rc
);
692 gmx_fatal(FARGS
,"Table type %d not implemented yet. (%s,%d)",
693 tp
,__FILE__
,__LINE__
);
696 /* Normal coulomb with cut-off correction for potential */
699 /* If in Shifting range add something to it */
703 Vtab
+= - A_3
*r13
- B_4
*r12
*r12
;
704 Ftab
+= A
*r12
+ B
*r13
;
709 if (tp
== etabEwaldUser
) {
714 if ((r
> r1
) && bSwitch
) {
715 Ftab
= Ftab
*swi
- Vtab
*swi1
;
719 /* Convert to single precision when we store to mem */
729 static void set_table_type(int tabsel
[],const t_forcerec
*fr
,bool b14only
)
733 /* Set the different table indices.
739 switch (fr
->eeltype
) {
751 eltype
= fr
->eeltype
;
756 tabsel
[etiCOUL
] = etabCOUL
;
760 tabsel
[etiCOUL
] = etabShift
;
763 if (fr
->rcoulomb
> fr
->rcoulomb_switch
)
764 tabsel
[etiCOUL
] = etabShift
;
766 tabsel
[etiCOUL
] = etabCOUL
;
770 tabsel
[etiCOUL
] = etabEwald
;
773 tabsel
[etiCOUL
] = etabEwaldSwitch
;
776 tabsel
[etiCOUL
] = etabEwaldUser
;
781 tabsel
[etiCOUL
] = etabRF
;
784 tabsel
[etiCOUL
] = etabRF_ZERO
;
787 tabsel
[etiCOUL
] = etabCOULSwitch
;
790 tabsel
[etiCOUL
] = etabUSER
;
793 tabsel
[etiCOUL
] = etabCOULEncad
;
796 gmx_fatal(FARGS
,"Invalid eeltype %d",eltype
);
799 /* Van der Waals time */
800 if (fr
->bBHAM
&& !b14only
) {
801 tabsel
[etiLJ6
] = etabLJ6
;
802 tabsel
[etiLJ12
] = etabEXPMIN
;
804 if (b14only
&& fr
->vdwtype
!= evdwUSER
)
807 vdwtype
= fr
->vdwtype
;
811 tabsel
[etiLJ6
] = etabLJ6Switch
;
812 tabsel
[etiLJ12
] = etabLJ12Switch
;
815 tabsel
[etiLJ6
] = etabLJ6Shift
;
816 tabsel
[etiLJ12
] = etabLJ12Shift
;
819 tabsel
[etiLJ6
] = etabUSER
;
820 tabsel
[etiLJ12
] = etabUSER
;
823 tabsel
[etiLJ6
] = etabLJ6
;
824 tabsel
[etiLJ12
] = etabLJ12
;
827 tabsel
[etiLJ6
] = etabLJ6Encad
;
828 tabsel
[etiLJ12
] = etabLJ12Encad
;
831 gmx_fatal(FARGS
,"Invalid vdwtype %d in %s line %d",vdwtype
,
837 t_forcetable
make_tables(FILE *out
,const output_env_t oenv
,
838 const t_forcerec
*fr
,
839 bool bVerbose
,const char *fn
,
842 const char *fns
[3] = { "ctab.xvg", "dtab.xvg", "rtab.xvg" };
843 const char *fns14
[3] = { "ctab14.xvg", "dtab14.xvg", "rtab14.xvg" };
846 bool b14only
,bReadTab
,bGenTab
;
848 int i
,j
,k
,nx
,nx0
,tabsel
[etiNR
];
853 b14only
= (flags
& GMX_MAKETABLES_14ONLY
);
855 if (flags
& GMX_MAKETABLES_FORCEUSER
) {
856 tabsel
[etiCOUL
] = etabUSER
;
857 tabsel
[etiLJ6
] = etabUSER
;
858 tabsel
[etiLJ12
] = etabUSER
;
860 set_table_type(tabsel
,fr
,b14only
);
870 /* Check whether we have to read or generate */
873 for(i
=0; (i
<etiNR
); i
++) {
874 if (tabsel
[i
] == etabUSER
|| tabsel
[i
] == etabEwaldUser
)
876 if (tabsel
[i
] != etabUSER
)
880 read_tables(out
,fn
,etiNR
,0,td
);
881 if (rtab
== 0 || (flags
& GMX_MAKETABLES_14ONLY
)) {
882 rtab
= td
[0].x
[td
[0].nx
-1];
886 if (td
[0].x
[td
[0].nx
-1] < rtab
)
887 gmx_fatal(FARGS
,"Tables in file %s not long enough for cut-off:\n"
888 "\tshould be at least %f nm\n",fn
,rtab
);
889 nx
= table
.n
= (int)(rtab
*td
[0].tabscale
+ 0.5);
891 table
.scale
= td
[0].tabscale
;
897 table
.scale
= 2000.0;
901 nx
= table
.n
= rtab
*table
.scale
;
905 if(fr
->bham_b_max
!=0)
906 table
.scale_exp
= table
.scale
/fr
->bham_b_max
;
908 table
.scale_exp
= table
.scale
;
911 /* Each table type (e.g. coul,lj6,lj12) requires four
912 * numbers per datapoint. For performance reasons we want
913 * the table data to be aligned to 16-byte. This is accomplished
914 * by allocating 16 bytes extra to a temporary pointer, and then
915 * calculating an aligned pointer. This new pointer must not be
916 * used in a free() call, but thankfully we're sloppy enough not
920 /* 12 fp entries per table point, nx+1 points, and 16 bytes extra to align it. */
921 p_tmp
= malloc(12*(nx
+1)*sizeof(real
)+16);
923 /* align it - size_t has the same same as a pointer */
924 table
.tab
= (real
*) (((size_t) p_tmp
+ 16) & (~((size_t) 15)));
927 for(k
=0; (k
<etiNR
); k
++) {
928 if (tabsel
[k
] != etabUSER
) {
929 init_table(out
,nx
,nx0
,
930 (tabsel
[k
] == etabEXPMIN
) ? table
.scale_exp
: table
.scale
,
932 fill_table(&(td
[k
]),tabsel
[k
],fr
);
934 fprintf(out
,"%s table with %d data points for %s%s.\n"
935 "Tabscale = %g points/nm\n",
936 tabsel
[k
]==etabEwaldUser
? "Modified" : "Generated",
937 td
[k
].nx
,b14only
?"1-4 ":"",tprops
[tabsel
[k
]].name
,
940 copy2table(table
.n
,k
*4,12,td
[k
].x
,td
[k
].v
,td
[k
].f
,table
.tab
);
942 if (bDebugMode() && bVerbose
) {
944 fp
=xvgropen(fns14
[k
],fns14
[k
],"r","V",oenv
);
946 fp
=xvgropen(fns
[k
],fns
[k
],"r","V",oenv
);
947 /* plot the output 5 times denser than the table data */
948 for(i
=5*((nx0
+1)/2); i
<5*table
.n
; i
++) {
949 x0
= i
*table
.r
/(5*(table
.n
-1));
950 evaluate_table(table
.tab
,4*k
,12,table
.scale
,x0
,&y0
,&yp
);
951 fprintf(fp
,"%15.10e %15.10e %15.10e\n",x0
,y0
,yp
);
955 done_tabledata(&(td
[k
]));
962 t_forcetable
make_gb_table(FILE *out
,const output_env_t oenv
,
963 const t_forcerec
*fr
,
967 const char *fns
[3] = { "gbctab.xvg", "gbdtab.xvg", "gbrtab.xvg" };
968 const char *fns14
[3] = { "gbctab14.xvg", "gbdtab14.xvg", "gbrtab14.xvg" };
971 bool bReadTab
,bGenTab
;
973 int i
,j
,k
,nx
,nx0
,tabsel
[etiNR
];
975 double r
,r2
,Vtab
,Ftab
,expterm
;
979 double abs_error_r
, abs_error_r2
;
980 double rel_error_r
, rel_error_r2
;
981 double rel_error_r_old
=0, rel_error_r2_old
=0;
982 double x0_r_error
, x0_r2_error
;
985 /* Only set a Coulomb table for GB */
992 /* Set the table dimensions for GB, not really necessary to
993 * use etiNR (since we only have one table, but ...)
996 table
.r
= fr
->gbtabr
;
997 table
.scale
= fr
->gbtabscale
;
999 table
.n
= table
.scale
*table
.r
;
1001 nx
= table
.scale
*table
.r
;
1003 /* Check whether we have to read or generate
1004 * We will always generate a table, so remove the read code
1005 * (Compare with original make_table function
1010 /* Each table type (e.g. coul,lj6,lj12) requires four
1011 * numbers per datapoint. For performance reasons we want
1012 * the table data to be aligned to 16-byte. This is accomplished
1013 * by allocating 16 bytes extra to a temporary pointer, and then
1014 * calculating an aligned pointer. This new pointer must not be
1015 * used in a free() call, but thankfully we're sloppy enough not
1019 /* 4 fp entries per table point, nx+1 points, and 16 bytes extra
1021 p_tmp
= malloc(4*(nx
+1)*sizeof(real
)+16);
1023 /* align it - size_t has the same same as a pointer */
1024 table
.tab
= (real
*) (((size_t) p_tmp
+ 16) & (~((size_t) 15)));
1026 init_table(out
,nx
,nx0
,table
.scale
,&(td
[0]),!bReadTab
);
1028 /* Local implementation so we don't have to use the etabGB
1029 * enum above, which will cause problems later when
1030 * making the other tables (right now even though we are using
1031 * GB, the normal Coulomb tables will be created, but this
1032 * will cause a problem since fr->eeltype==etabGB which will not
1033 * be defined in fill_table and set_table_type
1042 expterm
= exp(-0.25*r2
);
1044 Vtab
= 1/sqrt(r2
+expterm
);
1045 Ftab
= (r
-0.25*r
*expterm
)/((r2
+expterm
)*sqrt(r2
+expterm
));
1047 /* Convert to single precision when we store to mem */
1053 copy2table(table
.n
,0,4,td
[0].x
,td
[0].v
,td
[0].f
,table
.tab
);
1057 fp
=xvgropen(fns
[0],fns
[0],"r","V",oenv
);
1058 /* plot the output 5 times denser than the table data */
1059 /* for(i=5*nx0;i<5*table.n;i++) */
1060 for(i
=nx0
;i
<table
.n
;i
++)
1062 /* x0=i*table.r/(5*table.n); */
1063 x0
=i
*table
.r
/table
.n
;
1064 evaluate_table(table
.tab
,0,4,table
.scale
,x0
,&y0
,&yp
);
1065 fprintf(fp
,"%15.10e %15.10e %15.10e\n",x0
,y0
,yp
);
1072 for(i=100*nx0;i<99.81*table.n;i++)
1074 r = i*table.r/(100*table.n);
1076 expterm = exp(-0.25*r2);
1078 Vtab = 1/sqrt(r2+expterm);
1079 Ftab = (r-0.25*r*expterm)/((r2+expterm)*sqrt(r2+expterm));
1082 evaluate_table(table.tab,0,4,table.scale,r,&y0,&yp);
1083 printf("gb: i=%d, x0=%g, y0=%15.15f, Vtab=%15.15f, yp=%15.15f, Ftab=%15.15f\n",i,r, y0, Vtab, yp, Ftab);
1085 abs_error_r=fabs(y0-Vtab);
1086 abs_error_r2=fabs(yp-(-1)*Ftab);
1088 rel_error_r=abs_error_r/y0;
1089 rel_error_r2=fabs(abs_error_r2/yp);
1092 if(rel_error_r>rel_error_r_old)
1094 rel_error_r_old=rel_error_r;
1098 if(rel_error_r2>rel_error_r2_old)
1100 rel_error_r2_old=rel_error_r2;
1105 printf("gb: MAX REL ERROR IN R=%15.15f, MAX REL ERROR IN R2=%15.15f\n",rel_error_r_old, rel_error_r2_old);
1106 printf("gb: XO_R=%g, X0_R2=%g\n",x0_r_error, x0_r2_error);
1109 done_tabledata(&(td
[0]));
1117 bondedtable_t
make_bonded_table(FILE *fplog
,char *fn
,int angle
)
1128 read_tables(fplog
,fn
,1,angle
,&td
);
1130 /* Convert the table from degrees to radians */
1131 for(i
=0; i
<td
.nx
; i
++) {
1135 td
.tabscale
*= RAD2DEG
;
1138 tab
.scale
= td
.tabscale
;
1139 snew(tab
.tab
,tab
.n
*4);
1140 copy2table(tab
.n
,0,4,td
.x
,td
.v
,td
.f
,tab
.tab
);
1141 done_tabledata(&td
);