Partial commit of the project to remove all static variables.
[gromacs.git] / src / mdlib / force.c
blob4aa08272c2f247b184b4c1115af0e83ddbf53f0f
1 /*
2 * $Id$
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 3.1
11 * Copyright (c) 1991-2001, University of Groningen, The Netherlands
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * If you want to redistribute modifications, please consider that
18 * scientific software is very special. Version control is crucial -
19 * bugs must be traceable. We will be happy to consider code for
20 * inclusion in the official distribution, but derived work must not
21 * be called official GROMACS. Details are found in the README & COPYING
22 * files - if they are missing, get the official version at www.gromacs.org.
24 * To help us fund GROMACS development, we humbly ask that you cite
25 * the papers on the package - you can find them in the top README file.
27 * For more info, check our website at http://www.gromacs.org
29 * And Hey:
30 * Getting the Right Output Means no Artefacts in Calculating Stuff
33 #include <math.h>
34 #include "sysstuff.h"
35 #include "typedefs.h"
36 #include "macros.h"
37 #include "smalloc.h"
38 #include "assert.h"
39 #include "physics.h"
40 #include "macros.h"
41 #include "vec.h"
42 #include "force.h"
43 #include "invblock.h"
44 #include "confio.h"
45 #include "nsb.h"
46 #include "names.h"
47 #include "network.h"
48 #include "wnblist.h"
49 #include "pbc.h"
50 #include "ns.h"
51 #include "nrnb.h"
52 #include "bondf.h"
53 #include "mshift.h"
54 #include "txtdump.h"
55 #include "ewald_util.h"
56 #include "shift_util.h"
57 #include "pppm.h"
58 #include "ewald.h"
59 #include "pme.h"
60 #include "mdrun.h"
61 #include "copyrite.h"
63 t_forcerec *mk_forcerec(void)
65 t_forcerec *fr;
67 snew(fr,1);
69 return fr;
72 #ifdef DEBUG
73 static void pr_nbfp(FILE *fp,real *nbfp,bool bBHAM,int atnr)
75 int i,j;
77 for(i=0; (i<atnr); i++) {
78 for(j=0; (j<atnr); j++) {
79 fprintf(fp,"%2d - %2d",i,j);
80 if (bBHAM)
81 fprintf(fp," a=%10g, b=%10g, c=%10g\n",BHAMA(nbfp,atnr,i,j),
82 BHAMB(nbfp,atnr,i,j),BHAMC(nbfp,atnr,i,j));
83 else
84 fprintf(fp," c6=%10g, c12=%10g\n",C6(nbfp,atnr,i,j),
85 C12(nbfp,atnr,i,j));
89 #endif
91 static real *mk_nbfp(t_idef *idef,bool bBHAM)
93 real *nbfp;
94 int i,j,k,atnr;
96 atnr=idef->atnr;
97 if (bBHAM) {
98 snew(nbfp,3*atnr*atnr);
99 for(i=k=0; (i<atnr); i++) {
100 for(j=0; (j<atnr); j++,k++) {
101 BHAMA(nbfp,atnr,i,j) = idef->iparams[k].bham.a;
102 BHAMB(nbfp,atnr,i,j) = idef->iparams[k].bham.b;
103 BHAMC(nbfp,atnr,i,j) = idef->iparams[k].bham.c;
107 else {
108 snew(nbfp,2*atnr*atnr);
109 for(i=k=0; (i<atnr); i++) {
110 for(j=0; (j<atnr); j++,k++) {
111 C6(nbfp,atnr,i,j) = idef->iparams[k].lj.c6;
112 C12(nbfp,atnr,i,j) = idef->iparams[k].lj.c12;
116 return nbfp;
119 static void check_solvent(FILE *fp,t_topology *top,t_forcerec *fr,
120 t_mdatoms *md,t_nsborder *nsb)
122 /* This routine finds out whether a charge group can be used as
123 * solvent in the innerloops. The routine should be called once
124 * at the beginning of the MD program.
126 t_block *cgs,*excl,*mols;
127 atom_id *cgid;
128 int i,j,m,j0,j1,nj,k,aj,ak,tjA,tjB,nl_m,nl_n,nl_o;
129 int warncount;
130 bool bOneCG;
131 bool *bAllExcl,bAE,bOrder;
132 bool *bHaveLJ,*bHaveCoul;
134 cgs = &(top->blocks[ebCGS]);
135 excl = &(top->atoms.excl);
136 mols = &(top->blocks[ebMOLS]);
138 if (fp)
139 fprintf(fp,"Going to determine what solvent types we have.\n");
140 snew(fr->solvent_type,cgs->nr+1);
141 snew(fr->mno_index,(cgs->nr+1)*3);
143 /* Generate charge group number for all atoms */
144 cgid = make_invblock(cgs,cgs->nra);
146 warncount=0;
148 /* Loop over molecules */
149 if (fp)
150 fprintf(fp,"There are %d molecules, %d charge groups and %d atoms\n",
151 mols->nr,cgs->nr,cgs->nra);
152 for(i=0; (i<mols->nr); i++) {
153 /* Set boolean that determines whether the molecules consists of one CG */
154 bOneCG = TRUE;
155 /* Set some counters */
156 j0 = mols->index[i];
157 j1 = mols->index[i+1];
158 nj = j1-j0;
159 for(j=j0+1; (j<j1); j++) {
160 bOneCG = bOneCG && (cgid[mols->a[j]] == cgid[mols->a[j-1]]);
162 if (fr->bSolvOpt && bOneCG && nj>1) {
163 /* Check whether everything is excluded */
164 snew(bAllExcl,nj);
165 bAE = TRUE;
166 /* Loop over all atoms in molecule */
167 for(j=j0; (j<j1) && bAE; j++) {
168 /* Set a flag for each atom in the molecule that determines whether
169 * it is excluded or not
171 for(k=0; (k<nj); k++)
172 bAllExcl[k] = FALSE;
173 /* Now check all the exclusions of this atom */
174 for(k=excl->index[j]; (k<excl->index[j+1]); k++) {
175 ak = excl->a[k];
176 /* Consistency and range check */
177 if ((ak < j0) || (ak >= j1))
178 fatal_error(0,"Exclusion outside molecule? ak = %d, j0 = %d, j1 = 5d, mol is %d",ak,j0,j1,i);
179 bAllExcl[ak-j0] = TRUE;
181 /* Now sum up the booleans */
182 for(k=0; (k<nj); k++)
183 bAE = bAE && bAllExcl[k];
185 if (bAE) {
186 snew(bHaveCoul,nj);
187 snew(bHaveLJ,nj);
188 for(j=j0; (j<j1); j++) {
189 /* Check for coulomb */
190 aj = mols->a[j];
191 bHaveCoul[j-j0] = ((top->atoms.atom[aj].q != 0.0) ||
192 (top->atoms.atom[aj].qB != 0.0));
193 /* Check for LJ. */
194 tjA = top->atoms.atom[aj].type;
195 tjB = top->atoms.atom[aj].typeB;
196 bHaveLJ[j-j0] = FALSE;
197 for(k=0; (k<fr->ntype); k++) {
198 if (fr->bBHAM)
199 bHaveLJ[j-j0] = (bHaveLJ[j-j0] ||
200 (BHAMA(fr->nbfp,fr->ntype,tjA,k) != 0.0) ||
201 (BHAMB(fr->nbfp,fr->ntype,tjA,k) != 0.0) ||
202 (BHAMC(fr->nbfp,fr->ntype,tjA,k) != 0.0) ||
203 (BHAMA(fr->nbfp,fr->ntype,tjB,k) != 0.0) ||
204 (BHAMB(fr->nbfp,fr->ntype,tjB,k) != 0.0) ||
205 (BHAMC(fr->nbfp,fr->ntype,tjB,k) != 0.0));
206 else
207 bHaveLJ[j-j0] = (bHaveLJ[j-j0] ||
208 (C6(fr->nbfp,fr->ntype,tjA,k) != 0.0) ||
209 (C12(fr->nbfp,fr->ntype,tjA,k) != 0.0) ||
210 (C6(fr->nbfp,fr->ntype,tjB,k) != 0.0) ||
211 (C12(fr->nbfp,fr->ntype,tjB,k) != 0.0));
214 /* Now we have determined what particles have which interactions
215 * In the case of water-like molecules we only check for the number
216 * of particles and the LJ, not for the Coulomb. Let's just assume
217 * that the water loops are faster than the MNO loops anyway. DvdS
219 /* No - there's another problem: To optimize the water
220 * innerloop assumes the charge of the first i atom is constant
221 * qO, and charge on atoms 2/3 is constant qH. /EL
223 /* I won't write any altivec versions of the general solvent inner
224 * loops. Thus, when USE_PPC_ALTIVEC is defined it is faster
225 * to use the normal loops instead of the MNO solvent version. /EL
227 aj=mols->a[j0];
228 if((nj==3) && bHaveCoul[0] && bHaveLJ[0] &&
229 !bHaveLJ[1] && !bHaveLJ[2] &&
230 (top->atoms.atom[aj+1].q == top->atoms.atom[aj+2].q))
231 fr->solvent_type[cgid[aj]] = esolWATER;
232 else {
233 #ifdef USE_PPC_ALTIVEC
234 fr->solvent_type[cgid[aj]] = esolNO;
235 #else
236 /* Time to compute M & N & O */
237 for(k=0; (k<nj) && (bHaveLJ[k] && bHaveCoul[k]); k++)
239 nl_n = k;
240 for(; (k<nj) && (!bHaveLJ[k] && bHaveCoul[k]); k++)
242 nl_o = k;
243 for(; (k<nj) && (bHaveLJ[k] && !bHaveCoul[k]); k++)
245 nl_m = k;
246 /* Now check whether we're at the end of the pack */
247 bOrder = FALSE;
248 for(; (k<nj); k++)
249 bOrder = bOrder || (bHaveLJ[k] || bHaveCoul[k]);
250 if (bOrder) {
251 /* If we have a solvent molecule with LJC everywhere, then
252 * we shouldn't issue a warning. Only if we suspect something
253 * could be better.
255 if (nl_n != nj) {
256 warncount++;
257 if(warncount<11)
258 fprintf(fp,"The order in molecule %d could be optimized"
259 " for better performance\n",i);
260 if(warncount==10)
261 fprintf(fp,"(More than 10 molecules where the order can be optimized)\n");
263 nl_m = nl_n = nl_o = nj;
265 fr->mno_index[cgid[aj]*3] = nl_m;
266 fr->mno_index[cgid[aj]*3+1] = nl_n;
267 fr->mno_index[cgid[aj]*3+2] = nl_o;
268 fr->solvent_type[cgid[aj]] = esolMNO;
269 #endif /* MNO solvent if not using altivec */
272 /* Last check for perturbed atoms */
273 for(j=j0; (j<j1); j++)
274 if (md->bPerturbed[mols->a[j]])
275 fr->solvent_type[cgid[mols->a[j0]]] = esolNO;
277 sfree(bHaveLJ);
278 sfree(bHaveCoul);
280 else {
281 /* Turn off solvent optimization for all cg's in the molecule,
282 * here there is only one.
284 fr->solvent_type[cgid[mols->a[j0]]] = esolNO;
286 sfree(bAllExcl);
288 else {
289 /* Turn off solvent optimization for all cg's in the molecule */
290 for(j=mols->index[i]; (j<mols->index[i+1]); j++) {
291 fr->solvent_type[cgid[mols->a[j]]] = esolNO;
295 if (debug) {
296 for(i=0; (i<cgs->nr); i++)
297 fprintf(debug,"MNO: cg = %5d, m = %2d, n = %2d, o = %2d\n",
298 i,fr->mno_index[3*i],fr->mno_index[3*i+1],fr->mno_index[3*i+2]);
301 /* Now compute the number of solvent molecules, could be merged with code above */
302 fr->nMNOMol = 0;
303 fr->nWatMol = 0;
304 for(m=0; m<3; m++)
305 fr->nMNOav[m] = 0;
306 for(i=0; i<mols->nr; i++) {
307 j = mols->a[mols->index[i]];
308 if (j>=START(nsb) && j<START(nsb)+HOMENR(nsb)) {
309 if (fr->solvent_type[cgid[j]] == esolMNO) {
310 fr->nMNOMol++;
311 for(m=0; m<3; m++)
312 fr->nMNOav[m] += fr->mno_index[3*cgid[j]+m];
314 else if (fr->solvent_type[cgid[j]] == esolWATER)
315 fr->nWatMol++;
318 if (fr->nMNOMol > 0)
319 for(m=0; (m<3); m++)
320 fr->nMNOav[m] /= fr->nMNOMol;
322 sfree(cgid);
324 if (fp) {
325 fprintf(fp,"There are %d optimized solvent molecules on node %d\n",
326 fr->nMNOMol,nsb->nodeid);
327 if (fr->nMNOMol > 0)
328 fprintf(fp," aver. nr. of atoms per molecule: vdwc %.1f coul %.1f vdw %.1f\n",
329 fr->nMNOav[1],fr->nMNOav[2]-fr->nMNOav[1],fr->nMNOav[0]-fr->nMNOav[2]);
330 fprintf(fp,"There are %d optimized water molecules on node %d\n",
331 fr->nWatMol,nsb->nodeid);
335 static void calc_rffac(FILE *log,int eel,real eps,real Rc,real Temp,
336 real zsq,matrix box,
337 real *kappa,real *epsfac,real *krf,real *crf)
339 /* Compute constants for Generalized reaction field */
340 static bool bFirst=TRUE;
341 real k1,k2,I,vol,rmin;
343 if ((eel == eelRF) || (eel == eelGRF)) {
344 vol = det(box);
345 I = zsq/vol;
346 if (eel == eelGRF) {
347 /* Consistency check */
348 if (Temp <= 0.0)
349 fatal_error(0,"Temperature is %f while using"
350 " Generalized Reaction Field\n",Temp);
351 /* Ionic strength (only needed for eelGRF */
352 *kappa = sqrt(2*I/(EPSILON0*eps*BOLTZ*Temp));
354 else
355 *kappa = 0;
357 /* eps == 0 signals infinite dielectric */
358 if (eps == 0) {
359 *krf = 1/(2*Rc*Rc*Rc);
360 *crf = 0;
362 else {
363 k1 = (1+*kappa*Rc);
364 k2 = eps*sqr((real)(*kappa*Rc));
366 *krf = (((eps-1)*k1+k2)/((2*eps+1)*k1+2*k2)/(Rc*Rc*Rc));
367 *crf = 1/Rc + *krf*Rc*Rc;
369 *epsfac = ONE_4PI_EPS0;
370 rmin = pow(*krf*2.0,-1.0/3.0);
372 if (bFirst) {
373 if (eel == eelGRF)
374 please_cite(log,"Tironi95a");
375 fprintf(log,"%s:\n"
376 "epsRF = %10g, I = %10g, volume = %10g, kappa = %10g\n"
377 "rc = %10g, krf = %10g, crf = %10g, epsfac = %10g\n",
378 eel_names[eel],eps,I,vol,*kappa,Rc,*krf,*crf,*epsfac);
379 fprintf(log,
380 "The electrostatics potential has its minimum at rc = %g\n",
381 rmin);
383 bFirst=FALSE;
386 else {
387 /* If we're not using a reaction field, set the factor to 0
388 * and multiply the dielectric constant by 1/eps
390 *kappa = 0.0;
391 *krf = 0.0;
392 *crf = 0.0;
393 if (eps == 0)
394 eps = 1;
395 *epsfac = ONE_4PI_EPS0/eps;
399 void update_forcerec(FILE *log,t_forcerec *fr,matrix box)
401 calc_rffac(log,fr->eeltype,
402 fr->epsilon_r,fr->rcoulomb,fr->temp,fr->zsquare,box,
403 &fr->kappa,&fr->epsfac,&fr->k_rf,&fr->c_rf);
406 static double calc_avcsix(FILE *log,real *nbfp,int atnr,
407 int natoms,int type[],bool bBHAM)
409 int i,j,tpi,tpj;
410 double csix;
412 /* Check this code: do we really need a double loop? */
413 csix = 0;
414 for(i=0; (i<natoms); i++) {
415 tpi = type[i];
416 #ifdef DEBUG
417 if (tpi >= atnr)
418 fatal_error(0,"Atomtype[%d] = %d, maximum = %d",i,tpi,atnr);
419 #endif
420 for(j=0; (j<natoms); j++) {
421 tpj = type[j];
422 #ifdef DEBUG
423 if (tpj >= atnr)
424 fatal_error(0,"Atomtype[%d] = %d, maximum = %d",j,tpj,atnr);
425 #endif
426 if (bBHAM)
427 csix += BHAMC(nbfp,atnr,tpi,tpj);
428 else
429 csix += C6(nbfp,atnr,tpi,tpj);
432 csix /= (natoms*natoms);
433 if (debug)
434 fprintf(debug,"Average C6 parameter is: %10g\n",csix);
436 return csix;
439 void set_avcsix(FILE *log,t_forcerec *fr,t_mdatoms *mdatoms)
441 fr->avcsix=calc_avcsix(log,fr->nbfp,fr->ntype,mdatoms->nr,
442 mdatoms->typeA,fr->bBHAM);
445 static void set_bham_b_max(FILE *log,t_forcerec *fr,t_mdatoms *mdatoms)
447 int i,j,tpi,tpj,ntypes,natoms,*type;
448 real b,bmin;
449 real *nbfp;
451 fprintf(log,"Determining largest Buckingham b parameter for table\n");
452 nbfp = fr->nbfp;
453 ntypes = fr->ntype;
454 type = mdatoms->typeA;
455 natoms = mdatoms->nr;
457 bmin = -1;
458 fr->bham_b_max = 0;
459 for(i=0; (i<natoms); i++) {
460 tpi = type[i];
461 if (tpi >= ntypes)
462 fatal_error(0,"Atomtype[%d] = %d, maximum = %d",i,tpi,ntypes);
464 for(j=0; (j<natoms); j++) {
465 tpj = type[j];
466 if (tpj >= ntypes)
467 fatal_error(0,"Atomtype[%d] = %d, maximum = %d",j,tpj,ntypes);
468 b = BHAMB(nbfp,ntypes,tpi,tpj);
469 if (b > fr->bham_b_max)
470 fr->bham_b_max = b;
471 if ((b < bmin) || (bmin==-1))
472 bmin = b;
475 fprintf(log,"Buckingham b parameters, min: %g, max: %g\n",
476 bmin,fr->bham_b_max);
479 void init_forcerec(FILE *fp,
480 t_forcerec *fr,
481 t_inputrec *ir,
482 t_topology *top,
483 t_commrec *cr,
484 t_mdatoms *mdatoms,
485 t_nsborder *nsb,
486 matrix box,
487 bool bMolEpot,
488 char *tabfn,
489 bool bNoSolvOpt)
491 int i,j,m,natoms,ngrp,tabelemsize;
492 real q,zsq,nrdf,T;
493 rvec box_size;
494 double rtab;
495 t_block *mols,*cgs;
496 t_idef *idef;
498 if (check_box(box))
499 fatal_error(0,check_box(box));
501 cgs = &(top->blocks[ebCGS]);
502 mols = &(top->blocks[ebMOLS]);
503 idef = &(top->idef);
505 natoms = mdatoms->nr;
507 /* Shell stuff */
508 fr->fc_stepsize = ir->fc_stepsize;
510 /* Free energy */
511 fr->efep = ir->efep;
512 fr->sc_alpha = ir->sc_alpha;
513 fr->sc_sigma6 = pow(ir->sc_sigma,6);
515 /* Neighbour searching stuff */
516 fr->bGrid = (ir->ns_type == ensGRID);
517 fr->ndelta = ir->ndelta;
518 fr->ePBC = ir->ePBC;
519 fr->rlist = ir->rlist;
520 fr->rlistlong = max(ir->rlist,max(ir->rcoulomb,ir->rvdw));
521 fr->eeltype = ir->coulombtype;
522 fr->vdwtype = ir->vdwtype;
524 fr->bTwinRange = fr->rlistlong > fr->rlist;
525 fr->bEwald = fr->eeltype==eelPME || fr->eeltype==eelEWALD;
526 fr->bvdwtab = fr->vdwtype != evdwCUT;
527 fr->bRF = (fr->eeltype==eelRF || fr->eeltype==eelGRF) &&
528 fr->vdwtype==evdwCUT;
529 fr->bcoultab = (fr->eeltype!=eelCUT && !fr->bRF) || fr->bEwald;
531 if (getenv("GMX_FORCE_TABLES")) {
532 fr->bvdwtab = TRUE;
533 fr->bcoultab = TRUE;
536 if (fp) {
537 fprintf(fp,"Table routines are used for coulomb: %s\n",bool_names[fr->bcoultab]);
538 fprintf(fp,"Table routines are used for vdw: %s\n",bool_names[fr->bvdwtab ]);
541 /* Tables are used for direct ewald sum */
542 if(fr->bEwald) {
543 fr->ewaldcoeff=calc_ewaldcoeff(ir->rcoulomb, ir->ewald_rtol);
544 if (fp)
545 fprintf(fp,"Using a Gaussian width (1/beta) of %g nm for Ewald\n",
546 1/fr->ewaldcoeff);
549 /* Domain decomposition parallellism... */
550 fr->bDomDecomp = ir->bDomDecomp;
551 fr->Dimension = ir->decomp_dir;
553 /* Electrostatics */
554 fr->epsilon_r = ir->epsilon_r;
555 fr->fudgeQQ = ir->fudgeQQ;
556 fr->rcoulomb_switch = ir->rcoulomb_switch;
557 fr->rcoulomb = ir->rcoulomb;
559 if (bNoSolvOpt || getenv("GMX_NO_SOLV_OPT"))
560 fr->bSolvOpt = FALSE;
561 else
562 fr->bSolvOpt = TRUE;
564 /* Parameters for generalized RF */
565 fr->zsquare = 0.0;
566 fr->temp = 0.0;
568 if (fr->eeltype == eelGRF) {
569 zsq = 0.0;
570 for (i=0; (i<cgs->nr); i++) {
571 q = 0;
572 for(j=cgs->index[i]; (j<cgs->index[i+1]); j++)
573 q+=mdatoms->chargeT[cgs->a[j]];
574 if (q != 0.0)
575 /* Changed from square to fabs 990314 DvdS
576 * Does not make a difference for monovalent ions, but doe for
577 * divalent ions (Ca2+!!)
579 zsq += fabs(q);
581 fr->zsquare = zsq;
583 T = 0.0;
584 nrdf = 0.0;
585 for(i=0; (i<ir->opts.ngtc); i++) {
586 nrdf += ir->opts.nrdf[i];
587 T += (ir->opts.nrdf[i] * ir->opts.ref_t[i]);
589 if (nrdf == 0)
590 fatal_error(0,"No degrees of freedom!");
591 fr->temp = T/nrdf;
593 else if (EEL_LR(fr->eeltype) || (fr->eeltype == eelSHIFT) ||
594 (fr->eeltype == eelUSER) || (fr->eeltype == eelSWITCH)) {
595 /* We must use the long range cut-off for neighboursearching...
596 * An extra range of e.g. 0.1 nm (half the size of a charge group)
597 * is necessary for neighboursearching. This allows diffusion
598 * into the cut-off range (between neighborlist updates),
599 * and gives more accurate forces because all atoms within the short-range
600 * cut-off rc must be taken into account, while the ns criterium takes
601 * only those with the center of geometry within the cut-off.
602 * (therefore we have to add half the size of a charge group, plus
603 * something to account for diffusion if we have nstlist > 1)
605 for(m=0; (m<DIM); m++)
606 box_size[m]=box[m][m];
608 if (fr->phi == NULL)
609 snew(fr->phi,mdatoms->nr);
611 if ((fr->eeltype==eelPPPM) || (fr->eeltype==eelPOISSON) ||
612 (fr->eeltype == eelSHIFT && fr->rcoulomb > fr->rcoulomb_switch))
613 set_shift_consts(fp,fr->rcoulomb_switch,fr->rcoulomb,box_size,fr);
616 /* Initiate arrays */
617 if (fr->bTwinRange) {
618 snew(fr->f_twin,natoms);
619 snew(fr->fshift_twin,SHIFTS);
622 if (EEL_LR(fr->eeltype)) {
623 snew(fr->f_pme,natoms);
626 /* Mask that says whether or not this NBF list should be computed */
627 /* if (fr->bMask == NULL) {
628 ngrp = ir->opts.ngener*ir->opts.ngener;
629 snew(fr->bMask,ngrp);*/
630 /* Defaults to always */
631 /* for(i=0; (i<ngrp); i++)
632 fr->bMask[i] = TRUE;
635 if (fr->cg_cm == NULL)
636 snew(fr->cg_cm,cgs->nr);
637 if (fr->shift_vec == NULL)
638 snew(fr->shift_vec,SHIFTS);
640 if (fr->fshift == NULL)
641 snew(fr->fshift,SHIFTS);
643 if (bMolEpot && (fr->nmol==0)) {
644 fr->nmol=mols->nr;
645 fr->mol_nr=make_invblock(mols,natoms);
646 snew(fr->mol_epot,fr->nmol);
647 fr->nstcalc=ir->nstenergy;
650 if (fr->nbfp == NULL) {
651 fr->ntype = idef->atnr;
652 fr->bBHAM = (idef->functype[0] == F_BHAM);
653 fr->nbfp = mk_nbfp(idef,fr->bBHAM);
655 /* Copy the energy group exclusions */
656 fr->eg_excl = ir->opts.eg_excl;
658 /* Van der Waals stuff */
659 fr->rvdw = ir->rvdw;
660 fr->rvdw_switch = ir->rvdw_switch;
661 if ((fr->vdwtype != evdwCUT) && (fr->vdwtype != evdwUSER) && !fr->bBHAM) {
662 if (fr->rvdw_switch >= fr->rvdw)
663 fatal_error(0,"rvdw_switch (%g) must be < rvdw (%g)",
664 fr->rvdw_switch,fr->rvdw);
665 if (fp)
666 fprintf(fp,"Using %s Lennard-Jones, switch between %g and %g nm\n",
667 (fr->eeltype==eelSWITCH) ? "switched":"shifted",
668 fr->rvdw_switch,fr->rvdw);
671 if (fp)
672 fprintf(fp,"Cut-off's: NS: %g Coulomb: %g %s: %g\n",
673 fr->rlist,fr->rcoulomb,fr->bBHAM ? "BHAM":"LJ",fr->rvdw);
675 if (ir->eDispCorr != edispcNO)
676 set_avcsix(fp,fr,mdatoms);
677 if (fr->bBHAM)
678 set_bham_b_max(fp,fr,mdatoms);
680 /* Copy the GBSA data (radius, volume and surftens for each
681 * atomtype) from the topology atomtype section to forcerec.
683 snew(fr->atype_radius,fr->ntype);
684 snew(fr->atype_vol,fr->ntype);
685 snew(fr->atype_surftens,fr->ntype);
686 for(i=0;i<fr->ntype;i++)
687 fr->atype_radius[i]=top->atomtypes.radius[i];
688 for(i=0;i<fr->ntype;i++)
689 fr->atype_vol[i]=top->atomtypes.vol[i];
690 for(i=0;i<fr->ntype;i++)
691 fr->atype_surftens[i]=top->atomtypes.surftens[i];
693 /* Now update the rest of the vars */
694 update_forcerec(fp,fr,box);
695 /* if we are using LR electrostatics, and they are tabulated,
696 * the tables will contain shifted coulomb interactions.
697 * Since we want to use the non-shifted ones for 1-4
698 * coulombic interactions, we must have an extra set of
699 * tables. This should be done in tables.c, instead of this
700 * ugly hack, but it works for now...
703 #define MAX_14_DIST 1.0
704 /* Shell to account for the maximum chargegroup radius (2*0.2 nm)
705 * and diffusion during nstlist steps (0.2 nm)
706 * Changed 020624: Increased to 1.2 since we never check for this,
707 * so we must make absolutely sure the table length is always
708 * sufficient. It doesn't affect the performance either...
710 #define TAB_EXT 1.2
712 /* Construct tables.
713 * A little unnecessary to make both vdw and coul tables sometimes,
714 * but what the heck... */
716 if (fr->bcoultab || fr->bvdwtab) {
717 if (EEL_LR(fr->eeltype)) {
718 bool bcoulsave,bvdwsave;
719 /* generate extra tables for 1-4 interactions only
720 * fake the forcerec so make_tables thinks it should
721 * just create the non shifted version
723 bcoulsave=fr->bcoultab;
724 bvdwsave=fr->bvdwtab;
725 fr->bcoultab=FALSE;
726 fr->bvdwtab=FALSE;
727 fr->rtab=MAX_14_DIST;
728 make_tables(fp,fr,MASTER(cr),tabfn);
729 fr->bcoultab=bcoulsave;
730 fr->bvdwtab=bvdwsave;
731 fr->coulvdw14tab=fr->coulvdwtab;
732 fr->coulvdwtab=NULL;
734 fr->rtab = max(fr->rlistlong+TAB_EXT,MAX_14_DIST);
736 else if (fr->efep != efepNO) {
737 if (fr->rlistlong == 0) {
738 char *ptr,*envvar="FEP_TABLE_LENGTH";
739 fr->rtab = 5;
740 ptr = getenv(envvar);
741 if (ptr) {
742 sscanf(ptr,"%lf",&rtab);
743 fr->rtab = rtab;
745 if (fp)
746 fprintf(fp,"\nNote: Setting the free energy table length to %g nm\n"
747 " You can set this value with the environment variable %s"
748 "\n\n",fr->rtab,envvar);
750 else
751 fr->rtab = max(fr->rlistlong+TAB_EXT,MAX_14_DIST);
753 else
754 fr->rtab = MAX_14_DIST;
756 /* make tables for ordinary interactions */
757 make_tables(fp,fr,MASTER(cr),tabfn);
758 if(!(EEL_LR(fr->eeltype) && (fr->bcoultab || fr->bvdwtab)))
759 fr->coulvdw14tab=fr->coulvdwtab;
761 /* Copy the contents of the table to separate coulomb and LJ
762 * tables too, to improve cache performance.
764 tabelemsize=fr->bBHAM ? 16 : 12;
765 snew(fr->coultab,4*(fr->ntab+1));
766 snew(fr->vdwtab,(tabelemsize-4)*(fr->ntab+1));
767 for(i=0; i<=fr->ntab; i++) {
768 for(j=0; j<4; j++)
769 fr->coultab[4*i+j]=fr->coulvdwtab[tabelemsize*i+j];
770 for(j=0; j<tabelemsize-4; j++)
771 fr->vdwtab[(tabelemsize-4)*i+j]=fr->coulvdwtab[tabelemsize*i+4+j];
773 if (!fr->mno_index)
774 check_solvent(fp,top,fr,mdatoms,nsb);
777 #define pr_real(fp,r) fprintf(fp,"%s: %e\n",#r,r)
778 #define pr_int(fp,i) fprintf((fp),"%s: %d\n",#i,i)
779 #define pr_bool(fp,b) fprintf((fp),"%s: %s\n",#b,bool_names[b])
781 void pr_forcerec(FILE *fp,t_forcerec *fr,t_commrec *cr)
783 pr_real(fp,fr->rlist);
784 pr_real(fp,fr->rcoulomb);
785 pr_real(fp,fr->fudgeQQ);
786 pr_int(fp,fr->ndelta);
787 pr_bool(fp,fr->bGrid);
788 pr_bool(fp,fr->bTwinRange);
789 /*pr_int(fp,fr->cg0);
790 pr_int(fp,fr->hcg);*/
791 pr_int(fp,fr->ntab);
792 if (fr->ntab > 0) {
793 pr_real(fp,fr->rcoulomb_switch);
794 pr_real(fp,fr->rcoulomb);
797 pr_int(fp,fr->nmol);
798 pr_int(fp,fr->nstcalc);
800 fflush(fp);
803 void ns(FILE *fp,
804 t_forcerec *fr,
805 rvec x[],
806 rvec f[],
807 matrix box,
808 t_groups *grps,
809 t_grpopts *opts,
810 t_topology *top,
811 t_mdatoms *md,
812 t_commrec *cr,
813 t_nrnb *nrnb,
814 t_nsborder *nsb,
815 int step,
816 real lambda,
817 real *dvdlambda)
819 static bool bFirst=TRUE;
820 static int nDNL;
821 char *ptr;
822 int nsearch;
824 if (bFirst) {
825 ptr=getenv("DUMPNL");
826 if (ptr) {
827 nDNL=atoi(ptr);
828 fprintf(fp,"nDNL = %d\n",nDNL);
829 } else
830 nDNL=0;
831 /* Allocate memory for the neighbor lists */
832 init_neighbor_list(fp,fr,HOMENR(nsb));
834 bFirst=FALSE;
837 if (fr->bTwinRange)
838 fr->nlr=0;
840 /* Whether or not we do dynamic load balancing,
841 * workload contains the proper numbers of charge groups
842 * to be searched.
844 if (cr->nodeid == 0)
845 fr->cg0=0;
846 else
847 fr->cg0=nsb->workload[cr->nodeid-1];
848 fr->hcg=nsb->workload[cr->nodeid];
850 nsearch = search_neighbours(fp,fr,x,box,top,grps,cr,nsb,nrnb,md,
851 lambda,dvdlambda);
852 if (debug)
853 fprintf(debug,"nsearch = %d\n",nsearch);
855 /* Check whether we have to do dynamic load balancing */
856 /*if ((nsb->nstDlb > 0) && (mod(step,nsb->nstDlb) == 0))
857 count_nb(cr,nsb,&(top->blocks[ebCGS]),nns,fr->nlr,
858 &(top->idef),opts->ngener);
860 if (nDNL > 0)
861 dump_nblist(fp,fr,nDNL);
864 void force(FILE *fp, int step,
865 t_forcerec *fr, t_inputrec *ir,
866 t_idef *idef, t_nsborder *nsb,
867 t_commrec *cr, t_commrec *mcr,
868 t_nrnb *nrnb,
869 t_groups *grps, t_mdatoms *md,
870 int ngener, t_grpopts *opts,
871 rvec x[], rvec f[],
872 real epot[], t_fcdata *fcd,
873 bool bVerbose, matrix box,
874 real lambda, t_graph *graph,
875 t_block *excl, bool bNBFonly,
876 matrix lr_vir, rvec mu_tot,
877 real qsum, bool bGatherOnly)
879 int i,nit;
880 bool bDoEpot;
881 rvec box_size;
882 real Vlr,Vcorr=0;
884 /* Reset box */
885 for(i=0; (i<DIM); i++)
886 box_size[i]=box[i][i];
888 bDoEpot=((fr->nmol > 0) && (fr->nstcalc > 0) && (mod(step,fr->nstcalc)==0));
889 /* Reset epot... */
890 if (bDoEpot)
891 for(i=0; (i<fr->nmol); i++)
892 fr->mol_epot[i]=0.0;
893 debug_gmx();
895 /* Call the short range functions all in one go. */
896 do_fnbf(fp,cr,fr,x,f,md,
897 fr->bBHAM ? grps->estat.ee[egBHAM] : grps->estat.ee[egLJ],
898 grps->estat.ee[egCOUL],box_size,nrnb,
899 lambda,&epot[F_DVDL],FALSE,-1);
900 debug_gmx();
902 if (debug)
903 pr_rvecs(debug,0,"fshift after SR",fr->fshift,SHIFTS);
905 /* Shift the coordinates. Must be done before bonded forces and PPPM,
906 * but is also necessary for SHAKE and update, therefore it can NOT
907 * go when no bonded forces have to be evaluated.
909 if (debug && 0)
910 p_graph(debug,"DeBUGGGG",graph);
912 /* Check whether we need to do bondeds */
913 if (!bNBFonly) {
914 shift_self(graph,box,x);
915 if (debug && 0) {
916 fprintf(debug,"BBBBBBBBBBBBBBBB\n");
917 fprintf(debug,"%5d\n",graph->nnodes);
918 for(i=graph->start; (i<=graph->end); i++)
919 fprintf(debug,"%5d%5s%5s%5d%8.3f%8.3f%8.3f\n",
920 i,"A","B",i,x[i][XX],x[i][YY],x[i][ZZ]);
921 fprintf(debug,"%10.5f%10.5f%10.5f\n",
922 box[XX][XX],box[YY][YY],box[ZZ][ZZ]);
924 if (TRICLINIC(box))
925 inc_nrnb(nrnb,eNR_SHIFTX,2*graph->nnodes);
926 else
927 inc_nrnb(nrnb,eNR_SHIFTX,graph->nnodes);
928 debug_gmx();
931 if (EEL_LR(fr->eeltype)) {
932 switch (fr->eeltype) {
933 case eelPPPM:
934 Vlr = do_pppm(fp,FALSE,x,fr->f_pme,md->chargeT,
935 box_size,fr->phi,cr,nsb,nrnb);
936 break;
937 case eelPME:
938 Vlr = do_pme(fp,FALSE,ir,x,fr->f_pme,md->chargeT,
939 box,cr,nsb,nrnb,lr_vir,fr->ewaldcoeff,bGatherOnly);
940 break;
941 case eelEWALD:
942 Vlr = do_ewald(fp,FALSE,ir,x,fr->f_pme,md->chargeT,
943 box_size,cr,nsb,lr_vir,fr->ewaldcoeff);
944 break;
945 default:
946 Vlr = 0;
947 fatal_error(0,"No such electrostatics method implemented %s",
948 eel_names[fr->eeltype]);
950 if(fr->bEwald)
951 Vcorr =
952 ewald_LRcorrection(fp,nsb,cr,fr,md->chargeT,excl,x,box,mu_tot,qsum,
953 ir->ewald_geometry,ir->epsilon_surface,lr_vir);
954 else
955 Vcorr = shift_LRcorrection(fp,nsb,cr,fr,md->chargeT,excl,x,TRUE,box,lr_vir);
956 epot[F_LR] = Vlr + Vcorr;
957 if (debug)
958 fprintf(debug,"Vlr = %g, Vcorr = %g, Vlr_corr = %g\n",
959 Vlr,Vcorr,epot[F_LR]);
960 if (debug) {
961 pr_rvecs(debug,0,"lr_vir after corr",lr_vir,DIM);
962 pr_rvecs(debug,0,"fshift after LR Corrections",fr->fshift,SHIFTS);
965 debug_gmx();
967 if (debug)
968 print_nrnb(debug,nrnb);
969 debug_gmx();
971 if (!bNBFonly) {
972 calc_bonds(fp,cr,mcr,
973 idef,x,f,fr,graph,epot,nrnb,box,lambda,md,
974 opts->ngener,grps->estat.ee[egLJ14],grps->estat.ee[egCOUL14],
975 fcd,step,fr->bSepDVDL && do_per_step(step,ir->nstlog));
976 debug_gmx();
978 if (debug)
979 pr_rvecs(debug,0,"fshift after bondeds",fr->fshift,SHIFTS);
981 for(i=0; (i<F_EPOT); i++)
982 if (i != F_DISRES)
983 epot[F_EPOT]+=epot[i];