2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
52 #include "nonbonded.h"
67 #include "mpelogging.h"
68 #include "gmx_omp_nthreads.h"
82 gmx_grppairener_t *grppener,
84 gmx_bool bDoLongRangeNS)
89 GMX_MPE_LOG(ev_ns_start);
90 if (!fr->ns.nblist_initialized)
92 init_neighbor_list(fp, fr, md->homenr);
98 nsearch = search_neighbours(fp,fr,x,box,top,groups,cr,nrnb,md,
99 lambda,dvdlambda,grppener,
100 bFillGrid,bDoLongRangeNS,TRUE);
102 fprintf(debug,"nsearch = %d\n",nsearch);
104 /* Check whether we have to do dynamic load balancing */
105 /*if ((nsb->nstDlb > 0) && (mod(step,nsb->nstDlb) == 0))
106 count_nb(cr,nsb,&(top->blocks[ebCGS]),nns,fr->nlr,
107 &(top->idef),opts->ngener);
109 if (fr->ns.dump_nl > 0)
110 dump_nblist(fp,cr,fr,fr->ns.dump_nl);
112 GMX_MPE_LOG(ev_ns_finish);
115 static void reduce_thread_forces(int n,rvec *f,
118 int efpt_ind,real *dvdl,
119 int nthreads,f_thread_t *f_t)
123 /* This reduction can run over any number of threads */
124 #pragma omp parallel for num_threads(gmx_omp_nthreads_get(emntBonded)) private(t) schedule(static)
127 for(t=1; t<nthreads; t++)
129 rvec_inc(f[i],f_t[t].f[i]);
132 for(t=1; t<nthreads; t++)
134 *Vcorr += f_t[t].Vcorr;
135 *dvdl += f_t[t].dvdl[efpt_ind];
136 m_add(vir,f_t[t].vir,vir);
140 void do_force_lowlevel(FILE *fplog, gmx_large_int_t step,
141 t_forcerec *fr, t_inputrec *ir,
142 t_idef *idef, t_commrec *cr,
143 t_nrnb *nrnb, gmx_wallcycle_t wcycle,
146 rvec x[], history_t *hist,
149 gmx_enerdata_t *enerd,
167 gmx_bool bDoEpot,bSepDVDL,bSB;
171 real Vsr,Vlr,Vcorr=0;
175 double clam_i,vlam_i;
176 real dvdl_dum[efptNR], dvdl, dvdl_nb[efptNR], lam_i[efptNR];
180 double t0=0.0,t1,t2,t3; /* time measurement for coarse load balancing */
183 #define PRINT_SEPDVDL(s,v,dvdlambda) if (bSepDVDL) fprintf(fplog,sepdvdlformat,s,v,dvdlambda);
185 GMX_MPE_LOG(ev_force_start);
186 set_pbc(&pbc,fr->ePBC,box);
188 /* reset free energy components */
189 for (i=0;i<efptNR;i++)
196 for(i=0; (i<DIM); i++)
198 box_size[i]=box[i][i];
201 bSepDVDL=(fr->bSepDVDL && do_per_step(step,ir->nstlog));
204 /* do QMMM first if requested */
207 enerd->term[F_EQM] = calculate_QMMM(cr,x,f,fr,md);
212 fprintf(fplog,"Step %s: non-bonded V and dVdl for node %d:\n",
213 gmx_step_str(step,buf),cr->nodeid);
216 /* Call the short range functions all in one go. */
217 GMX_MPE_LOG(ev_do_fnbf_start);
220 /*#define TAKETIME ((cr->npmenodes) && (fr->timesteps < 12))*/
221 #define TAKETIME FALSE
224 MPI_Barrier(cr->mpi_comm_mygroup);
231 /* foreign lambda component for walls */
232 dvdl = do_walls(ir,fr,box,md,x,f,lambda[efptVDW],
233 enerd->grpp.ener[egLJSR],nrnb);
234 PRINT_SEPDVDL("Walls",0.0,dvdl);
235 enerd->dvdl_lin[efptVDW] += dvdl;
238 /* If doing GB, reset dvda and calculate the Born radii */
239 if (ir->implicit_solvent)
241 wallcycle_sub_start(wcycle, ewcsNONBONDED);
243 for(i=0;i<born->nr;i++)
250 calc_gb_rad(cr,fr,ir,top,atype,x,&(fr->gblist),born,md,nrnb);
253 wallcycle_sub_stop(wcycle, ewcsNONBONDED);
257 /* We only do non-bonded calculation with group scheme here, the verlet
258 * calls are done from do_force_cutsVERLET(). */
259 if (fr->cutoff_scheme == ecutsGROUP && (flags & GMX_FORCE_NONBONDED))
262 /* Add short-range interactions */
263 donb_flags |= GMX_NONBONDED_DO_SR;
265 if (flags & GMX_FORCE_FORCES)
267 donb_flags |= GMX_NONBONDED_DO_FORCE;
269 if (flags & GMX_FORCE_ENERGY)
271 donb_flags |= GMX_NONBONDED_DO_POTENTIAL;
273 if (flags & GMX_FORCE_DO_LR)
275 donb_flags |= GMX_NONBONDED_DO_LR;
278 wallcycle_sub_start(wcycle, ewcsNONBONDED);
279 do_nonbonded(cr,fr,x,f,f_longrange,md,excl,
280 &enerd->grpp,box_size,nrnb,
281 lambda,dvdl_nb,-1,-1,donb_flags);
283 /* If we do foreign lambda and we have soft-core interactions
284 * we have to recalculate the (non-linear) energies contributions.
286 if (fepvals->n_lambda > 0 && (flags & GMX_FORCE_DHDL) && fepvals->sc_alpha != 0)
288 for(i=0; i<enerd->n_lambda; i++)
290 for (j=0;j<efptNR;j++)
292 lam_i[j] = (i==0 ? lambda[j] : fepvals->all_lambda[j][i-1]);
294 reset_foreign_enerdata(enerd);
295 do_nonbonded(cr,fr,x,f,f_longrange,md,excl,
296 &(enerd->foreign_grpp),box_size,nrnb,
297 lam_i,dvdl_dum,-1,-1,
298 (donb_flags & ~GMX_NONBONDED_DO_FORCE) | GMX_NONBONDED_DO_FOREIGNLAMBDA);
299 sum_epot(&ir->opts,&(enerd->foreign_grpp),enerd->foreign_term);
300 enerd->enerpart_lambda[i] += enerd->foreign_term[F_EPOT];
303 wallcycle_sub_stop(wcycle, ewcsNONBONDED);
307 /* If we are doing GB, calculate bonded forces and apply corrections
308 * to the solvation forces */
309 /* MRS: Eventually, many need to include free energy contribution here! */
310 if (ir->implicit_solvent)
312 wallcycle_sub_start(wcycle, ewcsBONDED);
313 calc_gb_forces(cr,md,born,top,atype,x,f,fr,idef,
314 ir->gb_algorithm,ir->sa_algorithm,nrnb,bBornRadii,&pbc,graph,enerd);
315 wallcycle_sub_stop(wcycle, ewcsBONDED);
326 if (fepvals->sc_alpha!=0)
328 enerd->dvdl_nonlin[efptVDW] += dvdl_nb[efptVDW];
332 enerd->dvdl_lin[efptVDW] += dvdl_nb[efptVDW];
335 if (fepvals->sc_alpha!=0)
337 /* even though coulomb part is linear, we already added it, beacuse we
338 need to go through the vdw calculation anyway */
340 enerd->dvdl_nonlin[efptCOUL] += dvdl_nb[efptCOUL];
344 enerd->dvdl_lin[efptCOUL] += dvdl_nb[efptCOUL];
350 for(i=0; i<enerd->grpp.nener; i++)
354 enerd->grpp.ener[egBHAMSR][i] :
355 enerd->grpp.ener[egLJSR][i])
356 + enerd->grpp.ener[egCOULSR][i] + enerd->grpp.ener[egGB][i];
358 dvdlsum = dvdl_nb[efptVDW] + dvdl_nb[efptCOUL];
359 PRINT_SEPDVDL("VdW and Coulomb SR particle-p.",Vsr,dvdlsum);
363 GMX_MPE_LOG(ev_do_fnbf_finish);
367 pr_rvecs(debug,0,"fshift after SR",fr->fshift,SHIFTS);
370 /* Shift the coordinates. Must be done before bonded forces and PPPM,
371 * but is also necessary for SHAKE and update, therefore it can NOT
372 * go when no bonded forces have to be evaluated.
375 /* Here sometimes we would not need to shift with NBFonly,
376 * but we do so anyhow for consistency of the returned coordinates.
380 shift_self(graph,box,x);
383 inc_nrnb(nrnb,eNR_SHIFTX,2*graph->nnodes);
387 inc_nrnb(nrnb,eNR_SHIFTX,graph->nnodes);
390 /* Check whether we need to do bondeds or correct for exclusions */
392 ((flags & GMX_FORCE_BONDED)
393 || EEL_RF(fr->eeltype) || EEL_FULL(fr->eeltype)))
395 /* Since all atoms are in the rectangular or triclinic unit-cell,
396 * only single box vector shifts (2 in x) are required.
398 set_pbc_dd(&pbc,fr->ePBC,cr->dd,TRUE,box);
402 if (flags & GMX_FORCE_BONDED)
404 GMX_MPE_LOG(ev_calc_bonds_start);
406 wallcycle_sub_start(wcycle, ewcsBONDED);
407 calc_bonds(fplog,cr->ms,
408 idef,x,hist,f,fr,&pbc,graph,enerd,nrnb,lambda,md,fcd,
409 DOMAINDECOMP(cr) ? cr->dd->gatindex : NULL, atype, born,
411 fr->bSepDVDL && do_per_step(step,ir->nstlog),step);
413 /* Check if we have to determine energy differences
414 * at foreign lambda's.
416 if (fepvals->n_lambda > 0 && (flags & GMX_FORCE_DHDL) &&
417 idef->ilsort != ilsortNO_FE)
419 if (idef->ilsort != ilsortFE_SORTED)
421 gmx_incons("The bonded interactions are not sorted for free energy");
423 for(i=0; i<enerd->n_lambda; i++)
425 reset_foreign_enerdata(enerd);
426 for (j=0;j<efptNR;j++)
428 lam_i[j] = (i==0 ? lambda[j] : fepvals->all_lambda[j][i-1]);
430 calc_bonds_lambda(fplog,idef,x,fr,&pbc,graph,&(enerd->foreign_grpp),enerd->foreign_term,nrnb,lam_i,md,
431 fcd,DOMAINDECOMP(cr) ? cr->dd->gatindex : NULL);
432 sum_epot(&ir->opts,&(enerd->foreign_grpp),enerd->foreign_term);
433 enerd->enerpart_lambda[i] += enerd->foreign_term[F_EPOT];
437 GMX_MPE_LOG(ev_calc_bonds_finish);
438 wallcycle_sub_stop(wcycle, ewcsBONDED);
444 if (EEL_FULL(fr->eeltype))
446 bSB = (ir->nwall == 2);
450 svmul(ir->wall_ewald_zfac,boxs[ZZ],boxs[ZZ]);
451 box_size[ZZ] *= ir->wall_ewald_zfac;
454 clear_mat(fr->vir_el_recip);
461 /* With the Verlet scheme exclusion forces are calculated
462 * in the non-bonded kernel.
464 /* The TPI molecule does not have exclusions with the rest
465 * of the system and no intra-molecular PME grid contributions
466 * will be calculated in gmx_pme_calc_energy.
468 if ((ir->cutoff_scheme == ecutsGROUP && fr->n_tpi == 0) ||
469 ir->ewald_geometry != eewg3D ||
470 ir->epsilon_surface != 0)
474 wallcycle_sub_start(wcycle, ewcsEWALD_CORRECTION);
478 gmx_fatal(FARGS,"TPI with PME currently only works in a 3D geometry with tin-foil boundary conditions");
481 nthreads = gmx_omp_nthreads_get(emntBonded);
482 #pragma omp parallel for num_threads(nthreads) schedule(static)
483 for(t=0; t<nthreads; t++)
491 fnv = fr->f_novirsum;
492 vir = &fr->vir_el_recip;
499 vir = &fr->f_t[t].vir;
500 Vcorrt = &fr->f_t[t].Vcorr;
501 dvdlt = &fr->f_t[t].dvdl[efptCOUL];
502 for(i=0; i<fr->natoms_force; i++)
510 ewald_LRcorrection(fplog,
511 fr->excl_load[t],fr->excl_load[t+1],
514 md->nChargePerturbed ? md->chargeB : NULL,
515 ir->cutoff_scheme != ecutsVERLET,
516 excl,x,bSB ? boxs : box,mu_tot,
520 lambda[efptCOUL],dvdlt);
524 reduce_thread_forces(fr->natoms_force,fr->f_novirsum,
526 &Vcorr,efptCOUL,&dvdl,
530 wallcycle_sub_stop(wcycle, ewcsEWALD_CORRECTION);
535 Vcorr += ewald_charge_correction(cr,fr,lambda[efptCOUL],box,
536 &dvdl,fr->vir_el_recip);
539 PRINT_SEPDVDL("Ewald excl./charge/dip. corr.",Vcorr,dvdl);
540 enerd->dvdl_lin[efptCOUL] += dvdl;
551 case eelPMEUSERSWITCH:
553 if (cr->duty & DUTY_PME)
555 assert(fr->n_tpi >= 0);
556 if (fr->n_tpi == 0 || (flags & GMX_FORCE_STATECHANGED))
558 pme_flags = GMX_PME_SPREAD_Q | GMX_PME_SOLVE;
559 if (flags & GMX_FORCE_FORCES)
561 pme_flags |= GMX_PME_CALC_F;
563 if (flags & (GMX_FORCE_VIRIAL | GMX_FORCE_ENERGY))
565 pme_flags |= GMX_PME_CALC_ENER_VIR;
569 /* We don't calculate f, but we do want the potential */
570 pme_flags |= GMX_PME_CALC_POT;
572 wallcycle_start(wcycle,ewcPMEMESH);
573 status = gmx_pme_do(fr->pmedata,
574 md->start,md->homenr - fr->n_tpi,
576 md->chargeA,md->chargeB,
578 DOMAINDECOMP(cr) ? dd_pme_maxshift_x(cr->dd) : 0,
579 DOMAINDECOMP(cr) ? dd_pme_maxshift_y(cr->dd) : 0,
581 fr->vir_el_recip,fr->ewaldcoeff,
582 &Vlr,lambda[efptCOUL],&dvdl,
584 *cycles_pme = wallcycle_stop(wcycle,ewcPMEMESH);
586 /* We should try to do as little computation after
587 * this as possible, because parallel PME synchronizes
588 * the nodes, so we want all load imbalance of the rest
589 * of the force calculation to be before the PME call.
590 * DD load balancing is done on the whole time of
591 * the force call (without PME).
596 /* Determine the PME grid energy of the test molecule
597 * with the PME grid potential of the other charges.
599 gmx_pme_calc_energy(fr->pmedata,fr->n_tpi,
600 x + md->homenr - fr->n_tpi,
601 md->chargeA + md->homenr - fr->n_tpi,
604 PRINT_SEPDVDL("PME mesh",Vlr,dvdl);
608 Vlr = do_ewald(fplog,FALSE,ir,x,fr->f_novirsum,
609 md->chargeA,md->chargeB,
610 box_size,cr,md->homenr,
611 fr->vir_el_recip,fr->ewaldcoeff,
612 lambda[efptCOUL],&dvdl,fr->ewald_table);
613 PRINT_SEPDVDL("Ewald long-range",Vlr,dvdl);
616 gmx_fatal(FARGS,"No such electrostatics method implemented %s",
617 eel_names[fr->eeltype]);
621 gmx_fatal(FARGS,"Error %d in long range electrostatics routine %s",
622 status,EELTYPE(fr->eeltype));
624 /* Note that with separate PME nodes we get the real energies later */
625 enerd->dvdl_lin[efptCOUL] += dvdl;
626 enerd->term[F_COUL_RECIP] = Vlr + Vcorr;
629 fprintf(debug,"Vlr = %g, Vcorr = %g, Vlr_corr = %g\n",
630 Vlr,Vcorr,enerd->term[F_COUL_RECIP]);
631 pr_rvecs(debug,0,"vir_el_recip after corr",fr->vir_el_recip,DIM);
632 pr_rvecs(debug,0,"fshift after LR Corrections",fr->fshift,SHIFTS);
637 if (EEL_RF(fr->eeltype))
639 /* With the Verlet scheme exclusion forces are calculated
640 * in the non-bonded kernel.
642 if (ir->cutoff_scheme != ecutsVERLET && fr->eeltype != eelRF_NEC)
645 enerd->term[F_RF_EXCL] =
646 RF_excl_correction(fplog,fr,graph,md,excl,x,f,
647 fr->fshift,&pbc,lambda[efptCOUL],&dvdl);
650 enerd->dvdl_lin[efptCOUL] += dvdl;
651 PRINT_SEPDVDL("RF exclusion correction",
652 enerd->term[F_RF_EXCL],dvdl);
660 print_nrnb(debug,nrnb);
668 MPI_Barrier(cr->mpi_comm_mygroup);
671 if (fr->timesteps == 11)
673 fprintf(stderr,"* PP load balancing info: node %d, step %s, rel wait time=%3.0f%% , load string value: %7.2f\n",
674 cr->nodeid, gmx_step_str(fr->timesteps,buf),
675 100*fr->t_wait/(fr->t_wait+fr->t_fnbf),
676 (fr->t_fnbf+fr->t_wait)/fr->t_fnbf);
684 pr_rvecs(debug,0,"fshift after bondeds",fr->fshift,SHIFTS);
687 GMX_MPE_LOG(ev_force_finish);
691 void init_enerdata(int ngener,int n_lambda,gmx_enerdata_t *enerd)
695 for(i=0; i<F_NRE; i++)
698 enerd->foreign_term[i] = 0;
702 for(i=0; i<efptNR; i++) {
703 enerd->dvdl_lin[i] = 0;
704 enerd->dvdl_nonlin[i] = 0;
710 fprintf(debug,"Creating %d sized group matrix for energies\n",n2);
712 enerd->grpp.nener = n2;
713 enerd->foreign_grpp.nener = n2;
714 for(i=0; (i<egNR); i++)
716 snew(enerd->grpp.ener[i],n2);
717 snew(enerd->foreign_grpp.ener[i],n2);
722 enerd->n_lambda = 1 + n_lambda;
723 snew(enerd->enerpart_lambda,enerd->n_lambda);
731 void destroy_enerdata(gmx_enerdata_t *enerd)
735 for(i=0; (i<egNR); i++)
737 sfree(enerd->grpp.ener[i]);
740 for(i=0; (i<egNR); i++)
742 sfree(enerd->foreign_grpp.ener[i]);
747 sfree(enerd->enerpart_lambda);
751 static real sum_v(int n,real v[])
763 void sum_epot(t_grpopts *opts, gmx_grppairener_t *grpp, real *epot)
767 /* Accumulate energies */
768 epot[F_COUL_SR] = sum_v(grpp->nener,grpp->ener[egCOULSR]);
769 epot[F_LJ] = sum_v(grpp->nener,grpp->ener[egLJSR]);
770 epot[F_LJ14] = sum_v(grpp->nener,grpp->ener[egLJ14]);
771 epot[F_COUL14] = sum_v(grpp->nener,grpp->ener[egCOUL14]);
772 epot[F_COUL_LR] = sum_v(grpp->nener,grpp->ener[egCOULLR]);
773 epot[F_LJ_LR] = sum_v(grpp->nener,grpp->ener[egLJLR]);
774 /* We have already added 1-2,1-3, and 1-4 terms to F_GBPOL */
775 epot[F_GBPOL] += sum_v(grpp->nener,grpp->ener[egGB]);
777 /* lattice part of LR doesnt belong to any group
778 * and has been added earlier
780 epot[F_BHAM] = sum_v(grpp->nener,grpp->ener[egBHAMSR]);
781 epot[F_BHAM_LR] = sum_v(grpp->nener,grpp->ener[egBHAMLR]);
784 for(i=0; (i<F_EPOT); i++)
786 if (i != F_DISRESVIOL && i != F_ORIRESDEV)
788 epot[F_EPOT] += epot[i];
793 void sum_dhdl(gmx_enerdata_t *enerd, real *lambda, t_lambda *fepvals)
798 enerd->dvdl_lin[efptVDW] += enerd->term[F_DVDL_VDW]; /* include dispersion correction */
799 enerd->term[F_DVDL] = 0.0;
800 for (i=0;i<efptNR;i++)
802 if (fepvals->separate_dvdl[i])
804 /* could this be done more readably/compactly? */
813 index = F_DVDL_BONDED;
815 case (efptRESTRAINT):
816 index = F_DVDL_RESTRAINT;
825 enerd->term[index] = enerd->dvdl_lin[i] + enerd->dvdl_nonlin[i];
828 fprintf(debug,"dvdl-%s[%2d]: %f: non-linear %f + linear %f\n",
829 efpt_names[i],i,enerd->term[index],enerd->dvdl_nonlin[i],enerd->dvdl_lin[i]);
834 enerd->term[F_DVDL] += enerd->dvdl_lin[i] + enerd->dvdl_nonlin[i];
837 fprintf(debug,"dvd-%sl[%2d]: %f: non-linear %f + linear %f\n",
838 efpt_names[0],i,enerd->term[F_DVDL],enerd->dvdl_nonlin[i],enerd->dvdl_lin[i]);
843 /* Notes on the foreign lambda free energy difference evaluation:
844 * Adding the potential and ekin terms that depend linearly on lambda
845 * as delta lam * dvdl to the energy differences is exact.
846 * For the constraints this is not exact, but we have no other option
847 * without literally changing the lengths and reevaluating the energies at each step.
848 * (try to remedy this post 4.6 - MRS)
849 * For the non-bonded LR term we assume that the soft-core (if present)
850 * no longer affects the energy beyond the short-range cut-off,
851 * which is a very good approximation (except for exotic settings).
852 * (investigate how to overcome this post 4.6 - MRS)
855 for(i=0; i<fepvals->n_lambda; i++)
856 { /* note we are iterating over fepvals here!
857 For the current lam, dlam = 0 automatically,
858 so we don't need to add anything to the
859 enerd->enerpart_lambda[0] */
861 /* we don't need to worry about dvdl contributions to the current lambda, because
862 it's automatically zero */
864 /* first kinetic energy term */
865 dlam = (fepvals->all_lambda[efptMASS][i] - lambda[efptMASS]);
867 enerd->enerpart_lambda[i+1] += enerd->term[F_DKDL]*dlam;
869 for (j=0;j<efptNR;j++)
871 if (j==efptMASS) {continue;} /* no other mass term to worry about */
873 dlam = (fepvals->all_lambda[j][i]-lambda[j]);
874 enerd->enerpart_lambda[i+1] += dlam*enerd->dvdl_lin[j];
877 fprintf(debug,"enerdiff lam %g: (%15s), non-linear %f linear %f*%f\n",
878 fepvals->all_lambda[j][i],efpt_names[j],
879 (enerd->enerpart_lambda[i+1] - enerd->enerpart_lambda[0]),
880 dlam,enerd->dvdl_lin[j]);
887 void reset_foreign_enerdata(gmx_enerdata_t *enerd)
891 /* First reset all foreign energy components. Foreign energies always called on
892 neighbor search steps */
893 for(i=0; (i<egNR); i++)
895 for(j=0; (j<enerd->grpp.nener); j++)
897 enerd->foreign_grpp.ener[i][j] = 0.0;
901 /* potential energy components */
902 for(i=0; (i<=F_EPOT); i++)
904 enerd->foreign_term[i] = 0.0;
908 void reset_enerdata(t_grpopts *opts,
909 t_forcerec *fr,gmx_bool bNS,
910 gmx_enerdata_t *enerd,
916 /* First reset all energy components, except for the long range terms
917 * on the master at non neighbor search steps, since the long range
918 * terms have already been summed at the last neighbor search step.
920 bKeepLR = (fr->bTwinRange && !bNS);
921 for(i=0; (i<egNR); i++) {
922 if (!(bKeepLR && bMaster && (i == egCOULLR || i == egLJLR))) {
923 for(j=0; (j<enerd->grpp.nener); j++)
924 enerd->grpp.ener[i][j] = 0.0;
927 for (i=0;i<efptNR;i++)
929 enerd->dvdl_lin[i] = 0.0;
930 enerd->dvdl_nonlin[i] = 0.0;
933 /* Normal potential energy components */
934 for(i=0; (i<=F_EPOT); i++) {
935 enerd->term[i] = 0.0;
937 /* Initialize the dVdlambda term with the long range contribution */
938 /* Initialize the dvdl term with the long range contribution */
939 enerd->term[F_DVDL] = 0.0;
940 enerd->term[F_DVDL_COUL] = 0.0;
941 enerd->term[F_DVDL_VDW] = 0.0;
942 enerd->term[F_DVDL_BONDED] = 0.0;
943 enerd->term[F_DVDL_RESTRAINT] = 0.0;
944 enerd->term[F_DKDL] = 0.0;
945 if (enerd->n_lambda > 0)
947 for(i=0; i<enerd->n_lambda; i++)
949 enerd->enerpart_lambda[i] = 0.0;
952 /* reset foreign energy data - separate function since we also call it elsewhere */
953 reset_foreign_enerdata(enerd);