const struct t_graph* g,
gmx_grppairener_t* grpp,
real* epot,
+ gmx::ArrayRef<real> dvdl,
t_nrnb* nrnb,
const real* lambda,
const t_mdatoms* md,
int* global_atom_index)
{
real v;
- real dvdl_dum[efptNR] = { 0 };
rvec4* f;
rvec* fshift;
const t_pbc* pbc_null;
gmx::StepWorkload tempFlags;
tempFlags.computeEnergy = true;
v = calc_one_bond(0, ftype, idef, iatoms, iatoms.ssize(), workDivision, x, f,
- fshift, fr, pbc_null, g, grpp, nrnb, lambda, dvdl_dum, md, fcd,
+ fshift, fr, pbc_null, g, grpp, nrnb, lambda, dvdl.data(), md, fcd,
tempFlags, global_atom_index);
epot[ftype] += v;
}
*/
if (fepvals->n_lambda > 0 && stepWork.computeDhdl)
{
+ real dvdl[efptNR] = { 0 };
posres_wrapper_lambda(wcycle, fepvals, idef, &pbc_full, x, enerd, lambda, fr);
if (idef->ilsort != ilsortNO_FE)
lam_i[j] = (i == 0 ? lambda[j] : fepvals->all_lambda[j][i - 1]);
}
calc_listed_lambda(idef, x, fr, pbc, graph, &(enerd->foreign_grpp),
- enerd->foreign_term, nrnb, lam_i, md, fcd, global_atom_index);
+ enerd->foreign_term, dvdl, nrnb, lam_i, md, fcd, global_atom_index);
sum_epot(&(enerd->foreign_grpp), enerd->foreign_term);
enerd->enerpart_lambda[i] += enerd->foreign_term[F_EPOT];
+ for (int j = 0; j < efptNR; j++)
+ {
+ enerd->dhdlLambda[i] += dvdl[j];
+ dvdl[j] = 0;
+ }
}
wallcycle_sub_stop(wcycle, ewcsLISTED_FEP);
}
{
class ForceOutputs;
class StepWorkload;
+template<typename>
+class ArrayRef;
} // namespace gmx
//! Type of CPU function to compute a bonded interaction.
const struct t_graph* g,
gmx_grppairener_t* grpp,
real* epot,
+ gmx::ArrayRef<real> dvdl,
t_nrnb* nrnb,
const real* lambda,
const t_mdatoms* md,
wallcycle_sub_start_nocount(wcycle, ewcsRESTRAINTS);
for (size_t i = 0; i < enerd->enerpart_lambda.size(); i++)
{
- real dvdl_dum = 0, lambda_dum;
+ real dvdl = 0;
- lambda_dum = (i == 0 ? lambda[efptRESTRAINT] : fepvals->all_lambda[efptRESTRAINT][i - 1]);
+ const real lambda_dum =
+ (i == 0 ? lambda[efptRESTRAINT] : fepvals->all_lambda[efptRESTRAINT][i - 1]);
v = posres<false>(idef->il[F_POSRES].nr, idef->il[F_POSRES].iatoms, idef->iparams_posres, x,
- nullptr, fr->pbcType == PbcType::No ? nullptr : pbc, lambda_dum,
- &dvdl_dum, fr->rc_scaling, fr->pbcType, fr->posres_com, fr->posres_comB);
+ nullptr, fr->pbcType == PbcType::No ? nullptr : pbc, lambda_dum, &dvdl,
+ fr->rc_scaling, fr->pbcType, fr->posres_com, fr->posres_comB);
enerd->enerpart_lambda[i] += v;
+ enerd->dhdlLambda[i] += dvdl;
}
wallcycle_sub_stop(wcycle, ewcsRESTRAINTS);
}
gmx_enerdata_t::gmx_enerdata_t(int numEnergyGroups, int numFepLambdas) :
grpp(numEnergyGroups),
enerpart_lambda(numFepLambdas == 0 ? 0 : numFepLambdas + 1),
+ dhdlLambda(numFepLambdas == 0 ? 0 : numFepLambdas + 1),
foreign_grpp(numEnergyGroups)
{
}
int index;
enerd->dvdl_lin[efptVDW] += enerd->term[F_DVDL_VDW]; /* include dispersion correction */
+
+ for (size_t i = 0; i < enerd->enerpart_lambda.size(); i++)
+ {
+ enerd->dhdlLambda[i] += enerd->term[F_DVDL_VDW];
+ }
+
enerd->term[F_DVDL] = 0.0;
for (int i = 0; i < efptNR; i++)
{
}
}
+void reset_dvdl_enerdata(gmx_enerdata_t* enerd)
+{
+ for (int i = 0; i < efptNR; i++)
+ {
+ enerd->dvdl_lin[i] = 0.0;
+ enerd->dvdl_nonlin[i] = 0.0;
+ }
+}
+
void reset_enerdata(gmx_enerdata_t* enerd)
{
int i, j;
enerd->grpp.ener[i][j] = 0.0;
}
}
- for (i = 0; i < efptNR; i++)
- {
- enerd->dvdl_lin[i] = 0.0;
- enerd->dvdl_nonlin[i] = 0.0;
- }
/* Normal potential energy components */
for (i = 0; (i <= F_EPOT); i++)
enerd->term[F_DVDL_RESTRAINT] = 0.0;
enerd->term[F_DKDL] = 0.0;
std::fill(enerd->enerpart_lambda.begin(), enerd->enerpart_lambda.end(), 0);
- /* reset foreign energy data - separate function since we also call it elsewhere */
+ std::fill(enerd->dhdlLambda.begin(), enerd->dhdlLambda.end(), 0);
+ /* reset foreign energy data and dvdl - separate functions since they are also called elsewhere */
reset_foreign_enerdata(enerd);
+ reset_dvdl_enerdata(enerd);
}
void reset_foreign_enerdata(gmx_enerdata_t* enerd);
/* Resets only the foreign energy data */
+void reset_dvdl_enerdata(gmx_enerdata_t* enerd);
+/* Resets only the dvdl energy data */
+
void reset_enerdata(gmx_enerdata_t* enerd);
/* Resets the energy data */
real dvdl_walls = do_walls(*ir, *fr, box, *md, x, &forceWithVirial, lambda[efptVDW],
enerd->grpp.ener[egLJSR].data(), nrnb);
enerd->dvdl_lin[efptVDW] += dvdl_walls;
+
+ for (auto& dhdl : enerd->dhdlLambda)
+ {
+ dhdl += dvdl_walls;
+ }
}
/* Shift the coordinates. Must be done before listed forces and PPPM,
enerd->term[F_COUL_RECIP] = Vlr_q + ewaldOutput.Vcorr_q;
enerd->term[F_LJ_RECIP] = Vlr_lj + ewaldOutput.Vcorr_lj;
+ for (auto& dhdl : enerd->dhdlLambda)
+ {
+ dhdl += ewaldOutput.dvdl[efptVDW] + ewaldOutput.dvdl[efptCOUL];
+ }
+
if (debug)
{
fprintf(debug, "Vlr_q = %g, Vcorr_q = %g, Vlr_corr_q = %g\n", Vlr_q,
enerd->dvdl_lin[efptMASS] = static_cast<double>(dvdl_ekin);
enerd->term[F_EKIN] = trace(ekind->ekin);
+
+ for (auto& dhdl : enerd->dhdlLambda)
+ {
+ dhdl += enerd->dvdl_lin[efptMASS];
+ }
}
/* ########## Now pressure ############## */
enerd->term[F_COM_PULL] += pull_potential(pull_work, mdatoms, &pbc, cr, t, lambda[efptRESTRAINT],
as_rvec_array(x.data()), force, &dvdl);
enerd->dvdl_lin[efptRESTRAINT] += dvdl;
+ for (auto& dhdl : enerd->dhdlLambda)
+ {
+ dhdl += dvdl;
+ }
wallcycle_stop(wcycle, ewcPULLPOT);
}
enerd->dvdl_lin[efptCOUL] += dvdl_q;
enerd->dvdl_lin[efptVDW] += dvdl_lj;
+ for (auto& dhdl : enerd->dhdlLambda)
+ {
+ dhdl += dvdl_q + dvdl_lj;
+ }
+
if (wcycle)
{
dd_cycles_add(cr->dd, cycles_seppme, ddCyclPME);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
int fep_state = 0; /*current fep state -- just for printing */
std::vector<double> enerpart_lambda; /* Partial Hamiltonian for lambda and flambda[], includes at least all perturbed terms */
+ std::vector<double> dhdlLambda; /* dHdL at all neighboring lambda points (the current lambda point also at index 0). */
real foreign_term[F_NRE] = { 0 }; /* alternate array for storing foreign lambda energies */
struct gmx_grppairener_t foreign_grpp; /* alternate array for storing foreign lambda energies */
};
kernel_data.flags = (donb_flags & ~(GMX_NONBONDED_DO_FORCE | GMX_NONBONDED_DO_SHIFTFORCE))
| GMX_NONBONDED_DO_FOREIGNLAMBDA;
kernel_data.lambda = lam_i;
+ kernel_data.dvdl = dvdl_nb;
kernel_data.energygrp_elec = enerd->foreign_grpp.ener[egCOULSR].data();
kernel_data.energygrp_vdw = enerd->foreign_grpp.ener[egLJSR].data();
- /* Note that we add to kernel_data.dvdl, but ignore the result */
for (size_t i = 0; i < enerd->enerpart_lambda.size(); i++)
{
+ std::fill(std::begin(dvdl_nb), std::end(dvdl_nb), 0);
for (int j = 0; j < efptNR; j++)
{
lam_i[j] = (i == 0 ? lambda[j] : fepvals->all_lambda[j][i - 1]);
sum_epot(&(enerd->foreign_grpp), enerd->foreign_term);
enerd->enerpart_lambda[i] += enerd->foreign_term[F_EPOT];
+ enerd->dhdlLambda[i] += dvdl_nb[efptVDW] + dvdl_nb[efptCOUL];
+ }
+ }
+ else
+ {
+ for (size_t i = 0; i < enerd->enerpart_lambda.size(); i++)
+ {
+ enerd->dhdlLambda[i] += dvdl_nb[efptVDW] + dvdl_nb[efptCOUL];
}
}
wallcycle_sub_stop(wcycle_, ewcsNONBONDED_FEP);