From: Eliane Briand Date: Wed, 29 Sep 2021 18:20:22 +0000 (+0000) Subject: Relax requirement for bonded atom type names X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=31146476c633ccd15d1794ef0c4de77db9fda4ee;p=alexxy%2Fgromacs.git Relax requirement for bonded atom type names --- diff --git a/docs/reference-manual/topologies/topology-file-formats.rst b/docs/reference-manual/topologies/topology-file-formats.rst index 506a1dcca1..6f8443aca5 100644 --- a/docs/reference-manual/topologies/topology-file-formats.rst +++ b/docs/reference-manual/topologies/topology-file-formats.rst @@ -340,6 +340,8 @@ Description of the file layout: - Atoms in the same charge group must be listed consecutively +- Bonded atom type name must contain at least one non-digit character. + - The file is parsed only once, which implies that no forward references can be treated: items must be defined before they can be used diff --git a/docs/release-notes/2022/major/miscellaneous.rst b/docs/release-notes/2022/major/miscellaneous.rst index 1f050b2921..6532989556 100644 --- a/docs/release-notes/2022/major/miscellaneous.rst +++ b/docs/release-notes/2022/major/miscellaneous.rst @@ -13,3 +13,11 @@ grompp no longer modifies nstcomm grompp will no longer set nstcomm, the interval for center of mass motion removal, equal to nstcalcenergy when nstcomm < nstcalcenergy. A note is still printed in that case. + +Bonded atom types names can now start with a digit +"""""""""""""""""""""""""""""""""""""""""""""""""" + +Bonded atom types names in topologies were not allowed to start with a number. +Now all names are supported that contain at least one non-digit character. + +:issue:`4120` diff --git a/src/gromacs/gmxpreprocess/tests/CMakeLists.txt b/src/gromacs/gmxpreprocess/tests/CMakeLists.txt index 677aaa6ed6..5db15f0859 100644 --- a/src/gromacs/gmxpreprocess/tests/CMakeLists.txt +++ b/src/gromacs/gmxpreprocess/tests/CMakeLists.txt @@ -40,6 +40,7 @@ gmx_add_gtest_executable(gmxpreprocess-test genrestr.cpp gpp_atomtype.cpp gpp_bond_atomtype.cpp + grompp_directives.cpp insert_molecules.cpp readir.cpp solvate.cpp diff --git a/src/gromacs/gmxpreprocess/tests/directives.gro b/src/gromacs/gmxpreprocess/tests/directives.gro new file mode 100644 index 0000000000..ab05d7c925 --- /dev/null +++ b/src/gromacs/gmxpreprocess/tests/directives.gro @@ -0,0 +1,7 @@ +UNNAMED + 4 + 1 A N 1 0.305 0.792 -0.052 + 2 A C 1 1.305 0.792 -0.052 + 3 A O 1 2.305 0.792 -0.052 + 4 A S 1 3.305 0.792 -0.052 + 5.25681 5.26870 5.05080 diff --git a/src/gromacs/gmxpreprocess/tests/directives.top b/src/gromacs/gmxpreprocess/tests/directives.top new file mode 100644 index 0000000000..e1ceed8e03 --- /dev/null +++ b/src/gromacs/gmxpreprocess/tests/directives.top @@ -0,0 +1,44 @@ +; Minimal topology file to test edge-cases for directive parsing + +[ defaults ] +; nbfunc comb-rule gen-pairs fudgeLJ fudgeQQ +1 2 yes 0.5 0.8333 + + +[ atomtypes ] +; Cover all combinations of optional [bname] [at.num] +; name bname at.num mass charge ptype sigma epsilon +2C_ 2Cbonded 12.01 0.0000 A 0.339967 0.45773 +_ _bonded 6 12.01 0.0000 A 0.349967 0.45773 +4_ 7 12.01 0.0000 A 0.359967 0.45773 +5_ 12.01 0.0000 A 0.369967 0.45773 + +[ bondtypes ] +; i j func b0 kb +2Cbonded _bonded 1 0.10900 284512.0 + + +[ moleculetype ] +; Name nrexcl +A 0 + +[ atoms ] +; nr type resnr residue atom cgnr charge mass typeB chargeB massB + 1 2C_ 1 RES N 1 0.0 14.01 + 2 _ 1 RES C 2 0.0 14.01 + 3 4_ 1 RES O 2 0.0 14.01 + 4 5_ 1 RES S 2 0.0 14.01 + +[ bonds ] +; ai aj funct c0 c1 c2 c3 +; Bond without values: will result in "No default Bond types" if bonded name were not parsed + 1 2 1 + +[ system ] +; Name +minimal edge case system + +[ molecules ] +; Compound #mols +A 1 + diff --git a/src/gromacs/gmxpreprocess/tests/grompp_directives.cpp b/src/gromacs/gmxpreprocess/tests/grompp_directives.cpp new file mode 100644 index 0000000000..877033abd3 --- /dev/null +++ b/src/gromacs/gmxpreprocess/tests/grompp_directives.cpp @@ -0,0 +1,118 @@ +/* + * This file is part of the GROMACS molecular simulation package. + * + * Copyright (c) 2021 by the GROMACS development team. + * 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. + * + * GROMACS is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * GROMACS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GROMACS; if not, see + * http://www.gnu.org/licenses, or write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * If you want to redistribute modifications to GROMACS, please + * consider that scientific software is very special. Version + * control is crucial - bugs must be traceable. We will be happy to + * consider code for inclusion in the official distribution, but + * derived work must not be called official GROMACS. Details are found + * in the README & COPYING files - if they are missing, get the + * official version at http://www.gromacs.org. + * + * To help us fund GROMACS development, we humbly ask that you cite + * the research papers on the package. Check out http://www.gromacs.org. + */ +/*! \internal \file + * \brief + * Tests for grompp directives parsing + * + * \author Eliane Briand + */ + +#include "gmxpre.h" + +#include "gromacs/fileio/tpxio.h" +#include "gromacs/gmxpreprocess/grompp.h" +#include "gromacs/mdtypes/inputrec.h" +#include "gromacs/mdtypes/state.h" +#include "gromacs/utility/futil.h" +#include "gromacs/utility/textreader.h" +#include "gromacs/utility/textwriter.h" +#include "gromacs/topology/topology.h" + +#include "testutils/cmdlinetest.h" +#include "testutils/conftest.h" +#include "testutils/refdata.h" +#include "testutils/testfilemanager.h" +#include "testutils/textblockmatchers.h" + +namespace +{ + +using gmx::test::CommandLine; +using gmx::test::TestFileManager; + +class GromppDirectiveTest : public ::testing::Test +{ +public: + GromppDirectiveTest() = default; + +protected: + gmx::test::TestFileManager fileManager_; + std::string mdpContentString_ = + "title = Directive edge case test \n" + "integrator = md \n" + "nsteps = 1 \n" + "dt = 0.002 \n" + "vdwtype = cutoff \n" + "coulombtype = cutoff \n" + "tcoupl = no \n" + "pcoupl = no \n" + "pbc = xyz \n" + "gen_vel = yes \n"; +}; + +TEST_F(GromppDirectiveTest, edgeCaseAtomTypeNames) +{ + CommandLine cmdline; + cmdline.addOption("grompp"); + + const std::string mdpInputFileName = fileManager_.getTemporaryFilePath("directives.mdp"); + gmx::TextWriter::writeFileFromString(mdpInputFileName, mdpContentString_); + cmdline.addOption("-f", mdpInputFileName); + + + cmdline.addOption("-c", TestFileManager::getInputFilePath("directives.gro")); + cmdline.addOption("-p", TestFileManager::getInputFilePath("directives.top")); + + std::string outTprFilename = fileManager_.getTemporaryFilePath("directives.tpr"); + cmdline.addOption("-o", outTprFilename); + + ASSERT_EQ(0, gmx_grompp(cmdline.argc(), cmdline.argv())); + + { + gmx_mtop_t top_after; + t_inputrec ir_after; + t_state state; + read_tpx_state(outTprFilename.c_str(), &ir_after, &state, &top_after); + + // Check atomic numbers (or lack thereof coded as -1) + ASSERT_EQ(top_after.atomtypes.nr, 4); + EXPECT_EQ(top_after.atomtypes.atomnumber[0], -1); + EXPECT_EQ(top_after.atomtypes.atomnumber[1], 6); + EXPECT_EQ(top_after.atomtypes.atomnumber[2], 7); + EXPECT_EQ(top_after.atomtypes.atomnumber[3], -1); + } +} + +} // namespace diff --git a/src/gromacs/gmxpreprocess/toppush.cpp b/src/gromacs/gmxpreprocess/toppush.cpp index ebce88d383..da45441cbe 100644 --- a/src/gromacs/gmxpreprocess/toppush.cpp +++ b/src/gromacs/gmxpreprocess/toppush.cpp @@ -385,7 +385,12 @@ void push_at(t_symtab* symtab, } else { - have_bonded_type = (isalpha(tmpfield[1][0]) != 0); + // Attempt parsing field 1 to integer. If successful, *end == '\0' + char* end; + strtol(tmpfield[1], &end, 10); + + // If conversion fails, we do not have an atomic number but a bonded type + have_bonded_type = (*end != 0); have_atomic_number = !have_bonded_type; }