2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
37 #include "awh_setup.h"
45 #include <gmock/gmock.h>
46 #include <gmock/gmock-matchers.h>
47 #include <gtest/gtest.h>
49 #include "gromacs/applied_forces/awh/bias.h"
50 #include "gromacs/applied_forces/awh/correlationgrid.h"
51 #include "gromacs/applied_forces/awh/pointstate.h"
52 #include "gromacs/mdtypes/awh_params.h"
53 #include "gromacs/utility/arrayref.h"
54 #include "gromacs/utility/inmemoryserializer.h"
55 #include "gromacs/utility/stringutil.h"
57 #include "testutils/refdata.h"
58 #include "testutils/testasserts.h"
67 using ::testing::Pointwise;
69 std::vector<char> awhDimParamSerialized(AwhCoordinateProviderType inputCoordinateProvider,
74 double inputDiffusion)
76 AwhCoordinateProviderType eCoordProvider = inputCoordinateProvider;
77 int coordIndex = inputCoordIndex;
78 double forceConstant = 10;
79 double period = inputPeriod;
80 double diffusion = inputDiffusion;
81 double origin = inputOrigin;
82 double end = inputEnd;
83 double coordValueInit = inputOrigin;
84 double coverDiameter = 0;
86 gmx::InMemorySerializer serializer;
87 serializer.doEnumAsInt(&eCoordProvider);
88 serializer.doInt(&coordIndex);
89 serializer.doDouble(&origin);
90 serializer.doDouble(&end);
91 serializer.doDouble(&period);
92 serializer.doDouble(&forceConstant);
93 serializer.doDouble(&diffusion);
94 serializer.doDouble(&coordValueInit);
95 serializer.doDouble(&coverDiameter);
96 return serializer.finishAndGetBuffer();
100 * Prepare a memory buffer with serialized AwhBiasParams.
102 * \param[in] eawhgrowth Way to grow potential.
103 * \param[in] beta Value for 1/(kB*T).
104 * \param[in] inputErrorScaling Factor for initial error scaling.
105 * \param[in] dimensionParameterBuffers Buffers containing the dimension parameters.
106 * \param[in] shareGroup share group for, potentially, sharing the bias between simulations
107 * \param[in] inputUserData If there is a user provided PMF estimate.
109 static std::vector<char> awhBiasParamSerialized(AwhHistogramGrowthType eawhgrowth,
111 double inputErrorScaling,
112 ArrayRef<const std::vector<char>> dimensionParameterBuffers,
116 int ndim = dimensionParameterBuffers.size();
117 AwhTargetType eTarget = AwhTargetType::Constant;
118 double targetBetaScaling = 0;
119 double targetCutoff = 0;
120 AwhHistogramGrowthType eGrowth = eawhgrowth;
121 bool bUserData = inputUserData;
122 double errorInitial = inputErrorScaling / beta;
123 bool equilibrateHistogram = false;
125 gmx::InMemorySerializer serializer;
126 serializer.doEnumAsInt(&eTarget);
127 serializer.doDouble(&targetBetaScaling);
128 serializer.doDouble(&targetCutoff);
129 serializer.doEnumAsInt(&eGrowth);
130 int temp = static_cast<int>(bUserData);
131 serializer.doInt(&temp);
132 serializer.doDouble(&errorInitial);
133 serializer.doInt(&ndim);
134 serializer.doInt(&shareGroup);
135 serializer.doBool(&equilibrateHistogram);
137 auto awhDimBuffer = awhDimParamSerialized();
138 auto awhBiasBuffer = serializer.finishAndGetBuffer();
139 for (const auto& dimParamBuffer : dimensionParameterBuffers)
141 awhBiasBuffer.insert(awhBiasBuffer.end(), dimParamBuffer.begin(), dimParamBuffer.end());
143 return awhBiasBuffer;
147 * Prepare a memory buffer with serialized AwhParams.
149 * \param[in] eawhgrowth Way to grow potential.
150 * \param[in] eawhpotential Which potential to use.
151 * \param[in] beta Value for 1/(kB*T).
152 * \param[in] inputErrorScaling Factor for initial error scaling.
153 * \param[in] inputSeed Seed value to use.
154 * \param[in] dimensionParameterBuffers Buffers containing the dimension parameters.
155 * \param[in] biasShareGroup share group for, potentially, sharing the bias over simulations
156 * \param[in] inputUserData If there is a user provided PMF estimate.
158 static std::vector<char> awhParamSerialized(AwhHistogramGrowthType eawhgrowth,
159 AwhPotentialType eawhpotential,
161 double inputErrorScaling,
163 ArrayRef<const std::vector<char>> dimensionParameterBuffers,
168 int64_t seed = inputSeed;
170 int nstSampleCoord = 1;
171 int numSamplesUpdateFreeEnergy = 10;
172 AwhPotentialType ePotential = eawhpotential;
173 bool shareBiasMultisim = false;
175 gmx::InMemorySerializer serializer;
176 serializer.doInt(&numBias);
177 serializer.doInt(&nstOut);
178 serializer.doInt64(&seed);
179 serializer.doInt(&nstSampleCoord);
180 serializer.doInt(&numSamplesUpdateFreeEnergy);
181 serializer.doEnumAsInt(&ePotential);
182 serializer.doBool(&shareBiasMultisim);
184 auto awhParamBuffer = serializer.finishAndGetBuffer();
185 auto awhBiasBuffer = awhBiasParamSerialized(
186 eawhgrowth, beta, inputErrorScaling, dimensionParameterBuffers, biasShareGroup, inputUserData);
188 awhParamBuffer.insert(awhParamBuffer.end(), awhBiasBuffer.begin(), awhBiasBuffer.end());
190 return awhParamBuffer;
193 AwhTestParameters::AwhTestParameters(ISerializer* serializer) : awhParams(serializer) {}
195 * Helper function to set up the C-style AWH parameters for the test.
197 * Builds the test input data from serialized data.
199 AwhTestParameters getAwhTestParameters(AwhHistogramGrowthType eawhgrowth,
200 AwhPotentialType eawhpotential,
201 ArrayRef<const std::vector<char>> dimensionParameterBuffers,
205 double inputErrorScaling,
206 int numFepLambdaStates,
209 double convFactor = 1;
211 int64_t seed = 93471803;
213 auto awhParamBuffer = awhParamSerialized(
214 eawhgrowth, eawhpotential, beta, inputErrorScaling, seed, dimensionParameterBuffers, biasShareGroup, inputUserData);
215 gmx::InMemoryDeserializer deserializer(awhParamBuffer, false);
216 AwhTestParameters params(&deserializer);
222 params.dimParams.emplace_back(DimParams::fepLambdaDimParams(numFepLambdaStates, params.beta));
226 params.dimParams.emplace_back(DimParams::pullDimParams(convFactor, k, params.beta));
231 TEST(SerializationTest, CanSerializeDimParams)
233 auto awhDimBuffer = awhDimParamSerialized();
234 gmx::InMemoryDeserializer deserializer(awhDimBuffer, false);
235 AwhDimParams awhDimParams(&deserializer);
236 EXPECT_EQ(awhDimParams.coordinateProvider(), AwhCoordinateProviderType::Pull);
237 EXPECT_EQ(awhDimParams.coordinateIndex(), 0);
238 EXPECT_FLOAT_EQ(awhDimParams.forceConstant(), 10);
239 EXPECT_FLOAT_EQ(awhDimParams.period(), 0);
240 EXPECT_FLOAT_EQ(awhDimParams.diffusion(), 0.34690997);
241 EXPECT_FLOAT_EQ(awhDimParams.origin(), 0.5);
242 EXPECT_FLOAT_EQ(awhDimParams.end(), 1.5);
243 EXPECT_FLOAT_EQ(awhDimParams.initialCoordinate(), awhDimParams.origin());
244 EXPECT_FLOAT_EQ(awhDimParams.coverDiameter(), 0);
246 gmx::InMemorySerializer serializer;
247 awhDimParams.serialize(&serializer);
248 EXPECT_THAT(awhDimBuffer, Pointwise(Eq(), serializer.finishAndGetBuffer()));
251 TEST(SerializationTest, CanSerializeBiasParams)
253 auto awhDimBuffer = awhDimParamSerialized();
254 auto awhDimArrayRef = gmx::arrayRefFromArray(&awhDimBuffer, 1);
255 auto awhBiasBuffer = awhBiasParamSerialized(
256 AwhHistogramGrowthType::ExponentialLinear, 0.4, 0.5, awhDimArrayRef, 0, false);
257 gmx::InMemoryDeserializer deserializer(awhBiasBuffer, false);
258 AwhBiasParams awhBiasParams(&deserializer);
259 EXPECT_EQ(awhBiasParams.ndim(), 1);
260 EXPECT_EQ(awhBiasParams.targetDistribution(), AwhTargetType::Constant);
261 EXPECT_FLOAT_EQ(awhBiasParams.targetBetaScaling(), 0);
262 EXPECT_FLOAT_EQ(awhBiasParams.targetCutoff(), 0);
263 EXPECT_EQ(awhBiasParams.growthType(), AwhHistogramGrowthType::ExponentialLinear);
264 EXPECT_EQ(awhBiasParams.userPMFEstimate(), 0);
265 EXPECT_FLOAT_EQ(awhBiasParams.initialErrorEstimate(), 0.5 / 0.4);
266 EXPECT_EQ(awhBiasParams.shareGroup(), 0);
267 EXPECT_EQ(awhBiasParams.equilibrateHistogram(), false);
268 const auto& awhDimParams = awhBiasParams.dimParams()[0];
269 EXPECT_EQ(awhDimParams.coordinateProvider(), AwhCoordinateProviderType::Pull);
270 EXPECT_EQ(awhDimParams.coordinateIndex(), 0);
271 EXPECT_FLOAT_EQ(awhDimParams.forceConstant(), 10);
272 EXPECT_FLOAT_EQ(awhDimParams.period(), 0);
273 EXPECT_FLOAT_EQ(awhDimParams.diffusion(), 0.34690997);
274 EXPECT_FLOAT_EQ(awhDimParams.origin(), 0.5);
275 EXPECT_FLOAT_EQ(awhDimParams.end(), 1.5);
276 EXPECT_FLOAT_EQ(awhDimParams.initialCoordinate(), awhDimParams.origin());
277 EXPECT_FLOAT_EQ(awhDimParams.coverDiameter(), 0);
279 gmx::InMemorySerializer serializer;
280 awhBiasParams.serialize(&serializer);
281 EXPECT_THAT(awhBiasBuffer, Pointwise(Eq(), serializer.finishAndGetBuffer()));
284 TEST(SerializationTest, CanSerializeAwhParams)
286 auto awhDimBuffer = awhDimParamSerialized();
287 auto awhDimArrayRef = gmx::arrayRefFromArray(&awhDimBuffer, 1);
288 auto awhParamBuffer = awhParamSerialized(AwhHistogramGrowthType::ExponentialLinear,
289 AwhPotentialType::Convolved,
296 gmx::InMemoryDeserializer deserializer(awhParamBuffer, false);
297 AwhParams awhParams(&deserializer);
298 EXPECT_EQ(awhParams.numBias(), 1);
299 EXPECT_EQ(awhParams.seed(), 1337);
300 EXPECT_EQ(awhParams.nstout(), 0);
301 EXPECT_EQ(awhParams.nstSampleCoord(), 1);
302 EXPECT_EQ(awhParams.numSamplesUpdateFreeEnergy(), 10);
303 EXPECT_EQ(awhParams.potential(), AwhPotentialType::Convolved);
304 EXPECT_EQ(awhParams.shareBiasMultisim(), false);
305 const auto& awhBiasParams = awhParams.awhBiasParams()[0];
306 EXPECT_EQ(awhBiasParams.ndim(), 1);
307 EXPECT_EQ(awhBiasParams.targetDistribution(), AwhTargetType::Constant);
308 EXPECT_FLOAT_EQ(awhBiasParams.targetBetaScaling(), 0);
309 EXPECT_FLOAT_EQ(awhBiasParams.targetCutoff(), 0);
310 EXPECT_EQ(awhBiasParams.growthType(), AwhHistogramGrowthType::ExponentialLinear);
311 EXPECT_EQ(awhBiasParams.userPMFEstimate(), 0);
312 EXPECT_FLOAT_EQ(awhBiasParams.initialErrorEstimate(), 0.5 / 0.4);
313 EXPECT_EQ(awhBiasParams.shareGroup(), 0);
314 EXPECT_EQ(awhBiasParams.equilibrateHistogram(), false);
315 const auto& awhDimParams = awhBiasParams.dimParams()[0];
316 EXPECT_EQ(awhDimParams.coordinateProvider(), AwhCoordinateProviderType::Pull);
317 EXPECT_EQ(awhDimParams.coordinateIndex(), 0);
318 EXPECT_FLOAT_EQ(awhDimParams.forceConstant(), 10);
319 EXPECT_FLOAT_EQ(awhDimParams.period(), 0);
320 EXPECT_FLOAT_EQ(awhDimParams.diffusion(), 0.34690997);
321 EXPECT_FLOAT_EQ(awhDimParams.origin(), 0.5);
322 EXPECT_FLOAT_EQ(awhDimParams.end(), 1.5);
323 EXPECT_FLOAT_EQ(awhDimParams.initialCoordinate(), awhDimParams.origin());
324 EXPECT_FLOAT_EQ(awhDimParams.coverDiameter(), 0);
326 gmx::InMemorySerializer serializer;
327 awhParams.serialize(&serializer);
328 EXPECT_THAT(awhParamBuffer, Pointwise(Eq(), serializer.finishAndGetBuffer()));