2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2018,2019, 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 * Tests for the update groups functionality.
39 * \author berk Hess <hess@kth.se>
40 * \ingroup module_mdlib
44 #include "gromacs/mdlib/updategroups.h"
46 #include <gtest/gtest.h>
48 #include "gromacs/topology/topology.h"
50 #include "testutils/testasserts.h"
58 /* TODO: Actually initialize moltype.atoms.atom when this is converted to C++ */
60 /*! \brief Returns an ethane united-atom molecule */
61 gmx_moltype_t
ethaneUA()
63 gmx_moltype_t moltype
= {};
66 moltype
.ilist
[F_CONSTR
].iatoms
= { 0, 0, 1 };
71 /*! \brief Returns a methane molecule */
72 gmx_moltype_t
methane()
74 gmx_moltype_t moltype
= {};
77 moltype
.ilist
[F_CONSTR
].iatoms
= { 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4 };
82 /*! \brief Returns an ethane molecule */
83 gmx_moltype_t
ethane()
85 gmx_moltype_t moltype
= {};
88 moltype
.ilist
[F_CONSTR
].iatoms
= { 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 4, 5, 0, 4, 6, 0, 4, 7 };
89 moltype
.ilist
[F_ANGLES
].iatoms
= { 1, 1, 0, 2, 1, 1, 0, 3, 1, 2, 0, 3,
90 1, 5, 4, 6, 1, 5, 4, 7, 1, 6, 4, 7 };
95 /*! \brief Returns a butane united-atom molecule */
96 gmx_moltype_t
butaneUA()
98 gmx_moltype_t moltype
= {};
100 moltype
.atoms
.nr
= 4;
101 moltype
.ilist
[F_CONSTR
].iatoms
= { 0, 0, 1, 0, 1, 2, 0, 2, 3 };
106 /*! \brief Returns a three-site water molecule */
107 gmx_moltype_t
waterThreeSite()
109 gmx_moltype_t moltype
= {};
111 moltype
.atoms
.nr
= 3;
112 moltype
.ilist
[F_SETTLE
].iatoms
= { 0, 0, 1, 2 };
117 /*! \brief Returns a four-site water molecule with virtual site */
118 gmx_moltype_t
waterFourSite()
120 gmx_moltype_t moltype
= {};
122 moltype
.atoms
.nr
= 4;
123 moltype
.ilist
[F_SETTLE
].iatoms
= { 0, 1, 2, 3 };
124 moltype
.ilist
[F_VSITE3
].iatoms
= { 1, 0, 1, 2, 3 };
129 /*! \brief Returns a water molecule with flexible angle */
130 gmx_moltype_t
waterFlexAngle()
132 gmx_moltype_t moltype
= {};
134 moltype
.atoms
.nr
= 3;
135 moltype
.ilist
[F_CONSTR
].iatoms
= {
138 moltype
.ilist
[F_ANGLES
].iatoms
= {
148 TEST(UpdateGroups
, ethaneUA
)
152 mtop
.moltype
.emplace_back(ethaneUA());
154 iparams
.constr
= { 0.3, 0.3 };
155 mtop
.ffparams
.iparams
.push_back(iparams
);
157 auto updateGroups
= gmx::makeUpdateGroups(mtop
);
159 ASSERT_EQ(updateGroups
.size(), 1);
160 EXPECT_EQ(updateGroups
[0].numBlocks(), 1);
162 real temperature
= 298;
163 real maxRadius
= computeMaxUpdateGroupRadius(mtop
, updateGroups
, temperature
);
164 EXPECT_FLOAT_EQ(maxRadius
, 0.3 / 2);
167 TEST(UpdateGroups
, methane
)
171 mtop
.moltype
.emplace_back(methane());
173 iparams
.constr
= { 0.1, 0.1 };
174 mtop
.ffparams
.iparams
.push_back(iparams
);
176 auto updateGroups
= gmx::makeUpdateGroups(mtop
);
178 ASSERT_EQ(updateGroups
.size(), 1);
179 EXPECT_EQ(updateGroups
[0].numBlocks(), 1);
181 real temperature
= 298;
182 real maxRadius
= computeMaxUpdateGroupRadius(mtop
, updateGroups
, temperature
);
183 EXPECT_FLOAT_EQ(maxRadius
, 0.14);
185 TEST(UpdateGroups
, ethane
)
189 mtop
.moltype
.emplace_back(ethane());
191 iparams
.constr
= { 0.1, 0.1 };
192 mtop
.ffparams
.iparams
.push_back(iparams
);
193 iparams
.harmonic
= { 107.800, 276.144, 107.800, 276.144 };
194 mtop
.ffparams
.iparams
.push_back(iparams
);
196 auto updateGroups
= gmx::makeUpdateGroups(mtop
);
198 ASSERT_EQ(updateGroups
.size(), 1);
199 EXPECT_EQ(updateGroups
[0].numBlocks(), 2);
201 real temperature
= 298;
202 real maxRadius
= computeMaxUpdateGroupRadius(mtop
, updateGroups
, temperature
);
203 EXPECT_FLOAT_EQ(maxRadius
, 0.094746813);
206 maxRadius
= computeMaxUpdateGroupRadius(mtop
, updateGroups
, temperature
);
207 EXPECT_FLOAT_EQ(maxRadius
, 0.10310466);
210 maxRadius
= computeMaxUpdateGroupRadius(mtop
, updateGroups
, temperature
);
211 EXPECT_FLOAT_EQ(maxRadius
, 0.125);
214 TEST(UpdateGroups
, butaneUA
)
218 mtop
.moltype
.emplace_back(butaneUA());
220 iparams
.constr
= { 0.3, 0.3 };
221 mtop
.ffparams
.iparams
.push_back(iparams
);
223 auto updateGroups
= gmx::makeUpdateGroups(mtop
);
225 EXPECT_EQ(updateGroups
.size(), 0);
228 TEST(UpdateGroups
, waterThreeSite
)
232 mtop
.moltype
.emplace_back(waterThreeSite());
234 iparams
.settle
= { 0.1, 0.1633 };
235 mtop
.ffparams
.iparams
.push_back(iparams
);
237 auto updateGroups
= gmx::makeUpdateGroups(mtop
);
239 ASSERT_EQ(updateGroups
.size(), 1);
240 EXPECT_EQ(updateGroups
[0].numBlocks(), 1);
242 real temperature
= 298;
243 real maxRadius
= computeMaxUpdateGroupRadius(mtop
, updateGroups
, temperature
);
244 EXPECT_FLOAT_EQ(maxRadius
, 0.083887339);
247 // Tests update group with virtual site
248 TEST(UpdateGroups
, waterFourSite
)
252 mtop
.moltype
.emplace_back(waterFourSite());
253 t_iparams iparams
[2];
254 iparams
[0].settle
= { 0.1, 0.1633 };
255 iparams
[1].vsite
= { 0.128, 0.128 };
256 mtop
.ffparams
.iparams
.push_back(iparams
[0]);
257 mtop
.ffparams
.iparams
.push_back(iparams
[1]);
259 auto updateGroups
= gmx::makeUpdateGroups(mtop
);
261 ASSERT_EQ(updateGroups
.size(), 1);
262 EXPECT_EQ(updateGroups
[0].numBlocks(), 1);
265 TEST(UpdateGroups
, fourAtomsWithSettle
)
269 mtop
.moltype
.emplace_back(waterThreeSite());
270 mtop
.moltype
.back().atoms
.nr
= 4;
272 auto updateGroups
= gmx::makeUpdateGroups(mtop
);
274 ASSERT_EQ(updateGroups
.size(), 1);
275 EXPECT_EQ(updateGroups
[0].numBlocks(), 2);
278 // Tests groups with two constraints and an angle potential
279 TEST(UpdateGroups
, waterFlexAngle
)
283 mtop
.moltype
.emplace_back(waterFlexAngle());
285 iparams
.constr
= { 0.1, 0.1 };
286 mtop
.ffparams
.iparams
.push_back(iparams
);
287 iparams
.harmonic
= { 109.47, 383.0, 109.47, 383.0 };
288 mtop
.ffparams
.iparams
.push_back(iparams
);
290 auto updateGroups
= gmx::makeUpdateGroups(mtop
);
292 ASSERT_EQ(updateGroups
.size(), 1);
293 EXPECT_EQ(updateGroups
[0].numBlocks(), 1);
295 real temperature
= 298;
296 real maxRadius
= computeMaxUpdateGroupRadius(mtop
, updateGroups
, temperature
);
297 EXPECT_FLOAT_EQ(maxRadius
, 0.090824135);
300 maxRadius
= computeMaxUpdateGroupRadius(mtop
, updateGroups
, temperature
);
301 EXPECT_FLOAT_EQ(maxRadius
, 0.1);
304 maxRadius
= computeMaxUpdateGroupRadius(mtop
, updateGroups
, temperature
);
305 EXPECT_FLOAT_EQ(maxRadius
, 0.1);
308 TEST(UpdateGroups
, twoMoltypes
)
312 mtop
.moltype
.emplace_back(methane());
314 iparams
.constr
= { 0.1, 0.1 };
315 mtop
.ffparams
.iparams
.push_back(iparams
);
317 mtop
.moltype
.emplace_back(waterThreeSite());
318 // Note: iparams not accessed for SETTLE when not computing radius
320 auto updateGroups
= gmx::makeUpdateGroups(mtop
);
322 ASSERT_EQ(updateGroups
.size(), 2);
323 EXPECT_EQ(updateGroups
[0].numBlocks(), 1);
324 EXPECT_EQ(updateGroups
[1].numBlocks(), 1);