4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
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
30 * Getting the Right Output Means no Artefacts in Calculating Stuff
55 #include "ewald_util.h"
56 #include "shift_util.h"
63 t_forcerec
*mk_forcerec(void)
73 static void pr_nbfp(FILE *fp
,real
*nbfp
,bool bBHAM
,int atnr
)
77 for(i
=0; (i
<atnr
); i
++) {
78 for(j
=0; (j
<atnr
); j
++) {
79 fprintf(fp
,"%2d - %2d",i
,j
);
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
));
84 fprintf(fp
," c6=%10g, c12=%10g\n",C6(nbfp
,atnr
,i
,j
),
91 static real
*mk_nbfp(t_idef
*idef
,bool 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
;
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
;
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
;
128 int i
,j
,m
,j0
,j1
,nj
,k
,aj
,ak
,tjA
,tjB
,nl_m
,nl_n
,nl_o
;
131 bool *bAllExcl
,bAE
,bOrder
;
132 bool *bHaveLJ
,*bHaveCoul
;
134 cgs
= &(top
->blocks
[ebCGS
]);
135 excl
= &(top
->atoms
.excl
);
136 mols
= &(top
->blocks
[ebMOLS
]);
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
);
148 /* Loop over molecules */
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 */
155 /* Set some counters */
157 j1
= mols
->index
[i
+1];
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 */
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
++)
173 /* Now check all the exclusions of this atom */
174 for(k
=excl
->index
[j
]; (k
<excl
->index
[j
+1]); 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
];
188 for(j
=j0
; (j
<j1
); j
++) {
189 /* Check for coulomb */
191 bHaveCoul
[j
-j0
] = ((top
->atoms
.atom
[aj
].q
!= 0.0) ||
192 (top
->atoms
.atom
[aj
].qB
!= 0.0));
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
++) {
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));
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
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
;
233 #ifdef USE_PPC_ALTIVEC
234 fr
->solvent_type
[cgid
[aj
]] = esolNO
;
236 /* Time to compute M & N & O */
237 for(k
=0; (k
<nj
) && (bHaveLJ
[k
] && bHaveCoul
[k
]); k
++)
240 for(; (k
<nj
) && (!bHaveLJ
[k
] && bHaveCoul
[k
]); k
++)
243 for(; (k
<nj
) && (bHaveLJ
[k
] && !bHaveCoul
[k
]); k
++)
246 /* Now check whether we're at the end of the pack */
249 bOrder
= bOrder
|| (bHaveLJ
[k
] || bHaveCoul
[k
]);
251 /* If we have a solvent molecule with LJC everywhere, then
252 * we shouldn't issue a warning. Only if we suspect something
258 fprintf(fp
,"The order in molecule %d could be optimized"
259 " for better performance\n",i
);
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
;
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
;
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
;
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 */
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
) {
312 fr
->nMNOav
[m
] += fr
->mno_index
[3*cgid
[j
]+m
];
314 else if (fr
->solvent_type
[cgid
[j
]] == esolWATER
)
320 fr
->nMNOav
[m
] /= fr
->nMNOMol
;
325 fprintf(fp
,"There are %d optimized solvent molecules on node %d\n",
326 fr
->nMNOMol
,nsb
->nodeid
);
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
,
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
)) {
347 /* Consistency check */
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
));
357 /* eps == 0 signals infinite dielectric */
359 *krf
= 1/(2*Rc
*Rc
*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);
374 please_cite(log
,"Tironi95a");
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
);
380 "The electrostatics potential has its minimum at rc = %g\n",
387 /* If we're not using a reaction field, set the factor to 0
388 * and multiply the dielectric constant by 1/eps
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
)
412 /* Check this code: do we really need a double loop? */
414 for(i
=0; (i
<natoms
); i
++) {
418 fatal_error(0,"Atomtype[%d] = %d, maximum = %d",i
,tpi
,atnr
);
420 for(j
=0; (j
<natoms
); j
++) {
424 fatal_error(0,"Atomtype[%d] = %d, maximum = %d",j
,tpj
,atnr
);
427 csix
+= BHAMC(nbfp
,atnr
,tpi
,tpj
);
429 csix
+= C6(nbfp
,atnr
,tpi
,tpj
);
432 csix
/= (natoms
*natoms
);
434 fprintf(debug
,"Average C6 parameter is: %10g\n",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
;
451 fprintf(log
,"Determining largest Buckingham b parameter for table\n");
454 type
= mdatoms
->typeA
;
455 natoms
= mdatoms
->nr
;
459 for(i
=0; (i
<natoms
); i
++) {
462 fatal_error(0,"Atomtype[%d] = %d, maximum = %d",i
,tpi
,ntypes
);
464 for(j
=0; (j
<natoms
); j
++) {
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
)
471 if ((b
< bmin
) || (bmin
==-1))
475 fprintf(log
,"Buckingham b parameters, min: %g, max: %g\n",
476 bmin
,fr
->bham_b_max
);
479 void init_forcerec(FILE *fp
,
491 int i
,j
,m
,natoms
,ngrp
,tabelemsize
;
499 fatal_error(0,check_box(box
));
501 cgs
= &(top
->blocks
[ebCGS
]);
502 mols
= &(top
->blocks
[ebMOLS
]);
505 natoms
= mdatoms
->nr
;
508 fr
->fc_stepsize
= ir
->fc_stepsize
;
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
;
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")) {
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 */
543 fr
->ewaldcoeff
=calc_ewaldcoeff(ir
->rcoulomb
, ir
->ewald_rtol
);
545 fprintf(fp
,"Using a Gaussian width (1/beta) of %g nm for Ewald\n",
549 /* Domain decomposition parallellism... */
550 fr
->bDomDecomp
= ir
->bDomDecomp
;
551 fr
->Dimension
= ir
->decomp_dir
;
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
;
564 /* Parameters for generalized RF */
568 if (fr
->eeltype
== eelGRF
) {
570 for (i
=0; (i
<cgs
->nr
); i
++) {
572 for(j
=cgs
->index
[i
]; (j
<cgs
->index
[i
+1]); j
++)
573 q
+=mdatoms
->chargeT
[cgs
->a
[j
]];
575 /* Changed from square to fabs 990314 DvdS
576 * Does not make a difference for monovalent ions, but doe for
577 * divalent ions (Ca2+!!)
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
]);
590 fatal_error(0,"No degrees of freedom!");
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
];
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++)
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)) {
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 */
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
);
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
);
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
);
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...
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
;
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
;
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";
740 ptr
= getenv(envvar
);
742 sscanf(ptr
,"%lf",&rtab
);
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
);
751 fr
->rtab
= max(fr
->rlistlong
+TAB_EXT
,MAX_14_DIST
);
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
++) {
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
];
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);*/
793 pr_real(fp
,fr
->rcoulomb_switch
);
794 pr_real(fp
,fr
->rcoulomb
);
798 pr_int(fp
,fr
->nstcalc
);
819 static bool bFirst
=TRUE
;
825 ptr
=getenv("DUMPNL");
828 fprintf(fp
,"nDNL = %d\n",nDNL
);
831 /* Allocate memory for the neighbor lists */
832 init_neighbor_list(fp
,fr
,HOMENR(nsb
));
840 /* Whether or not we do dynamic load balancing,
841 * workload contains the proper numbers of charge groups
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
,
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);
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
,
869 t_groups
*grps
, t_mdatoms
*md
,
870 int ngener
, t_grpopts
*opts
,
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
)
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));
891 for(i
=0; (i
<fr
->nmol
); i
++)
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);
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.
910 p_graph(debug
,"DeBUGGGG",graph
);
912 /* Check whether we need to do bondeds */
914 shift_self(graph
,box
,x
);
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
]);
925 inc_nrnb(nrnb
,eNR_SHIFTX
,2*graph
->nnodes
);
927 inc_nrnb(nrnb
,eNR_SHIFTX
,graph
->nnodes
);
931 if (EEL_LR(fr
->eeltype
)) {
932 switch (fr
->eeltype
) {
934 Vlr
= do_pppm(fp
,FALSE
,x
,fr
->f_pme
,md
->chargeT
,
935 box_size
,fr
->phi
,cr
,nsb
,nrnb
);
938 Vlr
= do_pme(fp
,FALSE
,ir
,x
,fr
->f_pme
,md
->chargeT
,
939 box
,cr
,nsb
,nrnb
,lr_vir
,fr
->ewaldcoeff
,bGatherOnly
);
942 Vlr
= do_ewald(fp
,FALSE
,ir
,x
,fr
->f_pme
,md
->chargeT
,
943 box_size
,cr
,nsb
,lr_vir
,fr
->ewaldcoeff
);
947 fatal_error(0,"No such electrostatics method implemented %s",
948 eel_names
[fr
->eeltype
]);
952 ewald_LRcorrection(fp
,nsb
,cr
,fr
,md
->chargeT
,excl
,x
,box
,mu_tot
,qsum
,
953 ir
->ewald_geometry
,ir
->epsilon_surface
,lr_vir
);
955 Vcorr
= shift_LRcorrection(fp
,nsb
,cr
,fr
,md
->chargeT
,excl
,x
,TRUE
,box
,lr_vir
);
956 epot
[F_LR
] = Vlr
+ Vcorr
;
958 fprintf(debug
,"Vlr = %g, Vcorr = %g, Vlr_corr = %g\n",
959 Vlr
,Vcorr
,epot
[F_LR
]);
961 pr_rvecs(debug
,0,"lr_vir after corr",lr_vir
,DIM
);
962 pr_rvecs(debug
,0,"fshift after LR Corrections",fr
->fshift
,SHIFTS
);
968 print_nrnb(debug
,nrnb
);
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
));
979 pr_rvecs(debug
,0,"fshift after bondeds",fr
->fshift
,SHIFTS
);
981 for(i
=0; (i
<F_EPOT
); i
++)
983 epot
[F_EPOT
]+=epot
[i
];