4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * Green Red Orange Magenta Azure Cyan Skyblue
29 static char *SRCID_shift_util_c
= "$Id$";
35 #include "shift_util.h"
46 #define p2(x) ((x)*(x))
47 #define p3(x) ((x)*(x)*(x))
48 #define p4(x) ((x)*(x)*(x)*(x))
50 static real A
,A_3
,B
,B_4
,C
,c1
,c2
,c3
,c4
,c5
,c6
,One_4pi
,FourPi_V
,Vol
,N0
;
52 void set_shift_consts(FILE *log
,real r1
,real rc
,rvec box
,t_forcerec
*fr
)
54 /* A, B and C are recalculated in tables.c */
56 A
= (2*r1
-5*rc
)/(p3(rc
)*p2(rc
-r1
));
57 B
= (4*rc
-2*r1
)/(p3(rc
)*p3(rc
-r1
));
58 /*C = (10*rc*rc-5*rc*r1+r1*r1)/(6*rc*rc); Hermans Eq. not correct */
61 fatal_error(0,"r1 (%f) >= rc (%f) in %s, line %d",
62 r1
,rc
,__FILE__
,__LINE__
);
66 C
= 1/rc
-A_3
*p3(rc
-r1
)-B_4
*p4(rc
-r1
);
67 N0
= 2.0*M_PI
*p3(rc
)*p3(rc
-r1
);
69 Vol
=(box
[XX
]*box
[YY
]*box
[ZZ
]);
70 FourPi_V
=4.0*M_PI
/Vol
;
73 fprintf(log
,"Constants for short-range and fourier stuff:\n"
74 "r1 = %10.3f, rc = %10.3f\n"
75 "A = %10.3e, B = %10.3e, C = %10.3e, FourPi_V = %10.3e\n",
76 r1
,rc
,A
,B
,C
,FourPi_V
);
78 /* Constants derived by Mathematica */
79 c1
= -40*rc
*rc
+ 50*rc
*r1
- 16*r1
*r1
;
81 c3
= -10*rc
*rc
*rc
+ 20*rc
*rc
*r1
- 13*rc
*r1
*r1
+ 3*r1
*r1
*r1
;
82 c4
= -20*rc
*rc
+ 40*rc
*r1
- 14*r1
*r1
;
84 c6
= -5*rc
*rc
*r1
+ 7*rc
*r1
*r1
- 2*r1
*r1
*r1
;
87 fprintf(log
,"c1 = %10.3e, c2 = %10.3e, c3 = %10.3e\n"
88 "c4 = %10.3e, c5 = %10.3e, c6 = %10.3e, N0 = %10.3e\n",
89 c1
,c2
,c3
,c4
,c5
,c6
,N0
);
91 One_4pi
= 1.0/(4.0*M_PI
);
94 real
gk(real k
,real rc
,real r1
)
95 /* Spread function in Fourier space. Eqs. 56-64 */
101 /* c1 thru c6 consts are global variables! */
102 gg
= (FourPi_V
/ (N
*k
)) *
103 ( c1
*k
*cos(k
*rc
) + (c2
+c3
*k
*k
)*sin(k
*rc
) +
104 c4
*k
*cos(k
*r1
) + (c5
+c6
*k
*k
)*sin(k
*r1
) );
109 real
gknew(real k
,real rc
,real r1
)
116 return -15.0*((rck2
-3.0)*sin(rck
) + 3*rck
*cos(rck
))/(Vol
*rck2
*rck2
*rck
);
119 real
calc_dx2dx(rvec xi
,rvec xj
,rvec box
,rvec dx
)
125 for(m
=0; (m
<DIM
); m
++) {
127 if (ddx
< -0.5*box
[m
])
129 else if (ddx
>= 0.5*box
[m
])
137 real
calc_dx2(rvec xi
,rvec xj
,rvec box
)
141 return calc_dx2dx(xi
,xj
,box
,dx
);
144 real
shiftfunction(real r1
,real rc
,real R
)
155 return A
*dr
*dr
+B
*dr
*dr
*dr
;
158 real
new_f(real r
,real rc
)
165 return 1.5*rrc2
*rrc3
- 2.5*rrc3
+ 1.0;
168 real
new_phi(real r
,real rc
)
174 return 1/r
-(0.125/rc
)*(15 + 3*rrr
*rrr
- 10*rrr
);
177 real
old_f(real r
,real rc
,real r1
)
188 return 1+A
*r2
*dr
*dr
+B
*r2
*dr
*dr
*dr
;
191 real
old_phi(real r
,real rc
,real r1
)
202 return 1/r
-A_3
*dr
*dr
*dr
-B_4
*dr
*dr
*dr
*dr
- C
;
205 real
phi_sr(FILE *log
,int nj
,rvec x
[],real charge
[],real rc
,real r1
,rvec box
,
206 real phi
[],t_block
*excl
,rvec f_sr
[],bool bOld
)
208 int i
,j
,k
,m
,ni
,i1
,i2
;
209 real pp
,r2
,R
,R_1
,R_2
,rc2
;
210 real qi
,qj
,vsr
,eps
,fscal
;
217 for(i
=0; (i
<nj
-1); i
++) {
219 for(j
=i
+1; (j
<nj
); j
++) {
222 for(k
=i1
; (k
<i2
); k
++)
226 r2
=calc_dx2dx(x
[i
],x
[j
],box
,dx
);
233 fscal
= old_f(R
,rc
,r1
)*R_2
;
234 pp
= old_phi(R
,rc
,r1
);
237 fscal
= new_f(R
,rc
)*R_2
;
243 for(m
=0; (m
<DIM
); m
++) {
244 f_sr
[i
][m
] += dx
[m
]*fscal
;
245 f_sr
[j
][m
] -= dx
[m
]*fscal
;
252 fprintf(log
,"There were %d short range interactions, vsr=%g\n",ni
,vsr
);
257 real
spreadfunction(real r1
,real rc
,real R
)
268 return -One_4pi
*(dr
/R
)*(2*A
*(2*R
-r1
)+B
*dr
*(5*R
-2*r1
));
271 real
potential(real r1
,real rc
,real R
)
276 return (1.0/R
- A_3
*p3(R
-r1
) - B_4
*p4(R
-r1
) - C
);
283 real
shift_LRcorrection(FILE *fp
,t_nsborder
*nsb
,t_commrec
*cr
,t_forcerec
*fr
,
284 real charge
[],t_block
*excl
,rvec x
[],
285 bool bOld
,rvec box_size
,matrix lr_vir
)
287 static bool bFirst
=TRUE
;
289 int i
,i1
,i2
,j
,k
,m
,iv
,jv
;
291 double qq
; /* Necessary for precision */
292 double isp
=0.564189583547756;
293 real qi
,dr
,ddd
,dr2
,dr_1
,dr_3
,fscal
,Vexcl
,qtot
=0;
295 real r1
=fr
->rcoulomb_switch
;
296 real rc
=fr
->rcoulomb
;
298 int start
=START(nsb
);
299 int natoms
=HOMENR(nsb
);
303 for(i
=start
; (i
<start
+natoms
); i
++)
304 qq
+= charge
[i
]*charge
[i
];
306 /* Obsolete, until we implement dipole and charge corrections.
308 for(i=0;i<nsb->natoms;i++)
312 Vself
= 0.5*C
*ONE_4PI_EPS0
*qq
;
314 fprintf(fp
,"Long Range corrections for shifted interactions:\n");
315 fprintf(fp
,"r1 = %g, rc=%g\n",r1
,rc
);
316 fprintf(fp
,"start=%d,natoms=%d\n",start
,natoms
);
317 fprintf(fp
,"qq = %g, Vself=%g\n",qq
,Vself
);
324 for(i
=start
; (i
<start
+natoms
); i
++) {
325 /* Initiate local variables (for this i-particle) to 0 */
327 i2
= excl
->index
[i
+1];
328 qi
= charge
[i
]*ONE_4PI_EPS0
;
330 /* Loop over excluded neighbours */
331 for(j
=i1
; (j
<i2
); j
++) {
334 * First we must test whether k <> i, and then, because the
335 * exclusions are all listed twice i->k and k->i we must select
336 * just one of the two.
337 * As a minor optimization we only compute forces when the charges
343 /* Compute distance vector, no PBC check! */
345 for(m
=0; (m
<DIM
); m
++) {
346 ddd
= x
[i
][m
] - x
[k
][m
];
347 if(ddd
>box_size
[m
]/2) { /* ugly hack, */
348 ddd
-=box_size
[m
]; /* to fix pbc.. */
349 } else if (ddd
<-box_size
[m
]/2)
357 dr_3
= dr_1
*dr_1
*dr_1
;
358 /* Compute exclusion energy and scalar force */
360 Vexcl
+= qq
*(dr_1
-potential(r1
,rc
,dr
));
361 fscal
= qq
*(-shiftfunction(r1
,rc
,dr
))*dr_3
;
363 if ((fscal
!= 0) && debug
)
364 fprintf(debug
,"i: %d, k: %d, dr: %.3f fscal: %.3f\n",i
,k
,dr
,fscal
);
366 /* The force vector is obtained by multiplication with the
370 rvec_inc(fr
->flr
[k
],df
);
371 rvec_dec(fr
->flr
[i
],df
);
372 for(iv
=0;iv
<DIM
;iv
++)
373 for(jv
=0;jv
<DIM
;jv
++)
374 lr_vir
[iv
][jv
]+=0.5*dx
[iv
]*df
[jv
];
380 fprintf(fp
,"Long Range correction: Vexcl=%g\n",Vexcl
);
384 return (Vself
+Vexcl
);
388 void calc_ener(FILE *fp
,char *title
,bool bHeader
,int nmol
,
389 int natoms
,real phi
[],real charge
[],t_block
*excl
)
392 real qq
,qi
,vv
,V
,Vex
,Vc
,Vt
;
396 for(i
=0; (i
<natoms
); i
++) {
397 vv
= charge
[i
]*phi
[i
];
399 qq
+= charge
[i
]*charge
[i
];
402 Vc
= 0.5*C
*ONE_4PI_EPS0
*qq
;
405 for(i
=0; (i
<excl
->nr
); i
++) {
407 i2
= excl
->index
[i
+1];
409 for(j
=i1
; (j
<i2
); j
++) {
415 Vex
= qq
*0.5*C
*ONE_4PI_EPS0
;
420 fprintf(fp
,"%12s %12s %12s %12s %12s %12s\n",
421 "","Vphi","Vself","Vexcl","Vtot","1Mol");
424 fprintf(fp
,"%12s %12.5e %12.5e %12.5e %12.5e %12.5e\n",
425 title
,V
,Vc
,Vex
,Vt
,Vt
/nmol
);
428 real
phi_aver(int natoms
,real phi
[])
434 for(i
=0; (i
<natoms
); i
++)
435 phitot
=phitot
+phi
[i
];
437 return (phitot
/natoms
);
440 real
symmetrize_phi(FILE *log
,int natoms
,real phi
[],bool bVerbose
)
445 phitot
=phi_aver(natoms
,phi
);
447 fprintf(log
,"phi_aver = %10.3e\n",phitot
);
449 for(i
=0; (i
<natoms
); i
++)
455 static real
rgbset(real col
)
463 void plot_phi(char *fn
,rvec box
,int natoms
,rvec x
[],real phi
[])
466 real phi_max
,rr
,gg
,bb
,fac
,dx
,x0
,y0
;
472 for(i
=0; (i
<natoms
); i
++)
473 phi_max
=max(phi_max
,fabs(phi
[i
]));
476 fprintf(stderr
,"All values zero, see .out file\n");
482 fprintf(stderr
,"Scaling box by %g\n",fac
);
485 (real
)(fac
*box
[XX
]+2*offset
),(real
)(fac
*box
[YY
]+2*offset
));
486 ps_translate(eps
,offset
,offset
);
488 ps_box(eps
,1,1,(real
)(fac
*box
[XX
]-1),(real
)(fac
*box
[YY
]-1));
490 for(i
=0; (i
<natoms
); i
++) {
493 gg
=bb
=(1.0+(phi
[i
]/phi_max
));
495 rr
=gg
=(1.0-(phi
[i
]/phi_max
));
499 ps_color(eps
,rr
,gg
,bb
);
502 ps_fillbox(eps
,(real
)(x0
-dx
),(real
)(y0
-dx
),(real
)(x0
+dx
),(real
)(y0
+dx
));
507 void plot_qtab(char *fn
,int nx
,int ny
,int nz
,real
***qtab
)
518 npt
=(box
[XX
]*box
[YY
]*box
[ZZ
]);
525 for(ix
=-nx
; (ix
<nx
); ix
++)
526 for(iy
=-ny
; (iy
<ny
); iy
++)
527 for(iz
=-nz
; (iz
<nz
); iz
++,i
++) {
530 xx
[i
][ZZ
]=iz
+nz
+0.5; /* onzin */
531 phi
[i
]=qtab
[ix
+nx
][iy
+ny
][iz
+nz
];
534 plot_phi(fn
,box
,npt
,xx
,phi
);
540 void print_phi(char *fn
,int natoms
,rvec x
[],real phi
[])
546 for(i
=0; (i
<natoms
); i
++)
547 fprintf(fp
,"%10d %12.5e\n",i
,phi
[i
]);
551 void write_pqr(char *fn
,t_atoms
*atoms
,rvec x
[],real phi
[],real dx
)
557 for(i
=0; (i
<atoms
->nr
); i
++) {
558 rnr
=atoms
->atom
[i
].resnr
;
559 fprintf(fp
,"%-6s%5d %-4.4s%3.3s %c%4d %8.3f%8.3f%8.3f%6.2f%6.2f\n",
560 "ATOM",(i
+1),*atoms
->atomname
[i
],*atoms
->resname
[rnr
],' ',
562 10*(dx
+x
[i
][XX
]),10*x
[i
][YY
],10*(x
[i
][ZZ
]),0.0,phi
[i
]);
567 void write_grid_pqr(char *fn
,int nx
,int ny
,int nz
,real
***phi
)
574 for(i
=0; (i
<nx
); i
++)
575 for(j
=0; (j
<ny
); j
++)
576 for(k
=0; (k
<nz
); k
++,rnr
++)
577 fprintf(fp
,"%-6s%5d %-4.4s%3.3s %c%4d %8.3f%8.3f%8.3f%6.2f%6.2f\n",
578 "ATOM",(i
+1),"C","C",' ',
579 1+((rnr
+1) % 10000),fac
*i
,fac
*j
,fac
*k
,0.0,phi
[i
][j
][k
]);
584 real
analyse_diff(FILE *log
,char *label
,
585 int natom
,rvec ffour
[],rvec fpppm
[],
586 real phi_f
[],real phi_p
[],real phi_sr
[],
587 char *fcorr
,char *pcorr
,char *ftotcorr
,char *ptotcorr
)
590 FILE *fp
=NULL
,*gp
=NULL
;
591 real f2sum
=0,p2sum
=0;
592 real df
,fmax
,dp
,pmax
,rmsf
;
594 fmax
= fabs(ffour
[0][0]-fpppm
[0][0]);
595 pmax
= fabs(phi_f
[0] - phi_p
[0]);
597 for(i
=0; (i
<natom
); i
++) {
598 dp
= fabs(phi_f
[i
] - phi_p
[i
]);
601 for(m
=0; (m
<DIM
); m
++) {
602 df
= fabs(ffour
[i
][m
] - fpppm
[i
][m
]);
608 rmsf
= sqrt(f2sum
/(3.0*natom
));
609 fprintf(log
,"\n********************************\nERROR ANALYSIS for %s\n",
611 fprintf(log
,"%-10s%12s%12s\n","Error:","Max Abs","RMS");
612 fprintf(log
,"%-10s %10.3f %10.3f\n","Force",fmax
,rmsf
);
613 fprintf(log
,"%-10s %10.3f %10.3f\n","Potential",pmax
,sqrt(p2sum
/(natom
)));
616 fp
= xvgropen(fcorr
,"LR Force Correlation","Four-Force","PPPM-Force");
617 for(i
=0; (i
<natom
); i
++) {
618 for(m
=0; (m
<DIM
); m
++) {
619 fprintf(fp
,"%10.3f %10.3f\n",ffour
[i
][m
],fpppm
[i
][m
]);
623 xvgr_file(fcorr
,NULL
);
626 fp
= xvgropen(pcorr
,"LR Potential Correlation","Four-Pot","PPPM-Pot");
628 gp
= xvgropen(ptotcorr
,"Total Potential Correlation","Four-Pot","PPPM-Pot");
629 for(i
=0; (i
<natom
); i
++) {
631 fprintf(fp
,"%10.3f %10.3f\n",phi_f
[i
],phi_p
[i
]);
633 fprintf(gp
,"%10.3f %10.3f\n",phi_f
[i
]+phi_sr
[i
],phi_p
[i
]+phi_sr
[i
]);
637 xvgr_file(pcorr
,NULL
);
641 xvgr_file(ptotcorr
,NULL
);