4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * GROwing Monsters And Cloning Shrimps
47 /* All the possible (implemented) table functions */
49 etabLJ6
, etabLJ12
, etabLJ6Shift
, etabLJ12Shift
, etabShift
,
50 etabRF
, etabCOUL
, etabEwald
, etabLJ6Switch
, etabLJ12Switch
,etabCOULSwitch
,
51 etabEXPMIN
,etabUSER
, etabNR
53 static const char *tabnm
[etabNR
] = {
54 "LJ6", "LJ12", "LJ6Shift", "LJ12Shift", "Shift",
55 "RF", "COUL", "Ewald", "LJ6Switch", "LJ12Switch","COULSwitch",
59 /* This flag tells whether this is a Coulomb type funtion */
60 bool bCoulomb
[etabNR
] = { FALSE
, FALSE
, FALSE
, FALSE
, TRUE
,
61 TRUE
, TRUE
, TRUE
, FALSE
, FALSE
, TRUE
,
64 /* Index in the table that says which function to use */
65 enum { etiCOUL
, etiLJ6
, etiLJ12
, etiNR
};
74 #define pow2(x) ((x)*(x))
75 #define pow3(x) ((x)*(x)*(x))
76 #define pow4(x) ((x)*(x)*(x)*(x))
77 #define pow5(x) ((x)*(x)*(x)*(x)*(x))
79 /* Calculate the potential and force for an r value
80 * in exactly the same way it is done in the inner loop.
81 * VFtab is a pointer to the table data, offset is
82 * the point where we should begin and stride is
83 * 4 if we have a buckingham table, 3 otherwise.
84 * If you want to evaluate table no N, set offset to 4*N.
86 * We use normal precision here, since that is what we
87 * will use in the inner loops.
89 static void evaluate_table(real VFtab
[], int offset
, int stride
,
90 real tabscale
, real r
, real
*y
, real
*yp
)
94 real Y
,F
,Geps
,Heps2
,Fp
;
103 Geps
= eps
*VFtab
[n
+2];
104 Heps2
= eps2
*VFtab
[n
+3];
107 *yp
= (Fp
+Geps
+2.0*Heps2
)*tabscale
;
111 static void splint(real xa
[],real ya
[],real y2a
[],
112 int n
,real x
,real
*y
,real
*yp
)
121 while ((khi
-klo
) > 1) {
130 fatal_error(0,"Bad XA input to function splint");
133 *y
= a
*ya
[klo
]+b
*ya
[khi
]+((a
*a
*a
-a
)*y2a
[klo
]+(b
*b
*b
-b
)*y2a
[khi
])*(h
*h
)/6.0;
134 *yp
= (ya
[khi
]-ya
[klo
])/h
+((3*a
*a
-1)*y2a
[klo
]-(3*b
*b
-1)*y2a
[khi
])*h
/6.0;
137 F
= (ya
[khi
]-ya
[klo
]-(h
*h
/6.0)*(2*y2a
[klo
]+y2a
[khi
]));
138 G
= (h
*h
/2.0)*y2a
[klo
];
139 H
= (h
*h
/6.0)*(y2a
[khi
]-y2a
[klo
]);
140 *y
= ya
[klo
] + eps
*F
+ eps
*eps
*G
+ eps
*eps
*eps
*H
;
141 *yp
= (F
+ 2*eps
*G
+ 3*eps
*eps
*H
)/h
;
145 static void copy2table(int n
,int offset
,int stride
,
146 double x
[],double Vtab
[],double Vtab2
[],
147 real dest
[],real r_zeros
)
149 /* Use double prec. for the intermediary variables
150 * and temporary x/vtab/vtab2 data to avoid unnecessary
156 for(i
=1; (i
<n
-1); i
++) {
158 F
= (Vtab
[i
+1]-Vtab
[i
]-(h
*h
/6.0)*(2*Vtab2
[i
]+Vtab2
[i
+1]));
159 G
= (h
*h
/2.0)*Vtab2
[i
];
160 H
= (h
*h
/6.0)*(Vtab2
[i
+1]-Vtab2
[i
]);
161 nn0
= offset
+i
*stride
;
168 for(i
=1; (i
<n
-1); i
++) {
169 if (0.5*(x
[i
]+x
[i
+1]) >= r_zeros
) {
170 nn0
= offset
+i
*stride
;
180 static void init_table(FILE *fp
,int n
,int nx0
,int tabsel
,
181 real tabscale
,t_tabledata
*td
,bool bAlloc
)
187 td
->tabscale
= tabscale
;
193 for(i
=td
->nx0
; (i
<td
->nx
); i
++)
194 td
->x
[i
] = i
/tabscale
;
197 static void read_tables(FILE *fp
,char *fn
,t_tabledata td
[])
201 int k
,i
,nx
,nx0
,ny
,nny
;
206 libfn
= low_libfn(fn
,TRUE
);
207 nx
= read_xvg(libfn
,&yy
,&ny
);
209 fatal_error(0,"Trying to read file %s, but nr columns = %d, should be %d",
212 for(nx0
=0; bCont
&& (nx0
< nx
); nx0
++)
213 for(k
=1; (k
<ny
); k
++)
217 fatal_error(0,"All elements in table %s are zero!\n",libfn
);
219 tabscale
= (nx
-1)/(yy
[0][nx
-1] - yy
[0][0]);
220 for(k
=0; (k
<etiNR
); k
++) {
221 init_table(fp
,nx
,nx0
,etabUSER
,tabscale
,&(td
[k
]),TRUE
);
222 for(i
=0; (i
<nx
); i
++) {
223 td
[k
].x
[i
] = yy
[0][i
];
224 td
[k
].v
[i
] = yy
[2*k
+1][i
];
225 td
[k
].v2
[i
] = yy
[2*k
+2][i
];
228 for(i
=0; (i
<ny
); i
++)
233 fprintf(fp
,"Read user tables from %s with %d data points.\n"
234 "Tabscale = %g points/nm\n",libfn
,nx
,tabscale
);
237 static void done_tabledata(t_tabledata
*td
)
249 static void fill_table(t_tabledata
*td
,int tp
,t_forcerec
*fr
)
251 /* Fill the table according to the formulas in the manual.
252 * In principle, we only need the potential and the second
253 * derivative, but then we would have to do lots of calculations
254 * in the inner loop. By precalculating some terms (see manual)
255 * we get better eventual performance, despite a larger table.
257 * Since some of these higher-order terms are very small,
258 * we always use double precision to calculate them here, in order
259 * to avoid unnecessary loss of precision.
265 double r1
,rc
,r12
,r13
;
267 double expr
,Vtab
,Ftab
,Vtab2
,Ftab2
;
268 /* Parameters for David's function */
269 double A
=0,B
=0,C
=0,A_3
=0,B_4
=0;
270 /* Parameters for the switching function */
271 double ksw
,swi
,swi1
,swi2
;
272 /* Temporary parameters */
277 double ewc
=fr
->ewaldcoeff
;
278 double isp
= 0.564189583547756;
280 bSwitch
= ((tp
== etabLJ6Switch
) || (tp
== etabLJ12Switch
) ||
281 (tp
== etabCOULSwitch
));
282 bShift
= ((tp
== etabLJ6Shift
) || (tp
== etabLJ12Shift
) ||
286 r1
= fr
->rcoulomb_switch
;
290 r1
= fr
->rvdw_switch
;
294 ksw
= 1.0/(pow5(rc
-r1
));
300 else if (tp
== etabLJ6Shift
)
305 A
= p
* ((p
+1)*r1
-(p
+4)*rc
)/(pow(rc
,p
+2)*pow2(rc
-r1
));
306 B
= -p
* ((p
+1)*r1
-(p
+3)*rc
)/(pow(rc
,p
+2)*pow3(rc
-r1
));
307 C
= 1.0/pow(rc
,p
)-A
/3.0*pow3(rc
-r1
)-B
/4.0*pow4(rc
-r1
);
308 if (tp
== etabLJ6Shift
) {
316 if (debug
) { fprintf(debug
,"Further\n"); fflush(debug
); }
319 fp
=xvgropen("switch.xvg","switch","r","s");
321 for(i
=td
->nx0
; (i
<td
->nx
); i
++) {
331 /* swi is function, swi1 1st derivative and swi2 2nd derivative */
332 /* The switch function is 1 for r<r1, 0 for r>rc, and smooth for
333 * r1<=r<=rc. The 1st and 2nd derivatives are both zero at
335 * ksw is just the constant 1/(rc-r1)^5, to save some calculations...
341 swi
= swi1
= swi2
= 0.0;
343 swi
= 1 - 10*pow3(r
-r1
)*ksw
*pow2(rc
-r1
)
344 + 15*pow4(r
-r1
)*ksw
*(rc
-r1
) - 6*pow5(r
-r1
)*ksw
;
345 swi1
= -30*pow2(r
-r1
)*ksw
*pow2(rc
-r1
)
346 + 60*pow3(r
-r1
)*ksw
*(rc
-r1
) - 30*pow4(r
-r1
)*ksw
;
347 swi2
= -60*(r
-r1
)*ksw
*pow2(rc
-r1
)
348 + 180*pow2(r
-r1
)*ksw
*(rc
-r1
) - 120*pow3(r
-r1
)*ksw
;
351 else { /* not really needed, but avoids compiler warnings... */
356 fprintf(fp
,"%10g %10g %10g %10g\n",r
,swi
,swi1
,swi2
);
381 Ftab2
= 14.0*Vtab2
/r
;
390 Ftab2
= 14.0*Vtab2
/r
;
409 Vtab
= erfc(ewc
*r
)/r
;
410 Ftab
= erfc(ewc
*r
)/r2
+2*exp(-(ewc
*ewc
*r2
))*ewc
*isp
/r
;
411 Vtab2
= 2*erfc(ewc
*r
)/(r
*r2
)+4*exp(-(ewc
*ewc
*r2
))*ewc
*isp
/r2
+
412 4*ewc
*ewc
*ewc
*exp(-(ewc
*ewc
*r2
))*isp
;
413 Ftab2
= 6*erfc(ewc
*r
)/(r2
*r2
)+
414 12*exp(-(ewc
*ewc
*r2
))*ewc
*isp
/(r
*r2
)+
415 8*ewc
*ewc
*ewc
*exp(-(ewc
*ewc
*r2
))*isp
/r
+
416 8*ewc
*ewc
*ewc
*ewc
*ewc
*r
*exp(-(ewc
*ewc
*r2
))*isp
;
419 Vtab
= 1.0/r
+ fr
->k_rf
*r2
- fr
->c_rf
;
420 Ftab
= 1.0/r2
- 2*fr
->k_rf
*r
;
421 Vtab2
= 2.0/(r
*r2
) + 2*fr
->k_rf
;
432 fatal_error(0,"Table type %d not implemented yet. (%s,%d)",
433 tp
,__FILE__
,__LINE__
);
436 /* Normal coulomb with cut-off correction for potential */
439 /* If in Shifting range add something to it */
443 Vtab
+= - A_3
*r13
- B_4
*r12
*r12
;
444 Ftab
+= A
*r12
+ B
*r13
;
445 Vtab2
+= - 2.0*A
*(r
-r1
) - 3.0*B
*r12
;
446 Ftab2
+= 2.0*A
+ 6.0*B
*(r
-r1
);
451 if ((r
> r1
) && bSwitch
) {
456 Vtab2
= VtabT2
*swi
+ VtabT1
*swi1
+ VtabT1
*swi1
+ VtabT
*swi2
;
459 /* Convert to single precision when we store to mem */
469 static void set_table_type(int tabsel
[],t_forcerec
*fr
)
471 /* Set the different table indices.
475 switch (fr
->eeltype
) {
477 tabsel
[etiCOUL
] = etabCOUL
;
481 if ((fr
->rcoulomb
> fr
->rcoulomb_switch
) && fr
->bcoultab
)
482 tabsel
[etiCOUL
] = etabShift
;
484 tabsel
[etiCOUL
] = etabCOUL
; /* 1-4 */
487 if (fr
->rcoulomb
> fr
->rcoulomb_switch
)
488 tabsel
[etiCOUL
] = etabShift
;
490 tabsel
[etiCOUL
] = etabCOUL
;
495 tabsel
[etiCOUL
] = etabEwald
;
497 tabsel
[etiCOUL
] = etabCOUL
; /* 1-4 */
501 tabsel
[etiCOUL
] = etabRF
;
504 tabsel
[etiCOUL
] = etabCOULSwitch
;
507 tabsel
[etiCOUL
] = etabUSER
;
510 fatal_error(0,"Invalid eeltype %d in %s line %d",fr
->eeltype
,
514 /* Van der Waals time */
516 tabsel
[etiLJ6
] = etabLJ6
;
517 tabsel
[etiLJ12
] = etabEXPMIN
;
520 switch (fr
->vdwtype
) {
522 tabsel
[etiLJ6
] = etabLJ6Switch
;
523 tabsel
[etiLJ12
] = etabLJ12Switch
;
526 tabsel
[etiLJ6
] = etabLJ6Shift
;
527 tabsel
[etiLJ12
] = etabLJ12Shift
;
530 tabsel
[etiLJ6
] = etabUSER
;
531 tabsel
[etiLJ12
] = etabUSER
;
534 tabsel
[etiLJ6
] = etabLJ6
;
535 tabsel
[etiLJ12
] = etabLJ12
;
538 fatal_error(0,"Invalid vdwtype %d in %s line %d",fr
->vdwtype
,
544 void make_tables(FILE *out
,t_forcerec
*fr
,bool bVerbose
,char *fn
)
546 const char *fns
[3] = { "ctab.xvg", "dtab.xvg", "rtab.xvg" };
549 bool bReadTab
,bGenTab
;
551 int i
,j
,k
,nx
,nx0
,tabsel
[etiNR
];
553 set_table_type(tabsel
,fr
);
560 /* Check whether we have to read or generate */
563 for(i
=0; (i
<etiNR
); i
++) {
564 if (tabsel
[i
] == etabUSER
)
570 read_tables(out
,fn
,td
);
571 fr
->tabscale
= td
[0].tabscale
;
572 fr
->rtab
= td
[0].x
[td
[0].nx
-1];
574 nx
= fr
->ntab
= fr
->rtab
*fr
->tabscale
;
576 fatal_error(0,"Tables in file %s not long enough for cut-off:\n"
577 "\tshould be at least %f nm\n",fn
,rtab
);
582 fr
->tabscale
= 2000.0;
584 fr
->tabscale
= 500.0;
586 nx
= fr
->ntab
= fr
->rtab
*fr
->tabscale
;
589 /* Each table type (e.g. coul,lj6,lj12) requires four
590 * numbers per datapoint. The exponential Buckingham table
591 * requires an extra one for accuracy. Since we still have
592 * the coulomb and dispersion, there will be four table
593 * types with four elements each when we use Buckingham.
596 snew(fr
->coulvdwtab
,( fr
->bBHAM
? 16 :12 )*(nx
+1)+1);
597 for(k
=0; (k
<etiNR
); k
++) {
598 if (tabsel
[k
] != etabUSER
) {
599 init_table(out
,nx
,nx0
,tabsel
[k
],
600 (tabsel
[k
] == etabEXPMIN
) ? fr
->tabscale_exp
: fr
->tabscale
,
602 fill_table(&(td
[k
]),tabsel
[k
],fr
);
604 fprintf(out
,"Generated table with %d data points for %s.\n"
605 "Tabscale = %g points/nm\n",
606 td
[k
].nx
,tabnm
[tabsel
[k
]],td
[k
].tabscale
);
609 copy2table(td
[k
].nx
,k
*4,12,td
[k
].x
,td
[k
].v
,td
[k
].v2
,fr
->coulvdwtab
,-1);
611 if (bDebugMode() && bVerbose
) {
612 fp
=xvgropen(fns
[k
],fns
[k
],"r","V");
613 /* plot the output 5 times denser than the table data */
614 for(i
=5*nx0
;i
<5*fr
->ntab
;i
++) {
615 x0
=i
*fr
->rtab
/(5*fr
->ntab
);
616 evaluate_table(fr
->coulvdwtab
,4*k
,12,fr
->tabscale
,x0
,&y0
,&yp
);
617 fprintf(fp
,"%15.10e %15.10e %15.10e\n",x0
,y0
,yp
);
621 done_tabledata(&(td
[k
]));