Skip to content

Commit

Permalink
DRR: correctly separate the calculate and update (#1132)
Browse files Browse the repository at this point in the history
The previous implementation updates the internal states partially in
calculate(), which should be done in update(). This commit fixes the
issue.
  • Loading branch information
HanatoK authored Oct 11, 2024
1 parent eef95a7 commit 81f78e3
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 41 deletions.
31 changes: 22 additions & 9 deletions src/drr/DRR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,35 +414,48 @@ void DRRForceGrid::writeDivergence(const string &filename, const string &fmt) co
fclose(pDiv);
}

bool ABF::store_getbias(const vector<double> &pos, const vector<double> &f,
vector<double> &fbias) {
bool ABF::getbias(const vector<double> &pos, const vector<double> &f,
vector<double> &fbias) const {
if (!isInBoundary(pos)) {
std::fill(begin(fbias), end(fbias), 0.0);
return false;
}
const size_t baseaddr = sampleAddress(pos);
unsigned long int &count = samples[baseaddr];
++count;
const unsigned long int count = samples[baseaddr] + 1;
double factor = 2 * (static_cast<double>(count)) / mFullSamples - 1;
auto it_fa = begin(forces) + baseaddr * ndims;
auto it_fb = begin(fbias);
auto it_f = begin(f);
auto it_maxFactor = begin(mMaxFactors);
do {
while (it_f != end(f)) {
// Clamp to [0,maxFactors]
factor = factor < 0 ? 0 : factor > (*it_maxFactor) ? (*it_maxFactor) : factor;
(*it_fa) += (*it_f); // Accumulate instantaneous force
(*it_fb) = factor * (*it_fa) * (-1.0) /
(*it_fb) = factor * ((*it_fa) + (*it_f)) * (-1.0) /
static_cast<double>(count); // Calculate bias force
++it_fa;
++it_fb;
++it_f;
++it_maxFactor;
} while (it_f != end(f));

};
return true;
}

void ABF::store_force(const vector<double> &pos,
const vector<double> &f) {
if (!isInBoundary(pos)) {
return;
}
const size_t baseaddr = sampleAddress(pos);
samples[baseaddr] += 1;
auto it_fa = begin(forces) + baseaddr * ndims;
auto it_f = begin(f);
while (it_f != end(f)) {
*it_fa += *it_f;
++it_fa;
++it_f;
};
}

ABF ABF::mergewindow(const ABF &aWA, const ABF &aWB) {
const vector<DRRAxis> dR = merge(aWA.dimensions, aWB.dimensions);
const string suffix = ".abf";
Expand Down
8 changes: 5 additions & 3 deletions src/drr/DRR.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,11 @@ class ABF : public DRRForceGrid {
mMaxFactors = maxFactors;
}
// Store the "instantaneous" spring force of a point and get ABF bias forces.
bool store_getbias(const vector<double> &pos,
const vector<double> &f,
vector<double> &fbias);
bool getbias(const vector<double> &pos,
const vector<double> &f,
vector<double> &fbias) const;
void store_force(const vector<double> &pos,
const vector<double> &f);
static ABF mergewindow(const ABF &aWA, const ABF &aWB);
~ABF() {}

Expand Down
72 changes: 43 additions & 29 deletions src/drr/DynamicReferenceRestraining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,6 @@ DynamicReferenceRestraining::DynamicReferenceRestraining(
}

void DynamicReferenceRestraining::calculate() {
long long int step_now = getStep();
if (firsttime) {
for (size_t i = 0; i < ndims; ++i) {
fict[i] = getArgument(i);
Expand All @@ -711,6 +710,46 @@ void DynamicReferenceRestraining::calculate() {
}
firsttime = false;
}
if (withExternalForce == false) {
double ene = 0.0;
for (size_t i = 0; i < ndims; ++i) {
real[i] = getArgument(i);
springlength[i] = difference(i, fict[i], real[i]);
fictNoPBC[i] = real[i] - springlength[i];
double f = -kappa[i] * springlength[i];
ffict_measured[i] = -f;
ene += 0.5 * kappa[i] * springlength[i] * springlength[i];
setOutputForce(i, f);
ffict[i] = -f;
fict[i] = fictValue[i]->bringBackInPbc(fict[i]);
fictValue[i]->set(fict[i]);
vfictValue[i]->set(vfict_laststep[i]);
springforceValue[i]->set(ffict_measured[i]);
fictNoPBCValue[i]->set(fictNoPBC[i]);
}
setBias(ene);
ABFGrid.getbias(fict, ffict_measured, fbias);
} else {
for (size_t i = 0; i < ndims; ++i) {
real[i] = getArgument(i);
ffict_measured[i] = externalForceValue[i]->get();
if (withExternalFict) {
fictNoPBC[i] = externalFictValue[i]->get();
}
springforceValue[i]->set(ffict_measured[i]);
fictNoPBCValue[i]->set(fictNoPBC[i]);
}
ABFGrid.getbias(real, ffict_measured, fbias);
if (!nobias) {
for (size_t i = 0; i < ndims; ++i) {
setOutputForce(i, fbias[i]);
}
}
}
}

void DynamicReferenceRestraining::update() {
const long long int step_now = getStep();
if (step_now != 0) {
if ((step_now % int(outputfreq)) == 0) {
save(outputname, step_now);
Expand Down Expand Up @@ -748,40 +787,18 @@ void DynamicReferenceRestraining::calculate() {
}
}
if (withExternalForce == false) {
double ene = 0.0;
for (size_t i = 0; i < ndims; ++i) {
real[i] = getArgument(i);
springlength[i] = difference(i, fict[i], real[i]);
fictNoPBC[i] = real[i] - springlength[i];
double f = -kappa[i] * springlength[i];
ffict_measured[i] = -f;
ene += 0.5 * kappa[i] * springlength[i] * springlength[i];
setOutputForce(i, f);
ffict[i] = -f;
fict[i] = fictValue[i]->bringBackInPbc(fict[i]);
fictValue[i]->set(fict[i]);
vfictValue[i]->set(vfict_laststep[i]);
springforceValue[i]->set(ffict_measured[i]);
fictNoPBCValue[i]->set(fictNoPBC[i]);
ffict_measured[i] = kappa[i] * springlength[i];
}
setBias(ene);
ABFGrid.store_getbias(fict, ffict_measured, fbias);
ABFGrid.store_force(fict, ffict_measured);
} else {
for (size_t i = 0; i < ndims; ++i) {
real[i] = getArgument(i);
ffict_measured[i] = externalForceValue[i]->get();
if (withExternalFict) {
fictNoPBC[i] = externalFictValue[i]->get();
}
springforceValue[i]->set(ffict_measured[i]);
fictNoPBCValue[i]->set(fictNoPBC[i]);
}
ABFGrid.store_getbias(real, ffict_measured, fbias);
if (!nobias) {
for (size_t i = 0; i < ndims; ++i) {
setOutputForce(i, fbias[i]);
}
}
ABFGrid.store_force(real, ffict_measured);
}
if (useCZARestimator) {
CZARestimator.store(real, ffict_measured);
Expand All @@ -790,9 +807,6 @@ void DynamicReferenceRestraining::calculate() {
eabf_UI.update_output_filename(outputprefix);
eabf_UI.update(int(step_now), real, fictNoPBC);
}
}

void DynamicReferenceRestraining::update() {
if (withExternalForce == false) {
for (size_t i = 0; i < ndims; ++i) {
// consider additional forces on the fictitious particle
Expand Down

1 comment on commit 81f78e3

@PlumedBot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found broken examples in automatic/ANGLES.tmp
Found broken examples in automatic/ANN.tmp
Found broken examples in automatic/CAVITY.tmp
Found broken examples in automatic/CLASSICAL_MDS.tmp
Found broken examples in automatic/CLUSTER_DIAMETER.tmp
Found broken examples in automatic/CLUSTER_DISTRIBUTION.tmp
Found broken examples in automatic/CLUSTER_PROPERTIES.tmp
Found broken examples in automatic/CONSTANT.tmp
Found broken examples in automatic/CONTACT_MATRIX.tmp
Found broken examples in automatic/CONTACT_MATRIX_PROPER.tmp
Found broken examples in automatic/CONVERT_TO_FES.tmp
Found broken examples in automatic/COORDINATIONNUMBER.tmp
Found broken examples in automatic/DFSCLUSTERING.tmp
Found broken examples in automatic/DISTANCE_FROM_CONTOUR.tmp
Found broken examples in automatic/DUMPCUBE.tmp
Found broken examples in automatic/DUMPGRID.tmp
Found broken examples in automatic/EDS.tmp
Found broken examples in automatic/EMMI.tmp
Found broken examples in automatic/ENVIRONMENTSIMILARITY.tmp
Found broken examples in automatic/FIND_CONTOUR.tmp
Found broken examples in automatic/FIND_CONTOUR_SURFACE.tmp
Found broken examples in automatic/FIND_SPHERICAL_CONTOUR.tmp
Found broken examples in automatic/FOURIER_TRANSFORM.tmp
Found broken examples in automatic/FUNCPATHGENERAL.tmp
Found broken examples in automatic/FUNCPATHMSD.tmp
Found broken examples in automatic/FUNNEL.tmp
Found broken examples in automatic/FUNNEL_PS.tmp
Found broken examples in automatic/GHBFIX.tmp
Found broken examples in automatic/GPROPERTYMAP.tmp
Found broken examples in automatic/HBOND_MATRIX.tmp
Found broken examples in automatic/HISTOGRAM.tmp
Found broken examples in automatic/INCLUDE.tmp
Found broken examples in automatic/INCYLINDER.tmp
Found broken examples in automatic/INENVELOPE.tmp
Found broken examples in automatic/INTERPOLATE_GRID.tmp
Found broken examples in automatic/LOCAL_AVERAGE.tmp
Found broken examples in automatic/MAZE_OPTIMIZER_BIAS.tmp
Found broken examples in automatic/MAZE_RANDOM_ACCELERATION_MD.tmp
Found broken examples in automatic/MAZE_SIMULATED_ANNEALING.tmp
Found broken examples in automatic/MAZE_STEERED_MD.tmp
Found broken examples in automatic/METATENSOR.tmp
Found broken examples in automatic/MULTICOLVARDENS.tmp
Found broken examples in automatic/OUTPUT_CLUSTER.tmp
Found broken examples in automatic/PAMM.tmp
Found broken examples in automatic/PCA.tmp
Found broken examples in automatic/PCAVARS.tmp
Found broken examples in automatic/PIV.tmp
Found broken examples in automatic/PLUMED.tmp
Found broken examples in automatic/PYCVINTERFACE.tmp
Found broken examples in automatic/PYTHONFUNCTION.tmp
Found broken examples in automatic/Q3.tmp
Found broken examples in automatic/Q4.tmp
Found broken examples in automatic/Q6.tmp
Found broken examples in automatic/QUATERNION.tmp
Found broken examples in automatic/REWEIGHT_BIAS.tmp
Found broken examples in automatic/REWEIGHT_METAD.tmp
Found broken examples in automatic/SIZESHAPE_POSITION_LINEAR_PROJ.tmp
Found broken examples in automatic/SIZESHAPE_POSITION_MAHA_DIST.tmp
Found broken examples in automatic/SPRINT.tmp
Found broken examples in automatic/TETRAHEDRALPORE.tmp
Found broken examples in automatic/TORSIONS.tmp
Found broken examples in automatic/WHAM_HISTOGRAM.tmp
Found broken examples in automatic/WHAM_WEIGHTS.tmp
Found broken examples in AnalysisPP.md
Found broken examples in CollectiveVariablesPP.md
Found broken examples in MiscelaneousPP.md

Please sign in to comment.