# GROMACS 2019 4
# GROMACS 2020 5
# GROMACS 2021 6
+# GROMACS 2022 7
# LIBRARY_SOVERSION_MINOR so minor version for the built libraries.
# Should be increased for each release that changes only the implementation.
# In GROMACS, the typical policy is to increase it for each patch version
# The GROMACS convention is that these are the version number of the next
# release that is going to be made from this branch.
-set(GMX_VERSION_MAJOR 2021)
-set(GMX_VERSION_PATCH 4)
+set(GMX_VERSION_MAJOR 2022)
+set(GMX_VERSION_PATCH 0)
# The suffix, on the other hand, is used mainly for betas and release
# candidates, where it signifies the most recent such release from
# this branch; it will be empty before the first such release, as well
# here. The important thing is to minimize the chance of third-party
# code being able to dynamically link with a version of libgromacs
# that might not work.
-set(LIBRARY_SOVERSION_MAJOR 6)
+set(LIBRARY_SOVERSION_MAJOR 7)
set(LIBRARY_SOVERSION_MINOR 0)
set(LIBRARY_VERSION ${LIBRARY_SOVERSION_MAJOR}.${LIBRARY_SOVERSION_MINOR}.0)
endif()
set(GMX_VERSION_STRING "${GMX_VERSION}${GMX_VERSION_SUFFIX}")
-set(REGRESSIONTEST_BRANCH "release-2021")
+ set(REGRESSIONTEST_VERSION "${GMX_VERSION_STRING}")
++set(REGRESSIONTEST_BRANCH "master")
+ # Run the regressiontests packaging job with the correct pakage
+ # version string, and the release box checked, in order to have it
+ # build the regressiontests tarball with all the right naming. The
+ # naming affects the md5sum that has to go here, and if it isn't right
+ # release workflow will report a failure.
+ set(REGRESSIONTEST_MD5SUM "93956ea42c4d16fdd541518c05972989" CACHE INTERNAL "MD5 sum of the regressiontests tarball for this GROMACS version")
+
# If you are making a custom fork of GROMACS, please describe your
# fork, perhaps with its version number, in the value of
# GMX_VERSION_STRING_OF_FORK here. This string will appear in the
set(GMX_VERSION_STRING "${GMX_VERSION_STRING}-dev")
endif()
- set(REGRESSIONTEST_VERSION "${GMX_VERSION_STRING}")
- set(REGRESSIONTEST_BRANCH "master")
- # Run the regressiontests packaging job with the correct pakage
- # version string, and the release box checked, in order to have it
- # build the regressiontests tarball with all the right naming. The
- # naming affects the md5sum that has to go here, and if it isn't right
- # release workflow will report a failure.
- set(REGRESSIONTEST_MD5SUM "93956ea42c4d16fdd541518c05972989" CACHE INTERNAL "MD5 sum of the regressiontests tarball for this GROMACS version")
-
math(EXPR GMX_VERSION_NUMERIC
"${GMX_VERSION_MAJOR}*10000 + ${GMX_VERSION_PATCH}")
set(GMX_API_VERSION ${GMX_VERSION_NUMERIC})
- # If run with cmake -P from releng scripts, print out necessary version info
+ # If run with cmake -P from GitLab scripts, print out necessary version info
# as JSON.
if (CMAKE_SCRIPT_MODE_FILE)
message("{ \"version\": \"${GMX_VERSION_STRING}\", \"regressiontest-md5sum\": \"${REGRESSIONTEST_MD5SUM}\" }")
This requires configuring |Gromacs| to build with an external MPI
library. By default, this :ref:`mdrun <gmx mdrun>` executable is run with
-:ref:`mdrun_mpi`. All of the considerations for running single-node
+``gmx_mpi mdrun``. All of the considerations for running single-node
:ref:`mdrun <gmx mdrun>` still apply, except that ``-ntmpi`` and ``-nt`` cause a fatal
error, and instead the number of ranks is controlled by the
MPI environment.
mpirun -np 16 gmx_mpi mdrun
-Starts :ref:`mdrun_mpi` with 16 ranks, which are mapped to
+Starts :ref:`gmx mdrun` with 16 ranks, which are mapped to
the hardware by the MPI library, e.g. as specified
in an MPI hostfile. The available cores will be
automatically split among ranks using OpenMP threads,
mpirun -np 16 gmx_mpi mdrun -npme 5
-Starts :ref:`mdrun_mpi` with 16 ranks, as above, and
+Starts :ref:`gmx mdrun` with 16 ranks, as above, and
require that 5 of them are dedicated to the PME
component.
mpirun -np 11 gmx_mpi mdrun -ntomp 2 -npme 6 -ntomp_pme 1
-Starts :ref:`mdrun_mpi` with 11 ranks, as above, and
+Starts :ref:`gmx mdrun` with 11 ranks, as above, and
require that six of them are dedicated to the PME
component with one OpenMP thread each. The remaining
five do the PP component, with two OpenMP threads
mpirun -np 4 gmx_mpi mdrun -ntomp 6 -nb gpu -gputasks 00
-Starts :ref:`mdrun_mpi` on a machine with two nodes, using
+Starts :ref:`gmx mdrun` on a machine with two nodes, using
four total ranks, each rank with six OpenMP threads,
and both ranks on a node sharing GPU with ID 0.
mpirun -np 8 gmx_mpi mdrun -ntomp 3 -gputasks 0000
Using a same/similar hardware as above,
-starts :ref:`mdrun_mpi` on a machine with two nodes, using
+starts :ref:`gmx mdrun` on a machine with two nodes, using
eight total ranks, each rank with three OpenMP threads,
and all four ranks on a node sharing GPU with ID 0.
This may or may not be faster than the previous setup
mpirun -np 20 gmx_mpi mdrun -ntomp 4 -gputasks 00
-Starts :ref:`mdrun_mpi` with 20 ranks, and assigns the CPU cores evenly
+Starts :ref:`gmx mdrun` with 20 ranks, and assigns the CPU cores evenly
across ranks each to one OpenMP thread. This setup is likely to be
suitable when there are ten nodes, each with one GPU, and each node
has two sockets each of four cores.
mpirun -np 10 gmx_mpi mdrun -gpu_id 1
-Starts :ref:`mdrun_mpi` with 20 ranks, and assigns the CPU cores evenly
+Starts :ref:`gmx mdrun` with 20 ranks, and assigns the CPU cores evenly
across ranks each to one OpenMP thread. This setup is likely to be
suitable when there are ten nodes, each with two GPUs, but another
job on each node is using GPU 0. The job scheduler should set the
mpirun -np 20 gmx_mpi mdrun -gpu_id 01
-Starts :ref:`mdrun_mpi` with 20 ranks. This setup is likely
+Starts :ref:`gmx mdrun` with 20 ranks. This setup is likely
to be suitable when there are ten nodes, each with two
GPUs, but there is no need to specify ``-gpu_id`` for the
normal case where all the GPUs on the node are available
At the end of the log file of each run, the "Real cycle and time accounting" section
provides a table with runtime statistics for different parts of the :ref:`gmx mdrun` code
in rows of the table.
- The table contains colums indicating the number of ranks and threads that
+ The table contains columns indicating the number of ranks and threads that
executed the respective part of the run, wall-time and cycle
count aggregates (across all threads and ranks) averaged over the entire run.
The last column also shows what precentage of the total runtime each row represents.
* Don't use double precision unless you're absolute sure you need it.
* Compile the FFTW library (yourself) with the correct flags on x86 (in most
cases, the correct flags are automatically configured).
-* On x86, use gcc or icc as the compiler (not pgi or the Cray compiler).
+* On x86, use gcc as the compiler (not icc, pgi or the Cray compiler).
* On POWER, use gcc instead of IBM's xlc.
* Use a new compiler version, especially for gcc (e.g. from version 5 to 6
the performance of the compiled code improved a lot).
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
// Copy and assign disallowed by base.
};
* data. Each frame contains the histogram(s) for the points in that frame,
* interpreted such that the first column passed to pointsAdded() determines
* the bin and the rest give weights to be added to that bin (input data should
- * have at least two colums, and at least two columns should be added at the
+ * have at least two columns, and at least two columns should be added at the
* same time).
* Each input data set is processed independently into the corresponding output
* data set.
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
// Copy and assign disallowed by base.
};
* that bin.
* The input data is interpreted such that the first column passed to
* pointsAdded() determines the bin and the rest give values to be added to
- * that bin (input data should have at least two colums, and at least two
+ * that bin (input data should have at least two columns, and at least two
* columns should be added at the same time).
* All input columns for a data set are averaged into the same histogram.
*
private:
class Impl;
- PrivateImplPointer<Impl> impl_;
+ std::unique_ptr<Impl> impl_;
// Copy and assign disallowed by base.
};
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019,2020,2021, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020 by the GROMACS development team.
+ * Copyright (c) 2021, 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.
case ZZ: return realGridSizeFP[ZZ];
}
assert(false);
- return 0.0f;
+ return 0.0F;
}
/*! \brief Reduce the partial force contributions.
const int splineIndex,
const int lineIndex,
const float* realGridSizeFP,
- float& fx,
- float& fy,
- float& fz)
+ float& fx, // NOLINT(google-runtime-references)
+ float& fy, // NOLINT(google-runtime-references)
+ float& fz) // NOLINT(google-runtime-references)
{
- if (!(order & (order - 1))) // Only for orders of power of 2
+ if (gmx::isPowerOfTwo(order)) // Only for orders of power of 2
{
const unsigned int activeMask = c_fullWarpMask;
if (dimIndex < DIM)
{
const float n = read_grid_size(realGridSizeFP, dimIndex);
- *((float*)(&sm_forces[atomIndexLocal]) + dimIndex) = fx * n;
+ float* __restrict__ sm_forcesAtomIndexOffset =
+ reinterpret_cast<float*>(&sm_forces[atomIndexLocal]);
+ sm_forcesAtomIndexOffset[dimIndex] = fx * n;
}
}
else
if (sourceIndex == minStride * atomIndex)
{
- *((float*)(&sm_forces[atomIndex]) + dimIndex) =
+ float* __restrict__ sm_forcesAtomIndexOffset =
+ reinterpret_cast<float*>(&sm_forces[atomIndex]);
+ sm_forcesAtomIndexOffset[dimIndex] =
(sm_forceTemp[dimIndex][sourceIndex] + sm_forceTemp[dimIndex][sourceIndex + 1]) * n;
}
}
const float* __restrict__ gm_coefficientsB = kernelParams.atoms.d_coefficients[1];
const float* __restrict__ gm_gridA = kernelParams.grid.d_realGrid[0];
const float* __restrict__ gm_gridB = kernelParams.grid.d_realGrid[1];
- float* __restrict__ gm_forces = kernelParams.atoms.d_forces;
+ static_assert(sizeof(*kernelParams.atoms.d_forces) == 3 * sizeof(float));
+ float* __restrict__ gm_forces = reinterpret_cast<float*>(kernelParams.atoms.d_forces);
/* Global memory pointers for readGlobal */
const float* __restrict__ gm_theta = kernelParams.atoms.d_theta;
atomX = gm_coordinates[atomIndexGlobal];
atomCharge = gm_coefficientsA[atomIndexGlobal];
}
- calculate_splines<order, atomsPerBlock, atomsPerWarp, true, false>(
+ calculate_splines<order, atomsPerBlock, atomsPerWarp, true, false, numGrids>(
kernelParams, atomIndexOffset, atomX, atomCharge, sm_theta, sm_dtheta, sm_gridlineIndices);
__syncwarp();
}
- float fx = 0.0f;
- float fy = 0.0f;
- float fz = 0.0f;
+ float fx = 0.0F;
+ float fy = 0.0F;
+ float fz = 0.0F;
const int chargeCheck = pme_gpu_check_atom_charge(gm_coefficientsA[atomIndexGlobal]);
const int ithyMax = (threadsPerAtom == ThreadsPerAtom::Order) ? order : threadIdx.y + 1;
if (chargeCheck)
{
- sumForceComponents<order, atomsPerWarp, wrapX, wrapY>(
- &fx, &fy, &fz, ithyMin, ithyMax, ixBase, iz, nx, ny, pny, pnz, atomIndexLocal,
- splineIndexBase, tdz, sm_gridlineIndices, sm_theta, sm_dtheta, gm_gridA);
+ sumForceComponents<order, atomsPerWarp, wrapX, wrapY>(&fx,
+ &fy,
+ &fz,
+ ithyMin,
+ ithyMax,
+ ixBase,
+ iz,
+ nx,
+ ny,
+ pny,
+ pnz,
+ atomIndexLocal,
+ splineIndexBase,
+ tdz,
+ sm_gridlineIndices,
+ sm_theta,
+ sm_dtheta,
+ gm_gridA);
}
// Reduction of partial force contributions
__shared__ float3 sm_forces[atomsPerBlock];
- reduce_atom_forces<order, atomDataSize, blockSize>(sm_forces, atomIndexLocal, splineIndex, lineIndex,
- kernelParams.grid.realGridSizeFP, fx, fy, fz);
+ reduce_atom_forces<order, atomDataSize, blockSize>(
+ sm_forces, atomIndexLocal, splineIndex, lineIndex, kernelParams.grid.realGridSizeFP, fx, fy, fz);
__syncthreads();
/* Calculating the final forces with no component branching, atomsPerBlock threads */
const float scale = kernelParams.current.scale;
if (forceIndexLocal < atomsPerBlock)
{
- calculateAndStoreGridForces(sm_forces, forceIndexLocal, forceIndexGlobal,
- kernelParams.current.recipBox, scale, gm_coefficientsA);
+ calculateAndStoreGridForces(
+ sm_forces, forceIndexLocal, forceIndexGlobal, kernelParams.current.recipBox, scale, gm_coefficientsA);
}
__syncwarp();
{
int outputIndexLocal = i * iterThreads + threadLocalId;
int outputIndexGlobal = blockIndex * blockForcesSize + outputIndexLocal;
- float outputForceComponent = ((float*)sm_forces)[outputIndexLocal];
+ float outputForceComponent = (reinterpret_cast<float*>(sm_forces)[outputIndexLocal]);
gm_forces[outputIndexGlobal] = outputForceComponent;
}
}
{
/* We must sync here since the same shared memory is used as above. */
__syncthreads();
- fx = 0.0f;
- fy = 0.0f;
- fz = 0.0f;
+ fx = 0.0F;
+ fy = 0.0F;
+ fz = 0.0F;
const int chargeCheck = pme_gpu_check_atom_charge(gm_coefficientsB[atomIndexGlobal]);
if (chargeCheck)
{
- sumForceComponents<order, atomsPerWarp, wrapX, wrapY>(
- &fx, &fy, &fz, ithyMin, ithyMax, ixBase, iz, nx, ny, pny, pnz, atomIndexLocal,
- splineIndexBase, tdz, sm_gridlineIndices, sm_theta, sm_dtheta, gm_gridB);
+ sumForceComponents<order, atomsPerWarp, wrapX, wrapY>(&fx,
+ &fy,
+ &fz,
+ ithyMin,
+ ithyMax,
+ ixBase,
+ iz,
+ nx,
+ ny,
+ pny,
+ pnz,
+ atomIndexLocal,
+ splineIndexBase,
+ tdz,
+ sm_gridlineIndices,
+ sm_theta,
+ sm_dtheta,
+ gm_gridB);
}
// Reduction of partial force contributions
- reduce_atom_forces<order, atomDataSize, blockSize>(sm_forces, atomIndexLocal, splineIndex,
- lineIndex, kernelParams.grid.realGridSizeFP,
- fx, fy, fz);
+ reduce_atom_forces<order, atomDataSize, blockSize>(
+ sm_forces, atomIndexLocal, splineIndex, lineIndex, kernelParams.grid.realGridSizeFP, fx, fy, fz);
__syncthreads();
/* Calculating the final forces with no component branching, atomsPerBlock threads */
if (forceIndexLocal < atomsPerBlock)
{
- calculateAndStoreGridForces(sm_forces, forceIndexLocal, forceIndexGlobal,
- kernelParams.current.recipBox, 1.0F - scale, gm_coefficientsB);
+ calculateAndStoreGridForces(sm_forces,
+ forceIndexLocal,
+ forceIndexGlobal,
+ kernelParams.current.recipBox,
+ 1.0F - scale,
+ gm_coefficientsB);
}
__syncwarp();
{
int outputIndexLocal = i * iterThreads + threadLocalId;
int outputIndexGlobal = blockIndex * blockForcesSize + outputIndexLocal;
- float outputForceComponent = ((float*)sm_forces)[outputIndexLocal];
+ float outputForceComponent = (reinterpret_cast<float*>(sm_forces)[outputIndexLocal]);
gm_forces[outputIndexGlobal] += outputForceComponent;
}
}
*
* This is called from the spline_and_spread and gather PME kernels.
*/
-int __device__ __forceinline__ pme_gpu_check_atom_charge(const float coefficient)
+bool __device__ __forceinline__ pme_gpu_check_atom_charge(const float coefficient)
{
assert(isfinite(coefficient));
- return c_skipNeutralAtoms ? (coefficient != 0.0f) : 1;
+ return c_skipNeutralAtoms ? (coefficient != 0.0F) : true;
}
//! Controls if the atom and charge data is prefeched into shared memory or loaded per thread from global
template<>
__device__ inline void assertIsFinite(float3 gmx_unused arg)
{
- assert(isfinite(float(arg.x)));
- assert(isfinite(float(arg.y)));
- assert(isfinite(float(arg.z)));
+ assert(isfinite(static_cast<float>(arg.x)));
+ assert(isfinite(static_cast<float>(arg.y)));
+ assert(isfinite(static_cast<float>(arg.z)));
}
template<typename T>
__device__ inline void assertIsFinite(T gmx_unused arg)
{
- assert(isfinite(float(arg)));
+ assert(isfinite(static_cast<float>(arg)));
}
/*! \brief
* \tparam[in] atomsPerBlock Number of atoms processed by a block - should be accounted for
* in the sizes of the shared memory arrays.
* \tparam[in] atomsPerWarp Number of atoms processed by a warp
- * \tparam[in] writeSmDtheta Bool controlling if the theta derivative should be written to shared memory. Enables calculation of dtheta if set.
- * \tparam[in] writeGlobal A boolean which tells if the theta values and gridlines should be written to global memory. Enables calculation of dtheta if set.
- * \tparam[in] writeSmDtheta Bool controling if the theta derivative should be written to
++ * \tparam[in] writeSmDtheta Bool controlling if the theta derivative should be written to
+ * shared memory. Enables calculation of dtheta if set.
+ * \tparam[in] writeGlobal A boolean which tells if the theta values and gridlines should
+ * be written to global memory. Enables calculation of dtheta if
+ * set.
+ * \tparam[in] numGrids The number of grids using the splines.
* \param[in] kernelParams Input PME CUDA data in constant memory.
* \param[in] atomIndexOffset Starting atom index for the execution block w.r.t. global memory.
* \param[in] atomX Atom coordinate of atom processed by thread.
* \param[out] sm_gridlineIndices Atom gridline indices in the shared memory.
*/
- template<int order, int atomsPerBlock, int atomsPerWarp, bool writeSmDtheta, bool writeGlobal>
+ template<int order, int atomsPerBlock, int atomsPerWarp, bool writeSmDtheta, bool writeGlobal, int numGrids>
__device__ __forceinline__ void calculate_splines(const PmeGpuCudaKernelParams kernelParams,
const int atomIndexOffset,
const float3 atomX,
float* __restrict__ sm_dtheta,
int* __restrict__ sm_gridlineIndices)
{
+ assert(numGrids == 1 || numGrids == 2);
+ assert(numGrids == 1 || c_skipNeutralAtoms == false);
+
/* Global memory pointers for output */
float* __restrict__ gm_theta = kernelParams.atoms.d_theta;
float* __restrict__ gm_dtheta = kernelParams.atoms.d_dtheta;
const float shift = c_pmeMaxUnitcellShift;
/* Fractional coordinates along box vectors, adding a positive shift to ensure t is positive for triclinic boxes */
t = (t + shift) * n;
- tInt = (int)t;
+ tInt = static_cast<int>(t);
assert(sharedMemoryIndex < atomsPerBlock * DIM);
sm_fractCoords[sharedMemoryIndex] = t - tInt;
tableIndex += tInt;
// TODO have shared table for both parameters to share the fetch, as index is always same?
// TODO compare texture/LDG performance
- sm_fractCoords[sharedMemoryIndex] +=
- fetchFromParamLookupTable(kernelParams.grid.d_fractShiftsTable,
- kernelParams.fractShiftsTableTexture, tableIndex);
+ sm_fractCoords[sharedMemoryIndex] += fetchFromParamLookupTable(
+ kernelParams.grid.d_fractShiftsTable, kernelParams.fractShiftsTableTexture, tableIndex);
sm_gridlineIndices[sharedMemoryIndex] =
fetchFromParamLookupTable(kernelParams.grid.d_gridlineIndicesTable,
- kernelParams.gridlineIndicesTableTexture, tableIndex);
+ kernelParams.gridlineIndicesTableTexture,
+ tableIndex);
if (writeGlobal)
{
gm_gridlineIndices[atomIndexOffset * DIM + sharedMemoryIndex] =
/* B-spline calculation */
const int chargeCheck = pme_gpu_check_atom_charge(atomCharge);
- if (chargeCheck)
+ /* With FEP (numGrids == 2), we might have 0 charge in state A, but !=0 in state B, so we always calculate splines */
+ if (numGrids == 2 || chargeCheck)
{
float div;
int o = orderIndex; // This is an index that is set once for PME_GPU_PARALLEL_SPLINE == 1
assert(isfinite(dr));
/* dr is relative offset from lower cell limit */
- splineData[order - 1] = 0.0f;
+ splineData[order - 1] = 0.0F;
splineData[1] = dr;
- splineData[0] = 1.0f - dr;
+ splineData[0] = 1.0F - dr;
#pragma unroll
for (int k = 3; k < order; k++)
{
- div = 1.0f / (k - 1.0f);
+ div = 1.0F / (k - 1.0F);
splineData[k - 1] = div * dr * splineData[k - 2];
#pragma unroll
for (int l = 1; l < (k - 1); l++)
splineData[k - l - 1] =
div * ((dr + l) * splineData[k - l - 2] + (k - l - dr) * splineData[k - l - 1]);
}
- splineData[0] = div * (1.0f - dr) * splineData[0];
+ splineData[0] = div * (1.0F - dr) * splineData[0];
}
const int thetaIndexBase =
const int thetaIndex =
getSplineParamIndex<order, atomsPerWarp>(thetaIndexBase, dimIndex, o);
- const float dtheta = ((o > 0) ? splineData[o - 1] : 0.0f) - splineData[o];
+ const float dtheta = ((o > 0) ? splineData[o - 1] : 0.0F) - splineData[o];
assert(isfinite(dtheta));
assert(thetaIndex < order * DIM * atomsPerBlock);
if (writeSmDtheta)
}
}
- div = 1.0f / (order - 1.0f);
+ div = 1.0F / (order - 1.0F);
splineData[order - 1] = div * dr * splineData[order - 2];
#pragma unroll
for (int k = 1; k < (order - 1); k++)
* ((dr + k) * splineData[order - k - 2]
+ (order - k - dr) * splineData[order - k - 1]);
}
- splineData[0] = div * (1.0f - dr) * splineData[0];
+ splineData[0] = div * (1.0F - dr) * splineData[0];
/* Storing the spline values (theta) */
#pragma unroll
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team.
+ * Copyright (c) 2016,2017,2018,2019,2020 by the GROMACS development team.
* Copyright (c) 2021, 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
#include <string>
#include "gromacs/ewald/ewald_utils.h"
+#include "gromacs/fft/gpu_3dfft.h"
#include "gromacs/gpu_utils/device_context.h"
#include "gromacs/gpu_utils/device_stream.h"
#include "gromacs/gpu_utils/gpu_utils.h"
+#include "gromacs/gpu_utils/pmalloc.h"
+#if GMX_GPU_SYCL
+# include "gromacs/gpu_utils/syclutils.h"
+#endif
#include "gromacs/hardware/device_information.h"
#include "gromacs/math/invertmatrix.h"
#include "gromacs/math/units.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/logger.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/ewald/pme.h"
#if GMX_GPU_CUDA
-# include "gromacs/gpu_utils/pmalloc_cuda.h"
-
# include "pme.cuh"
-#elif GMX_GPU_OPENCL
-# include "gromacs/gpu_utils/gmxopencl.h"
#endif
-#include "gromacs/ewald/pme.h"
-
-#include "pme_gpu_3dfft.h"
#include "pme_gpu_calculate_splines.h"
#include "pme_gpu_constants.h"
#include "pme_gpu_program_impl.h"
for (int gridIndex = 0; gridIndex < pmeGpu->common->ngrids; gridIndex++)
{
allocateDeviceBuffer(&pmeGpu->kernelParams->constants.d_virialAndEnergy[gridIndex],
- c_virialAndEnergyCount, pmeGpu->archSpecific->deviceContext_);
+ c_virialAndEnergyCount,
+ pmeGpu->archSpecific->deviceContext_);
pmalloc(reinterpret_cast<void**>(&pmeGpu->staging.h_virialAndEnergy[gridIndex]), energyAndVirialSize);
}
}
{
for (int gridIndex = 0; gridIndex < pmeGpu->common->ngrids; gridIndex++)
{
- clearDeviceBufferAsync(&pmeGpu->kernelParams->constants.d_virialAndEnergy[gridIndex], 0,
- c_virialAndEnergyCount, pmeGpu->archSpecific->pmeStream_);
+ clearDeviceBufferAsync(&pmeGpu->kernelParams->constants.d_virialAndEnergy[gridIndex],
+ 0,
+ c_virialAndEnergyCount,
+ pmeGpu->archSpecific->pmeStream_);
}
}
GMX_ASSERT(gridIndex < pmeGpu->common->ngrids,
"Invalid combination of gridIndex and number of grids");
- const int splineValuesOffset[DIM] = { 0, pmeGpu->kernelParams->grid.realGridSize[XX],
+ const int splineValuesOffset[DIM] = { 0,
+ pmeGpu->kernelParams->grid.realGridSize[XX],
pmeGpu->kernelParams->grid.realGridSize[XX]
+ pmeGpu->kernelParams->grid.realGridSize[YY] };
memcpy(&pmeGpu->kernelParams->grid.splineValuesOffset, &splineValuesOffset, sizeof(splineValuesOffset));
+ pmeGpu->kernelParams->grid.realGridSize[ZZ];
const bool shouldRealloc = (newSplineValuesSize > pmeGpu->archSpecific->splineValuesSize[gridIndex]);
reallocateDeviceBuffer(&pmeGpu->kernelParams->grid.d_splineModuli[gridIndex],
- newSplineValuesSize, &pmeGpu->archSpecific->splineValuesSize[gridIndex],
+ newSplineValuesSize,
+ &pmeGpu->archSpecific->splineValuesSize[gridIndex],
&pmeGpu->archSpecific->splineValuesCapacity[gridIndex],
pmeGpu->archSpecific->deviceContext_);
if (shouldRealloc)
for (int i = 0; i < DIM; i++)
{
memcpy(pmeGpu->staging.h_splineModuli[gridIndex] + splineValuesOffset[i],
- pmeGpu->common->bsp_mod[i].data(), pmeGpu->common->bsp_mod[i].size() * sizeof(float));
+ pmeGpu->common->bsp_mod[i].data(),
+ pmeGpu->common->bsp_mod[i].size() * sizeof(float));
}
/* TODO: pin original buffer instead! */
copyToDeviceBuffer(&pmeGpu->kernelParams->grid.d_splineModuli[gridIndex],
- pmeGpu->staging.h_splineModuli[gridIndex], 0, newSplineValuesSize,
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
+ pmeGpu->staging.h_splineModuli[gridIndex],
+ 0,
+ newSplineValuesSize,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
void pme_gpu_free_bspline_values(const PmeGpu* pmeGpu)
void pme_gpu_realloc_forces(PmeGpu* pmeGpu)
{
- const size_t newForcesSize = pmeGpu->nAtomsAlloc * DIM;
+ const size_t newForcesSize = pmeGpu->nAtomsAlloc;
GMX_ASSERT(newForcesSize > 0, "Bad number of atoms in PME GPU");
- reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_forces, newForcesSize,
- &pmeGpu->archSpecific->forcesSize, &pmeGpu->archSpecific->forcesSizeAlloc,
+ reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_forces,
+ newForcesSize,
+ &pmeGpu->archSpecific->forcesSize,
+ &pmeGpu->archSpecific->forcesSizeAlloc,
pmeGpu->archSpecific->deviceContext_);
pmeGpu->staging.h_forces.reserveWithPadding(pmeGpu->nAtomsAlloc);
pmeGpu->staging.h_forces.resizeWithPadding(pmeGpu->kernelParams->atoms.nAtoms);
void pme_gpu_copy_input_forces(PmeGpu* pmeGpu)
{
GMX_ASSERT(pmeGpu->kernelParams->atoms.nAtoms > 0, "Bad number of atoms in PME GPU");
- float* h_forcesFloat = reinterpret_cast<float*>(pmeGpu->staging.h_forces.data());
- copyToDeviceBuffer(&pmeGpu->kernelParams->atoms.d_forces, h_forcesFloat, 0,
- DIM * pmeGpu->kernelParams->atoms.nAtoms, pmeGpu->archSpecific->pmeStream_,
- pmeGpu->settings.transferKind, nullptr);
+ copyToDeviceBuffer(&pmeGpu->kernelParams->atoms.d_forces,
+ pmeGpu->staging.h_forces.data(),
+ 0,
+ pmeGpu->kernelParams->atoms.nAtoms,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
void pme_gpu_copy_output_forces(PmeGpu* pmeGpu)
{
GMX_ASSERT(pmeGpu->kernelParams->atoms.nAtoms > 0, "Bad number of atoms in PME GPU");
- float* h_forcesFloat = reinterpret_cast<float*>(pmeGpu->staging.h_forces.data());
- copyFromDeviceBuffer(h_forcesFloat, &pmeGpu->kernelParams->atoms.d_forces, 0,
- DIM * pmeGpu->kernelParams->atoms.nAtoms, pmeGpu->archSpecific->pmeStream_,
- pmeGpu->settings.transferKind, nullptr);
+ copyFromDeviceBuffer(pmeGpu->staging.h_forces.data(),
+ &pmeGpu->kernelParams->atoms.d_forces,
+ 0,
+ pmeGpu->kernelParams->atoms.nAtoms,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
void pme_gpu_realloc_and_copy_input_coefficients(const PmeGpu* pmeGpu,
const size_t newCoefficientsSize = pmeGpu->nAtomsAlloc;
GMX_ASSERT(newCoefficientsSize > 0, "Bad number of atoms in PME GPU");
reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_coefficients[gridIndex],
- newCoefficientsSize, &pmeGpu->archSpecific->coefficientsSize[gridIndex],
+ newCoefficientsSize,
+ &pmeGpu->archSpecific->coefficientsSize[gridIndex],
&pmeGpu->archSpecific->coefficientsCapacity[gridIndex],
pmeGpu->archSpecific->deviceContext_);
copyToDeviceBuffer(&pmeGpu->kernelParams->atoms.d_coefficients[gridIndex],
- const_cast<float*>(h_coefficients), 0, pmeGpu->kernelParams->atoms.nAtoms,
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
+ const_cast<float*>(h_coefficients),
+ 0,
+ pmeGpu->kernelParams->atoms.nAtoms,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
const size_t paddingIndex = pmeGpu->kernelParams->atoms.nAtoms;
const size_t paddingCount = pmeGpu->nAtomsAlloc - paddingIndex;
if (paddingCount > 0)
{
- clearDeviceBufferAsync(&pmeGpu->kernelParams->atoms.d_coefficients[gridIndex], paddingIndex,
- paddingCount, pmeGpu->archSpecific->pmeStream_);
+ clearDeviceBufferAsync(&pmeGpu->kernelParams->atoms.d_coefficients[gridIndex],
+ paddingIndex,
+ paddingCount,
+ pmeGpu->archSpecific->pmeStream_);
}
}
const bool shouldRealloc = (newSplineDataSize > pmeGpu->archSpecific->splineDataSize);
int currentSizeTemp = pmeGpu->archSpecific->splineDataSize;
int currentSizeTempAlloc = pmeGpu->archSpecific->splineDataSizeAlloc;
- reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_theta, newSplineDataSize, ¤tSizeTemp,
- ¤tSizeTempAlloc, pmeGpu->archSpecific->deviceContext_);
- reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_dtheta, newSplineDataSize,
- &pmeGpu->archSpecific->splineDataSize, &pmeGpu->archSpecific->splineDataSizeAlloc,
+ reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_theta,
+ newSplineDataSize,
+ ¤tSizeTemp,
+ ¤tSizeTempAlloc,
+ pmeGpu->archSpecific->deviceContext_);
+ reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_dtheta,
+ newSplineDataSize,
+ &pmeGpu->archSpecific->splineDataSize,
+ &pmeGpu->archSpecific->splineDataSizeAlloc,
pmeGpu->archSpecific->deviceContext_);
// the host side reallocation
if (shouldRealloc)
{
const size_t newIndicesSize = DIM * pmeGpu->nAtomsAlloc;
GMX_ASSERT(newIndicesSize > 0, "Bad number of atoms in PME GPU");
- reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_gridlineIndices, newIndicesSize,
+ reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_gridlineIndices,
+ newIndicesSize,
&pmeGpu->archSpecific->gridlineIndicesSize,
&pmeGpu->archSpecific->gridlineIndicesSizeAlloc,
pmeGpu->archSpecific->deviceContext_);
if (pmeGpu->archSpecific->performOutOfPlaceFFT)
{
/* 2 separate grids */
- reallocateDeviceBuffer(&kernelParamsPtr->grid.d_fourierGrid[gridIndex], newComplexGridSize,
+ reallocateDeviceBuffer(&kernelParamsPtr->grid.d_fourierGrid[gridIndex],
+ newComplexGridSize,
&pmeGpu->archSpecific->complexGridSize[gridIndex],
&pmeGpu->archSpecific->complexGridCapacity[gridIndex],
pmeGpu->archSpecific->deviceContext_);
- reallocateDeviceBuffer(&kernelParamsPtr->grid.d_realGrid[gridIndex], newRealGridSize,
+ reallocateDeviceBuffer(&kernelParamsPtr->grid.d_realGrid[gridIndex],
+ newRealGridSize,
&pmeGpu->archSpecific->realGridSize[gridIndex],
&pmeGpu->archSpecific->realGridCapacity[gridIndex],
pmeGpu->archSpecific->deviceContext_);
{
/* A single buffer so that any grid will fit */
const int newGridsSize = std::max(newRealGridSize, newComplexGridSize);
- reallocateDeviceBuffer(&kernelParamsPtr->grid.d_realGrid[gridIndex], newGridsSize,
+ reallocateDeviceBuffer(&kernelParamsPtr->grid.d_realGrid[gridIndex],
+ newGridsSize,
&pmeGpu->archSpecific->realGridSize[gridIndex],
&pmeGpu->archSpecific->realGridCapacity[gridIndex],
pmeGpu->archSpecific->deviceContext_);
{
for (int gridIndex = 0; gridIndex < pmeGpu->common->ngrids; gridIndex++)
{
- clearDeviceBufferAsync(&pmeGpu->kernelParams->grid.d_realGrid[gridIndex], 0,
+ clearDeviceBufferAsync(&pmeGpu->kernelParams->grid.d_realGrid[gridIndex],
+ 0,
pmeGpu->archSpecific->realGridSize[gridIndex],
pmeGpu->archSpecific->pmeStream_);
}
const int newFractShiftsSize = cellCount * (nx + ny + nz);
initParamLookupTable(&kernelParamsPtr->grid.d_fractShiftsTable,
- &kernelParamsPtr->fractShiftsTableTexture, pmeGpu->common->fsh.data(),
- newFractShiftsSize, pmeGpu->archSpecific->deviceContext_);
+ &kernelParamsPtr->fractShiftsTableTexture,
+ pmeGpu->common->fsh.data(),
+ newFractShiftsSize,
+ pmeGpu->archSpecific->deviceContext_);
initParamLookupTable(&kernelParamsPtr->grid.d_gridlineIndicesTable,
- &kernelParamsPtr->gridlineIndicesTableTexture, pmeGpu->common->nn.data(),
- newFractShiftsSize, pmeGpu->archSpecific->deviceContext_);
+ &kernelParamsPtr->gridlineIndicesTableTexture,
+ pmeGpu->common->nn.data(),
+ newFractShiftsSize,
+ pmeGpu->archSpecific->deviceContext_);
}
void pme_gpu_free_fract_shifts(const PmeGpu* pmeGpu)
auto* kernelParamsPtr = pmeGpu->kernelParams.get();
#if GMX_GPU_CUDA
destroyParamLookupTable(&kernelParamsPtr->grid.d_fractShiftsTable,
- kernelParamsPtr->fractShiftsTableTexture);
+ &kernelParamsPtr->fractShiftsTableTexture);
destroyParamLookupTable(&kernelParamsPtr->grid.d_gridlineIndicesTable,
- kernelParamsPtr->gridlineIndicesTableTexture);
-#elif GMX_GPU_OPENCL
+ &kernelParamsPtr->gridlineIndicesTableTexture);
+#elif GMX_GPU_OPENCL || GMX_GPU_SYCL
freeDeviceBuffer(&kernelParamsPtr->grid.d_fractShiftsTable);
freeDeviceBuffer(&kernelParamsPtr->grid.d_gridlineIndicesTable);
#endif
void pme_gpu_copy_input_gather_grid(const PmeGpu* pmeGpu, const float* h_grid, const int gridIndex)
{
- copyToDeviceBuffer(&pmeGpu->kernelParams->grid.d_realGrid[gridIndex], h_grid, 0,
+ copyToDeviceBuffer(&pmeGpu->kernelParams->grid.d_realGrid[gridIndex],
+ h_grid,
+ 0,
pmeGpu->archSpecific->realGridSize[gridIndex],
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
void pme_gpu_copy_output_spread_grid(const PmeGpu* pmeGpu, float* h_grid, const int gridIndex)
{
- copyFromDeviceBuffer(h_grid, &pmeGpu->kernelParams->grid.d_realGrid[gridIndex], 0,
+ copyFromDeviceBuffer(h_grid,
+ &pmeGpu->kernelParams->grid.d_realGrid[gridIndex],
+ 0,
pmeGpu->archSpecific->realGridSize[gridIndex],
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
pmeGpu->archSpecific->syncSpreadGridD2H.markEvent(pmeGpu->archSpecific->pmeStream_);
}
{
const size_t splinesCount = DIM * pmeGpu->nAtomsAlloc * pmeGpu->common->pme_order;
auto* kernelParamsPtr = pmeGpu->kernelParams.get();
- copyFromDeviceBuffer(pmeGpu->staging.h_dtheta, &kernelParamsPtr->atoms.d_dtheta, 0, splinesCount,
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
- copyFromDeviceBuffer(pmeGpu->staging.h_theta, &kernelParamsPtr->atoms.d_theta, 0, splinesCount,
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
- copyFromDeviceBuffer(pmeGpu->staging.h_gridlineIndices, &kernelParamsPtr->atoms.d_gridlineIndices,
- 0, kernelParamsPtr->atoms.nAtoms * DIM, pmeGpu->archSpecific->pmeStream_,
- pmeGpu->settings.transferKind, nullptr);
+ copyFromDeviceBuffer(pmeGpu->staging.h_dtheta,
+ &kernelParamsPtr->atoms.d_dtheta,
+ 0,
+ splinesCount,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
+ copyFromDeviceBuffer(pmeGpu->staging.h_theta,
+ &kernelParamsPtr->atoms.d_theta,
+ 0,
+ splinesCount,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
+ copyFromDeviceBuffer(pmeGpu->staging.h_gridlineIndices,
+ &kernelParamsPtr->atoms.d_gridlineIndices,
+ 0,
+ kernelParamsPtr->atoms.nAtoms * DIM,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
void pme_gpu_copy_input_gather_atom_data(const PmeGpu* pmeGpu)
auto* kernelParamsPtr = pmeGpu->kernelParams.get();
// TODO: could clear only the padding and not the whole thing, but this is a test-exclusive code anyway
- clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_gridlineIndices, 0, pmeGpu->nAtomsAlloc * DIM,
+ clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_gridlineIndices,
+ 0,
+ pmeGpu->nAtomsAlloc * DIM,
pmeGpu->archSpecific->pmeStream_);
- clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_dtheta, 0,
+ clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_dtheta,
+ 0,
pmeGpu->nAtomsAlloc * pmeGpu->common->pme_order * DIM,
pmeGpu->archSpecific->pmeStream_);
- clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_theta, 0,
+ clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_theta,
+ 0,
pmeGpu->nAtomsAlloc * pmeGpu->common->pme_order * DIM,
pmeGpu->archSpecific->pmeStream_);
- copyToDeviceBuffer(&kernelParamsPtr->atoms.d_dtheta, pmeGpu->staging.h_dtheta, 0, splinesCount,
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
- copyToDeviceBuffer(&kernelParamsPtr->atoms.d_theta, pmeGpu->staging.h_theta, 0, splinesCount,
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
- copyToDeviceBuffer(&kernelParamsPtr->atoms.d_gridlineIndices, pmeGpu->staging.h_gridlineIndices,
- 0, kernelParamsPtr->atoms.nAtoms * DIM, pmeGpu->archSpecific->pmeStream_,
- pmeGpu->settings.transferKind, nullptr);
+ copyToDeviceBuffer(&kernelParamsPtr->atoms.d_dtheta,
+ pmeGpu->staging.h_dtheta,
+ 0,
+ splinesCount,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
+ copyToDeviceBuffer(&kernelParamsPtr->atoms.d_theta,
+ pmeGpu->staging.h_theta,
+ 0,
+ splinesCount,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
+ copyToDeviceBuffer(&kernelParamsPtr->atoms.d_gridlineIndices,
+ pmeGpu->staging.h_gridlineIndices,
+ 0,
+ kernelParamsPtr->atoms.nAtoms * DIM,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
void pme_gpu_sync_spread_grid(const PmeGpu* pmeGpu)
if (pme_gpu_settings(pmeGpu).performGPUFFT)
{
pmeGpu->archSpecific->fftSetup.resize(0);
+ const bool performOutOfPlaceFFT = pmeGpu->archSpecific->performOutOfPlaceFFT;
+ const bool allocateGrid = false;
+ MPI_Comm comm = MPI_COMM_NULL;
+ std::array<int, 1> gridOffsetsInXForEachRank = { 0 };
+ std::array<int, 1> gridOffsetsInYForEachRank = { 0 };
+#if GMX_GPU_CUDA
+ const gmx::FftBackend backend = gmx::FftBackend::Cufft;
+#elif GMX_GPU_OPENCL
+ const gmx::FftBackend backend = gmx::FftBackend::Ocl;
+#elif GMX_GPU_SYCL
+ const gmx::FftBackend backend = gmx::FftBackend::Sycl;
+#else
+ GMX_RELEASE_ASSERT(false, "Unknown GPU backend");
+ const gmx::FftBackend backend = gmx::FftBackend::Count;
+#endif
+
+ PmeGpuGridParams& grid = pme_gpu_get_kernel_params_base_ptr(pmeGpu)->grid;
for (int gridIndex = 0; gridIndex < pmeGpu->common->ngrids; gridIndex++)
{
- pmeGpu->archSpecific->fftSetup.push_back(std::make_unique<GpuParallel3dFft>(pmeGpu, gridIndex));
+ pmeGpu->archSpecific->fftSetup.push_back(
+ std::make_unique<gmx::Gpu3dFft>(backend,
+ allocateGrid,
+ comm,
+ gridOffsetsInXForEachRank,
+ gridOffsetsInYForEachRank,
+ grid.realGridSize[ZZ],
+ performOutOfPlaceFFT,
+ pmeGpu->archSpecific->deviceContext_,
+ pmeGpu->archSpecific->pmeStream_,
+ grid.realGridSize,
+ grid.realGridSizePadded,
+ grid.complexGridSizePadded,
+ &(grid.d_realGrid[gridIndex]),
+ &(grid.d_fourierGrid[gridIndex])));
}
}
}
pmeGpu->common->nn.insert(pmeGpu->common->nn.end(), pme->nnz, pme->nnz + cellCount * pme->nkz);
pmeGpu->common->runMode = pme->runMode;
pmeGpu->common->isRankPmeOnly = !pme->bPPnode;
- pmeGpu->common->boxScaler = pme->boxScaler;
+ pmeGpu->common->boxScaler = pme->boxScaler.get();
}
/*! \libinternal \brief
GMX_ASSERT(pmeGpu->common->epsilon_r != 0.0F, "PME GPU: bad electrostatic coefficient");
auto* kernelParamsPtr = pme_gpu_get_kernel_params_base_ptr(pmeGpu);
- kernelParamsPtr->constants.elFactor = ONE_4PI_EPS0 / pmeGpu->common->epsilon_r;
+ kernelParamsPtr->constants.elFactor = gmx::c_one4PiEps0 / pmeGpu->common->epsilon_r;
}
void pme_gpu_get_real_grid_sizes(const PmeGpu* pmeGpu, gmx::IVec* gridSize, gmx::IVec* paddedGridSize)
* In CUDA result can be nullptr stub, per GpuRegionTimer implementation.
*
* \param[in] pmeGpu The PME GPU data structure.
- * \param[in] PMEStageId The PME GPU stage gtPME_ index from the enum in src/gromacs/timing/gpu_timing.h
+ * \param[in] pmeStageId The PME GPU stage gtPME_ index from the enum in src/gromacs/timing/gpu_timing.h
*/
-static CommandEvent* pme_gpu_fetch_timing_event(const PmeGpu* pmeGpu, size_t PMEStageId)
+static CommandEvent* pme_gpu_fetch_timing_event(const PmeGpu* pmeGpu, PmeStage pmeStageId)
{
CommandEvent* timingEvent = nullptr;
if (pme_gpu_timings_enabled(pmeGpu))
{
- GMX_ASSERT(PMEStageId < pmeGpu->archSpecific->timingEvents.size(),
- "Wrong PME GPU timing event index");
- timingEvent = pmeGpu->archSpecific->timingEvents[PMEStageId].fetchNextEvent();
+ GMX_ASSERT(pmeStageId < PmeStage::Count, "Wrong PME GPU timing event index");
+ timingEvent = pmeGpu->archSpecific->timingEvents[pmeStageId].fetchNextEvent();
}
return timingEvent;
}
void pme_gpu_3dfft(const PmeGpu* pmeGpu, gmx_fft_direction dir, const int grid_index)
{
- int timerId = (dir == GMX_FFT_REAL_TO_COMPLEX) ? gtPME_FFT_R2C : gtPME_FFT_C2R;
+ PmeStage timerId = (dir == GMX_FFT_REAL_TO_COMPLEX) ? PmeStage::FftTransformR2C
+ : PmeStage::FftTransformC2R;
pme_gpu_start_timing(pmeGpu, timerId);
pmeGpu->archSpecific->fftSetup[grid_index]->perform3dFft(
*
* \return Pointer to CUDA kernel
*/
-static auto selectSplineKernelPtr(const PmeGpu* pmeGpu,
- ThreadsPerAtom threadsPerAtom,
+static auto selectSplineKernelPtr(const PmeGpu* pmeGpu,
+ ThreadsPerAtom threadsPerAtom,
bool gmx_unused writeSplinesToGlobal,
const int numGrids)
{
{
kernelPtr = pmeGpu->programHandle_->impl_->spreadKernelThPerAtom4Dual;
}
+ else
{
kernelPtr = pmeGpu->programHandle_->impl_->spreadKernelThPerAtom4Single;
}
config.gridSize[0] = dimGrid.first;
config.gridSize[1] = dimGrid.second;
- int timingId;
+ PmeStage timingId;
PmeGpuProgramImpl::PmeKernelHandle kernelPtr = nullptr;
if (computeSplines)
{
if (spreadCharges)
{
- timingId = gtPME_SPLINEANDSPREAD;
- kernelPtr = selectSplineAndSpreadKernelPtr(pmeGpu, pmeGpu->settings.threadsPerAtom,
+ timingId = PmeStage::SplineAndSpread;
+ kernelPtr = selectSplineAndSpreadKernelPtr(pmeGpu,
+ pmeGpu->settings.threadsPerAtom,
writeGlobal || (!recalculateSplines),
pmeGpu->common->ngrids);
}
else
{
- timingId = gtPME_SPLINE;
- kernelPtr = selectSplineKernelPtr(pmeGpu, pmeGpu->settings.threadsPerAtom,
+ timingId = PmeStage::Spline;
+ kernelPtr = selectSplineKernelPtr(pmeGpu,
+ pmeGpu->settings.threadsPerAtom,
writeGlobal || (!recalculateSplines),
pmeGpu->common->ngrids);
}
}
else
{
- timingId = gtPME_SPREAD;
- kernelPtr = selectSpreadKernelPtr(pmeGpu, pmeGpu->settings.threadsPerAtom,
- writeGlobal || (!recalculateSplines), pmeGpu->common->ngrids);
+ timingId = PmeStage::Spread;
+ kernelPtr = selectSpreadKernelPtr(pmeGpu,
+ pmeGpu->settings.threadsPerAtom,
+ writeGlobal || (!recalculateSplines),
+ pmeGpu->common->ngrids);
}
#if c_canEmbedBuffers
const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr);
#else
- const auto kernelArgs = prepareGpuKernelArguments(
- kernelPtr, config, kernelParamsPtr, &kernelParamsPtr->atoms.d_theta,
- &kernelParamsPtr->atoms.d_dtheta, &kernelParamsPtr->atoms.d_gridlineIndices,
- &kernelParamsPtr->grid.d_realGrid[FEP_STATE_A], &kernelParamsPtr->grid.d_realGrid[FEP_STATE_B],
- &kernelParamsPtr->grid.d_fractShiftsTable, &kernelParamsPtr->grid.d_gridlineIndicesTable,
- &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_A],
- &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_B], &kernelParamsPtr->atoms.d_coordinates);
+ const auto kernelArgs =
+ prepareGpuKernelArguments(kernelPtr,
+ config,
+ kernelParamsPtr,
+ &kernelParamsPtr->atoms.d_theta,
+ &kernelParamsPtr->atoms.d_dtheta,
+ &kernelParamsPtr->atoms.d_gridlineIndices,
+ &kernelParamsPtr->grid.d_realGrid[FEP_STATE_A],
+ &kernelParamsPtr->grid.d_realGrid[FEP_STATE_B],
+ &kernelParamsPtr->grid.d_fractShiftsTable,
+ &kernelParamsPtr->grid.d_gridlineIndicesTable,
+ &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_A],
+ &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_B],
+ &kernelParamsPtr->atoms.d_coordinates);
#endif
- launchGpuKernel(kernelPtr, config, pmeGpu->archSpecific->pmeStream_, timingEvent,
- "PME spline/spread", kernelArgs);
+ launchGpuKernel(
+ kernelPtr, config, pmeGpu->archSpecific->pmeStream_, timingEvent, "PME spline/spread", kernelArgs);
pme_gpu_stop_timing(pmeGpu, timingId);
const auto& settings = pmeGpu->settings;
float* h_gridFloat = reinterpret_cast<float*>(h_grid);
if (copyInputAndOutputGrid)
{
- copyToDeviceBuffer(&kernelParamsPtr->grid.d_fourierGrid[gridIndex], h_gridFloat, 0,
+ copyToDeviceBuffer(&kernelParamsPtr->grid.d_fourierGrid[gridIndex],
+ h_gridFloat,
+ 0,
pmeGpu->archSpecific->complexGridSize[gridIndex],
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
int majorDim = -1, middleDim = -1, minorDim = -1;
/ gridLinesPerBlock;
config.gridSize[2] = pmeGpu->kernelParams->grid.complexGridSize[majorDim];
- int timingId = gtPME_SOLVE;
+ PmeStage timingId = PmeStage::Solve;
PmeGpuProgramImpl::PmeKernelHandle kernelPtr = nullptr;
if (gridOrdering == GridOrdering::YZX)
{
#if c_canEmbedBuffers
const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr);
#else
- const auto kernelArgs = prepareGpuKernelArguments(
- kernelPtr, config, kernelParamsPtr, &kernelParamsPtr->grid.d_splineModuli[gridIndex],
- &kernelParamsPtr->constants.d_virialAndEnergy[gridIndex],
- &kernelParamsPtr->grid.d_fourierGrid[gridIndex]);
+ const auto kernelArgs =
+ prepareGpuKernelArguments(kernelPtr,
+ config,
+ kernelParamsPtr,
+ &kernelParamsPtr->grid.d_splineModuli[gridIndex],
+ &kernelParamsPtr->constants.d_virialAndEnergy[gridIndex],
+ &kernelParamsPtr->grid.d_fourierGrid[gridIndex]);
#endif
- launchGpuKernel(kernelPtr, config, pmeGpu->archSpecific->pmeStream_, timingEvent, "PME solve",
- kernelArgs);
+ launchGpuKernel(kernelPtr, config, pmeGpu->archSpecific->pmeStream_, timingEvent, "PME solve", kernelArgs);
pme_gpu_stop_timing(pmeGpu, timingId);
if (computeEnergyAndVirial)
{
copyFromDeviceBuffer(pmeGpu->staging.h_virialAndEnergy[gridIndex],
- &kernelParamsPtr->constants.d_virialAndEnergy[gridIndex], 0,
- c_virialAndEnergyCount, pmeGpu->archSpecific->pmeStream_,
- pmeGpu->settings.transferKind, nullptr);
+ &kernelParamsPtr->constants.d_virialAndEnergy[gridIndex],
+ 0,
+ c_virialAndEnergyCount,
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
if (copyInputAndOutputGrid)
{
- copyFromDeviceBuffer(h_gridFloat, &kernelParamsPtr->grid.d_fourierGrid[gridIndex], 0,
+ copyFromDeviceBuffer(h_gridFloat,
+ &kernelParamsPtr->grid.d_fourierGrid[gridIndex],
+ 0,
pmeGpu->archSpecific->complexGridSize[gridIndex],
- pmeGpu->archSpecific->pmeStream_, pmeGpu->settings.transferKind, nullptr);
+ pmeGpu->archSpecific->pmeStream_,
+ pmeGpu->settings.transferKind,
+ nullptr);
}
}
// TODO test different cache configs
- int timingId = gtPME_GATHER;
+ PmeStage timingId = PmeStage::Gather;
PmeGpuProgramImpl::PmeKernelHandle kernelPtr =
- selectGatherKernelPtr(pmeGpu, pmeGpu->settings.threadsPerAtom,
- readGlobal || (!recalculateSplines), pmeGpu->common->ngrids);
+ selectGatherKernelPtr(pmeGpu,
+ pmeGpu->settings.threadsPerAtom,
+ readGlobal || (!recalculateSplines),
+ pmeGpu->common->ngrids);
// TODO design kernel selection getters and make PmeGpu a friend of PmeGpuProgramImpl
pme_gpu_start_timing(pmeGpu, timingId);
#if c_canEmbedBuffers
const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr);
#else
- const auto kernelArgs = prepareGpuKernelArguments(
- kernelPtr, config, kernelParamsPtr, &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_A],
- &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_B],
- &kernelParamsPtr->grid.d_realGrid[FEP_STATE_A], &kernelParamsPtr->grid.d_realGrid[FEP_STATE_B],
- &kernelParamsPtr->atoms.d_theta, &kernelParamsPtr->atoms.d_dtheta,
- &kernelParamsPtr->atoms.d_gridlineIndices, &kernelParamsPtr->atoms.d_forces);
+ const auto kernelArgs =
+ prepareGpuKernelArguments(kernelPtr,
+ config,
+ kernelParamsPtr,
+ &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_A],
+ &kernelParamsPtr->atoms.d_coefficients[FEP_STATE_B],
+ &kernelParamsPtr->grid.d_realGrid[FEP_STATE_A],
+ &kernelParamsPtr->grid.d_realGrid[FEP_STATE_B],
+ &kernelParamsPtr->atoms.d_theta,
+ &kernelParamsPtr->atoms.d_dtheta,
+ &kernelParamsPtr->atoms.d_gridlineIndices,
+ &kernelParamsPtr->atoms.d_forces);
#endif
- launchGpuKernel(kernelPtr, config, pmeGpu->archSpecific->pmeStream_, timingEvent, "PME gather",
- kernelArgs);
+ launchGpuKernel(kernelPtr, config, pmeGpu->archSpecific->pmeStream_, timingEvent, "PME gather", kernelArgs);
pme_gpu_stop_timing(pmeGpu, timingId);
if (pmeGpu->settings.useGpuForceReduction)
}
}
-void* pme_gpu_get_kernelparam_forces(const PmeGpu* pmeGpu)
+DeviceBuffer<gmx::RVec> pme_gpu_get_kernelparam_forces(const PmeGpu* pmeGpu)
{
if (pmeGpu && pmeGpu->kernelParams)
{
}
else
{
- return nullptr;
+ return DeviceBuffer<gmx::RVec>{};
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
/* Thread index w.r.t. block */
assert((get_local_id(2) * get_local_size(1) + get_local_id(1)) * get_local_size(0) + get_local_id(0)
< MAX_INT);
+ assert(numGrids == 1 || numGrids == 2);
+ assert(numGrids == 1 || c_skipNeutralAtoms == false);
const int threadLocalIndex =
(int)((get_local_id(2) * get_local_size(1) + get_local_id(1)) * get_local_size(0)
+ get_local_id(0));
/* B-spline calculation */
const int chargeCheck = pme_gpu_check_atom_charge(sm_coefficients[atomIndexLocal]);
- if (chargeCheck)
+ /* With FEP (numGrids == 2), we might have 0 charge in state A, but !=0 in state B, so we always calculate splines */
+ if (numGrids == 2 || chargeCheck)
{
int o = orderIndex; // This is an index that is set once for PME_GPU_PARALLEL_SPLINE == 1
pme_gpu_stage_atom_data(sm_coordinates, gm_coordinates, DIM);
barrier(CLK_LOCAL_MEM_FENCE);
- calculate_splines(kernelParams, atomIndexOffset, sm_coordinates, sm_coefficients, sm_theta,
- sm_gridlineIndices, sm_fractCoords, gm_theta, gm_dtheta,
- gm_gridlineIndices, gm_fractShiftsTable, gm_gridlineIndicesTable);
+ calculate_splines(kernelParams,
+ atomIndexOffset,
+ sm_coordinates,
+ sm_coefficients,
+ sm_theta,
+ sm_gridlineIndices,
+ sm_fractCoords,
+ gm_theta,
+ gm_dtheta,
+ gm_gridlineIndices,
+ gm_fractShiftsTable,
+ gm_gridlineIndicesTable);
#if !defined(_AMD_SOURCE_) && !defined(_NVIDIA_SOURCE_)
/* This is only here for execution of e.g. 32-sized warps on 16-wide hardware; this was
* __syncwarp() in CUDA. #2519
/* Spline data - only thetas (dthetas will only be needed in gather) */
pme_gpu_stage_atom_data(sm_theta, gm_theta, DIM * order);
/* Gridline indices - they're actually int and not float, but C99 is angry about overloads */
- pme_gpu_stage_atom_data((__local float*)sm_gridlineIndices,
- (__global const float*)gm_gridlineIndices, DIM);
+ pme_gpu_stage_atom_data(
+ (__local float*)sm_gridlineIndices, (__global const float*)gm_gridlineIndices, DIM);
barrier(CLK_LOCAL_MEM_FENCE);
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013-2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2013-2016,2017,2018,2019,2020,2021, 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.
{
atomX = gm_coordinates[atomIndexGlobal];
}
- calculate_splines<order, atomsPerBlock, atomsPerWarp, false, writeGlobal>(
+ calculate_splines<order, atomsPerBlock, atomsPerWarp, false, writeGlobal, numGrids>(
kernelParams, atomIndexOffset, atomX, atomCharge, sm_theta, &dtheta, sm_gridlineIndices);
__syncwarp();
}
/* Spreading */
if (spreadCharges)
{
- spread_charges<order, wrapX, wrapY, 0, threadsPerAtom>(kernelParams, &atomCharge,
- sm_gridlineIndices, sm_theta);
+ spread_charges<order, wrapX, wrapY, 0, threadsPerAtom>(
+ kernelParams, &atomCharge, sm_gridlineIndices, sm_theta);
}
if (numGrids == 2)
{
}
if (spreadCharges)
{
- spread_charges<order, wrapX, wrapY, 1, threadsPerAtom>(kernelParams, &atomCharge,
- sm_gridlineIndices, sm_theta);
+ spread_charges<order, wrapX, wrapY, 1, threadsPerAtom>(
+ kernelParams, &atomCharge, sm_gridlineIndices, sm_theta);
}
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019,2020,2021, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020 by the GROMACS development team.
+ * Copyright (c) 2021, 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.
const auto runMode = (mode == CodePath::CPU) ? PmeRunMode::CPU : PmeRunMode::Mixed;
t_commrec dummyCommrec = { 0 };
NumPmeDomains numPmeDomains = { 1, 1 };
- gmx_pme_t* pmeDataRaw = gmx_pme_init(&dummyCommrec, numPmeDomains, inputRec, false, false, true,
- ewaldCoeff_q, ewaldCoeff_lj, 1, runMode, nullptr,
- deviceContext, deviceStream, pmeGpuProgram, dummyLogger);
+ gmx_pme_t* pmeDataRaw = gmx_pme_init(&dummyCommrec,
+ numPmeDomains,
+ inputRec,
+ false,
+ false,
+ true,
+ ewaldCoeff_q,
+ ewaldCoeff_lj,
+ 1,
+ runMode,
+ nullptr,
+ deviceContext,
+ deviceStream,
+ pmeGpuProgram,
+ dummyLogger);
PmeSafePointer pme(pmeDataRaw); // taking ownership
// TODO get rid of this with proper matrix type
// TODO: Pin the host buffer and use async memory copies
// TODO: Special constructor for PME-only rank / PME-tests is used here. There should be a mechanism to
// restrict one from using other constructor here.
- return std::make_unique<StatePropagatorDataGpu>(deviceStream, *deviceContext, GpuApiCallBehavior::Sync,
- pme_gpu_get_block_size(&pme), nullptr);
+ return std::make_unique<StatePropagatorDataGpu>(
+ deviceStream, *deviceContext, GpuApiCallBehavior::Sync, pme_gpu_get_block_size(&pme), nullptr);
}
//! PME initialization with atom data
atc = &(pme->atc[0]);
atc->x = coordinates;
atc->coefficient = charges;
- gmx_pme_reinit_atoms(pme, atomCount, charges.data(), nullptr);
+ gmx_pme_reinit_atoms(pme, atomCount, charges, {});
/* With decomposition there would be more boilerplate atc code here, e.g. do_redist_pos_coeffs */
break;
atc = &(pme->atc[0]);
// We need to set atc->n for passing the size in the tests
atc->setNumAtoms(atomCount);
- gmx_pme_reinit_atoms(pme, atomCount, charges.data(), nullptr);
+ gmx_pme_reinit_atoms(pme, atomCount, charges, {});
stateGpu->reinit(atomCount, atomCount);
stateGpu->copyCoordinatesToGpu(arrayRefFromArray(coordinates.data(), coordinates.size()),
- gmx::AtomLocality::All);
+ gmx::AtomLocality::Local);
pme_gpu_set_kernelparam_coordinates(pme->gpu, stateGpu->getCoordinates());
break;
switch (mode)
{
case CodePath::CPU:
- gmx_parallel_3dfft_real_limits(pme->pfft_setup[gridIndex], gridSize, gridOffsetUnused,
- paddedGridSize);
+ gmx_parallel_3dfft_real_limits(
+ pme->pfft_setup[gridIndex], gridSize, gridOffsetUnused, paddedGridSize);
break;
case CodePath::GPU:
{
const size_t gridIndex = 0;
IVec gridOffsetUnused, complexOrderUnused;
- gmx_parallel_3dfft_complex_limits(pme->pfft_setup[gridIndex], complexOrderUnused, gridSize,
- gridOffsetUnused, paddedGridSize); // TODO: what about YZX ordering?
+ gmx_parallel_3dfft_complex_limits(
+ pme->pfft_setup[gridIndex], complexOrderUnused, gridSize, gridOffsetUnused, paddedGridSize); // TODO: what about YZX ordering?
}
//! Getting the PME grid memory buffer and its sizes - template definition
IVec& /*unused*/) //NOLINT(google-runtime-references)
{
GMX_THROW(InternalError("Deleted function call"));
- // explicitly deleting general template does not compile in clang/icc, see https://llvm.org/bugs/show_bug.cgi?id=17537
+ // explicitly deleting general template does not compile in clang, see https://llvm.org/bugs/show_bug.cgi?id=17537
}
//! Getting the PME real grid memory buffer and its sizes
switch (mode)
{
case CodePath::CPU:
- spread_on_grid(pme, atc, &pme->pmegrid[gridIndex], computeSplines, spreadCharges,
+ spread_on_grid(pme,
+ atc,
+ &pme->pmegrid[gridIndex],
+ computeSplines,
+ spreadCharges,
fftgrid != nullptr ? fftgrid[gridIndex] : nullptr,
- computeSplinesForZeroCharges, gridIndex);
+ computeSplinesForZeroCharges,
+ gridIndex);
if (spreadCharges && !pme->bUseThreads)
{
wrap_periodic_pmegrid(pme, pmegrid);
break;
case PmeSolveAlgorithm::LennardJones:
- solve_pme_lj_yzx(pme, &h_grid, useLorentzBerthelot, cellVolume,
- computeEnergyAndVirial, pme->nthread, threadIndex);
+ solve_pme_lj_yzx(pme,
+ &h_grid,
+ useLorentzBerthelot,
+ cellVolume,
+ computeEnergyAndVirial,
+ pme->nthread,
+ threadIndex);
break;
default: GMX_THROW(InternalError("Test not implemented for this mode"));
switch (mode)
{
case CodePath::GPU:
- memcpy(pme_gpu_staging(pme->gpu).h_gridlineIndices, gridLineIndices.data(),
+ memcpy(pme_gpu_staging(pme->gpu).h_gridlineIndices,
+ gridLineIndices.data(),
atomCount * sizeof(gridLineIndices[0]));
break;
{
case CodePath::GPU: // intentional absence of break, the grid will be copied from the host buffer in testing mode
case CodePath::CPU:
- std::memset(grid, 0,
- paddedGridSize[XX] * paddedGridSize[YY] * paddedGridSize[ZZ] * sizeof(ValueType));
+ std::memset(grid, 0, paddedGridSize[XX] * paddedGridSize[YY] * paddedGridSize[ZZ] * sizeof(ValueType));
for (const auto& gridValue : gridValues)
{
for (int i = 0; i < DIM; i++)
PmeTestHardwareContext::PmeTestHardwareContext() : codePath_(CodePath::CPU) {}
PmeTestHardwareContext::PmeTestHardwareContext(TestDevice* testDevice) :
- codePath_(CodePath::CPU), testDevice_(testDevice)
- codePath_(CodePath::GPU),
- testDevice_(testDevice)
++ codePath_(CodePath::GPU), testDevice_(testDevice)
{
setActiveDevice(testDevice_->deviceInfo());
pmeGpuProgram_ = buildPmeGpuProgram(testDevice_->deviceContext());
#include "gromacs/gmxana/gmx_ana.h"
#include "gromacs/gmxana/gstat.h"
#include "gromacs/math/gmxcomplex.h"
+#include "gromacs/math/units.h"
#include "gromacs/math/utilities.h"
#include "gromacs/utility/arraysize.h"
#include "gromacs/utility/fatalerror.h"
fprintf(fp, "%10.5e %10.5e %10.5e\n", nu, kw.re, kw.im);
fprintf(cp, "%10.5e %10.5e\n", kw.re, kw.im);
}
- printf("MAXEPS = %10.5e at frequency %10.5e GHz (tauD = %8.1f ps)\n", maxeps, numax,
+ printf("MAXEPS = %10.5e at frequency %10.5e GHz (tauD = %8.1f ps)\n",
+ maxeps,
+ numax,
1000 / (2 * M_PI * numax));
xvgrclose(fp);
xvgrclose(cp);
{ "-nsmooth", FALSE, etINT, { &nsmooth }, "Number of points for smoothing" }
};
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa,
- asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
dt = yd[0][1] - yd[0][0];
nxtail = std::min(static_cast<int>(tail / dt), nx);
- printf("Read data set containing %d colums and %d rows\n", ny, nx);
+ printf("Read data set containing %d columns and %d rows\n", ny, nx);
printf("Assuming (from data) that timestep is %g, nxtail = %d\n", dt, nxtail);
snew(y, 6);
for (i = 0; (i < ny); i++)
}
printf("DATA INTEGRAL: %5.1f, tauD(old) = %5.1f ps, "
"tau_slope = %5.1f, tau_slope,D = %5.1f ps\n",
- integral, integral * rffac, fitparms[0], fitparms[0] * rffac);
+ integral,
+ integral * rffac,
+ fitparms[0],
+ fitparms[0] * rffac);
- printf("tau_D from tau1 = %8.3g , eps(Infty) = %8.3f\n", fitparms[0] * (1 + fitparms[1] * lambda),
+ printf("tau_D from tau1 = %8.3g , eps(Infty) = %8.3f\n",
+ fitparms[0] * (1 + fitparms[1] * lambda),
1 + ((1 - fitparms[1]) * (eps0 - 1)) / (1 + fitparms[1] * lambda));
fitintegral = numerical_deriv(nx, y[0], y[1], y[3], y[4], y[5], tendInt, nsmooth);
#include "gromacs/linearalgebra/eigensolver.h"
#include "gromacs/math/do_fit.h"
#include "gromacs/math/functions.h"
+#include "gromacs/math/units.h"
#include "gromacs/math/utilities.h"
#include "gromacs/math/vec.h"
#include "gromacs/pbcutil/rmpbc.h"
"respect to the reference structure is calculated.[PAR]",
"With the option [TT]-aniso[tt], [THISMODULE] will compute anisotropic",
"temperature factors and then it will also output average coordinates",
- "and a [REF].pdb[ref] file with ANISOU records (corresonding to the [TT]-oq[tt]",
+ "and a [REF].pdb[ref] file with ANISOU records (corresponding to the [TT]-oq[tt]",
"or [TT]-ox[tt] option). Please note that the U values",
"are orientation-dependent, so before comparison with experimental data",
"you should verify that you fit to the experimental coordinates.[PAR]",
static gmx_bool bRes = FALSE, bAniso = FALSE, bFit = TRUE;
t_pargs pargs[] = {
{ "-res", FALSE, etBOOL, { &bRes }, "Calculate averages for each residue" },
- { "-aniso", FALSE, etBOOL, { &bAniso }, "Compute anisotropic termperature factors" },
+ { "-aniso", FALSE, etBOOL, { &bAniso }, "Compute anisotropic temperature factors" },
{ "-fit",
FALSE,
etBOOL,
{ efXVG, "-oc", "correl", ffOPTWR }, { efLOG, "-dir", "rmsf", ffOPTWR } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pargs),
- pargs, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(
+ &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pargs), pargs, asize(desc), desc, 0, nullptr, &oenv))
{
return 0;
}
|| top.atoms.atom[index[i]].resind != top.atoms.atom[index[i + 1]].resind)
{
resind = top.atoms.atom[index[i]].resind;
- pdb_bfac = find_pdb_bfac(pdbatoms, &top.atoms.resinfo[resind],
- *(top.atoms.atomname[index[i]]));
+ pdb_bfac = find_pdb_bfac(
+ pdbatoms, &top.atoms.resinfo[resind], *(top.atoms.atomname[index[i]]));
- fprintf(fp, "%5d %10.5f %10.5f\n",
+ fprintf(fp,
+ "%5d %10.5f %10.5f\n",
bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i] + 1,
- rmsf[i] * bfac, pdb_bfac);
+ rmsf[i] * bfac,
+ pdb_bfac);
}
}
xvgrclose(fp);
if (!bRes || i + 1 == isize
|| top.atoms.atom[index[i]].resind != top.atoms.atom[index[i + 1]].resind)
{
- fprintf(fp, "%5d %8.4f\n",
+ fprintf(fp,
+ "%5d %8.4f\n",
bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i] + 1,
std::sqrt(rmsf[i]));
}
if (!bRes || i + 1 == isize
|| top.atoms.atom[index[i]].resind != top.atoms.atom[index[i + 1]].resind)
{
- fprintf(fp, "%5d %8.4f\n",
+ fprintf(fp,
+ "%5d %8.4f\n",
bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i] + 1,
std::sqrt(rmsf[i]));
}
{
rvec_inc(pdbx[index[i]], xcm);
}
- write_sto_conf_indexed(opt2fn("-oq", NFILE, fnm), title, pdbatoms, pdbx, nullptr, pbcType,
- pdbbox, isize, index);
+ write_sto_conf_indexed(
+ opt2fn("-oq", NFILE, fnm), title, pdbatoms, pdbx, nullptr, pbcType, pdbbox, isize, index);
}
if (opt2bSet("-ox", NFILE, fnm))
{
}
}
/* Write a .pdb file with B-factors and optionally anisou records */
- write_sto_conf_indexed(opt2fn("-ox", NFILE, fnm), title, pdbatoms, bFactorX, nullptr,
- pbcType, pdbbox, isize, index);
+ write_sto_conf_indexed(
+ opt2fn("-ox", NFILE, fnm), title, pdbatoms, bFactorX, nullptr, pbcType, pdbbox, isize, index);
sfree(bFactorX);
}
if (bAniso)
#include <cstring>
#include <algorithm>
-#include <sstream>
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/tpxio.h"
enNr
};
/*! \brief
- * enum for type of input files (pdos, tpr, or pullf)
+ * enum for type of input files (tpr or pullx/pullf)
*/
enum
{
whamin_unknown,
whamin_tpr,
whamin_pullxf,
- whamin_pdo
};
/*! \brief enum for bootstrapping method
bsMethod_trajGauss
};
- //! Parameters of one pull coodinate
+ //! Parameters of one pull coordinate
typedef struct
{
- int pull_type; //!< such as constraint, umbrella, ...
- int geometry; //!< such as distance, direction, cylinder
- int ngroup; //!< the number of pull groups involved
- ivec dim; //!< pull dimension with geometry distance
- int ndim; //!< nr of pull_dim != 0
- real k; //!< force constants in tpr file
- real init_dist; //!< reference displacement
- char coord_unit[256]; //!< unit of the displacement
+ PullingAlgorithm pull_type; //!< such as constraint, umbrella, ...
+ PullGroupGeometry geometry; //!< such as distance, direction, cylinder
+ int ngroup; //!< the number of pull groups involved
+ ivec dim; //!< pull dimension with geometry distance
+ int ndim; //!< nr of pull_dim != 0
+ real k; //!< force constants in tpr file
+ real init_dist; //!< reference displacement
+ char coord_unit[256]; //!< unit of the displacement
} t_pullcoord;
//! Parameters of the umbrella potentials
gmx_bool bPrintComp; //!< Components of pull distance written to pullx.xvg ?
/*!\}*/
- /*!
- * \name Using PDO files common until gromacs 3.x
- */
- /*!\{*/
- int nSkip;
- char Reference[256];
- int nPull;
- int nDim;
- ivec Dims;
- char PullName[4][256];
- double UmbPos[4][3];
- double UmbCons[4][3];
- /*!\}*/
} t_UmbrellaHeader;
//! Data in the umbrella histograms
typedef struct
{
- int nPull; //!< nr of pull groups in this pdo or pullf/x file
+ int nPull; //!< nr of pull groups in this pullf/pullx file
double** Histo; //!< nPull histograms
double** cum; //!< nPull cumulative distribution functions
int nBin; //!< nr of bins. identical to opt->bins
double* k; //!< force constants for the nPull coords
double* pos; //!< umbrella positions for the nPull coords
double* z; //!< z=(-Fi/kT) for the nPull coords. These values are iteratively computed during wham
- int* N; //!< nr of data points in nPull histograms.
- int* Ntot; //!< also nr of data points. N and Ntot only differ if bHistEq==TRUE
+ int* N; //!< nr of data points in nPull histograms.
+ int* Ntot; //!< also nr of data points. N and Ntot only differ if bHistEq==TRUE
/*! \brief g = 1 + 2*tau[int]/dt where tau is the integrated autocorrelation time.
*
*/
/*!\{*/
const char *fnTpr, *fnPullf, *fnCoordSel;
- const char *fnPdo, *fnPullx; //!< file names of input
- gmx_bool bTpr, bPullf, bPdo, bPullx; //!< input file types given?
- real tmin, tmax, dt; //!< only read input within tmin and tmax with dt
+ const char* fnPullx; //!< file names of input
+ gmx_bool bTpr, bPullf, bPullx; //!< input file types given?
+ real tmin, tmax, dt; //!< only read input within tmin and tmax with dt
gmx_bool bInitPotByIntegration; //!< before WHAM, guess potential by force integration. Yields 1.5 to 2 times faster convergence
int stepUpdateContrib; //!< update contribution table every ... iterations. Accelerates WHAM.
* \name Basic WHAM options
*/
/*!\{*/
- int bins; //!< nr of bins, min, max, and dz of profile
- real min, max, dz;
- real Temperature, Tolerance; //!< temperature, converged when probability changes less than Tolerance
- gmx_bool bCycl; //!< generate cyclic (periodic) PMF
+ int bins; //!< nr of bins, min, max, and dz of profile
+ real min, max, dz;
+ real Temperature, Tolerance; //!< temperature, converged when probability changes less than Tolerance
+ gmx_bool bCycl; //!< generate cyclic (periodic) PMF
/*!\}*/
/*!
* \name Output control
opt->tabX[i] = y[0][i];
opt->tabY[i] = y[1][i];
}
- printf("Found equally spaced tabulated potential from %g to %g, spacing %g\n", opt->tabMin,
- opt->tabMax, opt->tabDz);
-}
-
-//! Read the header of an PDO file (position, force const, nr of groups)
-static void read_pdo_header(FILE* file, t_UmbrellaHeader* header, t_UmbrellaOptions* opt)
-{
- char line[2048];
- char Buffer0[256], Buffer1[256], Buffer2[256], Buffer3[256], Buffer4[256];
- int i;
- std::istringstream ist;
-
- /* line 1 */
- if (fgets(line, 2048, file) == nullptr)
- {
- gmx_fatal(FARGS, "Error reading header from pdo file\n");
- }
- ist.str(line);
- ist >> Buffer0 >> Buffer1 >> Buffer2;
- if (std::strcmp(Buffer1, "UMBRELLA") != 0)
- {
- gmx_fatal(FARGS,
- "This does not appear to be a valid pdo file. Found %s, expected %s\n"
- "(Found in first line: `%s')\n",
- Buffer1, "UMBRELLA", line);
- }
- if (std::strcmp(Buffer2, "3.0") != 0)
- {
- gmx_fatal(FARGS, "This does not appear to be a version 3.0 pdo file");
- }
-
- /* line 2 */
- if (fgets(line, 2048, file) == nullptr)
- {
- gmx_fatal(FARGS, "Error reading header from pdo file\n");
- }
- ist.str(line);
- ist >> Buffer0 >> Buffer1 >> Buffer2 >> header->Dims[0] >> header->Dims[1] >> header->Dims[2];
- /* printf("%d %d %d\n", header->Dims[0],header->Dims[1],header->Dims[2]); */
-
- header->nDim = header->Dims[0] + header->Dims[1] + header->Dims[2];
- if (header->nDim != 1)
- {
- gmx_fatal(FARGS, "Currently only supports one dimension");
- }
-
- /* line3 */
- if (fgets(line, 2048, file) == nullptr)
- {
- gmx_fatal(FARGS, "Error reading header from pdo file\n");
- }
- ist.str(line);
- ist >> Buffer0 >> Buffer1 >> header->nSkip;
-
- /* line 4 */
- if (fgets(line, 2048, file) == nullptr)
- {
- gmx_fatal(FARGS, "Error reading header from pdo file\n");
- }
- ist.str(line);
- ist >> Buffer0 >> Buffer1 >> Buffer2 >> header->Reference;
-
- /* line 5 */
- if (fgets(line, 2048, file) == nullptr)
- {
- gmx_fatal(FARGS, "Error reading header from pdo file\n");
- }
- ist.str(line);
- ist >> Buffer0 >> Buffer1 >> Buffer2 >> Buffer3 >> Buffer4 >> header->nPull;
-
- if (opt->verbose)
- {
- printf("\tFound nPull=%d , nSkip=%d, ref=%s\n", header->nPull, header->nSkip, header->Reference);
- }
-
- for (i = 0; i < header->nPull; ++i)
- {
- if (fgets(line, 2048, file) == nullptr)
- {
- gmx_fatal(FARGS, "Error reading header from pdo file\n");
- }
- ist.str(line);
- ist >> Buffer0 >> Buffer1 >> Buffer2 >> header->PullName[i];
- ist >> Buffer0 >> Buffer1 >> header->UmbPos[i][0];
- ist >> Buffer0 >> Buffer1 >> header->UmbCons[i][0];
-
- if (opt->verbose)
- {
- printf("\tpullgroup %d, pullname = %s, UmbPos = %g, UmbConst = %g\n", i,
- header->PullName[i], header->UmbPos[i][0], header->UmbCons[i][0]);
- }
- }
-
- if (fgets(line, 2048, file) == nullptr)
- {
- gmx_fatal(FARGS, "Cannot read from file\n");
- }
- ist.str(line);
- ist >> Buffer3;
- if (std::strcmp(Buffer3, "#####") != 0)
- {
- gmx_fatal(FARGS, "Expected '#####', found %s. Hick.\n", Buffer3);
- }
+ printf("Found equally spaced tabulated potential from %g to %g, spacing %g\n",
+ opt->tabMin,
+ opt->tabMax,
+ opt->tabDz);
}
//! smarter fgets
return ptr;
}
-/*! \brief Read the data columns of and PDO file.
- *
- * TO DO: Get rid of the scanf function to avoid the clang warning.
- * At the moment, this warning is avoided by hiding the format string
- * the variable fmtlf.
- */
-static void read_pdo_data(FILE* file,
- t_UmbrellaHeader* header,
- int fileno,
- t_UmbrellaWindow* win,
- t_UmbrellaOptions* opt,
- gmx_bool bGetMinMax,
- real* mintmp,
- real* maxtmp)
-{
- int i, inttemp, bins, count, ntot;
- real minval, maxval, minfound = 1e20, maxfound = -1e20;
- double temp, time, time0 = 0, dt;
- char* ptr = nullptr;
- t_UmbrellaWindow* window = nullptr;
- gmx_bool timeok, dt_ok = true;
- char * tmpbuf = nullptr, fmt[256], fmtign[256], fmtlf[5] = "%lf";
- int len = STRLEN, dstep = 1;
- const int blocklen = 4096;
- int* lennow = nullptr;
-
- if (!bGetMinMax)
- {
- bins = opt->bins;
- minval = opt->min;
- maxval = opt->max;
-
- window = win + fileno;
- /* Need to alocate memory and set up structure */
- window->nPull = header->nPull;
- window->nBin = bins;
-
- snew(window->Histo, window->nPull);
- snew(window->z, window->nPull);
- snew(window->k, window->nPull);
- snew(window->pos, window->nPull);
- snew(window->N, window->nPull);
- snew(window->Ntot, window->nPull);
- snew(window->g, window->nPull);
- snew(window->bsWeight, window->nPull);
-
- window->bContrib = nullptr;
-
- if (opt->bCalcTauInt)
- {
- snew(window->ztime, window->nPull);
- }
- else
- {
- window->ztime = nullptr;
- }
- snew(lennow, window->nPull);
-
- for (i = 0; i < window->nPull; ++i)
- {
- window->z[i] = 1;
- window->bsWeight[i] = 1.;
- snew(window->Histo[i], bins);
- window->k[i] = header->UmbCons[i][0];
- window->pos[i] = header->UmbPos[i][0];
- window->N[i] = 0;
- window->Ntot[i] = 0;
- window->g[i] = 1.;
- if (opt->bCalcTauInt)
- {
- window->ztime[i] = nullptr;
- }
- }
-
- /* Done with setup */
- }
- else
- {
- minfound = 1e20;
- maxfound = -1e20;
- minval = maxval = bins = 0; /* Get rid of warnings */
- }
-
- count = 0;
- snew(tmpbuf, len);
- while ((ptr = fgets3(file, tmpbuf, &len)) != nullptr)
- {
- trim(ptr);
-
- if (ptr[0] == '#' || std::strlen(ptr) < 2)
- {
- continue;
- }
-
- /* Initiate format string */
- fmtign[0] = '\0';
- std::strcat(fmtign, "%*s");
-
- sscanf(ptr, fmtlf, &time); /* printf("Time %f\n",time); */
- /* Round time to fs */
- time = 1.0 / 1000 * (gmx::roundToInt64(time * 1000));
-
- /* get time step of pdo file */
- if (count == 0)
- {
- time0 = time;
- }
- else if (count == 1)
- {
- dt = time - time0;
- if (opt->dt > 0.0)
- {
- dstep = gmx::roundToInt(opt->dt / dt);
- if (dstep == 0)
- {
- dstep = 1;
- }
- }
- if (!bGetMinMax)
- {
- window->dt = dt * dstep;
- }
- }
- count++;
-
- dt_ok = ((count - 1) % dstep == 0);
- timeok = (dt_ok && time >= opt->tmin && time <= opt->tmax);
- /* if (opt->verbose)
- printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n",
- time,opt->tmin, opt->tmax, dt_ok,timeok); */
-
- if (timeok)
- {
- for (i = 0; i < header->nPull; ++i)
- {
- std::strcpy(fmt, fmtign);
- std::strcat(fmt, "%lf"); /* Creating a format stings such as "%*s...%*s%lf" */
- std::strcat(fmtign, "%*s"); /* ignoring one more entry in the next loop */
- if (sscanf(ptr, fmt, &temp))
- {
- temp += header->UmbPos[i][0];
- if (bGetMinMax)
- {
- if (temp < minfound)
- {
- minfound = temp;
- }
- if (temp > maxfound)
- {
- maxfound = temp;
- }
- }
- else
- {
- if (opt->bCalcTauInt)
- {
- /* save time series for autocorrelation analysis */
- ntot = window->Ntot[i];
- if (ntot >= lennow[i])
- {
- lennow[i] += blocklen;
- srenew(window->ztime[i], lennow[i]);
- }
- window->ztime[i][ntot] = temp;
- }
-
- temp -= minval;
- temp /= (maxval - minval);
- temp *= bins;
- temp = std::floor(temp);
-
- inttemp = static_cast<int>(temp);
- if (opt->bCycl)
- {
- if (inttemp < 0)
- {
- inttemp += bins;
- }
- else if (inttemp >= bins)
- {
- inttemp -= bins;
- }
- }
-
- if (inttemp >= 0 && inttemp < bins)
- {
- window->Histo[i][inttemp] += 1.;
- window->N[i]++;
- }
- window->Ntot[i]++;
- }
- }
- }
- }
- if (time > opt->tmax)
- {
- if (opt->verbose)
- {
- printf("time %f larger than tmax %f, stop reading pdo file\n", time, opt->tmax);
- }
- break;
- }
- }
-
- if (bGetMinMax)
- {
- *mintmp = minfound;
- *maxtmp = maxfound;
- }
-
- sfree(lennow);
- sfree(tmpbuf);
-}
-
/*! \brief Set identical weights for all histograms
*
* Normally, the weight is given by the number data points in each
gmx_fatal(FARGS,
"Distance %f out of bounds of tabulated potential (jl=%d, ju=%d).\n"
"Provide an extended table.",
- dist, jl, ju);
+ dist,
+ jl,
+ ju);
}
pl = opt->tabY[jl];
pu = opt->tabY[ju];
}
}
/* Note: there are two contributions to bin k in the wham equations:
- i) N[j]*exp(- U/(BOLTZ*opt->Temperature) + window[i].z[j])
- ii) exp(- U/(BOLTZ*opt->Temperature))
+ i) N[j]*exp(- U/(c_boltz*opt->Temperature) + window[i].z[j])
+ ii) exp(- U/(c_boltz*opt->Temperature))
where U is the umbrella potential
If any of these number is larger wham_contrib_lim, I set contrib=TRUE
*/
{
U = tabulated_pot(distance, opt); /* Use tabulated potential */
}
- contrib1 = profile[k] * std::exp(-U / (BOLTZ * opt->Temperature));
- contrib2 = window[i].N[j] * std::exp(-U / (BOLTZ * opt->Temperature) + window[i].z[j]);
+ contrib1 = profile[k] * std::exp(-U / (gmx::c_boltz * opt->Temperature));
+ contrib2 = window[i].N[j]
+ * std::exp(-U / (gmx::c_boltz * opt->Temperature) + window[i].z[j]);
window[i].bContrib[j][k] = (contrib1 > wham_contrib_lim || contrib2 > wham_contrib_lim);
bAnyContrib = bAnyContrib || window[i].bContrib[j][k];
if (window[i].bContrib[j][k])
{
printf("Initialized rapid wham stuff (contrib tolerance %g)\n"
"Evaluating only %d of %d expressions.\n\n",
- wham_contrib_lim, nContrib, nTot);
+ wham_contrib_lim,
+ nContrib,
+ nTot);
}
if (opt->verbose)
U = tabulated_pot(distance, opt); /* Use tabulated potential */
}
denom += invg * window[j].N[k]
- * std::exp(-U / (BOLTZ * opt->Temperature) + window[j].z[k]);
+ * std::exp(-U / (gmx::c_boltz * opt->Temperature) + window[j].z[k]);
}
}
profile[i] = num / denom;
{
U = tabulated_pot(distance, opt); /* Use tabulated potential */
}
- total += profile[k] * std::exp(-U / (BOLTZ * opt->Temperature));
+ total += profile[k] * std::exp(-U / (gmx::c_boltz * opt->Temperature));
}
/* Avoid floating point exception if window is far outside min and max */
if (total != 0.0)
if (min > 0. || max < 0.)
{
- gmx_fatal(FARGS, "Cannot symmetrize profile around z=0 with min=%f and max=%f\n", opt->min,
- opt->max);
+ gmx_fatal(FARGS, "Cannot symmetrize profile around z=0 with min=%f and max=%f\n", opt->min, opt->max);
}
snew(prof2, bins);
}
else if (opt->unit == en_kJ)
{
- unit_factor = BOLTZ * opt->Temperature;
+ unit_factor = gmx::c_boltz * opt->Temperature;
}
else if (opt->unit == en_kCal)
{
- unit_factor = (BOLTZ / CAL2JOULE) * opt->Temperature;
+ unit_factor = (gmx::c_boltz / gmx::c_cal2Joule) * opt->Temperature;
}
else
{
gmx_fatal(FARGS,
"Ups, random iWin = %d, nPull = %d, nr = %d, "
"blockLength = %d, blockBase = %d\n",
- ipullRandom, nPull, nr, blockLength, blockBase);
+ ipullRandom,
+ nPull,
+ nr,
+ blockLength,
+ blockBase);
}
randomArray[ipull] = ipullRandom;
}
printf("Wrote boot strap result to %s\n", fnres);
}
-//! Return type of input file based on file extension (xvg, pdo, or tpr)
+//! Return type of input file based on file extension (xvg or tpr)
static int whaminFileType(char* fn)
{
int len;
{
return whamin_pullxf;
}
- else if (std::strcmp(fn + len - 3, "pdo") == 0 || std::strcmp(fn + len - 6, "pdo.gz") == 0)
- {
- return whamin_pdo;
- }
else
{
- gmx_fatal(FARGS, "Unknown file type of %s. Should be tpr, xvg, or pdo.\n", fn);
+ gmx_fatal(FARGS,
+ "Unknown file type of %s. Should be tpr or xvg. Use GROMACS 2021 or earlier to "
+ "read pdo files.\n",
+ fn);
}
}
-//! Read the files names in pdo-files.dat, pullf/x-files.dat, tpr-files.dat
+//! Read the files names in pullf/pullx-files.dat, tpr-files.dat
static void read_wham_in(const char* fn, char*** filenamesRet, int* nfilesRet, t_UmbrellaOptions* opt)
{
char **filename = nullptr, tmp[WHAM_MAXFILELEN + 2];
*nfilesRet = nread;
}
-//! Open a file or a pipe to a gzipped file
-static FILE* open_pdo_pipe(const char* fn, t_UmbrellaOptions* opt, gmx_bool* bPipeOpen)
-{
- char Buffer[2048], gunzip[1024], *Path = nullptr;
- FILE* pipe = nullptr;
- static gmx_bool bFirst = true;
-
- /* gzipped pdo file? */
- if ((std::strcmp(fn + std::strlen(fn) - 3, ".gz") == 0))
- {
- /* search gunzip executable */
- if (!(Path = getenv("GMX_PATH_GZIP")))
- {
- if (gmx_fexist("/bin/gunzip"))
- {
- sprintf(gunzip, "%s", "/bin/gunzip");
- }
- else if (gmx_fexist("/usr/bin/gunzip"))
- {
- sprintf(gunzip, "%s", "/usr/bin/gunzip");
- }
- else
- {
- gmx_fatal(FARGS,
- "Cannot find executable gunzip in /bin or /usr/bin.\n"
- "You may want to define the path to gunzip "
- "with the environment variable GMX_PATH_GZIP.");
- }
- }
- else
- {
- sprintf(gunzip, "%s/gunzip", Path);
- if (!gmx_fexist(gunzip))
- {
- gmx_fatal(FARGS,
- "Cannot find executable %s. Please define the path to gunzip"
- " in the environmental varialbe GMX_PATH_GZIP.",
- gunzip);
- }
- }
- if (bFirst)
- {
- printf("Using gunzip executable %s\n", gunzip);
- bFirst = false;
- }
- if (!gmx_fexist(fn))
- {
- gmx_fatal(FARGS, "File %s does not exist.\n", fn);
- }
- sprintf(Buffer, "%s -c < %s", gunzip, fn);
- if (opt->verbose)
- {
- printf("Executing command '%s'\n", Buffer);
- }
-#if HAVE_PIPES
- if ((pipe = popen(Buffer, "r")) == nullptr)
- {
- gmx_fatal(FARGS, "Unable to open pipe to `%s'\n", Buffer);
- }
-#else
- gmx_fatal(FARGS, "Cannot open a compressed file on platform without pipe support");
-#endif
- *bPipeOpen = TRUE;
- }
- else
- {
- pipe = gmx_ffopen(fn, "r");
- *bPipeOpen = FALSE;
- }
-
- return pipe;
-}
-
-//! Close file or pipe
-static void pdo_close_file(FILE* fp)
-{
-#if HAVE_PIPES
- pclose(fp);
-#else
- gmx_ffclose(fp);
-#endif
-}
-
-//! Reading all pdo files
-static void read_pdo_files(char** fn, int nfiles, t_UmbrellaHeader* header, t_UmbrellaWindow* window, t_UmbrellaOptions* opt)
-{
- FILE* file;
- real mintmp, maxtmp, done = 0.;
- int i;
- gmx_bool bPipeOpen;
- /* char Buffer0[1000]; */
-
- if (nfiles < 1)
- {
- gmx_fatal(FARGS, "No files found. Hick.");
- }
-
- /* if min and max are not given, get min and max from the input files */
- if (opt->bAuto)
- {
- printf("Automatic determination of boundaries from %d pdo files...\n", nfiles);
- opt->min = 1e20;
- opt->max = -1e20;
- for (i = 0; i < nfiles; ++i)
- {
- file = open_pdo_pipe(fn[i], opt, &bPipeOpen);
- /*fgets(Buffer0,999,file);
- fprintf(stderr,"First line '%s'\n",Buffer0); */
- done = 100.0 * (i + 1) / nfiles;
- fprintf(stdout, "\rOpening %s ... [%2.0f%%]", fn[i], done);
- fflush(stdout);
- if (opt->verbose)
- {
- printf("\n");
- }
- read_pdo_header(file, header, opt);
- /* here only determine min and max of this window */
- read_pdo_data(file, header, i, nullptr, opt, TRUE, &mintmp, &maxtmp);
- if (maxtmp > opt->max)
- {
- opt->max = maxtmp;
- }
- if (mintmp < opt->min)
- {
- opt->min = mintmp;
- }
- if (bPipeOpen)
- {
- pdo_close_file(file);
- }
- else
- {
- gmx_ffclose(file);
- }
- }
- printf("\n");
- printf("\nDetermined boundaries to %f and %f\n\n", opt->min, opt->max);
- if (opt->bBoundsOnly)
- {
- printf("Found option -boundsonly, now exiting.\n");
- exit(0);
- }
- }
- /* store stepsize in profile */
- opt->dz = (opt->max - opt->min) / opt->bins;
-
- /* Having min and max, we read in all files */
- /* Loop over all files */
- for (i = 0; i < nfiles; ++i)
- {
- done = 100.0 * (i + 1) / nfiles;
- fprintf(stdout, "\rOpening %s ... [%2.0f%%]", fn[i], done);
- fflush(stdout);
- if (opt->verbose)
- {
- printf("\n");
- }
- file = open_pdo_pipe(fn[i], opt, &bPipeOpen);
- read_pdo_header(file, header, opt);
- /* load data into window */
- read_pdo_data(file, header, i, window, opt, FALSE, nullptr, nullptr);
- if ((window + i)->Ntot[0] == 0)
- {
- fprintf(stderr, "\nWARNING, no data points read from file %s (check -b option)\n", fn[i]);
- }
- if (bPipeOpen)
- {
- pdo_close_file(file);
- }
- else
- {
- gmx_ffclose(file);
- }
- }
- printf("\n");
- for (i = 0; i < nfiles; ++i)
- {
- sfree(fn[i]);
- }
- sfree(fn);
-}
-
//! translate 0/1 to N/Y to write pull dimensions
#define int2YN(a) (((a) == 0) ? ("N") : ("Y"))
* so we need to multiply with the internal units (radians for angle)
* to user units (degrees for an angle) with the same power.
*/
- header->pcrd[i].k =
- ir->pull->coord[i].k
- / gmx::square(pull_conversion_factor_internal2userinput(&ir->pull->coord[i]));
+ header->pcrd[i].k = ir->pull->coord[i].k
+ / gmx::square(pull_conversion_factor_internal2userinput(ir->pull->coord[i]));
header->pcrd[i].init_dist = ir->pull->coord[i].init;
copy_ivec(ir->pull->coord[i].dim, header->pcrd[i].dim);
header->pcrd[i].ndim =
header->pcrd[i].dim[XX] + header->pcrd[i].dim[YY] + header->pcrd[i].dim[ZZ];
- std::strcpy(header->pcrd[i].coord_unit, pull_coordinate_units(&ir->pull->coord[i]));
+ std::strcpy(header->pcrd[i].coord_unit, pull_coordinate_units(ir->pull->coord[i]));
- if (ir->efep != efepNO && ir->pull->coord[i].k != ir->pull->coord[i].kB)
+ if (ir->efep != FreeEnergyPerturbationType::No && ir->pull->coord[i].k != ir->pull->coord[i].kB)
{
gmx_fatal(FARGS,
"Seems like you did free-energy perturbation, and you perturbed the force "
gmx_fatal(FARGS,
"Found %d pull coordinates in %s, but %d columns in the respective line\n"
"coordinate selection file (option -is)\n",
- ir->pull->ncoord, fn, coordsel->n);
+ ir->pull->ncoord,
+ fn,
+ coordsel->n);
}
}
/* Check pull coords for consistency */
- int geom = -1;
- ivec thedim = { 0, 0, 0 };
- bool geometryIsSet = false;
+ PullGroupGeometry geom = PullGroupGeometry::Count;
+ ivec thedim = { 0, 0, 0 };
+ bool geometryIsSet = false;
for (int i = 0; i < ir->pull->ncoord; i++)
{
if (coordsel == nullptr || coordsel->bUse[i])
{
- if (header->pcrd[i].pull_type != epullUMBRELLA)
+ if (header->pcrd[i].pull_type != PullingAlgorithm::Umbrella)
{
gmx_fatal(FARGS,
"%s: Pull coordinate %d is of type \"%s\", expected \"umbrella\". Only "
"umbrella coodinates can enter WHAM.\n"
- "If you have umrella and non-umbrella coordinates, you can select the "
+ "If you have umbrella and non-umbrella coordinates, you can select the "
"umbrella coordinates with gmx wham -is\n",
- fn, i + 1, epull_names[header->pcrd[i].pull_type]);
+ fn,
+ i + 1,
+ enumValueToString(header->pcrd[i].pull_type));
}
if (!geometryIsSet)
{
"%s, coordinate %d: %s)\n"
"If you want to use only some pull coordinates in WHAM, please select "
"them with option gmx wham -is\n",
- fn, epullg_names[geom], i + 1, epullg_names[header->pcrd[i].geometry]);
+ fn,
+ enumValueToString(geom),
+ i + 1,
+ enumValueToString(header->pcrd[i].geometry));
}
if (thedim[XX] != header->pcrd[i].dim[XX] || thedim[YY] != header->pcrd[i].dim[YY]
|| thedim[ZZ] != header->pcrd[i].dim[ZZ])
"%s %s %s, coordinate %d: %s %s %s)\n"
"If you want to use only some pull coordinates in WHAM, please select "
"them with option gmx wham -is\n",
- fn, int2YN(thedim[XX]), int2YN(thedim[YY]), int2YN(thedim[ZZ]), i + 1,
- int2YN(header->pcrd[i].dim[XX]), int2YN(header->pcrd[i].dim[YY]),
+ fn,
+ int2YN(thedim[XX]),
+ int2YN(thedim[YY]),
+ int2YN(thedim[ZZ]),
+ i + 1,
+ int2YN(header->pcrd[i].dim[XX]),
+ int2YN(header->pcrd[i].dim[YY]),
int2YN(header->pcrd[i].dim[ZZ]));
}
- if (header->pcrd[i].geometry == epullgCYL)
+ if (header->pcrd[i].geometry == PullGroupGeometry::Cylinder)
{
if (header->pcrd[i].dim[XX] || header->pcrd[i].dim[YY] || (!header->pcrd[i].dim[ZZ]))
{
FARGS,
"With pull geometry 'cylinder', expected pulling in Z direction only.\n"
"However, found dimensions [%s %s %s]\n",
- int2YN(header->pcrd[i].dim[XX]), int2YN(header->pcrd[i].dim[YY]),
+ int2YN(header->pcrd[i].dim[XX]),
+ int2YN(header->pcrd[i].dim[YY]),
int2YN(header->pcrd[i].dim[ZZ]));
}
}
gmx_fatal(FARGS,
"%s: Pull coordinate %d has force constant of of %g.\n"
"That doesn't seem to be an Umbrella tpr.\n",
- fn, i + 1, header->pcrd[i].k);
+ fn,
+ i + 1,
+ header->pcrd[i].k);
}
}
}
int maxlen = 0;
for (int i = 0; i < ir->pull->ncoord; i++)
{
- int lentmp = strlen(epullg_names[header->pcrd[i].geometry]);
+ int lentmp = strlen(enumValueToString(header->pcrd[i].geometry));
maxlen = (lentmp > maxlen) ? lentmp : maxlen;
}
char fmt[STRLEN];
for (int i = 0; i < ir->pull->ncoord; i++)
{
bool use = (coordsel == nullptr || coordsel->bUse[i]);
- printf(fmt, epullg_names[header->pcrd[i].geometry], header->pcrd[i].k, header->pcrd[i].init_dist,
- int2YN(header->pcrd[i].dim[XX]), int2YN(header->pcrd[i].dim[YY]),
- int2YN(header->pcrd[i].dim[ZZ]), header->pcrd[i].ndim, use ? "Yes" : "No");
+ printf(fmt,
+ enumValueToString(header->pcrd[i].geometry),
+ header->pcrd[i].k,
+ header->pcrd[i].init_dist,
+ int2YN(header->pcrd[i].dim[XX]),
+ int2YN(header->pcrd[i].dim[YY]),
+ int2YN(header->pcrd[i].dim[ZZ]),
+ header->pcrd[i].ndim,
+ use ? "Yes" : "No");
printf("\tPull group coordinates of %d groups expected in pullx files.\n",
ir->pull->bPrintCOM ? header->pcrd[i].ngroup : 0);
}
printf("\t\treaction coordinate: %d\n"
"\t\tcenter-of-mass of groups: %d\n"
"\t\treference position column: %s\n",
- 1, nColCOMCrd[i], (header->bPrintRefValue ? "Yes" : "No"));
+ 1,
+ nColCOMCrd[i],
+ (header->bPrintRefValue ? "Yes" : "No"));
}
printf("\tFound %d times in %s\n", nt, fn);
bFirst = FALSE;
gmx_fatal(FARGS,
"Expected %d columns (including time column) in %s, but found %d."
" Maybe you confused options -if and -ix ?",
- nColExpect, fn, ny);
+ nColExpect,
+ fn,
+ ny);
}
if (!bGetMinMax)
gmx_fatal(FARGS,
"tpr file contains %d pull groups, but expected %d from group selection "
"file\n",
- header->npullcrds, coordsel->n);
+ header->npullcrds,
+ coordsel->n);
}
window->nPull = coordsel->nUse;
}
/* Do you want that time frame? */
t = 1.0 / 1000 * (gmx::roundToInt64((y[0][i] * 1000))); /* round time to fs */
- /* get time step of pdo file and get dstep from opt->dt */
+ /* get time step and get dstep from opt->dt */
if (i == 0)
{
time0 = t;
gmx_fatal(FARGS,
"gUsed too large (%d, nPull=%d). This error should have been "
"caught before.\n",
- gUsed, window->nPull);
+ gUsed,
+ window->nPull);
}
if (opt->bCalcTauInt && !bGetMinMax)
if (whaminFileType(fnPull[i]) != whamin_pullxf)
{
gmx_fatal(FARGS,
- "Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n", i);
- }
- read_pull_xf(fnPull[i], header, nullptr, opt, TRUE, &mintmp, &maxtmp,
+ "Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n",
+ i);
+ }
+ read_pull_xf(fnPull[i],
+ header,
+ nullptr,
+ opt,
+ TRUE,
+ &mintmp,
+ &maxtmp,
(opt->nCoordsel > 0) ? &opt->coordsel[i] : nullptr);
if (maxtmp > opt->max)
{
read_tpr_header(fnTprs[i], header, opt, (opt->nCoordsel > 0) ? &opt->coordsel[i] : nullptr);
if (whaminFileType(fnPull[i]) != whamin_pullxf)
{
- gmx_fatal(FARGS,
- "Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n", i);
+ gmx_fatal(
+ FARGS, "Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n", i);
}
- read_pull_xf(fnPull[i], header, window + i, opt, FALSE, nullptr, nullptr,
+ read_pull_xf(fnPull[i],
+ header,
+ window + i,
+ opt,
+ FALSE,
+ nullptr,
+ nullptr,
(opt->nCoordsel > 0) ? &opt->coordsel[i] : nullptr);
if (window[i].Ntot[0] == 0)
{
nlines = read_xvg(fn, &iact, &ny);
if (nlines != nwins)
{
- gmx_fatal(FARGS, "Found %d lines with integrated autocorrelation times in %s.\nExpected %d",
- nlines, fn, nwins);
+ gmx_fatal(FARGS,
+ "Found %d lines with integrated autocorrelation times in %s.\nExpected %d",
+ nlines,
+ fn,
+ nwins);
}
for (i = 0; i < nlines; i++)
{
if (opt->verbose)
{
- fpcorr = xvgropen("hist_autocorr.xvg", "Autocorrelation functions of umbrella windows",
- "time [ps]", "autocorrelation function", opt->oenv);
+ fpcorr = xvgropen("hist_autocorr.xvg",
+ "Autocorrelation functions of umbrella windows",
+ "time [ps]",
+ "autocorrelation function",
+ opt->oenv);
}
printf("\n");
for (i = 0; i < nwins; i++)
{
- fprintf(stdout, "\rEstimating integrated autocorrelation times ... [%2.0f%%] ...",
+ fprintf(stdout,
+ "\rEstimating integrated autocorrelation times ... [%2.0f%%] ...",
100. * (i + 1) / nwins);
fflush(stdout);
ntot = window[i].Ntot[0];
gmx_fatal(FARGS,
"Encountered different nr of frames in different pull groups.\n"
"That should not happen. (%d and %d)\n",
- ntot, window[i].Ntot[ig]);
+ ntot,
+ window[i].Ntot[ig]);
}
ztime = window[i].ztime[ig];
fprintf(stderr,
"\nWARNING, no data point in bin %d (z=%g) !\n"
"You may not get a reasonable profile. Check your histograms!\n",
- j, z);
+ j,
+ z);
}
/* and check for poor sampling */
else if (relcount < 0.005 && !bBoundary)
*/
for (j = 0; j < opt->bins; ++j)
{
- pot[j] = std::exp(-pot[j] / (BOLTZ * opt->Temperature));
+ pot[j] = std::exp(-pot[j] / (gmx::c_boltz * opt->Temperature));
}
calc_z(pot, window, nWindows, opt, TRUE);
printf("\nUse only these pull coordinates:\n");
for (iline = 0; iline < nTpr; iline++)
{
- printf("%s (%d of %d coordinates):", fnTpr[iline], opt->coordsel[iline].nUse,
+ printf("%s (%d of %d coordinates):",
+ fnTpr[iline],
+ opt->coordsel[iline].nUse,
opt->coordsel[iline].n);
for (i = 0; i < opt->coordsel[iline].n; i++)
{
" provides the pull force output file names ([TT]pullf.xvg[tt]) with option [TT]-if[tt].",
" From the pull force the position in the umbrella potential is",
" computed. This does not work with tabulated umbrella potentials.",
- "* With option [TT]-ip[tt], the user provides file names of (gzipped) [REF].pdo[ref] ",
- " files, i.e.",
- " the GROMACS 3.3 umbrella output files. If you have some unusual",
- " reaction coordinate you may also generate your own [REF].pdo[ref] files and",
- " feed them with the [TT]-ip[tt] option into to [THISMODULE]. The [REF].pdo[ref] file ",
- " header must be similar to the following::",
- "",
- " # UMBRELLA 3.0",
- " # Component selection: 0 0 1",
- " # nSkip 1",
- " # Ref. Group 'TestAtom'",
- " # Nr. of pull groups 2",
- " # Group 1 'GR1' Umb. Pos. 5.0 Umb. Cons. 1000.0",
- " # Group 2 'GR2' Umb. Pos. 2.0 Umb. Cons. 500.0",
- " #####",
"",
- " The number of pull groups, umbrella positions, force constants, and names ",
- " may (of course) differ. Following the header, a time column and ",
- " a data column for each pull group follows (i.e. the displacement",
- " with respect to the umbrella center). Up to four pull groups are possible ",
- " per [REF].pdo[ref] file at present.[PAR]",
"By default, all pull coordinates found in all pullx/pullf files are used in WHAM. If ",
"only ",
"some of the pull coordinates should be used, a pull coordinate selection file (option ",
"",
"Always check whether the histograms sufficiently overlap.[PAR]",
"The umbrella potential is assumed to be harmonic and the force constants are ",
- "read from the [REF].tpr[ref] or [REF].pdo[ref] files. If a non-harmonic umbrella force ",
+ "read from the [REF].tpr[ref] files. If a non-harmonic umbrella force ",
"was applied ",
"a tabulated potential can be provided with [TT]-tab[tt].",
"",
"less robust) method such as fitting to a double exponential, you can ",
"compute the IACTs with [gmx-analyze] and provide them to [THISMODULE] with the file ",
"[TT]iact-in.dat[tt] (option [TT]-iiact[tt]), which should contain one line per ",
- "input file ([REF].pdo[ref] or pullx/f file) and one column per pull coordinate in the ",
+ "input file (pullx/pullf file) and one column per pull coordinate in the ",
"respective file.",
"",
"Error analysis",
{ efDAT, "-ix", "pullx-files", ffOPTRD }, /* wham input: pullf.xvg's and tprs */
{ efDAT, "-if", "pullf-files", ffOPTRD }, /* wham input: pullf.xvg's and tprs */
{ efDAT, "-it", "tpr-files", ffOPTRD }, /* wham input: tprs */
- { efDAT, "-ip", "pdo-files", ffOPTRD }, /* wham input: pdo files (gmx3 style) */
{ efDAT, "-is", "coordsel", ffOPTRD }, /* input: select pull coords to use */
{ efXVG, "-o", "profile", ffWRITE }, /* output file for profile */
{ efXVG, "-hist", "histo", ffWRITE }, /* output file for histograms */
t_UmbrellaWindow* window = nullptr;
double * profile, maxchange = 1e20;
gmx_bool bMinSet, bMaxSet, bAutoSet, bExact = FALSE;
- char ** fninTpr, **fninPull, **fninPdo;
+ char ** fninTpr, **fninPull;
const char* fnPull;
FILE * histout, *profout;
char xlabel[STRLEN], ylabel[256], title[256];
opt.stepchange = 100;
opt.stepUpdateContrib = 100;
- if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr,
- &opt.oenv))
+ if (!parse_common_args(
+ &argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &opt.oenv))
{
return 0;
}
opt.bProf0Set = opt2parg_bSet("-zprof0", asize(pa), pa);
opt.bTab = opt2bSet("-tab", NFILE, fnm);
- opt.bPdo = opt2bSet("-ip", NFILE, fnm);
opt.bTpr = opt2bSet("-it", NFILE, fnm);
opt.bPullx = opt2bSet("-ix", NFILE, fnm);
opt.bPullf = opt2bSet("-if", NFILE, fnm);
{
gmx_fatal(FARGS,
"Force input does not work with tabulated potentials. "
- "Provide pullx.xvg or pdo files!");
+ "Provide pullx.xvg files!");
}
- if (!opt.bPdo && !WHAMBOOLXOR(opt.bPullx, opt.bPullf))
+ if (!WHAMBOOLXOR(opt.bPullx, opt.bPullf))
{
gmx_fatal(FARGS, "Give either pullx (-ix) OR pullf (-if) data. Not both.");
}
- if (!opt.bPdo && !(opt.bTpr || opt.bPullf || opt.bPullx))
- {
- gmx_fatal(FARGS,
- "gmx wham supports three input modes, pullx, pullf, or pdo file input."
- "\n\n Check gmx wham -h !");
- }
- opt.fnPdo = opt2fn("-ip", NFILE, fnm);
opt.fnTpr = opt2fn("-it", NFILE, fnm);
opt.fnPullf = opt2fn("-if", NFILE, fnm);
opt.fnPullx = opt2fn("-ix", NFILE, fnm);
}
/* Reading gmx4/gmx5 pull output and tpr files */
- if (opt.bTpr || opt.bPullf || opt.bPullx)
- {
- read_wham_in(opt.fnTpr, &fninTpr, &nfiles, &opt);
-
- fnPull = opt.bPullf ? opt.fnPullf : opt.fnPullx;
- read_wham_in(fnPull, &fninPull, &nfiles2, &opt);
- printf("Found %d tpr and %d pull %s files in %s and %s, respectively\n", nfiles, nfiles2,
- opt.bPullf ? "force" : "position", opt.fnTpr, fnPull);
- if (nfiles != nfiles2)
- {
- gmx_fatal(FARGS, "Found %d file names in %s, but %d in %s\n", nfiles, opt.fnTpr, nfiles2, fnPull);
- }
-
- /* Read file that selects the pull group to be used */
- if (opt.fnCoordSel != nullptr)
- {
- readPullCoordSelection(&opt, fninTpr, nfiles);
- }
+ read_wham_in(opt.fnTpr, &fninTpr, &nfiles, &opt);
- window = initUmbrellaWindows(nfiles);
- read_tpr_pullxf_files(fninTpr, fninPull, nfiles, &header, window, &opt);
+ fnPull = opt.bPullf ? opt.fnPullf : opt.fnPullx;
+ read_wham_in(fnPull, &fninPull, &nfiles2, &opt);
+ printf("Found %d tpr and %d pull %s files in %s and %s, respectively\n",
+ nfiles,
+ nfiles2,
+ opt.bPullf ? "force" : "position",
+ opt.fnTpr,
+ fnPull);
+ if (nfiles != nfiles2)
+ {
+ gmx_fatal(FARGS, "Found %d file names in %s, but %d in %s\n", nfiles, opt.fnTpr, nfiles2, fnPull);
}
- else
- { /* reading pdo files */
- if (opt.fnCoordSel != nullptr)
- {
- gmx_fatal(FARGS,
- "Reading a -is file is not supported with PDO input files.\n"
- "Use awk or a similar tool to pick the required pull groups from your PDO "
- "files\n");
- }
- read_wham_in(opt.fnPdo, &fninPdo, &nfiles, &opt);
- printf("Found %d pdo files in %s\n", nfiles, opt.fnPdo);
- window = initUmbrellaWindows(nfiles);
- read_pdo_files(fninPdo, nfiles, &header, window, &opt);
+
+ /* Read file that selects the pull group to be used */
+ if (opt.fnCoordSel != nullptr)
+ {
+ readPullCoordSelection(&opt, fninTpr, nfiles);
}
+ window = initUmbrellaWindows(nfiles);
+ read_tpr_pullxf_files(fninTpr, fninPull, nfiles, &header, window, &opt);
+
/* It is currently assumed that all pull coordinates have the same geometry, so they also have the same coordinate units.
We can therefore get the units for the xlabel from the first coordinate. */
sprintf(xlabel, "\\xx\\f{} (%s)", header.pcrd[0].coord_unit);
/* Bootstrap Method */
if (opt.nBootStrap)
{
- do_bootstrapping(opt2fn("-bsres", NFILE, fnm), opt2fn("-bsprof", NFILE, fnm),
- opt2fn("-hist", NFILE, fnm), xlabel, ylabel, profile, window, nwins, &opt);
+ do_bootstrapping(opt2fn("-bsres", NFILE, fnm),
+ opt2fn("-bsprof", NFILE, fnm),
+ opt2fn("-hist", NFILE, fnm),
+ xlabel,
+ ylabel,
+ profile,
+ window,
+ nwins,
+ &opt);
}
sfree(profile);
#include <cstring>
#include <algorithm>
+#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "gromacs/gmxpreprocess/toputil.h"
#include "gromacs/math/functions.h"
#include "gromacs/math/units.h"
+#include "gromacs/math/utilities.h"
#include "gromacs/math/vec.h"
#include "gromacs/mdtypes/md_enums.h"
#include "gromacs/topology/ifunc.h"
int nhyd,
const std::string& nextheavy,
const std::string& dummy) :
- atomtype(type),
- isplanar(planar),
- nHydrogens(nhyd),
- nextHeavyType(nextheavy),
- dummyMass(dummy)
+ atomtype(type), isplanar(planar), nHydrogens(nhyd), nextHeavyType(nextheavy), dummyMass(dummy)
{
}
//! Type for the XH3/XH2 atom.
* \param[in] v Value for distance.
*/
VirtualSiteBond(const std::string& a1, const std::string& a2, real v) :
- atom1(a1),
- atom2(a2),
- value(v)
+ atom1(a1), atom2(a2), value(v)
{
}
//! Atom 1 in bond.
* \param[in] v Value for angle.
*/
VirtualSiteAngle(const std::string& a1, const std::string& a2, const std::string& a3, real v) :
- atom1(a1),
- atom2(a2),
- atom3(a3),
- value(v)
+ atom1(a1), atom2(a2), atom3(a3), value(v)
{
}
//! Atom 1 in angle.
{
if (pline[0] == OPENDIR)
{
- strncpy(dirstr, pline + 1, STRLEN - 2);
+ strncpy(dirstr, pline + 1, STRLEN - 1);
if ((ch = strchr(dirstr, CLOSEDIR)) != nullptr)
{
(*ch) = 0;
else if (numberOfSites == 4)
{
/* angle */
- vsitetoplist->back().angle.emplace_back(s1String, s2String, s3String,
- strtod(s4, nullptr));
+ vsitetoplist->back().angle.emplace_back(
+ s1String, s2String, s3String, strtod(s4, nullptr));
/* angle */
}
else
{
gmx_fatal(FARGS,
"Need 3 or 4 values to specify bond/angle values in %s: %s\n",
- ddbname, pline);
+ ddbname,
+ pline);
}
}
break;
default:
gmx_fatal(FARGS,
- "Didnt find a case for directive %s in read_vsite_database\n",
- "Didn't find a case for directive %s in read_vsite_database\n", dirstr);
++ "Didn't find a case for directive %s in read_vsite_database\n",
+ dirstr);
}
}
}
});
if (foundBond == found->bond.end())
{
- gmx_fatal(FARGS, "Couldnt find bond %s-%s for residue %s in vsite database.\n",
- atom1.c_str(), atom2.c_str(), res.c_str());
+ gmx_fatal(FARGS,
+ "Couldnt find bond %s-%s for residue %s in vsite database.\n",
+ atom1.c_str(),
+ atom2.c_str(),
+ res.c_str());
}
return foundBond->value;
if (foundAngle == found->angle.end())
{
- gmx_fatal(FARGS, "Couldnt find angle %s-%s-%s for residue %s in vsite database.\n",
- atom1.c_str(), atom2.c_str(), atom3.c_str(), res.c_str());
+ gmx_fatal(FARGS,
+ "Couldnt find angle %s-%s-%s for residue %s in vsite database.\n",
+ atom1.c_str(),
+ atom2.c_str(),
+ atom3.c_str(),
+ res.c_str());
}
return foundAngle->value;
/* find heavy atom bound to this hydrogen */
heavy = NOTSET;
for (auto parm = psb->interactionTypes.begin();
- (parm != psb->interactionTypes.end()) && (heavy == NOTSET); parm++)
+ (parm != psb->interactionTypes.end()) && (heavy == NOTSET);
+ parm++)
{
if (parm->ai() == atom)
{
fprintf(fp, "\n");
}
-static int get_atype(int atom, t_atoms* at, gmx::ArrayRef<const PreprocessResidue> rtpFFDB, ResidueType* rt)
+static int get_atype(int atom,
+ t_atoms* at,
+ gmx::ArrayRef<const PreprocessResidue> rtpFFDB,
+ const ResidueTypeMap& residueTypeMap)
{
int type;
bool bNterm;
{
/* get type from rtpFFDB */
auto localPpResidue = getDatabaseEntry(*(at->resinfo[at->atom[atom].resind].name), rtpFFDB);
- bNterm = rt->namedResidueHasType(*(at->resinfo[at->atom[atom].resind].name), "Protein")
+ bNterm = namedResidueHasType(
+ residueTypeMap, *(at->resinfo[at->atom[atom].resind].name), "Protein")
&& (at->atom[atom].resind == 0);
int j = search_jtype(*localPpResidue, *(at->atomname[atom]), bNterm);
type = localPpResidue->atom[j].type;
static int vsite_nm2type(const char* name, PreprocessingAtomTypes* atype)
{
- int tp;
-
- tp = atype->atomTypeFromName(name);
- if (tp == NOTSET)
+ auto tp = atype->atomTypeFromName(name);
+ if (!tp.has_value())
{
gmx_fatal(FARGS, "Dummy mass type (%s) not found in atom type database", name);
}
- return tp;
+ return *tp;
}
-static real get_amass(int atom, t_atoms* at, gmx::ArrayRef<const PreprocessResidue> rtpFFDB, ResidueType* rt)
+static real get_amass(int atom,
+ t_atoms* at,
+ gmx::ArrayRef<const PreprocessResidue> rtpFFDB,
+ const ResidueTypeMap& residueTypeMap)
{
real mass;
bool bNterm;
{
/* get mass from rtpFFDB */
auto localPpResidue = getDatabaseEntry(*(at->resinfo[at->atom[atom].resind].name), rtpFFDB);
- bNterm = rt->namedResidueHasType(*(at->resinfo[at->atom[atom].resind].name), "Protein")
+ bNterm = namedResidueHasType(
+ residueTypeMap, *(at->resinfo[at->atom[atom].resind].name), "Protein")
&& (at->atom[atom].resind == 0);
int j = search_jtype(*localPpResidue, *(at->atomname[atom]), bNterm);
mass = localPpResidue->atom[j].m;
gmx_fatal(FARGS,
"cannot make constraint in add_vsites for %d heavy "
"atoms and %d hydrogen atoms",
- nrheavies, nrHatoms);
+ nrheavies,
+ nrHatoms);
}
my_add_param(&(plist[F_CONSTRNC]), Hatoms[i], heavies[0], NOTSET);
}
case F_VSITE3OUT:
if (nrheavies < 2)
{
- gmx_fatal(FARGS, "Not enough heavy atoms (%d) for %s (min 3)",
- nrheavies + 1, interaction_function[vsite_type[Hatoms[i]]].name);
+ gmx_fatal(FARGS,
+ "Not enough heavy atoms (%d) for %s (min 3)",
+ nrheavies + 1,
+ interaction_function[vsite_type[Hatoms[i]]].name);
}
add_vsite3_atoms(&plist[ftype], Hatoms[i], Heavy, heavies[0], heavies[1], bSwapParity);
break;
case F_VSITE4FDN:
if (nrheavies < 3)
{
- gmx_fatal(FARGS, "Not enough heavy atoms (%d) for %s (min 4)",
- nrheavies + 1, interaction_function[vsite_type[Hatoms[i]]].name);
+ gmx_fatal(FARGS,
+ "Not enough heavy atoms (%d) for %s (min 4)",
+ nrheavies + 1,
+ interaction_function[vsite_type[Hatoms[i]]].name);
}
add_vsite4_atoms(&plist[ftype], Hatoms[0], Heavy, heavies[0], heavies[1], heavies[2]);
break;
default:
- gmx_fatal(FARGS, "can't use add_vsites for interaction function %s",
+ gmx_fatal(FARGS,
+ "can't use add_vsites for interaction function %s",
interaction_function[vsite_type[Hatoms[i]]].name);
} /* switch ftype */
} /* else */
} /* for i */
}
-#define ANGLE_6RING (DEG2RAD * 120)
+#define ANGLE_6RING (gmx::c_deg2Rad * 120)
/* cosine rule: a^2 = b^2 + c^2 - 2 b c cos(alpha) */
/* get a^2 when a, b and alpha are given: */
b_CE3_HE3 = get_ddb_bond(vsitetop, "TRP", "CE3", "HE3");
b_CZ3_HZ3 = get_ddb_bond(vsitetop, "TRP", "CZ3", "HZ3");
- a_NE1_CE2_CD2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "NE1", "CE2", "CD2");
- a_CE2_CD2_CG = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CE2", "CD2", "CG");
- a_CB_CG_CD2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CB", "CG", "CD2");
- a_CD2_CG_CD1 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CD2", "CG", "CD1");
-
- a_CE2_CD2_CE3 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CE2", "CD2", "CE3");
- a_CD2_CE2_CZ2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CD2", "CE2", "CZ2");
- a_CD2_CE3_CZ3 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CD2", "CE3", "CZ3");
- a_CE3_CZ3_HZ3 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CE3", "CZ3", "HZ3");
- a_CZ2_CH2_HH2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CZ2", "CH2", "HH2");
- a_CE2_CZ2_HZ2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CE2", "CZ2", "HZ2");
- a_CE2_CZ2_CH2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CE2", "CZ2", "CH2");
- a_CG_CD1_HD1 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CG", "CD1", "HD1");
- a_HE1_NE1_CE2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "HE1", "NE1", "CE2");
- a_CD2_CE3_HE3 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CD2", "CE3", "HE3");
+ a_NE1_CE2_CD2 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "NE1", "CE2", "CD2");
+ a_CE2_CD2_CG = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "CE2", "CD2", "CG");
+ a_CB_CG_CD2 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "CB", "CG", "CD2");
+ a_CD2_CG_CD1 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "CD2", "CG", "CD1");
+
+ a_CE2_CD2_CE3 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "CE2", "CD2", "CE3");
+ a_CD2_CE2_CZ2 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "CD2", "CE2", "CZ2");
+ a_CD2_CE3_CZ3 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "CD2", "CE3", "CZ3");
+ a_CE3_CZ3_HZ3 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "CE3", "CZ3", "HZ3");
+ a_CZ2_CH2_HH2 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "CZ2", "CH2", "HH2");
+ a_CE2_CZ2_HZ2 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "CE2", "CZ2", "HZ2");
+ a_CE2_CZ2_CH2 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "CE2", "CZ2", "CH2");
+ a_CG_CD1_HD1 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "CG", "CD1", "HD1");
+ a_HE1_NE1_CE2 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "HE1", "NE1", "CE2");
+ a_CD2_CE3_HE3 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TRP", "CD2", "CE3", "HE3");
/* Calculate local coordinates.
* y-axis (x=0) is the bond CD2-CE2.
*/
rvec_sub(x[ats[atCB]], x[ats[atCG]], r_ij);
rvec_sub(x[ats[atCD2]], x[ats[atCG]], r_ik);
- calc_vsite3_param(xcom[0], ycom[0], xi[atCG], yi[atCG], xi[atCB], yi[atCB], xi[atCD2],
- yi[atCD2], &a, &b);
+ calc_vsite3_param(
+ xcom[0], ycom[0], xi[atCG], yi[atCG], xi[atCB], yi[atCB], xi[atCD2], yi[atCD2], &a, &b);
svmul(a, r_ij, t1);
svmul(b, r_ik, t2);
rvec_add(t1, t2, t1);
rvec_add(t1, x[ats[atCG]], (*newx)[atM[0]]);
- calc_vsite3_param(xcom[1], ycom[1], xi[atCG], yi[atCG], xi[atCB], yi[atCB], xi[atCD2],
- yi[atCD2], &a, &b);
+ calc_vsite3_param(
+ xcom[1], ycom[1], xi[atCG], yi[atCG], xi[atCB], yi[atCB], xi[atCD2], yi[atCD2], &a, &b);
svmul(a, r_ij, t1);
svmul(b, r_ik, t2);
rvec_add(t1, t2, t1);
(*newatom)[atM[j]].m = (*newatom)[atM[j]].mB = mM[j];
(*newatom)[atM[j]].q = (*newatom)[atM[j]].qB = 0.0;
(*newatom)[atM[j]].type = (*newatom)[atM[j]].typeB = tpM;
- (*newatom)[atM[j]].ptype = eptAtom;
+ (*newatom)[atM[j]].ptype = ParticleType::Atom;
(*newatom)[atM[j]].resind = at->atom[i0].resind;
(*newatom)[atM[j]].elem[0] = 'M';
(*newatom)[atM[j]].elem[1] = '\0';
{
if ((*vsite_type)[ats[i]] == F_VSITE3)
{
- calc_vsite3_param(xi[i], yi[i], xcom[0], ycom[0], xcom[1], ycom[1], xi[atCB], yi[atCB],
- &a, &b);
- add_vsite3_param(&plist[F_VSITE3], ats[i], add_shift + atM[0], add_shift + atM[1],
- ats[atCB], a, b);
+ calc_vsite3_param(
+ xi[i], yi[i], xcom[0], ycom[0], xcom[1], ycom[1], xi[atCB], yi[atCB], &a, &b);
+ add_vsite3_param(
+ &plist[F_VSITE3], ats[i], add_shift + atM[0], add_shift + atM[1], ats[atCB], a, b);
}
}
return nvsite;
bond_ch = get_ddb_bond(vsitetop, "TYR", "CD1", "HD1");
bond_co = get_ddb_bond(vsitetop, "TYR", "CZ", "OH");
bond_oh = get_ddb_bond(vsitetop, "TYR", "OH", "HH");
- angle_coh = DEG2RAD * get_ddb_angle(vsitetop, "TYR", "CZ", "OH", "HH");
+ angle_coh = gmx::c_deg2Rad * get_ddb_angle(vsitetop, "TYR", "CZ", "OH", "HH");
xi[atCG] = -bond_cc + bond_cc * std::cos(ANGLE_6RING);
xi[atCD1] = -bond_cc;
(*newatom)[atM].m = (*newatom)[atM].mB = mM;
(*newatom)[atM].q = (*newatom)[atM].qB = 0.0;
(*newatom)[atM].type = (*newatom)[atM].typeB = tpM;
- (*newatom)[atM].ptype = eptAtom;
+ (*newatom)[atM].ptype = ParticleType::Atom;
(*newatom)[atM].resind = at->atom[i0].resind;
(*newatom)[atM].elem[0] = 'M';
(*newatom)[atM].elem[1] = '\0';
b_CE1_NE2 = get_ddb_bond(vsitetop, resname, "CE1", "NE2");
b_CG_CD2 = get_ddb_bond(vsitetop, resname, "CG", "CD2");
b_CD2_NE2 = get_ddb_bond(vsitetop, resname, "CD2", "NE2");
- a_CG_ND1_CE1 = DEG2RAD * get_ddb_angle(vsitetop, resname, "CG", "ND1", "CE1");
- a_CG_CD2_NE2 = DEG2RAD * get_ddb_angle(vsitetop, resname, "CG", "CD2", "NE2");
- a_ND1_CE1_NE2 = DEG2RAD * get_ddb_angle(vsitetop, resname, "ND1", "CE1", "NE2");
- a_CE1_NE2_CD2 = DEG2RAD * get_ddb_angle(vsitetop, resname, "CE1", "NE2", "CD2");
+ a_CG_ND1_CE1 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, resname, "CG", "ND1", "CE1");
+ a_CG_CD2_NE2 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, resname, "CG", "CD2", "NE2");
+ a_ND1_CE1_NE2 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, resname, "ND1", "CE1", "NE2");
+ a_CE1_NE2_CD2 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, resname, "CE1", "NE2", "CD2");
if (ats[atHD1] != NOTSET)
{
b_ND1_HD1 = get_ddb_bond(vsitetop, resname, "ND1", "HD1");
- a_CE1_ND1_HD1 = DEG2RAD * get_ddb_angle(vsitetop, resname, "CE1", "ND1", "HD1");
+ a_CE1_ND1_HD1 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, resname, "CE1", "ND1", "HD1");
}
if (ats[atHE2] != NOTSET)
{
b_NE2_HE2 = get_ddb_bond(vsitetop, resname, "NE2", "HE2");
- a_CE1_NE2_HE2 = DEG2RAD * get_ddb_angle(vsitetop, resname, "CE1", "NE2", "HE2");
+ a_CE1_NE2_HE2 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, resname, "CE1", "NE2", "HE2");
}
if (ats[atHD2] != NOTSET)
{
b_CD2_HD2 = get_ddb_bond(vsitetop, resname, "CD2", "HD2");
- a_NE2_CD2_HD2 = DEG2RAD * get_ddb_angle(vsitetop, resname, "NE2", "CD2", "HD2");
+ a_NE2_CD2_HD2 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, resname, "NE2", "CD2", "HD2");
}
if (ats[atHE1] != NOTSET)
{
b_CE1_HE1 = get_ddb_bond(vsitetop, resname, "CE1", "HE1");
- a_NE2_CE1_HE1 = DEG2RAD * get_ddb_angle(vsitetop, resname, "NE2", "CE1", "HE1");
+ a_NE2_CE1_HE1 = gmx::c_deg2Rad * get_ddb_angle(vsitetop, resname, "NE2", "CE1", "HE1");
}
/* constraints between CG, CE1 and NE1 */
/* HE1 */
if (ats[atHE1] != NOTSET)
{
- calc_vsite3_param(x[atHE1], y[atHE1], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG],
- y[atCG], &a, &b);
+ calc_vsite3_param(
+ x[atHE1], y[atHE1], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG], y[atCG], &a, &b);
add_vsite3_param(&plist[F_VSITE3], ats[atHE1], ats[atCE1], ats[atNE2], ats[atCG], a, b);
}
/* HE2 */
if (ats[atHE2] != NOTSET)
{
- calc_vsite3_param(x[atHE2], y[atHE2], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG],
- y[atCG], &a, &b);
+ calc_vsite3_param(
+ x[atHE2], y[atHE2], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG], y[atCG], &a, &b);
add_vsite3_param(&plist[F_VSITE3], ats[atHE2], ats[atNE2], ats[atCE1], ats[atCG], a, b);
}
/* ND1 */
- calc_vsite3_param(x[atND1], y[atND1], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG], y[atCG],
- &a, &b);
+ calc_vsite3_param(
+ x[atND1], y[atND1], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG], y[atCG], &a, &b);
add_vsite3_param(&plist[F_VSITE3], ats[atND1], ats[atNE2], ats[atCE1], ats[atCG], a, b);
/* CD2 */
- calc_vsite3_param(x[atCD2], y[atCD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG], y[atCG],
- &a, &b);
+ calc_vsite3_param(
+ x[atCD2], y[atCD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG], y[atCG], &a, &b);
add_vsite3_param(&plist[F_VSITE3], ats[atCD2], ats[atCE1], ats[atNE2], ats[atCG], a, b);
/* HD1 */
if (ats[atHD1] != NOTSET)
{
- calc_vsite3_param(x[atHD1], y[atHD1], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG],
- y[atCG], &a, &b);
+ calc_vsite3_param(
+ x[atHD1], y[atHD1], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG], y[atCG], &a, &b);
add_vsite3_param(&plist[F_VSITE3], ats[atHD1], ats[atNE2], ats[atCE1], ats[atCG], a, b);
}
/* HD2 */
if (ats[atHD2] != NOTSET)
{
- calc_vsite3_param(x[atHD2], y[atHD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG],
- y[atCG], &a, &b);
+ calc_vsite3_param(
+ x[atHD2], y[atHD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG], y[atCG], &a, &b);
add_vsite3_param(&plist[F_VSITE3], ats[atHD2], ats[atCE1], ats[atNE2], ats[atCG], a, b);
}
return nvsite;
}
}
-static char atomnamesuffix[] = "1234";
+static const char atomnamesuffix[] = "1234";
void do_vsites(gmx::ArrayRef<const PreprocessResidue> rtpFFDB,
PreprocessingAtomTypes* atype,
/* the atnms for every residue MUST correspond to the enums in the
gen_vsites_* (one for each residue) routines! */
/* also the atom names in atnms MUST be in the same order as in the .rtp! */
- const char* atnms[resNR][MAXATOMSPERRESIDUE + 1] = {
- { "CG", /* PHE */
- "CD1", "HD1", "CD2", "HD2", "CE1", "HE1", "CE2", "HE2", "CZ", "HZ", nullptr },
- { "CB", /* TRP */
- "CG", "CD1", "HD1", "CD2", "NE1", "HE1", "CE2", "CE3", "HE3", "CZ2", "HZ2", "CZ3", "HZ3",
- "CH2", "HH2", nullptr },
- { "CG", /* TYR */
- "CD1", "HD1", "CD2", "HD2", "CE1", "HE1", "CE2", "HE2", "CZ", "OH", "HH", nullptr },
- { "CG", /* HIS */
- "ND1", "HD1", "CD2", "HD2", "CE1", "HE1", "NE2", "HE2", nullptr }
- };
+ const char* atnms[resNR][MAXATOMSPERRESIDUE + 1] = { { "CG", /* PHE */
+ "CD1",
+ "HD1",
+ "CD2",
+ "HD2",
+ "CE1",
+ "HE1",
+ "CE2",
+ "HE2",
+ "CZ",
+ "HZ",
+ nullptr },
+ { "CB", /* TRP */
+ "CG",
+ "CD1",
+ "HD1",
+ "CD2",
+ "NE1",
+ "HE1",
+ "CE2",
+ "CE3",
+ "HE3",
+ "CZ2",
+ "HZ2",
+ "CZ3",
+ "HZ3",
+ "CH2",
+ "HH2",
+ nullptr },
+ { "CG", /* TYR */
+ "CD1",
+ "HD1",
+ "CD2",
+ "HD2",
+ "CE1",
+ "HE1",
+ "CE2",
+ "HE2",
+ "CZ",
+ "OH",
+ "HH",
+ nullptr },
+ { "CG", /* HIS */
+ "ND1",
+ "HD1",
+ "CD2",
+ "HD2",
+ "CE1",
+ "HE1",
+ "NE2",
+ "HE2",
+ nullptr } };
if (debug)
{
/* make index to tell which residues were already processed */
std::vector<bool> bResProcessed(at->nres);
- ResidueType rt;
+ ResidueTypeMap residueTypeMap = residueTypeMapFromLibraryFile("residuetypes.dat");
/* generate vsite constructions */
/* loop over all atoms */
* N-terminus that must be treated first.
*/
if (bVsiteAromatics && (strcmp(*(at->atomname[i]), "CA") == 0) && !bResProcessed[resind]
- && rt.namedResidueHasType(*(at->resinfo[resind].name), "Protein"))
+ && namedResidueHasType(residueTypeMap, *(at->resinfo[resind].name), "Protein"))
{
/* mark this residue */
bResProcessed[resind] = TRUE;
"not enough atoms found (%d, need %d) in "
"residue %s %d while\n "
"generating aromatics virtual site construction",
- nrfound, needed, resnm, at->resinfo[resind].nr);
+ nrfound,
+ needed,
+ resnm,
+ at->resinfo[resind].nr);
}
/* Advance overall atom counter */
i++;
{
fprintf(stderr, "TRP at %d\n", o2n[ats[0]] + 1);
}
- nvsite += gen_vsites_trp(atype, &newx, &newatom, &newatomname, &o2n,
- &newvsite_type, &newcgnr, symtab, &nadd, *x, cgnr, at,
- vsite_type, plist, nrfound, ats, add_shift, vsitetop);
+ nvsite += gen_vsites_trp(atype,
+ &newx,
+ &newatom,
+ &newatomname,
+ &o2n,
+ &newvsite_type,
+ &newcgnr,
+ symtab,
+ &nadd,
+ *x,
+ cgnr,
+ at,
+ vsite_type,
+ plist,
+ nrfound,
+ ats,
+ add_shift,
+ vsitetop);
break;
case resTYR:
if (debug)
{
fprintf(stderr, "TYR at %d\n", o2n[ats[0]] + 1);
}
- nvsite += gen_vsites_tyr(atype, &newx, &newatom, &newatomname, &o2n,
- &newvsite_type, &newcgnr, symtab, &nadd, *x, cgnr, at,
- vsite_type, plist, nrfound, ats, add_shift, vsitetop);
+ nvsite += gen_vsites_tyr(atype,
+ &newx,
+ &newatom,
+ &newatomname,
+ &o2n,
+ &newvsite_type,
+ &newcgnr,
+ symtab,
+ &nadd,
+ *x,
+ cgnr,
+ at,
+ vsite_type,
+ plist,
+ nrfound,
+ ats,
+ add_shift,
+ vsitetop);
break;
case resHIS:
if (debug)
{
/* find heavy atom, count #bonds from it and #H atoms bound to it
and return H atom numbers (Hatoms) and heavy atom numbers (heavies) */
- count_bonds(i, &plist[F_BONDS], at->atomname, &nrbonds, &nrHatoms, Hatoms, &Heavy,
- &nrheavies, heavies);
+ count_bonds(i, &plist[F_BONDS], at->atomname, &nrbonds, &nrHatoms, Hatoms, &Heavy, &nrheavies, heavies);
/* get Heavy atom type */
- tpHeavy = get_atype(Heavy, at, rtpFFDB, &rt);
- strcpy(tpname, atype->atomNameFromAtomType(tpHeavy));
+ tpHeavy = get_atype(Heavy, at, rtpFFDB, residueTypeMap);
+ strcpy(tpname, *atype->atomNameFromAtomType(tpHeavy));
bWARNING = FALSE;
bAddVsiteParam = TRUE;
/* get dummy mass type from first char of heavy atom type (N or C) */
strcpy(nexttpname,
- atype->atomNameFromAtomType(get_atype(heavies[0], at, rtpFFDB, &rt)));
+ *atype->atomNameFromAtomType(get_atype(heavies[0], at, rtpFFDB, residueTypeMap)));
std::string ch = get_dummymass_name(vsiteconflist, tpname, nexttpname);
std::string name;
if (ch.empty())
FARGS,
"Can't find dummy mass for type %s bonded to type %s in the "
"virtual site database (.vsd files). Add it to the database!\n",
- tpname, nexttpname);
+ tpname,
+ nexttpname);
}
else
{
gmx_fatal(FARGS,
"A dummy mass for type %s bonded to type %s is required, but "
"no virtual site database (.vsd) files where found.\n",
- tpname, nexttpname);
+ tpname,
+ nexttpname);
}
}
else
/* get atom masses, and set Heavy and Hatoms mass to zero */
for (int j = 0; j < nrHatoms; j++)
{
- mHtot += get_amass(Hatoms[j], at, rtpFFDB, &rt);
+ mHtot += get_amass(Hatoms[j], at, rtpFFDB, residueTypeMap);
at->atom[Hatoms[j]].m = at->atom[Hatoms[j]].mB = 0;
}
- mtot = mHtot + get_amass(Heavy, at, rtpFFDB, &rt);
+ mtot = mHtot + get_amass(Heavy, at, rtpFFDB, residueTypeMap);
at->atom[Heavy].m = at->atom[Heavy].mB = 0;
if (mHmult != 1.0)
{
newatom[ni0 + j].m = newatom[ni0 + j].mB = mtot / NMASS;
newatom[ni0 + j].q = newatom[ni0 + j].qB = 0.0;
newatom[ni0 + j].type = newatom[ni0 + j].typeB = tpM;
- newatom[ni0 + j].ptype = eptAtom;
+ newatom[ni0 + j].ptype = ParticleType::Atom;
newatom[ni0 + j].resind = at->atom[i0].resind;
newatom[ni0 + j].elem[0] = 'M';
newatom[ni0 + j].elem[1] = '\0';
/* generate Heavy, H1, H2 and H3 from M1, M2 and heavies[0] */
/* note that vsite_type cannot be NOTSET, because we just set it */
- add_vsite3_atoms(&plist[(*vsite_type)[Heavy]], Heavy, heavies[0],
- add_shift + ni0, add_shift + ni0 + 1, FALSE);
+ add_vsite3_atoms(&plist[(*vsite_type)[Heavy]],
+ Heavy,
+ heavies[0],
+ add_shift + ni0,
+ add_shift + ni0 + 1,
+ FALSE);
for (int j = 0; j < nrHatoms; j++)
{
- add_vsite3_atoms(&plist[(*vsite_type)[Hatoms[j]]], Hatoms[j], heavies[0],
- add_shift + ni0, add_shift + ni0 + 1, Hat_SwapParity[j]);
+ add_vsite3_atoms(&plist[(*vsite_type)[Hatoms[j]]],
+ Hatoms[j],
+ heavies[0],
+ add_shift + ni0,
+ add_shift + ni0 + 1,
+ Hat_SwapParity[j]);
}
#undef NMASS
}
"Cannot convert atom %d %s (bound to a heavy atom "
"%s with \n"
" %d bonds and %d bound hydrogens atoms) to virtual site\n",
- i + 1, *(at->atomname[i]), tpname, nrbonds, nrHatoms);
+ i + 1,
+ *(at->atomname[i]),
+ tpname,
+ nrbonds,
+ nrHatoms);
}
if (bAddVsiteParam)
{
fprintf(debug, "Before inserting new atoms:\n");
for (int i = 0; i < at->nr; i++)
{
- fprintf(debug, "%4d %4d %4s %4d %4s %6d %-10s\n", i + 1, o2n[i] + 1,
- at->atomname[i] ? *(at->atomname[i]) : "(NULL)", at->resinfo[at->atom[i].resind].nr,
+ fprintf(debug,
+ "%4d %4d %4s %4d %4s %6d %-10s\n",
+ i + 1,
+ o2n[i] + 1,
+ at->atomname[i] ? *(at->atomname[i]) : "(NULL)",
+ at->resinfo[at->atom[i].resind].nr,
at->resinfo[at->atom[i].resind].name ? *(at->resinfo[at->atom[i].resind].name) : "(NULL)",
(*cgnr)[i],
((*vsite_type)[i] == NOTSET) ? "NOTSET" : interaction_function[(*vsite_type)[i]].name);
{
if (newatomname[i])
{
- fprintf(debug, "%4d %4s %4d %6d %-10s\n", i + 1,
- newatomname[i] ? *(newatomname[i]) : "(NULL)", newatom[i].resind, newcgnr[i],
+ fprintf(debug,
+ "%4d %4s %4d %6d %-10s\n",
+ i + 1,
+ newatomname[i] ? *(newatomname[i]) : "(NULL)",
+ newatom[i].resind,
+ newcgnr[i],
(newvsite_type[i] == NOTSET) ? "NOTSET"
: interaction_function[newvsite_type[i]].name);
}
gmx_fatal(FARGS,
"Added impossible amount of dummy masses "
"(%d on a total of %d atoms)\n",
- nadd, at->nr - nadd);
+ nadd,
+ at->nr - nadd);
}
if (debug)
fprintf(debug, "After inserting new atoms:\n");
for (int i = 0; i < at->nr; i++)
{
- fprintf(debug, "%4d %4s %4d %4s %6d %-10s\n", i + 1,
- at->atomname[i] ? *(at->atomname[i]) : "(NULL)", at->resinfo[at->atom[i].resind].nr,
+ fprintf(debug,
+ "%4d %4s %4d %4s %6d %-10s\n",
+ i + 1,
+ at->atomname[i] ? *(at->atomname[i]) : "(NULL)",
+ at->resinfo[at->atom[i].resind].nr,
at->resinfo[at->atom[i].resind].name ? *(at->resinfo[at->atom[i].resind].name) : "(NULL)",
(*cgnr)[i],
((*vsite_type)[i] == NOTSET) ? "NOTSET" : interaction_function[(*vsite_type)[i]].name);
/* find bonded heavy atom */
int a = NOTSET;
for (auto parm = psb->interactionTypes.begin();
- (parm != psb->interactionTypes.end()) && (a == NOTSET); parm++)
+ (parm != psb->interactionTypes.end()) && (a == NOTSET);
+ parm++)
{
/* if other atom is not a virtual site, it is the one we want */
if ((parm->ai() == i) && !is_vsite(vsite_type[parm->aj()]))
#include <algorithm>
#include <memory>
+#include <numeric>
#include <string>
#include "gromacs/applied_forces/awh/read_params.h"
#include "gromacs/gmxpreprocess/toputil.h"
#include "gromacs/math/functions.h"
#include "gromacs/math/units.h"
+#include "gromacs/math/utilities.h"
#include "gromacs/math/vec.h"
#include "gromacs/mdlib/calc_verletbuf.h"
+#include "gromacs/mdlib/vcm.h"
#include "gromacs/mdrun/mdmodules.h"
+#include "gromacs/mdtypes/awh_params.h"
#include "gromacs/mdtypes/inputrec.h"
#include "gromacs/mdtypes/md_enums.h"
#include "gromacs/mdtypes/multipletimestepping.h"
#include "gromacs/utility/keyvaluetreebuilder.h"
#include "gromacs/utility/keyvaluetreemdpwriter.h"
#include "gromacs/utility/keyvaluetreetransform.h"
-#include "gromacs/utility/mdmodulenotification.h"
+#include "gromacs/utility/mdmodulesnotifiers.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/strconvert.h"
#include "gromacs/utility/stringcompare.h"
#include "gromacs/utility/stringutil.h"
#include "gromacs/utility/textwriter.h"
-#define MAXPTR 254
#define NOGID 255
using gmx::BasicVector;
struct gmx_inputrec_strings
{
- char tcgrps[STRLEN], tau_t[STRLEN], ref_t[STRLEN], acc[STRLEN], accgrps[STRLEN], freeze[STRLEN],
- frdim[STRLEN], energy[STRLEN], user1[STRLEN], user2[STRLEN], vcm[STRLEN],
- x_compressed_groups[STRLEN], couple_moltype[STRLEN], orirefitgrp[STRLEN],
- egptable[STRLEN], egpexcl[STRLEN], wall_atomtype[STRLEN], wall_density[STRLEN],
- deform[STRLEN], QMMM[STRLEN], imd_grp[STRLEN];
- char fep_lambda[efptNR][STRLEN];
- char lambda_weights[STRLEN];
- std::vector<std::string> pullGroupNames;
- std::vector<std::string> rotateGroupNames;
+ char tcgrps[STRLEN], tau_t[STRLEN], ref_t[STRLEN], freeze[STRLEN], frdim[STRLEN],
+ energy[STRLEN], user1[STRLEN], user2[STRLEN], vcm[STRLEN], x_compressed_groups[STRLEN],
+ couple_moltype[STRLEN], orirefitgrp[STRLEN], egptable[STRLEN], egpexcl[STRLEN],
+ wall_atomtype[STRLEN], wall_density[STRLEN], deform[STRLEN], QMMM[STRLEN], imd_grp[STRLEN];
+ gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, std::string> fep_lambda;
+ char lambda_weights[STRLEN];
+ std::vector<std::string> pullGroupNames;
+ std::vector<std::string> rotateGroupNames;
char anneal[STRLEN], anneal_npoints[STRLEN], anneal_time[STRLEN], anneal_temp[STRLEN];
};
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static gmx_inputrec_strings* inputrecStrings = nullptr;
void init_inputrec_strings()
* make a rest group for the remaining particles. */
};
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static const char* constraints[eshNR + 1] = { "none", "h-bonds", "all-bonds",
"h-angles", "all-angles", nullptr };
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static const char* couple_lam[ecouplamNR + 1] = { "vdw-q", "vdw", "q", "none", nullptr };
-static void GetSimTemps(int ntemps, t_simtemp* simtemp, double* temperature_lambdas)
+static void getSimTemps(int ntemps, t_simtemp* simtemp, gmx::ArrayRef<double> temperature_lambdas)
{
int i;
for (i = 0; i < ntemps; i++)
{
/* simple linear scaling -- allows more control */
- if (simtemp->eSimTempScale == esimtempLINEAR)
+ if (simtemp->eSimTempScale == SimulatedTempering::Linear)
{
simtemp->temperatures[i] =
simtemp->simtemp_low
+ (simtemp->simtemp_high - simtemp->simtemp_low) * temperature_lambdas[i];
}
else if (simtemp->eSimTempScale
- == esimtempGEOMETRIC) /* should give roughly equal acceptance for constant heat capacity . . . */
+ == SimulatedTempering::Geometric) /* should give roughly equal acceptance for constant heat capacity . . . */
{
simtemp->temperatures[i] = simtemp->simtemp_low
* std::pow(simtemp->simtemp_high / simtemp->simtemp_low,
static_cast<real>((1.0 * i) / (ntemps - 1)));
}
- else if (simtemp->eSimTempScale == esimtempEXPONENTIAL)
+ else if (simtemp->eSimTempScale == SimulatedTempering::Exponential)
{
simtemp->temperatures[i] = simtemp->simtemp_low
+ (simtemp->simtemp_high - simtemp->simtemp_low)
else
{
char errorstr[128];
- sprintf(errorstr, "eSimTempScale=%d not defined", simtemp->eSimTempScale);
+ sprintf(errorstr, "eSimTempScale=%s not defined", enumValueToString(simtemp->eSimTempScale));
gmx_fatal(FARGS, "%s", errorstr);
}
}
}
}
-static int lcd(int n1, int n2)
-{
- int d, i;
-
- d = 1;
- for (i = 2; (i <= n1 && i <= n2); i++)
- {
- if (n1 % i == 0 && n2 % i == 0)
- {
- d = i;
- }
- }
-
- return d;
-}
-
//! Convert legacy mdp entries to modern ones.
-static void process_interaction_modifier(int* eintmod)
-{
- if (*eintmod == eintmodPOTSHIFT_VERLET_UNSUPPORTED)
- {
- *eintmod = eintmodPOTSHIFT;
- }
-}
-
-static void checkMtsRequirement(const t_inputrec& ir, const char* param, const int nstValue, warninp_t wi)
+static void process_interaction_modifier(InteractionModifiers* eintmod)
{
- GMX_RELEASE_ASSERT(ir.mtsLevels.size() >= 2, "Need at least two levels for MTS");
- const int mtsFactor = ir.mtsLevels.back().stepFactor;
- if (nstValue % mtsFactor != 0)
+ if (*eintmod == InteractionModifiers::PotShiftVerletUnsupported)
{
- auto message = gmx::formatString(
- "With MTS, %s = %d should be a multiple of mts-factor = %d", param, nstValue, mtsFactor);
- warning_error(wi, message.c_str());
+ *eintmod = InteractionModifiers::PotShift;
}
}
-static void setupMtsLevels(gmx::ArrayRef<gmx::MtsLevel> mtsLevels,
- const t_inputrec& ir,
- const t_gromppopts& opts,
- warninp_t wi)
-{
- /* MD-VV has no MTS support yet.
- * SD1 needs different scaling coefficients for the different MTS forces
- * and the different forces are currently not available in ForceBuffers.
- */
- if (ir.eI != eiMD)
- {
- auto message = gmx::formatString(
- "Multiple time stepping is only supported with integrator %s", ei_names[eiMD]);
- warning_error(wi, message.c_str());
- }
- if (opts.numMtsLevels != 2)
- {
- warning_error(wi, "Only mts-levels = 2 is supported");
- }
- else
- {
- const std::vector<std::string> inputForceGroups = gmx::splitString(opts.mtsLevel2Forces);
- auto& forceGroups = mtsLevels[1].forceGroups;
- for (const auto& inputForceGroup : inputForceGroups)
- {
- bool found = false;
- int nameIndex = 0;
- for (const auto& forceGroupName : gmx::mtsForceGroupNames)
- {
- if (gmx::equalCaseInsensitive(inputForceGroup, forceGroupName))
- {
- forceGroups.set(nameIndex);
- found = true;
- }
- nameIndex++;
- }
- if (!found)
- {
- auto message =
- gmx::formatString("Unknown MTS force group '%s'", inputForceGroup.c_str());
- warning_error(wi, message.c_str());
- }
- }
-
- if (mtsLevels[1].stepFactor <= 1)
- {
- gmx_fatal(FARGS, "mts-factor should be larger than 1");
- }
-
- // Make the level 0 use the complement of the force groups of group 1
- mtsLevels[0].forceGroups = ~mtsLevels[1].forceGroups;
- mtsLevels[0].stepFactor = 1;
-
- if ((EEL_FULL(ir.coulombtype) || EVDW_PME(ir.vdwtype))
- && !mtsLevels[1].forceGroups[static_cast<int>(gmx::MtsForceGroups::LongrangeNonbonded)])
- {
- warning_error(wi,
- "With long-range electrostatics and/or LJ treatment, the long-range part "
- "has to be part of the mts-level2-forces");
- }
-
- if (ir.nstcalcenergy > 0)
- {
- checkMtsRequirement(ir, "nstcalcenergy", ir.nstcalcenergy, wi);
- }
- checkMtsRequirement(ir, "nstenergy", ir.nstenergy, wi);
- checkMtsRequirement(ir, "nstlog", ir.nstlog, wi);
- if (ir.efep != efepNO)
- {
- checkMtsRequirement(ir, "nstdhdl", ir.fepvals->nstdhdl, wi);
- }
-
- if (ir.bPull)
- {
- const int pullMtsLevel = gmx::forceGroupMtsLevel(ir.mtsLevels, gmx::MtsForceGroups::Pull);
- if (ir.pull->nstxout % ir.mtsLevels[pullMtsLevel].stepFactor != 0)
- {
- warning_error(wi, "pull-nstxout should be a multiple of mts-factor");
- }
- if (ir.pull->nstfout % ir.mtsLevels[pullMtsLevel].stepFactor != 0)
- {
- warning_error(wi, "pull-nstfout should be a multiple of mts-factor");
- }
- }
- }
-}
-
-void check_ir(const char* mdparin,
- const gmx::MdModulesNotifier& mdModulesNotifier,
- t_inputrec* ir,
- t_gromppopts* opts,
- warninp_t wi)
+void check_ir(const char* mdparin,
+ const gmx::MDModulesNotifiers& mdModulesNotifiers,
+ t_inputrec* ir,
+ t_gromppopts* opts,
+ warninp_t wi)
/* Check internal consistency.
* NOTE: index groups are not set here yet, don't check things
* like temperature coupling group options here, but in triple_check
char err_buf[256], warn_buf[STRLEN];
int i, j;
real dt_pcoupl;
- t_lambda* fep = ir->fepvals;
- t_expanded* expand = ir->expandedvals;
+ t_lambda* fep = ir->fepvals.get();
+ t_expanded* expand = ir->expandedvals.get();
set_warning_line(wi, mdparin, -1);
- if (ir->coulombtype == eelRF_NEC_UNSUPPORTED)
+ /* We cannot check MTS requirements with an invalid MTS setup
+ * and we will already have generated errors with an invalid MTS setup.
+ */
+ if (gmx::haveValidMtsSetup(*ir))
{
- sprintf(warn_buf, "%s electrostatics is no longer supported", eel_names[eelRF_NEC_UNSUPPORTED]);
- warning_error(wi, warn_buf);
+ std::vector<std::string> errorMessages = gmx::checkMtsRequirements(*ir);
+
+ for (const auto& errorMessage : errorMessages)
+ {
+ warning_error(wi, errorMessage.c_str());
+ }
+ }
+
+ if (ir->coulombtype == CoulombInteractionType::RFNecUnsupported)
+ {
+ std::string message =
+ gmx::formatString("%s electrostatics is no longer supported",
+ enumValueToString(CoulombInteractionType::RFNecUnsupported));
+ warning_error(wi, message);
}
/* BASIC CUT-OFF STUFF */
{
warning_error(wi, "rvdw should be >= 0");
}
- if (ir->rlist < 0 && !(ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0))
+ if (ir->rlist < 0 && !(ir->cutoff_scheme == CutoffScheme::Verlet && ir->verletbuf_tol > 0))
{
warning_error(wi, "rlist should be >= 0");
}
process_interaction_modifier(&ir->coulomb_modifier);
process_interaction_modifier(&ir->vdw_modifier);
- if (ir->cutoff_scheme == ecutsGROUP)
+ if (ir->cutoff_scheme == CutoffScheme::Group)
{
gmx_fatal(FARGS,
"The group cutoff scheme has been removed since GROMACS 2020. "
"Please use the Verlet cutoff scheme.");
}
- if (ir->cutoff_scheme == ecutsVERLET)
+ if (ir->cutoff_scheme == CutoffScheme::Verlet)
{
real rc_max;
{
// Since we have PME coulomb + LJ cut-off kernels with rcoulomb>rvdw
// for PME load balancing, we can support this exception.
- bool bUsesPmeTwinRangeKernel = (EEL_PME_EWALD(ir->coulombtype) && ir->vdwtype == evdwCUT
- && ir->rcoulomb > ir->rvdw);
+ bool bUsesPmeTwinRangeKernel =
+ (EEL_PME_EWALD(ir->coulombtype) && ir->vdwtype == VanDerWaalsType::Cut
+ && ir->rcoulomb > ir->rvdw);
if (!bUsesPmeTwinRangeKernel)
{
warning_error(wi,
}
}
- if (ir->vdwtype == evdwSHIFT || ir->vdwtype == evdwSWITCH)
+ if (ir->vdwtype == VanDerWaalsType::Shift || ir->vdwtype == VanDerWaalsType::Switch)
{
- if (ir->vdw_modifier == eintmodNONE || ir->vdw_modifier == eintmodPOTSHIFT)
+ if (ir->vdw_modifier == InteractionModifiers::None
+ || ir->vdw_modifier == InteractionModifiers::PotShift)
{
- ir->vdw_modifier = (ir->vdwtype == evdwSHIFT ? eintmodFORCESWITCH : eintmodPOTSWITCH);
+ ir->vdw_modifier =
+ (ir->vdwtype == VanDerWaalsType::Shift ? InteractionModifiers::ForceSwitch
+ : InteractionModifiers::PotSwitch);
sprintf(warn_buf,
"Replacing vdwtype=%s by the equivalent combination of vdwtype=%s and "
"vdw_modifier=%s",
- evdw_names[ir->vdwtype], evdw_names[evdwCUT], eintmod_names[ir->vdw_modifier]);
+ enumValueToString(ir->vdwtype),
+ enumValueToString(VanDerWaalsType::Cut),
+ enumValueToString(ir->vdw_modifier));
warning_note(wi, warn_buf);
- ir->vdwtype = evdwCUT;
+ ir->vdwtype = VanDerWaalsType::Cut;
}
else
{
- sprintf(warn_buf, "Unsupported combination of vdwtype=%s and vdw_modifier=%s",
- evdw_names[ir->vdwtype], eintmod_names[ir->vdw_modifier]);
+ sprintf(warn_buf,
+ "Unsupported combination of vdwtype=%s and vdw_modifier=%s",
+ enumValueToString(ir->vdwtype),
+ enumValueToString(ir->vdw_modifier));
warning_error(wi, warn_buf);
}
}
- if (!(ir->vdwtype == evdwCUT || ir->vdwtype == evdwPME))
+ if (!(ir->vdwtype == VanDerWaalsType::Cut || ir->vdwtype == VanDerWaalsType::Pme))
{
warning_error(wi,
"With Verlet lists only cut-off and PME LJ interactions are supported");
}
- if (!(ir->coulombtype == eelCUT || EEL_RF(ir->coulombtype) || EEL_PME(ir->coulombtype)
- || ir->coulombtype == eelEWALD))
+ if (!(ir->coulombtype == CoulombInteractionType::Cut || EEL_RF(ir->coulombtype)
+ || EEL_PME(ir->coulombtype) || ir->coulombtype == CoulombInteractionType::Ewald))
{
warning_error(wi,
"With Verlet lists only cut-off, reaction-field, PME and Ewald "
"electrostatics are supported");
}
- if (!(ir->coulomb_modifier == eintmodNONE || ir->coulomb_modifier == eintmodPOTSHIFT))
+ if (!(ir->coulomb_modifier == InteractionModifiers::None
+ || ir->coulomb_modifier == InteractionModifiers::PotShift))
{
- sprintf(warn_buf, "coulomb_modifier=%s is not supported", eintmod_names[ir->coulomb_modifier]);
+ sprintf(warn_buf, "coulomb_modifier=%s is not supported", enumValueToString(ir->coulomb_modifier));
warning_error(wi, warn_buf);
}
if (EEL_USER(ir->coulombtype))
{
- sprintf(warn_buf, "Coulomb type %s is not supported with the verlet scheme",
- eel_names[ir->coulombtype]);
+ sprintf(warn_buf,
+ "Coulomb type %s is not supported with the verlet scheme",
+ enumValueToString(ir->coulombtype));
warning_error(wi, warn_buf);
}
/* GENERAL INTEGRATOR STUFF */
if (!EI_MD(ir->eI))
{
- if (ir->etc != etcNO)
+ if (ir->etc != TemperatureCoupling::No)
{
if (EI_RANDOM(ir->eI))
{
"Setting tcoupl from '%s' to 'no'. %s handles temperature coupling "
"implicitly. See the documentation for more information on which "
"parameters affect temperature for %s.",
- etcoupl_names[ir->etc], ei_names[ir->eI], ei_names[ir->eI]);
+ enumValueToString(ir->etc),
+ enumValueToString(ir->eI),
+ enumValueToString(ir->eI));
}
else
{
sprintf(warn_buf,
"Setting tcoupl from '%s' to 'no'. Temperature coupling does not apply to "
"%s.",
- etcoupl_names[ir->etc], ei_names[ir->eI]);
+ enumValueToString(ir->etc),
+ enumValueToString(ir->eI));
}
warning_note(wi, warn_buf);
}
- ir->etc = etcNO;
+ ir->etc = TemperatureCoupling::No;
}
- if (ir->eI == eiVVAK)
+ if (ir->eI == IntegrationAlgorithm::VVAK)
{
sprintf(warn_buf,
"Integrator method %s is implemented primarily for validation purposes; for "
"molecular dynamics, you should probably be using %s or %s",
- ei_names[eiVVAK], ei_names[eiMD], ei_names[eiVV]);
+ enumValueToString(IntegrationAlgorithm::VVAK),
+ enumValueToString(IntegrationAlgorithm::MD),
+ enumValueToString(IntegrationAlgorithm::VV));
warning_note(wi, warn_buf);
}
if (!EI_DYNAMICS(ir->eI))
{
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
sprintf(warn_buf,
"Setting pcoupl from '%s' to 'no'. Pressure coupling does not apply to %s.",
- epcoupl_names[ir->epc], ei_names[ir->eI]);
+ enumValueToString(ir->epc),
+ enumValueToString(ir->eI));
warning_note(wi, warn_buf);
}
- ir->epc = epcNO;
+ ir->epc = PressureCoupling::No;
}
if (EI_DYNAMICS(ir->eI))
{
*/
if (ir->nstlist > 0)
{
- ir->nstcalcenergy = lcd(ir->nstenergy, ir->nstlist);
+ ir->nstcalcenergy = std::gcd(ir->nstenergy, ir->nstlist);
}
else
{
}
}
else if ((ir->nstenergy > 0 && ir->nstcalcenergy > ir->nstenergy)
- || (ir->efep != efepNO && ir->fepvals->nstdhdl > 0
+ || (ir->efep != FreeEnergyPerturbationType::No && ir->fepvals->nstdhdl > 0
&& (ir->nstcalcenergy > ir->fepvals->nstdhdl)))
{
int min_nst = ir->nstenergy;
/* find the smallest of ( nstenergy, nstdhdl ) */
- if (ir->efep != efepNO && ir->fepvals->nstdhdl > 0
+ if (ir->efep != FreeEnergyPerturbationType::No && ir->fepvals->nstdhdl > 0
&& (ir->nstenergy == 0 || ir->fepvals->nstdhdl < ir->nstenergy))
{
min_nst = ir->fepvals->nstdhdl;
min_name = nstdh;
}
/* If the user sets nstenergy small, we should respect that */
- sprintf(warn_buf, "Setting nstcalcenergy (%d) equal to %s (%d)", ir->nstcalcenergy,
- min_name, min_nst);
+ sprintf(warn_buf, "Setting nstcalcenergy (%d) equal to %s (%d)", ir->nstcalcenergy, min_name, min_nst);
warning_note(wi, warn_buf);
ir->nstcalcenergy = min_nst;
}
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
if (ir->nstpcouple < 0)
{
if (ir->nstcalcenergy > 0)
{
- if (ir->efep != efepNO)
+ if (ir->efep != FreeEnergyPerturbationType::No)
{
/* nstdhdl should be a multiple of nstcalcenergy */
check_nst("nstcalcenergy", ir->nstcalcenergy, "nstdhdl", &ir->fepvals->nstdhdl, wi);
if (ir->bExpanded)
{
/* nstexpanded should be a multiple of nstcalcenergy */
- check_nst("nstcalcenergy", ir->nstcalcenergy, "nstexpanded",
- &ir->expandedvals->nstexpanded, wi);
+ check_nst("nstcalcenergy", ir->nstcalcenergy, "nstexpanded", &ir->expandedvals->nstexpanded, wi);
}
/* for storing exact averages nstenergy should be
* a multiple of nstcalcenergy
check_nst("nstcalcenergy", ir->nstcalcenergy, "nstenergy", &ir->nstenergy, wi);
}
- // Inquire all MdModules, if their parameters match with the energy
+ // Inquire all MDModules, if their parameters match with the energy
// calculation frequency
gmx::EnergyCalculationFrequencyErrors energyCalculationFrequencyErrors(ir->nstcalcenergy);
- mdModulesNotifier.preProcessingNotifications_.notify(&energyCalculationFrequencyErrors);
+ mdModulesNotifiers.preProcessingNotifier_.notify(&energyCalculationFrequencyErrors);
// Emit all errors from the energy calculation frequency checks
for (const std::string& energyFrequencyErrorMessage :
}
/* LD STUFF */
- if ((EI_SD(ir->eI) || ir->eI == eiBD) && ir->bContinuation && ir->ld_seed != -1)
+ if ((EI_SD(ir->eI) || ir->eI == IntegrationAlgorithm::BD) && ir->bContinuation && ir->ld_seed != -1)
{
warning_note(wi,
"You are doing a continuation with SD or BD, make sure that ld_seed is "
warning(wi, warn_buf);
}
- if ((EI_SD(ir->eI) || ir->eI == eiBD) && ir->bContinuation && ir->ld_seed != -1)
+ if ((EI_SD(ir->eI) || ir->eI == IntegrationAlgorithm::BD) && ir->bContinuation && ir->ld_seed != -1)
{
warning_note(wi,
"You are doing a continuation with SD or BD, make sure that ld_seed is "
bool bAllTempZero = TRUE;
for (i = 0; i < fep->n_lambda; i++)
{
- sprintf(err_buf, "Entry %d for %s must be between 0 and 1, instead is %g", i,
- efpt_names[efptTEMPERATURE], fep->all_lambda[efptTEMPERATURE][i]);
- CHECK((fep->all_lambda[efptTEMPERATURE][i] < 0) || (fep->all_lambda[efptTEMPERATURE][i] > 1));
- if (fep->all_lambda[efptTEMPERATURE][i] > 0)
+ sprintf(err_buf,
+ "Entry %d for %s must be between 0 and 1, instead is %g",
+ i,
+ enumValueToString(FreeEnergyPerturbationCouplingType::Temperature),
+ fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Temperature)][i]);
+ CHECK((fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Temperature)][i] < 0)
+ || (fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Temperature)][i]
+ > 1));
+ if (fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Temperature)][i] > 0)
{
bAllTempZero = FALSE;
}
CHECK(bAllTempZero == TRUE);
sprintf(err_buf, "Simulated tempering is currently only compatible with md-vv");
- CHECK(ir->eI != eiVV);
+ CHECK(ir->eI != IntegrationAlgorithm::VV);
/* check compatability of the temperature coupling with simulated tempering */
- if (ir->etc == etcNOSEHOOVER)
+ if (ir->etc == TemperatureCoupling::NoseHoover)
{
sprintf(warn_buf,
"Nose-Hoover based temperature control such as [%s] my not be "
"entirelyconsistent with simulated tempering",
- etcoupl_names[ir->etc]);
+ enumValueToString(ir->etc));
warning_note(wi, warn_buf);
}
sprintf(err_buf,
"Higher simulated tempering temperature (%g) must be >= than the simulated "
"tempering lower temperature (%g)",
- ir->simtempvals->simtemp_high, ir->simtempvals->simtemp_low);
+ ir->simtempvals->simtemp_high,
+ ir->simtempvals->simtemp_low);
CHECK(ir->simtempvals->simtemp_high <= ir->simtempvals->simtemp_low);
- sprintf(err_buf, "Higher simulated tempering temperature (%g) must be >= zero",
+ sprintf(err_buf,
+ "Higher simulated tempering temperature (%g) must be >= zero",
ir->simtempvals->simtemp_high);
CHECK(ir->simtempvals->simtemp_high <= 0);
- sprintf(err_buf, "Lower simulated tempering temperature (%g) must be >= zero",
+ sprintf(err_buf,
+ "Lower simulated tempering temperature (%g) must be >= zero",
ir->simtempvals->simtemp_low);
CHECK(ir->simtempvals->simtemp_low <= 0);
}
/* verify free energy options */
- if (ir->efep != efepNO)
+ if (ir->efep != FreeEnergyPerturbationType::No)
{
- fep = ir->fepvals;
+ fep = ir->fepvals.get();
sprintf(err_buf, "The soft-core power is %d and can only be 1 or 2", fep->sc_power);
CHECK(fep->sc_alpha != 0 && fep->sc_power != 1 && fep->sc_power != 2);
fep->delta_lambda);
CHECK(fep->delta_lambda > 0 && ((fep->init_fep_state > 0) || (fep->init_lambda > 0)));
- sprintf(err_buf, "Can't use positive delta-lambda (%g) with expanded ensemble simulations",
+ sprintf(err_buf,
+ "Can't use positive delta-lambda (%g) with expanded ensemble simulations",
fep->delta_lambda);
- CHECK(fep->delta_lambda > 0 && (ir->efep == efepEXPANDED));
+ CHECK(fep->delta_lambda > 0 && (ir->efep == FreeEnergyPerturbationType::Expanded));
sprintf(err_buf, "Can only use expanded ensemble with md-vv (for now)");
- CHECK(!(EI_VV(ir->eI)) && (ir->efep == efepEXPANDED));
+ CHECK(!(EI_VV(ir->eI)) && (ir->efep == FreeEnergyPerturbationType::Expanded));
sprintf(err_buf, "Free-energy not implemented for Ewald");
- CHECK(ir->coulombtype == eelEWALD);
+ CHECK(ir->coulombtype == CoulombInteractionType::Ewald);
/* check validty of lambda inputs */
if (fep->n_lambda == 0)
{
/* Clear output in case of no states:*/
- sprintf(err_buf, "init-lambda-state set to %d: no lambda states are defined.",
- fep->init_fep_state);
+ sprintf(err_buf, "init-lambda-state set to %d: no lambda states are defined.", fep->init_fep_state);
CHECK((fep->init_fep_state >= 0) && (fep->n_lambda == 0));
}
else
{
- sprintf(err_buf, "initial thermodynamic state %d does not exist, only goes to %d",
- fep->init_fep_state, fep->n_lambda - 1);
+ sprintf(err_buf,
+ "initial thermodynamic state %d does not exist, only goes to %d",
+ fep->init_fep_state,
+ fep->n_lambda - 1);
CHECK((fep->init_fep_state >= fep->n_lambda));
}
sprintf(err_buf,
"init-lambda=%g while init-lambda-state=%d. Lambda state must be set either with "
"init-lambda-state or with init-lambda, but not both",
- fep->init_lambda, fep->init_fep_state);
+ fep->init_lambda,
+ fep->init_fep_state);
CHECK((fep->init_fep_state >= 0) && (fep->init_lambda >= 0));
{
int n_lambda_terms;
n_lambda_terms = 0;
- for (i = 0; i < efptNR; i++)
+ for (i = 0; i < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); i++)
{
if (fep->separate_dvdl[i])
{
}
}
- for (j = 0; j < efptNR; j++)
+ for (j = 0; j < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); j++)
{
for (i = 0; i < fep->n_lambda; i++)
{
- sprintf(err_buf, "Entry %d for %s must be between 0 and 1, instead is %g", i,
- efpt_names[j], fep->all_lambda[j][i]);
+ auto enumValue = static_cast<FreeEnergyPerturbationCouplingType>(j);
+ sprintf(err_buf,
+ "Entry %d for %s must be between 0 and 1, instead is %g",
+ i,
+ enumValueToString(enumValue),
+ fep->all_lambda[j][i]);
CHECK((fep->all_lambda[j][i] < 0) || (fep->all_lambda[j][i] > 1));
}
}
"For state %d, vdw-lambdas (%f) is changing with vdw softcore, while "
"coul-lambdas (%f) is nonzero without coulomb softcore: this will lead to "
"crashes, and is not supported.",
- i, fep->all_lambda[efptVDW][i], fep->all_lambda[efptCOUL][i]);
+ i,
+ fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)][i],
+ fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)][i]);
CHECK((fep->sc_alpha > 0)
- && (((fep->all_lambda[efptCOUL][i] > 0.0) && (fep->all_lambda[efptCOUL][i] < 1.0))
- && ((fep->all_lambda[efptVDW][i] > 0.0) && (fep->all_lambda[efptVDW][i] < 1.0))));
+ && (((fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)][i] > 0.0)
+ && (fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)][i] < 1.0))
+ && ((fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)][i] > 0.0)
+ && (fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)][i]
+ < 1.0))));
}
}
"energy conservation, but usually other effects dominate. With a common sigma "
"value of %g nm the fraction of the particle-particle potential at the cut-off "
"at lambda=%g is around %.1e, while ewald-rtol is %.1e.",
- fep->sc_r_power, sigma, lambda, r_sc - 1.0, ir->ewald_rtol);
+ fep->sc_r_power,
+ sigma,
+ lambda,
+ r_sc - 1.0,
+ ir->ewald_rtol);
warning_note(wi, warn_buf);
}
/* Free Energy Checks -- In an ideal world, slow growth and FEP would
be treated differently, but that's the next step */
- for (i = 0; i < efptNR; i++)
+ for (i = 0; i < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); i++)
{
+ auto enumValue = static_cast<FreeEnergyPerturbationCouplingType>(i);
for (j = 0; j < fep->n_lambda; j++)
{
- sprintf(err_buf, "%s[%d] must be between 0 and 1", efpt_names[i], j);
+ sprintf(err_buf, "%s[%d] must be between 0 and 1", enumValueToString(enumValue), j);
CHECK((fep->all_lambda[i][j] < 0) || (fep->all_lambda[i][j] > 1));
}
}
}
- if ((ir->bSimTemp) || (ir->efep == efepEXPANDED))
+ if ((ir->bSimTemp) || (ir->efep == FreeEnergyPerturbationType::Expanded))
{
- fep = ir->fepvals;
+ fep = ir->fepvals.get();
/* checking equilibration of weights inputs for validity */
sprintf(err_buf,
"weight-equil-number-all-lambda (%d) is ignored if lmc-weights-equil is not equal "
"to %s",
- expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]);
- CHECK((expand->equil_n_at_lam > 0) && (expand->elmceq != elmceqNUMATLAM));
+ expand->equil_n_at_lam,
+ enumValueToString(LambdaWeightWillReachEquilibrium::NumAtLambda));
+ CHECK((expand->equil_n_at_lam > 0)
+ && (expand->elmceq != LambdaWeightWillReachEquilibrium::NumAtLambda));
sprintf(err_buf,
"weight-equil-number-samples (%d) is ignored if lmc-weights-equil is not equal to "
"%s",
- expand->equil_samples, elmceq_names[elmceqSAMPLES]);
- CHECK((expand->equil_samples > 0) && (expand->elmceq != elmceqSAMPLES));
+ expand->equil_samples,
+ enumValueToString(LambdaWeightWillReachEquilibrium::Samples));
+ CHECK((expand->equil_samples > 0) && (expand->elmceq != LambdaWeightWillReachEquilibrium::Samples));
sprintf(err_buf,
"weight-equil-number-steps (%d) is ignored if lmc-weights-equil is not equal to %s",
- expand->equil_steps, elmceq_names[elmceqSTEPS]);
- CHECK((expand->equil_steps > 0) && (expand->elmceq != elmceqSTEPS));
+ expand->equil_steps,
+ enumValueToString(LambdaWeightWillReachEquilibrium::Steps));
+ CHECK((expand->equil_steps > 0) && (expand->elmceq != LambdaWeightWillReachEquilibrium::Steps));
sprintf(err_buf,
"weight-equil-wl-delta (%d) is ignored if lmc-weights-equil is not equal to %s",
- expand->equil_samples, elmceq_names[elmceqWLDELTA]);
- CHECK((expand->equil_wl_delta > 0) && (expand->elmceq != elmceqWLDELTA));
+ expand->equil_samples,
+ enumValueToString(LambdaWeightWillReachEquilibrium::WLDelta));
+ CHECK((expand->equil_wl_delta > 0) && (expand->elmceq != LambdaWeightWillReachEquilibrium::WLDelta));
sprintf(err_buf,
"weight-equil-count-ratio (%f) is ignored if lmc-weights-equil is not equal to %s",
- expand->equil_ratio, elmceq_names[elmceqRATIO]);
- CHECK((expand->equil_ratio > 0) && (expand->elmceq != elmceqRATIO));
+ expand->equil_ratio,
+ enumValueToString(LambdaWeightWillReachEquilibrium::Ratio));
+ CHECK((expand->equil_ratio > 0) && (expand->elmceq != LambdaWeightWillReachEquilibrium::Ratio));
sprintf(err_buf,
"weight-equil-number-all-lambda (%d) must be a positive integer if "
"lmc-weights-equil=%s",
- expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]);
- CHECK((expand->equil_n_at_lam <= 0) && (expand->elmceq == elmceqNUMATLAM));
+ expand->equil_n_at_lam,
+ enumValueToString(LambdaWeightWillReachEquilibrium::NumAtLambda));
+ CHECK((expand->equil_n_at_lam <= 0)
+ && (expand->elmceq == LambdaWeightWillReachEquilibrium::NumAtLambda));
sprintf(err_buf,
"weight-equil-number-samples (%d) must be a positive integer if "
"lmc-weights-equil=%s",
- expand->equil_samples, elmceq_names[elmceqSAMPLES]);
- CHECK((expand->equil_samples <= 0) && (expand->elmceq == elmceqSAMPLES));
+ expand->equil_samples,
+ enumValueToString(LambdaWeightWillReachEquilibrium::Samples));
+ CHECK((expand->equil_samples <= 0) && (expand->elmceq == LambdaWeightWillReachEquilibrium::Samples));
sprintf(err_buf,
"weight-equil-number-steps (%d) must be a positive integer if lmc-weights-equil=%s",
- expand->equil_steps, elmceq_names[elmceqSTEPS]);
- CHECK((expand->equil_steps <= 0) && (expand->elmceq == elmceqSTEPS));
+ expand->equil_steps,
+ enumValueToString(LambdaWeightWillReachEquilibrium::Steps));
+ CHECK((expand->equil_steps <= 0) && (expand->elmceq == LambdaWeightWillReachEquilibrium::Steps));
- sprintf(err_buf, "weight-equil-wl-delta (%f) must be > 0 if lmc-weights-equil=%s",
- expand->equil_wl_delta, elmceq_names[elmceqWLDELTA]);
- CHECK((expand->equil_wl_delta <= 0) && (expand->elmceq == elmceqWLDELTA));
+ sprintf(err_buf,
+ "weight-equil-wl-delta (%f) must be > 0 if lmc-weights-equil=%s",
+ expand->equil_wl_delta,
+ enumValueToString(LambdaWeightWillReachEquilibrium::WLDelta));
+ CHECK((expand->equil_wl_delta <= 0)
+ && (expand->elmceq == LambdaWeightWillReachEquilibrium::WLDelta));
- sprintf(err_buf, "weight-equil-count-ratio (%f) must be > 0 if lmc-weights-equil=%s",
- expand->equil_ratio, elmceq_names[elmceqRATIO]);
- CHECK((expand->equil_ratio <= 0) && (expand->elmceq == elmceqRATIO));
+ sprintf(err_buf,
+ "weight-equil-count-ratio (%f) must be > 0 if lmc-weights-equil=%s",
+ expand->equil_ratio,
+ enumValueToString(LambdaWeightWillReachEquilibrium::Ratio));
+ CHECK((expand->equil_ratio <= 0) && (expand->elmceq == LambdaWeightWillReachEquilibrium::Ratio));
- sprintf(err_buf, "lmc-weights-equil=%s only possible when lmc-stats = %s or lmc-stats %s",
- elmceq_names[elmceqWLDELTA], elamstats_names[elamstatsWL], elamstats_names[elamstatsWWL]);
- CHECK((expand->elmceq == elmceqWLDELTA) && (!EWL(expand->elamstats)));
+ sprintf(err_buf,
+ "lmc-weights-equil=%s only possible when lmc-stats = %s or lmc-stats %s",
+ enumValueToString(LambdaWeightWillReachEquilibrium::WLDelta),
+ enumValueToString(LambdaWeightCalculation::WL),
+ enumValueToString(LambdaWeightCalculation::WWL));
+ CHECK((expand->elmceq == LambdaWeightWillReachEquilibrium::WLDelta) && (!EWL(expand->elamstats)));
sprintf(err_buf, "lmc-repeats (%d) must be greater than 0", expand->lmc_repeats);
CHECK((expand->lmc_repeats <= 0));
sprintf(err_buf,
"init-lambda-state (%d) must be zero if lmc-forced-nstart (%d)> 0 and lmc-move != "
"'no'",
- fep->init_fep_state, expand->lmc_forced_nstart);
+ fep->init_fep_state,
+ expand->lmc_forced_nstart);
CHECK((fep->init_fep_state != 0) && (expand->lmc_forced_nstart > 0)
- && (expand->elmcmove != elmcmoveNO));
+ && (expand->elmcmove != LambdaMoveCalculation::No));
sprintf(err_buf, "lmc-forced-nstart (%d) must not be negative", expand->lmc_forced_nstart);
CHECK((expand->lmc_forced_nstart < 0));
- sprintf(err_buf, "init-lambda-state (%d) must be in the interval [0,number of lambdas)",
+ sprintf(err_buf,
+ "init-lambda-state (%d) must be in the interval [0,number of lambdas)",
fep->init_fep_state);
CHECK((fep->init_fep_state < 0) || (fep->init_fep_state >= fep->n_lambda));
CHECK((expand->wl_scale <= 0) || (expand->wl_scale >= 1));
/* if there is no temperature control, we need to specify an MC temperature */
- if (!integratorHasReferenceTemperature(ir) && (expand->elmcmove != elmcmoveNO)
- && (expand->mc_temp <= 0.0))
+ if (!integratorHasReferenceTemperature(ir)
+ && (expand->elmcmove != LambdaMoveCalculation::No) && (expand->mc_temp <= 0.0))
{
sprintf(err_buf,
"If there is no temperature control, and lmc-mcmove!='no', mc_temp must be set "
{
sprintf(err_buf,
"nst-transition-matrix (%d) must be an integer multiple of nstlog (%d)",
- expand->nstTij, ir->nstlog);
+ expand->nstTij,
+ ir->nstlog);
CHECK((expand->nstTij % ir->nstlog) != 0);
}
}
{
if (ir->pbcType == PbcType::No)
{
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
warning(wi, "Turning off pressure coupling for vacuum system");
- ir->epc = epcNO;
+ ir->epc = PressureCoupling::No;
}
}
else
{
- sprintf(err_buf, "Can not have pressure coupling with pbc=%s",
+ sprintf(err_buf,
+ "Can not have pressure coupling with pbc=%s",
c_pbcTypeNames[ir->pbcType].c_str());
- CHECK(ir->epc != epcNO);
+ CHECK(ir->epc != PressureCoupling::No);
}
sprintf(err_buf, "Can not have Ewald with pbc=%s", c_pbcTypeNames[ir->pbcType].c_str());
CHECK(EEL_FULL(ir->coulombtype));
- sprintf(err_buf, "Can not have dispersion correction with pbc=%s",
+ sprintf(err_buf,
+ "Can not have dispersion correction with pbc=%s",
c_pbcTypeNames[ir->pbcType].c_str());
- CHECK(ir->eDispCorr != edispcNO);
+ CHECK(ir->eDispCorr != DispersionCorrectionType::No);
}
if (ir->rlist == 0.0)
"with coulombtype = %s or coulombtype = %s\n"
"without periodic boundary conditions (pbc = %s) and\n"
"rcoulomb and rvdw set to zero",
- eel_names[eelCUT], eel_names[eelUSER], c_pbcTypeNames[PbcType::No].c_str());
- CHECK(((ir->coulombtype != eelCUT) && (ir->coulombtype != eelUSER))
+ enumValueToString(CoulombInteractionType::Cut),
+ enumValueToString(CoulombInteractionType::User),
+ c_pbcTypeNames[PbcType::No].c_str());
+ CHECK(((ir->coulombtype != CoulombInteractionType::Cut)
+ && (ir->coulombtype != CoulombInteractionType::User))
|| (ir->pbcType != PbcType::No) || (ir->rcoulomb != 0.0) || (ir->rvdw != 0.0));
if (ir->nstlist > 0)
{
// TODO Change this behaviour. There should be exactly one way
// to turn off an algorithm.
- ir->comm_mode = ecmNO;
+ ir->comm_mode = ComRemovalAlgorithm::No;
}
- if (ir->comm_mode != ecmNO)
+ if (ir->comm_mode != ComRemovalAlgorithm::No)
{
if (ir->nstcomm < 0)
{
ir->nstcomm = abs(ir->nstcomm);
}
- if (ir->nstcalcenergy > 0 && ir->nstcomm < ir->nstcalcenergy)
+ if (ir->nstcalcenergy > 0 && ir->nstcomm < ir->nstcalcenergy
+ && ir->comm_mode != ComRemovalAlgorithm::LinearAccelerationCorrection)
{
warning_note(wi,
- "nstcomm < nstcalcenergy defeats the purpose of nstcalcenergy, setting "
- "nstcomm to nstcalcenergy");
- ir->nstcomm = ir->nstcalcenergy;
+ "nstcomm < nstcalcenergy defeats the purpose of nstcalcenergy, consider "
+ "setting nstcomm equal to nstcalcenergy for less overhead");
}
- if (ir->comm_mode == ecmANGULAR)
+ if (ir->comm_mode == ComRemovalAlgorithm::Angular)
{
sprintf(err_buf,
"Can not remove the rotation around the center of mass with periodic "
}
}
- if (EI_STATE_VELOCITY(ir->eI) && !EI_SD(ir->eI) && ir->pbcType == PbcType::No && ir->comm_mode != ecmANGULAR)
+ if (EI_STATE_VELOCITY(ir->eI) && !EI_SD(ir->eI) && ir->pbcType == PbcType::No
+ && ir->comm_mode != ComRemovalAlgorithm::Angular)
{
sprintf(warn_buf,
"Tumbling and flying ice-cubes: We are not removing rotation around center of mass "
"in a non-periodic system. You should probably set comm_mode = ANGULAR or use "
"integrator = %s.",
- ei_names[eiSD1]);
+ enumValueToString(IntegrationAlgorithm::SD1));
warning_note(wi, warn_buf);
}
/* TEMPERATURE COUPLING */
- if (ir->etc == etcYES)
+ if (ir->etc == TemperatureCoupling::Yes)
{
- ir->etc = etcBERENDSEN;
+ ir->etc = TemperatureCoupling::Berendsen;
warning_note(wi,
"Old option for temperature coupling given: "
"changing \"yes\" to \"Berendsen\"\n");
}
- if ((ir->etc == etcNOSEHOOVER) || (ir->epc == epcMTTK))
+ if ((ir->etc == TemperatureCoupling::NoseHoover) || (ir->epc == PressureCoupling::Mttk))
{
if (ir->opts.nhchainlength < 1)
{
warning(wi, warn_buf);
}
- if (ir->etc == etcNOSEHOOVER && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1)
+ if (ir->etc == TemperatureCoupling::NoseHoover && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1)
{
warning_note(
wi,
ir->opts.nhchainlength = 0;
}
- if (ir->eI == eiVVAK)
+ if (ir->eI == IntegrationAlgorithm::VVAK)
{
sprintf(err_buf,
"%s implemented primarily for validation, and requires nsttcouple = 1 and "
"nstpcouple = 1.",
- ei_names[eiVVAK]);
+ enumValueToString(IntegrationAlgorithm::VVAK));
CHECK((ir->nsttcouple != 1) || (ir->nstpcouple != 1));
}
if (ETC_ANDERSEN(ir->etc))
{
- sprintf(err_buf, "%s temperature control not supported for integrator %s.",
- etcoupl_names[ir->etc], ei_names[ir->eI]);
+ sprintf(err_buf,
+ "%s temperature control not supported for integrator %s.",
+ enumValueToString(ir->etc),
+ enumValueToString(ir->eI));
CHECK(!(EI_VV(ir->eI)));
- if (ir->nstcomm > 0 && (ir->etc == etcANDERSEN))
+ if (ir->nstcomm > 0 && (ir->etc == TemperatureCoupling::Andersen))
{
sprintf(warn_buf,
"Center of mass removal not necessary for %s. All velocities of coupled "
"groups are rerandomized periodically, so flying ice cube errors will not "
"occur.",
- etcoupl_names[ir->etc]);
+ enumValueToString(ir->etc));
warning_note(wi, warn_buf);
}
sprintf(err_buf,
"nstcomm must be 1, not %d for %s, as velocities of atoms in coupled groups are "
"randomized every time step",
- ir->nstcomm, etcoupl_names[ir->etc]);
- CHECK(ir->nstcomm > 1 && (ir->etc == etcANDERSEN));
+ ir->nstcomm,
+ enumValueToString(ir->etc));
+ CHECK(ir->nstcomm > 1 && (ir->etc == TemperatureCoupling::Andersen));
}
- if (ir->etc == etcBERENDSEN)
+ if (ir->etc == TemperatureCoupling::Berendsen)
{
sprintf(warn_buf,
"The %s thermostat does not generate the correct kinetic energy distribution. You "
"might want to consider using the %s thermostat.",
- ETCOUPLTYPE(ir->etc), ETCOUPLTYPE(etcVRESCALE));
+ enumValueToString(ir->etc),
+ enumValueToString(TemperatureCoupling::VRescale));
warning_note(wi, warn_buf);
}
- if ((ir->etc == etcNOSEHOOVER || ETC_ANDERSEN(ir->etc)) && ir->epc == epcBERENDSEN)
+ if ((ir->etc == TemperatureCoupling::NoseHoover || ETC_ANDERSEN(ir->etc))
+ && ir->epc == PressureCoupling::Berendsen)
{
sprintf(warn_buf,
"Using Berendsen pressure coupling invalidates the "
}
/* PRESSURE COUPLING */
- if (ir->epc == epcISOTROPIC)
+ if (ir->epc == PressureCoupling::Isotropic)
{
- ir->epc = epcBERENDSEN;
+ ir->epc = PressureCoupling::Berendsen;
warning_note(wi,
"Old option for pressure coupling given: "
"changing \"Isotropic\" to \"Berendsen\"\n");
}
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
dt_pcoupl = ir->nstpcouple * ir->delta_t;
sprintf(warn_buf,
"For proper integration of the %s barostat, tau-p (%g) should be at least %d "
"times larger than nstpcouple*dt (%g)",
- EPCOUPLTYPE(ir->epc), ir->tau_p, pcouple_min_integration_steps(ir->epc), dt_pcoupl);
+ enumValueToString(ir->epc),
+ ir->tau_p,
+ pcouple_min_integration_steps(ir->epc),
+ dt_pcoupl);
warning(wi, warn_buf);
}
sprintf(err_buf,
"compressibility must be > 0 when using pressure"
" coupling %s\n",
- EPCOUPLTYPE(ir->epc));
+ enumValueToString(ir->epc));
CHECK(ir->compress[XX][XX] < 0 || ir->compress[YY][YY] < 0 || ir->compress[ZZ][ZZ] < 0
|| (trace(ir->compress) == 0 && ir->compress[YY][XX] <= 0 && ir->compress[ZZ][XX] <= 0
&& ir->compress[ZZ][YY] <= 0));
- if (epcPARRINELLORAHMAN == ir->epc && opts->bGenVel)
+ if (PressureCoupling::ParrinelloRahman == ir->epc && opts->bGenVel)
{
sprintf(warn_buf,
"You are generating velocities so I am assuming you "
"equilibrating first with Berendsen pressure coupling. If "
"you are not equilibrating the system, you can probably "
"ignore this warning.",
- epcoupl_names[ir->epc]);
+ enumValueToString(ir->epc));
warning(wi, warn_buf);
}
}
if (!EI_VV(ir->eI))
{
- if (ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::Mttk)
{
warning_error(wi, "MTTK pressure coupling requires a Velocity-verlet integrator");
}
/* ELECTROSTATICS */
/* More checks are in triple check (grompp.c) */
- if (ir->coulombtype == eelSWITCH)
+ if (ir->coulombtype == CoulombInteractionType::Switch)
{
sprintf(warn_buf,
"coulombtype = %s is only for testing purposes and can lead to serious "
"artifacts, advice: use coulombtype = %s",
- eel_names[ir->coulombtype], eel_names[eelRF_ZERO]);
+ enumValueToString(ir->coulombtype),
+ enumValueToString(CoulombInteractionType::RFZero));
warning(wi, warn_buf);
}
{
/* reaction field (at the cut-off) */
- if (ir->coulombtype == eelRF_ZERO && ir->epsilon_rf != 0)
+ if (ir->coulombtype == CoulombInteractionType::RFZero && ir->epsilon_rf != 0)
{
sprintf(warn_buf,
"With coulombtype = %s, epsilon-rf must be 0, assuming you meant epsilon_rf=0",
- eel_names[ir->coulombtype]);
+ enumValueToString(ir->coulombtype));
warning(wi, warn_buf);
ir->epsilon_rf = 0.0;
}
CHECK((ir->epsilon_rf < ir->epsilon_r && ir->epsilon_rf != 0) || (ir->epsilon_r == 0));
if (ir->epsilon_rf == ir->epsilon_r)
{
- sprintf(warn_buf, "Using epsilon-rf = epsilon-r with %s does not make sense",
- eel_names[ir->coulombtype]);
+ sprintf(warn_buf,
+ "Using epsilon-rf = epsilon-r with %s does not make sense",
+ enumValueToString(ir->coulombtype));
warning(wi, warn_buf);
}
}
sprintf(err_buf,
"With coulombtype = %s rcoulomb_switch must be < rcoulomb. Or, better: Use the "
"potential modifier options!",
- eel_names[ir->coulombtype]);
+ enumValueToString(ir->coulombtype));
CHECK(ir->rcoulomb_switch >= ir->rcoulomb);
}
}
- if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT)
+ if (ir->coulombtype == CoulombInteractionType::Switch || ir->coulombtype == CoulombInteractionType::Shift)
{
sprintf(err_buf,
"Explicit switch/shift coulomb interactions cannot be used in combination with a "
"secondary coulomb-modifier.");
- CHECK(ir->coulomb_modifier != eintmodNONE);
+ CHECK(ir->coulomb_modifier != InteractionModifiers::None);
}
- if (ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT)
+ if (ir->vdwtype == VanDerWaalsType::Switch || ir->vdwtype == VanDerWaalsType::Shift)
{
sprintf(err_buf,
"Explicit switch/shift vdw interactions cannot be used in combination with a "
"secondary vdw-modifier.");
- CHECK(ir->vdw_modifier != eintmodNONE);
+ CHECK(ir->vdw_modifier != InteractionModifiers::None);
}
- if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT || ir->vdwtype == evdwSWITCH
- || ir->vdwtype == evdwSHIFT)
+ if (ir->coulombtype == CoulombInteractionType::Switch || ir->coulombtype == CoulombInteractionType::Shift
+ || ir->vdwtype == VanDerWaalsType::Switch || ir->vdwtype == VanDerWaalsType::Shift)
{
sprintf(warn_buf,
"The switch/shift interaction settings are just for compatibility; you will get "
warning_note(wi, warn_buf);
}
- if (ir->coulombtype == eelPMESWITCH || ir->coulomb_modifier == eintmodPOTSWITCH)
+ if (ir->coulombtype == CoulombInteractionType::PmeSwitch
+ || ir->coulomb_modifier == InteractionModifiers::PotSwitch)
{
if (ir->rcoulomb_switch / ir->rcoulomb < 0.9499)
{
"The switching range should be 5%% or less (currently %.2f%% using a switching "
"range of %4f-%4f) for accurate electrostatic energies, energy conservation "
"will be good regardless, since ewald_rtol = %g.",
- percentage, ir->rcoulomb_switch, ir->rcoulomb, ir->ewald_rtol);
+ percentage,
+ ir->rcoulomb_switch,
+ ir->rcoulomb,
+ ir->ewald_rtol);
warning(wi, warn_buf);
}
}
- if (ir->vdwtype == evdwSWITCH || ir->vdw_modifier == eintmodPOTSWITCH)
+ if (ir->vdwtype == VanDerWaalsType::Switch || ir->vdw_modifier == InteractionModifiers::PotSwitch)
{
if (ir->rvdw_switch == 0)
{
if (EEL_FULL(ir->coulombtype))
{
- if (ir->coulombtype == eelPMESWITCH || ir->coulombtype == eelPMEUSER
- || ir->coulombtype == eelPMEUSERSWITCH)
+ if (ir->coulombtype == CoulombInteractionType::PmeSwitch
+ || ir->coulombtype == CoulombInteractionType::PmeUser
+ || ir->coulombtype == CoulombInteractionType::PmeUserSwitch)
{
- sprintf(err_buf, "With coulombtype = %s, rcoulomb must be <= rlist",
- eel_names[ir->coulombtype]);
+ sprintf(err_buf,
+ "With coulombtype = %s, rcoulomb must be <= rlist",
+ enumValueToString(ir->coulombtype));
CHECK(ir->rcoulomb > ir->rlist);
}
}
{
// TODO: Move these checks into the ewald module with the options class
int orderMin = 3;
- int orderMax = (ir->coulombtype == eelP3M_AD ? 8 : 12);
+ int orderMax = (ir->coulombtype == CoulombInteractionType::P3mAD ? 8 : 12);
if (ir->pme_order < orderMin || ir->pme_order > orderMax)
{
- sprintf(warn_buf, "With coulombtype = %s, you should have %d <= pme-order <= %d",
- eel_names[ir->coulombtype], orderMin, orderMax);
+ sprintf(warn_buf,
+ "With coulombtype = %s, you should have %d <= pme-order <= %d",
+ enumValueToString(ir->coulombtype),
+ orderMin,
+ orderMax);
warning_error(wi, warn_buf);
}
}
if (ir->nwall == 2 && EEL_FULL(ir->coulombtype))
{
- if (ir->ewald_geometry == eewg3D)
+ if (ir->ewald_geometry == EwaldGeometry::ThreeD)
{
- sprintf(warn_buf, "With pbc=%s you should use ewald-geometry=%s",
- c_pbcTypeNames[ir->pbcType].c_str(), eewg_names[eewg3DC]);
+ sprintf(warn_buf,
+ "With pbc=%s you should use ewald-geometry=%s",
+ c_pbcTypeNames[ir->pbcType].c_str(),
+ enumValueToString(EwaldGeometry::ThreeDC));
warning(wi, warn_buf);
}
/* This check avoids extra pbc coding for exclusion corrections */
sprintf(err_buf, "wall-ewald-zfac should be >= 2");
CHECK(ir->wall_ewald_zfac < 2);
}
- if ((ir->ewald_geometry == eewg3DC) && (ir->pbcType != PbcType::XY) && EEL_FULL(ir->coulombtype))
+ if ((ir->ewald_geometry == EwaldGeometry::ThreeDC) && (ir->pbcType != PbcType::XY)
+ && EEL_FULL(ir->coulombtype))
{
- sprintf(warn_buf, "With %s and ewald_geometry = %s you should use pbc = %s",
- eel_names[ir->coulombtype], eewg_names[eewg3DC], c_pbcTypeNames[PbcType::XY].c_str());
+ sprintf(warn_buf,
+ "With %s and ewald_geometry = %s you should use pbc = %s",
+ enumValueToString(ir->coulombtype),
+ enumValueToString(EwaldGeometry::ThreeDC),
+ c_pbcTypeNames[PbcType::XY].c_str());
warning(wi, warn_buf);
}
if ((ir->epsilon_surface != 0) && EEL_FULL(ir->coulombtype))
"You are applying a switch function to vdw forces or potentials from %g to %g "
"nm, which is more than half the interaction range, whereas switch functions "
"are intended to act only close to the cut-off.",
- ir->rvdw_switch, ir->rvdw);
+ ir->rvdw_switch,
+ ir->rvdw);
warning_note(wi, warn_buf);
}
}
- if (ir->vdwtype == evdwPME)
+ if (ir->vdwtype == VanDerWaalsType::Pme)
{
- if (!(ir->vdw_modifier == eintmodNONE || ir->vdw_modifier == eintmodPOTSHIFT))
+ if (!(ir->vdw_modifier == InteractionModifiers::None
+ || ir->vdw_modifier == InteractionModifiers::PotShift))
{
- sprintf(err_buf, "With vdwtype = %s, the only supported modifiers are %s and %s",
- evdw_names[ir->vdwtype], eintmod_names[eintmodPOTSHIFT], eintmod_names[eintmodNONE]);
+ sprintf(err_buf,
+ "With vdwtype = %s, the only supported modifiers are %s and %s",
+ enumValueToString(ir->vdwtype),
+ enumValueToString(InteractionModifiers::PotShift),
+ enumValueToString(InteractionModifiers::None));
warning_error(wi, err_buf);
}
}
- if (ir->vdwtype == evdwUSER && ir->eDispCorr != edispcNO)
+ if (ir->vdwtype == VanDerWaalsType::User && ir->eDispCorr != DispersionCorrectionType::No)
{
warning_note(wi,
"You have selected user tables with dispersion correction, the dispersion "
"really want dispersion correction to -C6/r^6.");
}
- if (ir->eI == eiLBFGS && (ir->coulombtype == eelCUT || ir->vdwtype == evdwCUT) && ir->rvdw != 0)
+ if (ir->eI == IntegrationAlgorithm::LBFGS
+ && (ir->coulombtype == CoulombInteractionType::Cut || ir->vdwtype == VanDerWaalsType::Cut)
+ && ir->rvdw != 0)
{
warning(wi, "For efficient BFGS minimization, use switch/shift/pme instead of cut-off.");
}
- if (ir->eI == eiLBFGS && ir->nbfgscorr <= 0)
+ if (ir->eI == IntegrationAlgorithm::LBFGS && ir->nbfgscorr <= 0)
{
warning(wi, "Using L-BFGS with nbfgscorr<=0 just gets you steepest descent.");
}
/* IMPLICIT SOLVENT */
- if (ir->coulombtype == eelGB_NOTUSED)
+ if (ir->coulombtype == CoulombInteractionType::GBNotused)
{
- sprintf(warn_buf, "Invalid option %s for coulombtype", eel_names[ir->coulombtype]);
+ sprintf(warn_buf, "Invalid option %s for coulombtype", enumValueToString(ir->coulombtype));
warning_error(wi, warn_buf);
}
}
// cosine acceleration is only supported in leap-frog
- if (ir->cos_accel != 0.0 && ir->eI != eiMD)
+ if (ir->cos_accel != 0.0 && ir->eI != IntegrationAlgorithm::MD)
{
warning_error(wi, "cos-acceleration is only supported by integrator = md");
}
str = the input string
n = the (pre-allocated) number of doubles read
r = the output array of doubles. */
-static void parse_n_real(char* str, int* n, real** r, warninp_t wi)
+static std::vector<real> parse_n_real(const std::string& str, int* n, warninp_t wi)
{
auto values = gmx::splitString(str);
*n = values.size();
- snew(*r, *n);
+ std::vector<real> r;
for (int i = 0; i < *n; i++)
{
try
{
- (*r)[i] = gmx::fromString<real>(values[i]);
+ r.emplace_back(gmx::fromString<real>(values[i]));
}
catch (gmx::GromacsException&)
{
- warning_error(wi, "Invalid value " + values[i]
- + " in string in mdp file. Expected a real number.");
+ warning_error(wi,
+ "Invalid value " + values[i]
+ + " in string in mdp file. Expected a real number.");
}
}
+ return r;
}
-static void do_fep_params(t_inputrec* ir, char fep_lambda[][STRLEN], char weights[STRLEN], warninp_t wi)
+static void do_fep_params(t_inputrec* ir, gmx::ArrayRef<std::string> fep_lambda, char weights[STRLEN], warninp_t wi)
{
- int i, j, max_n_lambda, nweights, nfep[efptNR];
- t_lambda* fep = ir->fepvals;
- t_expanded* expand = ir->expandedvals;
- real** count_fep_lambdas;
- bool bOneLambda = TRUE;
-
- snew(count_fep_lambdas, efptNR);
+ int i, j, max_n_lambda, nweights;
+ t_lambda* fep = ir->fepvals.get();
+ t_expanded* expand = ir->expandedvals.get();
+ gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, std::vector<real>> count_fep_lambdas;
+ bool bOneLambda = TRUE;
+ gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, int> nfep;
/* FEP input processing */
/* first, identify the number of lambda values for each type.
All that are nonzero must have the same number */
- for (i = 0; i < efptNR; i++)
+ for (auto i : keysOf(nfep))
{
- parse_n_real(fep_lambda[i], &(nfep[i]), &(count_fep_lambdas[i]), wi);
+ count_fep_lambdas[i] = parse_n_real(fep_lambda[static_cast<int>(i)], &(nfep[i]), wi);
}
/* now, determine the number of components. All must be either zero, or equal. */
max_n_lambda = 0;
- for (i = 0; i < efptNR; i++)
+ for (auto i : keysOf(nfep))
{
if (nfep[i] > max_n_lambda)
{
}
}
- for (i = 0; i < efptNR; i++)
+ for (auto i : keysOf(nfep))
{
if (nfep[i] == 0)
{
}
else if (nfep[i] == max_n_lambda)
{
- if (i != efptTEMPERATURE) /* we treat this differently -- not really a reason to compute
+ if (i != FreeEnergyPerturbationCouplingType::Temperature) /* we treat this differently -- not really a reason to compute
the derivative with respect to the temperature currently */
{
ir->fepvals->separate_dvdl[i] = TRUE;
gmx_fatal(FARGS,
"Number of lambdas (%d) for FEP type %s not equal to number of other types "
"(%d)",
- nfep[i], efpt_names[i], max_n_lambda);
+ nfep[i],
+ enumValueToString(i),
+ max_n_lambda);
}
}
/* we don't print out dhdl if the temperature is changing, since we can't correctly define dhdl in this case */
- ir->fepvals->separate_dvdl[efptTEMPERATURE] = FALSE;
+ ir->fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Temperature] = FALSE;
/* the number of lambdas is the number we've read in, which is either zero
or the same for all */
fep->n_lambda = max_n_lambda;
- /* allocate space for the array of lambda values */
- snew(fep->all_lambda, efptNR);
/* if init_lambda is defined, we need to set lambda */
if ((fep->init_lambda > 0) && (fep->n_lambda == 0))
{
- ir->fepvals->separate_dvdl[efptFEP] = TRUE;
+ ir->fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Fep] = TRUE;
}
/* otherwise allocate the space for all of the lambdas, and transfer the data */
- for (i = 0; i < efptNR; i++)
+ for (auto i : keysOf(nfep))
{
- snew(fep->all_lambda[i], fep->n_lambda);
+ fep->all_lambda[i].resize(fep->n_lambda);
if (nfep[i] > 0) /* if it's zero, then the count_fep_lambda arrays
are zero */
{
{
fep->all_lambda[i][j] = static_cast<double>(count_fep_lambdas[i][j]);
}
- sfree(count_fep_lambdas[i]);
}
}
- sfree(count_fep_lambdas);
/* "fep-vals" is either zero or the full number. If zero, we'll need to define fep-lambdas for
internal bookkeeping -- for now, init_lambda */
- if ((nfep[efptFEP] == 0) && (fep->init_lambda >= 0))
+ if ((nfep[FreeEnergyPerturbationCouplingType::Fep] == 0) && (fep->init_lambda >= 0))
{
for (i = 0; i < fep->n_lambda; i++)
{
- fep->all_lambda[efptFEP][i] = fep->init_lambda;
+ fep->all_lambda[FreeEnergyPerturbationCouplingType::Fep][i] = fep->init_lambda;
}
}
}
else
{
- for (i = 0; i < efptNR; i++)
+ for (auto i : keysOf(nfep))
{
- if ((nfep[i] != 0) && (i != efptFEP))
+ if ((nfep[i] != 0) && (i != FreeEnergyPerturbationCouplingType::Fep))
{
bOneLambda = FALSE;
}
specified (i.e. nfep[i] == 0). This means if fep is not defined,
they are all zero. */
- for (i = 0; i < efptNR; i++)
+ for (auto i : keysOf(nfep))
{
- if ((nfep[i] == 0) && (i != efptFEP))
+ if ((nfep[i] == 0) && (i != FreeEnergyPerturbationCouplingType::Fep))
{
for (j = 0; j < fep->n_lambda; j++)
{
- fep->all_lambda[i][j] = fep->all_lambda[efptFEP][j];
+ fep->all_lambda[i][j] = fep->all_lambda[FreeEnergyPerturbationCouplingType::Fep][j];
}
}
}
/* now read in the weights */
- parse_n_real(weights, &nweights, &(expand->init_lambda_weights), wi);
+ expand->init_lambda_weights = parse_n_real(weights, &nweights, wi);
if (nweights == 0)
{
- snew(expand->init_lambda_weights, fep->n_lambda); /* initialize to zero */
+ expand->init_lambda_weights.resize(fep->n_lambda); /* initialize to zero */
}
else if (nweights != fep->n_lambda)
{
- gmx_fatal(FARGS, "Number of weights (%d) is not equal to number of lambda values (%d)",
- nweights, fep->n_lambda);
+ gmx_fatal(FARGS,
+ "Number of weights (%d) is not equal to number of lambda values (%d)",
+ nweights,
+ fep->n_lambda);
}
- if ((expand->nstexpanded < 0) && (ir->efep != efepNO))
+ if ((expand->nstexpanded < 0) && (ir->efep != FreeEnergyPerturbationType::No))
{
expand->nstexpanded = fep->nstdhdl;
/* if you don't specify nstexpanded when doing expanded ensemble free energy calcs, it is set to nstdhdl */
static void do_simtemp_params(t_inputrec* ir)
{
-
- snew(ir->simtempvals->temperatures, ir->fepvals->n_lambda);
- GetSimTemps(ir->fepvals->n_lambda, ir->simtempvals, ir->fepvals->all_lambda[efptTEMPERATURE]);
+ ir->simtempvals->temperatures.resize(ir->fepvals->n_lambda);
+ getSimTemps(ir->fepvals->n_lambda,
+ ir->simtempvals.get(),
+ ir->fepvals->all_lambda[FreeEnergyPerturbationCouplingType::Temperature]);
}
template<typename T>
auto message = gmx::formatString(
"Invalid value for mdp option %s. %s should only consist of integers separated "
"by spaces.",
- name, name);
+ name,
+ name);
warning_error(wi, message);
}
++i;
auto message = gmx::formatString(
"Invalid value for mdp option %s. %s should only consist of real numbers "
"separated by spaces.",
- name, name);
+ name,
+ name);
warning_error(wi, message);
}
++i;
}
}
-static void convertRvecs(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char* name, rvec* outputs)
-{
- int i = 0, d = 0;
- for (const auto& input : inputs)
- {
- try
- {
- outputs[i][d] = gmx::fromString<real>(input);
- }
- catch (gmx::GromacsException&)
- {
- auto message = gmx::formatString(
- "Invalid value for mdp option %s. %s should only consist of real numbers "
- "separated by spaces.",
- name, name);
- warning_error(wi, message);
- }
- ++d;
- if (d == DIM)
- {
- d = 0;
- ++i;
- }
- }
-}
-
static void do_wall_params(t_inputrec* ir, char* wall_atomtype, char* wall_density, t_gromppopts* opts, warninp_t wi)
{
opts->wall_atomtype[0] = nullptr;
auto wallAtomTypes = gmx::splitString(wall_atomtype);
if (wallAtomTypes.size() != size_t(ir->nwall))
{
- gmx_fatal(FARGS, "Expected %d elements for wall_atomtype, found %zu", ir->nwall,
+ gmx_fatal(FARGS,
+ "Expected %d elements for wall_atomtype, found %zu",
+ ir->nwall,
wallAtomTypes.size());
}
GMX_RELEASE_ASSERT(ir->nwall < 3, "Invalid number of walls");
opts->wall_atomtype[i] = gmx_strdup(wallAtomTypes[i].c_str());
}
- if (ir->wall_type == ewt93 || ir->wall_type == ewt104)
+ if (ir->wall_type == WallType::NineThree || ir->wall_type == WallType::TenFour)
{
auto wallDensity = gmx::splitString(wall_density);
if (wallDensity.size() != size_t(ir->nwall))
{
- gmx_fatal(FARGS, "Expected %d elements for wall-density, found %zu", ir->nwall,
+ gmx_fatal(FARGS,
+ "Expected %d elements for wall-density, found %zu",
+ ir->nwall,
wallDensity.size());
}
convertReals(wi, wallDensity, "wall-density", ir->wall_density);
{
/* read expanded ensemble parameters */
printStringNewline(inp, "expanded ensemble variables");
- expand->nstexpanded = get_eint(inp, "nstexpanded", -1, wi);
- expand->elamstats = get_eeenum(inp, "lmc-stats", elamstats_names, wi);
- expand->elmcmove = get_eeenum(inp, "lmc-move", elmcmove_names, wi);
- expand->elmceq = get_eeenum(inp, "lmc-weights-equil", elmceq_names, wi);
+ expand->nstexpanded = get_eint(inp, "nstexpanded", -1, wi);
+ expand->elamstats = getEnum<LambdaWeightCalculation>(inp, "lmc-stats", wi);
+ expand->elmcmove = getEnum<LambdaMoveCalculation>(inp, "lmc-move", wi);
+ expand->elmceq = getEnum<LambdaWeightWillReachEquilibrium>(inp, "lmc-weights-equil", wi);
expand->equil_n_at_lam = get_eint(inp, "weight-equil-number-all-lambda", -1, wi);
expand->equil_samples = get_eint(inp, "weight-equil-number-samples", -1, wi);
expand->equil_steps = get_eint(inp, "weight-equil-number-steps", -1, wi);
expand->gibbsdeltalam = get_eint(inp, "lmc-gibbsdelta", -1, wi);
expand->lmc_forced_nstart = get_eint(inp, "lmc-forced-nstart", 0, wi);
expand->bSymmetrizedTMatrix =
- (get_eeenum(inp, "symmetrized-transition-matrix", yesno_names, wi) != 0);
+ (getEnum<Boolean>(inp, "symmetrized-transition-matrix", wi) != Boolean::No);
expand->nstTij = get_eint(inp, "nst-transition-matrix", -1, wi);
expand->minvarmin = get_eint(inp, "mininum-var-min", 100, wi); /*default is reasonable */
expand->c_range = get_eint(inp, "weight-c-range", 0, wi); /* default is just C=0 */
expand->wl_scale = get_ereal(inp, "wl-scale", 0.8, wi);
expand->wl_ratio = get_ereal(inp, "wl-ratio", 0.8, wi);
expand->init_wl_delta = get_ereal(inp, "init-wl-delta", 1.0, wi);
- expand->bWLoneovert = (get_eeenum(inp, "wl-oneovert", yesno_names, wi) != 0);
+ expand->bWLoneovert = (getEnum<Boolean>(inp, "wl-oneovert", wi) != Boolean::No);
}
/*! \brief Return whether an end state with the given coupling-lambda
double dumdub[2][6];
int i, j, m;
char warn_buf[STRLEN];
- t_lambda* fep = ir->fepvals;
- t_expanded* expand = ir->expandedvals;
+ t_lambda* fep = ir->fepvals.get();
+ t_expanded* expand = ir->expandedvals.get();
const char* no_names[] = { "no", nullptr };
setStringEntry(&inp, "define", opts->define, nullptr);
printStringNewline(&inp, "RUN CONTROL PARAMETERS");
- ir->eI = get_eeenum(&inp, "integrator", ei_names, wi);
+ ir->eI = getEnum<IntegrationAlgorithm>(&inp, "integrator", wi);
printStringNoNewline(&inp, "Start time and timestep in ps");
ir->init_t = get_ereal(&inp, "tinit", 0.0, wi);
ir->delta_t = get_ereal(&inp, "dt", 0.001, wi);
&inp, "Part index is updated automatically on checkpointing (keeps files separate)");
ir->simulation_part = get_eint(&inp, "simulation-part", 1, wi);
printStringNoNewline(&inp, "Multiple time-stepping");
- ir->useMts = (get_eeenum(&inp, "mts", yesno_names, wi) != 0);
+ ir->useMts = (getEnum<Boolean>(&inp, "mts", wi) != Boolean::No);
if (ir->useMts)
{
- opts->numMtsLevels = get_eint(&inp, "mts-levels", 2, wi);
- ir->mtsLevels.resize(2);
- gmx::MtsLevel& mtsLevel = ir->mtsLevels[1];
- opts->mtsLevel2Forces = setStringEntry(&inp, "mts-level2-forces", "longrange-nonbonded");
- mtsLevel.stepFactor = get_eint(&inp, "mts-level2-factor", 2, wi);
+ gmx::GromppMtsOpts& mtsOpts = opts->mtsOpts;
+ mtsOpts.numLevels = get_eint(&inp, "mts-levels", 2, wi);
+ mtsOpts.level2Forces = setStringEntry(&inp, "mts-level2-forces", "longrange-nonbonded");
+ mtsOpts.level2Factor = get_eint(&inp, "mts-level2-factor", 2, wi);
// We clear after reading without dynamics to not force the user to remove MTS mdp options
if (!EI_DYNAMICS(ir->eI))
{
ir->useMts = false;
- ir->mtsLevels.clear();
}
}
printStringNoNewline(&inp, "mode for center of mass motion removal");
- ir->comm_mode = get_eeenum(&inp, "comm-mode", ecm_names, wi);
+ ir->comm_mode = getEnum<ComRemovalAlgorithm>(&inp, "comm-mode", wi);
printStringNoNewline(&inp, "number of steps for center of mass motion removal");
ir->nstcomm = get_eint(&inp, "nstcomm", 100, wi);
printStringNoNewline(&inp, "group(s) for center of mass motion removal");
/* Neighbor searching */
printStringNewline(&inp, "NEIGHBORSEARCHING PARAMETERS");
printStringNoNewline(&inp, "cut-off scheme (Verlet: particle based cut-offs)");
- ir->cutoff_scheme = get_eeenum(&inp, "cutoff-scheme", ecutscheme_names, wi);
+ ir->cutoff_scheme = getEnum<CutoffScheme>(&inp, "cutoff-scheme", wi);
printStringNoNewline(&inp, "nblist update frequency");
ir->nstlist = get_eint(&inp, "nstlist", 10, wi);
printStringNoNewline(&inp, "Periodic boundary conditions: xyz, no, xy");
pbcTypesNamesChar.push_back(pbcTypeName.c_str());
}
ir->pbcType = static_cast<PbcType>(get_eeenum(&inp, "pbc", pbcTypesNamesChar.data(), wi));
- ir->bPeriodicMols = get_eeenum(&inp, "periodic-molecules", yesno_names, wi) != 0;
+ ir->bPeriodicMols = getEnum<Boolean>(&inp, "periodic-molecules", wi) != Boolean::No;
printStringNoNewline(&inp,
"Allowed energy error due to the Verlet buffer in kJ/mol/ps per atom,");
printStringNoNewline(&inp, "a value of -1 means: use rlist");
/* Electrostatics */
printStringNewline(&inp, "OPTIONS FOR ELECTROSTATICS AND VDW");
printStringNoNewline(&inp, "Method for doing electrostatics");
- ir->coulombtype = get_eeenum(&inp, "coulombtype", eel_names, wi);
- ir->coulomb_modifier = get_eeenum(&inp, "coulomb-modifier", eintmod_names, wi);
+ ir->coulombtype = getEnum<CoulombInteractionType>(&inp, "coulombtype", wi);
+ ir->coulomb_modifier = getEnum<InteractionModifiers>(&inp, "coulomb-modifier", wi);
printStringNoNewline(&inp, "cut-off lengths");
ir->rcoulomb_switch = get_ereal(&inp, "rcoulomb-switch", 0.0, wi);
ir->rcoulomb = get_ereal(&inp, "rcoulomb", 1.0, wi);
- printStringNoNewline(&inp,
- "Relative dielectric constant for the medium and the reaction field");
+ printStringNoNewline(&inp, "Relative dielectric constant for the medium and the reaction field");
ir->epsilon_r = get_ereal(&inp, "epsilon-r", 1.0, wi);
ir->epsilon_rf = get_ereal(&inp, "epsilon-rf", 0.0, wi);
printStringNoNewline(&inp, "Method for doing Van der Waals");
- ir->vdwtype = get_eeenum(&inp, "vdw-type", evdw_names, wi);
- ir->vdw_modifier = get_eeenum(&inp, "vdw-modifier", eintmod_names, wi);
+ ir->vdwtype = getEnum<VanDerWaalsType>(&inp, "vdw-type", wi);
+ ir->vdw_modifier = getEnum<InteractionModifiers>(&inp, "vdw-modifier", wi);
printStringNoNewline(&inp, "cut-off lengths");
ir->rvdw_switch = get_ereal(&inp, "rvdw-switch", 0.0, wi);
ir->rvdw = get_ereal(&inp, "rvdw", 1.0, wi);
printStringNoNewline(&inp, "Apply long range dispersion corrections for Energy and Pressure");
- ir->eDispCorr = get_eeenum(&inp, "DispCorr", edispc_names, wi);
+ ir->eDispCorr = getEnum<DispersionCorrectionType>(&inp, "DispCorr", wi);
printStringNoNewline(&inp, "Extension of the potential lookup tables beyond the cut-off");
ir->tabext = get_ereal(&inp, "table-extension", 1.0, wi);
printStringNoNewline(&inp, "Separate tables between energy group pairs");
ir->pme_order = get_eint(&inp, "pme-order", 4, wi);
ir->ewald_rtol = get_ereal(&inp, "ewald-rtol", 0.00001, wi);
ir->ewald_rtol_lj = get_ereal(&inp, "ewald-rtol-lj", 0.001, wi);
- ir->ljpme_combination_rule = get_eeenum(&inp, "lj-pme-comb-rule", eljpme_names, wi);
- ir->ewald_geometry = get_eeenum(&inp, "ewald-geometry", eewg_names, wi);
+ ir->ljpme_combination_rule = getEnum<LongRangeVdW>(&inp, "lj-pme-comb-rule", wi);
+ ir->ewald_geometry = getEnum<EwaldGeometry>(&inp, "ewald-geometry", wi);
ir->epsilon_surface = get_ereal(&inp, "epsilon-surface", 0.0, wi);
/* Implicit solvation is no longer supported, but we need grompp
/* Coupling stuff */
printStringNewline(&inp, "OPTIONS FOR WEAK COUPLING ALGORITHMS");
printStringNoNewline(&inp, "Temperature coupling");
- ir->etc = get_eeenum(&inp, "tcoupl", etcoupl_names, wi);
+ ir->etc = getEnum<TemperatureCoupling>(&inp, "tcoupl", wi);
ir->nsttcouple = get_eint(&inp, "nsttcouple", -1, wi);
ir->opts.nhchainlength = get_eint(&inp, "nh-chain-length", 10, wi);
- ir->bPrintNHChains = (get_eeenum(&inp, "print-nose-hoover-chain-variables", yesno_names, wi) != 0);
+ ir->bPrintNHChains = (getEnum<Boolean>(&inp, "print-nose-hoover-chain-variables", wi) != Boolean::No);
printStringNoNewline(&inp, "Groups to couple separately");
setStringEntry(&inp, "tc-grps", inputrecStrings->tcgrps, nullptr);
printStringNoNewline(&inp, "Time constant (ps) and reference temperature (K)");
setStringEntry(&inp, "tau-t", inputrecStrings->tau_t, nullptr);
setStringEntry(&inp, "ref-t", inputrecStrings->ref_t, nullptr);
printStringNoNewline(&inp, "pressure coupling");
- ir->epc = get_eeenum(&inp, "pcoupl", epcoupl_names, wi);
- ir->epct = get_eeenum(&inp, "pcoupltype", epcoupltype_names, wi);
+ ir->epc = getEnum<PressureCoupling>(&inp, "pcoupl", wi);
+ ir->epct = getEnum<PressureCouplingType>(&inp, "pcoupltype", wi);
ir->nstpcouple = get_eint(&inp, "nstpcouple", -1, wi);
printStringNoNewline(&inp, "Time constant (ps), compressibility (1/bar) and reference P (bar)");
ir->tau_p = get_ereal(&inp, "tau-p", 1.0, wi);
setStringEntry(&inp, "compressibility", dumstr[0], nullptr);
setStringEntry(&inp, "ref-p", dumstr[1], nullptr);
printStringNoNewline(&inp, "Scaling of reference coordinates, No, All or COM");
- ir->refcoord_scaling = get_eeenum(&inp, "refcoord-scaling", erefscaling_names, wi);
+ ir->refcoord_scaling = getEnum<RefCoordScaling>(&inp, "refcoord-scaling", wi);
/* QMMM */
printStringNewline(&inp, "OPTIONS FOR QMMM calculations");
- ir->bQMMM = (get_eeenum(&inp, "QMMM", yesno_names, wi) != 0);
+ ir->bQMMM = (getEnum<Boolean>(&inp, "QMMM", wi) != Boolean::No);
printStringNoNewline(&inp, "Groups treated with MiMiC");
setStringEntry(&inp, "QMMM-grps", inputrecStrings->QMMM, nullptr);
/* Startup run */
printStringNewline(&inp, "GENERATE VELOCITIES FOR STARTUP RUN");
- opts->bGenVel = (get_eeenum(&inp, "gen-vel", yesno_names, wi) != 0);
+ opts->bGenVel = (getEnum<Boolean>(&inp, "gen-vel", wi) != Boolean::No);
opts->tempi = get_ereal(&inp, "gen-temp", 300.0, wi);
opts->seed = get_eint(&inp, "gen-seed", -1, wi);
printStringNewline(&inp, "OPTIONS FOR BONDS");
opts->nshake = get_eeenum(&inp, "constraints", constraints, wi);
printStringNoNewline(&inp, "Type of constraint algorithm");
- ir->eConstrAlg = get_eeenum(&inp, "constraint-algorithm", econstr_names, wi);
+ ir->eConstrAlg = getEnum<ConstraintAlgorithm>(&inp, "constraint-algorithm", wi);
printStringNoNewline(&inp, "Do not constrain the start configuration");
- ir->bContinuation = (get_eeenum(&inp, "continuation", yesno_names, wi) != 0);
+ ir->bContinuation = (getEnum<Boolean>(&inp, "continuation", wi) != Boolean::No);
printStringNoNewline(&inp,
"Use successive overrelaxation to reduce the number of shake iterations");
- ir->bShakeSOR = (get_eeenum(&inp, "Shake-SOR", yesno_names, wi) != 0);
+ ir->bShakeSOR = (getEnum<Boolean>(&inp, "Shake-SOR", wi) != Boolean::No);
printStringNoNewline(&inp, "Relative tolerance of shake");
ir->shake_tol = get_ereal(&inp, "shake-tol", 0.0001, wi);
printStringNoNewline(&inp, "Highest order in the expansion of the constraint coupling matrix");
printStringNoNewline(&inp, "rotates over more degrees than");
ir->LincsWarnAngle = get_ereal(&inp, "lincs-warnangle", 30.0, wi);
printStringNoNewline(&inp, "Convert harmonic bonds to morse potentials");
- opts->bMorse = (get_eeenum(&inp, "morse", yesno_names, wi) != 0);
+ opts->bMorse = (getEnum<Boolean>(&inp, "morse", wi) != Boolean::No);
/* Energy group exclusions */
printStringNewline(&inp, "ENERGY GROUP EXCLUSIONS");
printStringNoNewline(
&inp, "Number of walls, type, atom types, densities and box-z scale factor for Ewald");
ir->nwall = get_eint(&inp, "nwall", 0, wi);
- ir->wall_type = get_eeenum(&inp, "wall-type", ewt_names, wi);
+ ir->wall_type = getEnum<WallType>(&inp, "wall-type", wi);
ir->wall_r_linpot = get_ereal(&inp, "wall-r-linpot", -1, wi);
setStringEntry(&inp, "wall-atomtype", inputrecStrings->wall_atomtype, nullptr);
setStringEntry(&inp, "wall-density", inputrecStrings->wall_density, nullptr);
/* COM pulling */
printStringNewline(&inp, "COM PULLING");
- ir->bPull = (get_eeenum(&inp, "pull", yesno_names, wi) != 0);
+ ir->bPull = (getEnum<Boolean>(&inp, "pull", wi) != Boolean::No);
if (ir->bPull)
{
ir->pull = std::make_unique<pull_params_t>();
{
for (int c = 0; c < ir->pull->ncoord; c++)
{
- if (ir->pull->coord[c].eType == epullCONSTRAINT)
+ if (ir->pull->coord[c].eType == PullingAlgorithm::Constraint)
{
warning_error(wi,
"Constraint COM pulling is not supported in combination with "
/* AWH biasing
NOTE: needs COM pulling or free energy input */
printStringNewline(&inp, "AWH biasing");
- ir->bDoAwh = (get_eeenum(&inp, "awh", yesno_names, wi) != 0);
+ ir->bDoAwh = (getEnum<Boolean>(&inp, "awh", wi) != Boolean::No);
if (ir->bDoAwh)
{
- ir->awhParams = gmx::readAwhParams(&inp, wi);
+ ir->awhParams = std::make_unique<gmx::AwhParams>(&inp, wi);
}
/* Enforced rotation */
printStringNewline(&inp, "ENFORCED ROTATION");
printStringNoNewline(&inp, "Enforced rotation: No or Yes");
- ir->bRot = (get_eeenum(&inp, "rotation", yesno_names, wi) != 0);
+ ir->bRot = (getEnum<Boolean>(&inp, "rotation", wi) != Boolean::No);
if (ir->bRot)
{
snew(ir->rot, 1);
/* Refinement */
printStringNewline(&inp, "NMR refinement stuff");
printStringNoNewline(&inp, "Distance restraints type: No, Simple or Ensemble");
- ir->eDisre = get_eeenum(&inp, "disre", edisre_names, wi);
+ ir->eDisre = getEnum<DistanceRestraintRefinement>(&inp, "disre", wi);
printStringNoNewline(
&inp, "Force weighting of pairs in one distance restraint: Conservative or Equal");
- ir->eDisreWeighting = get_eeenum(&inp, "disre-weighting", edisreweighting_names, wi);
+ ir->eDisreWeighting = getEnum<DistanceRestraintWeighting>(&inp, "disre-weighting", wi);
printStringNoNewline(&inp, "Use sqrt of the time averaged times the instantaneous violation");
- ir->bDisreMixed = (get_eeenum(&inp, "disre-mixed", yesno_names, wi) != 0);
+ ir->bDisreMixed = (getEnum<Boolean>(&inp, "disre-mixed", wi) != Boolean::No);
ir->dr_fc = get_ereal(&inp, "disre-fc", 1000.0, wi);
ir->dr_tau = get_ereal(&inp, "disre-tau", 0.0, wi);
printStringNoNewline(&inp, "Output frequency for pair distances to energy file");
ir->nstdisreout = get_eint(&inp, "nstdisreout", 100, wi);
printStringNoNewline(&inp, "Orientation restraints: No or Yes");
- opts->bOrire = (get_eeenum(&inp, "orire", yesno_names, wi) != 0);
+ opts->bOrire = (getEnum<Boolean>(&inp, "orire", wi) != Boolean::No);
printStringNoNewline(&inp, "Orientation restraints force constant and tau for time averaging");
ir->orires_fc = get_ereal(&inp, "orire-fc", 0.0, wi);
ir->orires_tau = get_ereal(&inp, "orire-tau", 0.0, wi);
/* free energy variables */
printStringNewline(&inp, "Free energy variables");
- ir->efep = get_eeenum(&inp, "free-energy", efep_names, wi);
+ ir->efep = getEnum<FreeEnergyPerturbationType>(&inp, "free-energy", wi);
setStringEntry(&inp, "couple-moltype", inputrecStrings->couple_moltype, nullptr);
opts->couple_lam0 = get_eeenum(&inp, "couple-lambda0", couple_lam, wi);
opts->couple_lam1 = get_eeenum(&inp, "couple-lambda1", couple_lam, wi);
- opts->bCoupleIntra = (get_eeenum(&inp, "couple-intramol", yesno_names, wi) != 0);
+ opts->bCoupleIntra = (getEnum<Boolean>(&inp, "couple-intramol", wi) != Boolean::No);
fep->init_lambda = get_ereal(&inp, "init-lambda", -1, wi); /* start with -1 so
we can recognize if
fep->init_fep_state = get_eint(&inp, "init-lambda-state", -1, wi);
fep->delta_lambda = get_ereal(&inp, "delta-lambda", 0.0, wi);
fep->nstdhdl = get_eint(&inp, "nstdhdl", 50, wi);
- setStringEntry(&inp, "fep-lambdas", inputrecStrings->fep_lambda[efptFEP], nullptr);
- setStringEntry(&inp, "mass-lambdas", inputrecStrings->fep_lambda[efptMASS], nullptr);
- setStringEntry(&inp, "coul-lambdas", inputrecStrings->fep_lambda[efptCOUL], nullptr);
- setStringEntry(&inp, "vdw-lambdas", inputrecStrings->fep_lambda[efptVDW], nullptr);
- setStringEntry(&inp, "bonded-lambdas", inputrecStrings->fep_lambda[efptBONDED], nullptr);
- setStringEntry(&inp, "restraint-lambdas", inputrecStrings->fep_lambda[efptRESTRAINT], nullptr);
- setStringEntry(&inp, "temperature-lambdas", inputrecStrings->fep_lambda[efptTEMPERATURE], nullptr);
+ inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Fep] =
+ setStringEntry(&inp, "fep-lambdas", "");
+ inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Mass] =
+ setStringEntry(&inp, "mass-lambdas", "");
+ inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Coul] =
+ setStringEntry(&inp, "coul-lambdas", "");
+ inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Vdw] =
+ setStringEntry(&inp, "vdw-lambdas", "");
+ inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Bonded] =
+ setStringEntry(&inp, "bonded-lambdas", "");
+ inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Restraint] =
+ setStringEntry(&inp, "restraint-lambdas", "");
+ inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Temperature] =
+ setStringEntry(&inp, "temperature-lambdas", "");
fep->lambda_neighbors = get_eint(&inp, "calc-lambda-neighbors", 1, wi);
setStringEntry(&inp, "init-lambda-weights", inputrecStrings->lambda_weights, nullptr);
- fep->edHdLPrintEnergy = get_eeenum(&inp, "dhdl-print-energy", edHdLPrintEnergy_names, wi);
+ fep->edHdLPrintEnergy = getEnum<FreeEnergyPrintEnergy>(&inp, "dhdl-print-energy", wi);
fep->sc_alpha = get_ereal(&inp, "sc-alpha", 0.0, wi);
fep->sc_power = get_eint(&inp, "sc-power", 1, wi);
fep->sc_r_power = get_ereal(&inp, "sc-r-power", 6.0, wi);
fep->sc_sigma = get_ereal(&inp, "sc-sigma", 0.3, wi);
- fep->bScCoul = (get_eeenum(&inp, "sc-coul", yesno_names, wi) != 0);
+ fep->bScCoul = (getEnum<Boolean>(&inp, "sc-coul", wi) != Boolean::No);
fep->dh_hist_size = get_eint(&inp, "dh_hist_size", 0, wi);
fep->dh_hist_spacing = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
- fep->separate_dhdl_file = get_eeenum(&inp, "separate-dhdl-file", separate_dhdl_file_names, wi);
- fep->dhdl_derivatives = get_eeenum(&inp, "dhdl-derivatives", dhdl_derivatives_names, wi);
+ fep->separate_dhdl_file = getEnum<SeparateDhdlFile>(&inp, "separate-dhdl-file", wi);
+ fep->dhdl_derivatives = getEnum<DhDlDerivativeCalculation>(&inp, "dhdl-derivatives", wi);
fep->dh_hist_size = get_eint(&inp, "dh_hist_size", 0, wi);
fep->dh_hist_spacing = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
/* Non-equilibrium MD stuff */
printStringNewline(&inp, "Non-equilibrium MD stuff");
- setStringEntry(&inp, "acc-grps", inputrecStrings->accgrps, nullptr);
- setStringEntry(&inp, "accelerate", inputrecStrings->acc, nullptr);
setStringEntry(&inp, "freezegrps", inputrecStrings->freeze, nullptr);
setStringEntry(&inp, "freezedim", inputrecStrings->frdim, nullptr);
ir->cos_accel = get_ereal(&inp, "cos-acceleration", 0, wi);
/* simulated tempering variables */
printStringNewline(&inp, "simulated tempering variables");
- ir->bSimTemp = (get_eeenum(&inp, "simulated-tempering", yesno_names, wi) != 0);
- ir->simtempvals->eSimTempScale = get_eeenum(&inp, "simulated-tempering-scaling", esimtemp_names, wi);
+ ir->bSimTemp = (getEnum<Boolean>(&inp, "simulated-tempering", wi) != Boolean::No);
+ ir->simtempvals->eSimTempScale = getEnum<SimulatedTempering>(&inp, "simulated-tempering-scaling", wi);
ir->simtempvals->simtemp_low = get_ereal(&inp, "sim-temp-low", 300.0, wi);
ir->simtempvals->simtemp_high = get_ereal(&inp, "sim-temp-high", 300.0, wi);
/* expanded ensemble variables */
- if (ir->efep == efepEXPANDED || ir->bSimTemp)
+ if (ir->efep == FreeEnergyPerturbationType::Expanded || ir->bSimTemp)
{
read_expandedparams(&inp, expand, wi);
}
printStringNewline(&inp,
"Ion/water position swapping for computational electrophysiology setups");
printStringNoNewline(&inp, "Swap positions along direction: no, X, Y, Z");
- ir->eSwapCoords = get_eeenum(&inp, "swapcoords", eSwapTypes_names, wi);
- if (ir->eSwapCoords != eswapNO)
+ ir->eSwapCoords = getEnum<SwapType>(&inp, "swapcoords", wi);
+ if (ir->eSwapCoords != SwapType::No)
{
char buf[STRLEN];
int nIonTypes;
{
warning_error(wi, "You need to provide at least one ion type for position exchanges.");
}
- ir->swap->ngrp = nIonTypes + eSwapFixedGrpNR;
+ ir->swap->ngrp = nIonTypes + static_cast<int>(SwapGroupSplittingType::Count);
snew(ir->swap->grp, ir->swap->ngrp);
for (i = 0; i < ir->swap->ngrp; i++)
{
}
printStringNoNewline(&inp,
"Two index groups that contain the compartment-partitioning atoms");
- setStringEntry(&inp, "split-group0", ir->swap->grp[eGrpSplit0].molname, nullptr);
- setStringEntry(&inp, "split-group1", ir->swap->grp[eGrpSplit1].molname, nullptr);
+ setStringEntry(&inp,
+ "split-group0",
+ ir->swap->grp[static_cast<int>(SwapGroupSplittingType::Split0)].molname,
+ nullptr);
+ setStringEntry(&inp,
+ "split-group1",
+ ir->swap->grp[static_cast<int>(SwapGroupSplittingType::Split1)].molname,
+ nullptr);
printStringNoNewline(&inp,
"Use center of mass of split groups (yes/no), otherwise center of "
"geometry is used");
- ir->swap->massw_split[0] = (get_eeenum(&inp, "massw-split0", yesno_names, wi) != 0);
- ir->swap->massw_split[1] = (get_eeenum(&inp, "massw-split1", yesno_names, wi) != 0);
+ ir->swap->massw_split[0] = (getEnum<Boolean>(&inp, "massw-split0", wi) != Boolean::No);
+ ir->swap->massw_split[1] = (getEnum<Boolean>(&inp, "massw-split1", wi) != Boolean::No);
printStringNoNewline(&inp, "Name of solvent molecules");
- setStringEntry(&inp, "solvent-group", ir->swap->grp[eGrpSolvent].molname, nullptr);
+ setStringEntry(&inp,
+ "solvent-group",
+ ir->swap->grp[static_cast<int>(SwapGroupSplittingType::Solvent)].molname,
+ nullptr);
printStringNoNewline(&inp,
"Split cylinder: radius, upper and lower extension (nm) (this will "
printStringNoNewline(&inp, "-1 means fix the numbers as found in step 0");
for (i = 0; i < nIonTypes; i++)
{
- int ig = eSwapFixedGrpNR + i;
+ int ig = static_cast<int>(SwapGroupSplittingType::Count) + i;
sprintf(buf, "iontype%d-name", i);
setStringEntry(&inp, buf, ir->swap->grp[ig].molname, nullptr);
{
dumdub[m][i] = 0.0;
}
- if (ir->epc)
+ if (ir->epc != PressureCoupling::No)
{
switch (ir->epct)
{
- case epctISOTROPIC:
+ case PressureCouplingType::Isotropic:
if (sscanf(dumstr[m], "%lf", &(dumdub[m][XX])) != 1)
{
warning_error(
}
dumdub[m][YY] = dumdub[m][ZZ] = dumdub[m][XX];
break;
- case epctSEMIISOTROPIC:
- case epctSURFACETENSION:
+ case PressureCouplingType::SemiIsotropic:
+ case PressureCouplingType::SurfaceTension:
if (sscanf(dumstr[m], "%lf%lf", &(dumdub[m][XX]), &(dumdub[m][ZZ])) != 2)
{
warning_error(
}
dumdub[m][YY] = dumdub[m][XX];
break;
- case epctANISOTROPIC:
- if (sscanf(dumstr[m], "%lf%lf%lf%lf%lf%lf", &(dumdub[m][XX]), &(dumdub[m][YY]),
- &(dumdub[m][ZZ]), &(dumdub[m][3]), &(dumdub[m][4]), &(dumdub[m][5]))
+ case PressureCouplingType::Anisotropic:
+ if (sscanf(dumstr[m],
+ "%lf%lf%lf%lf%lf%lf",
+ &(dumdub[m][XX]),
+ &(dumdub[m][YY]),
+ &(dumdub[m][ZZ]),
+ &(dumdub[m][3]),
+ &(dumdub[m][4]),
+ &(dumdub[m][5]))
!= 6)
{
warning_error(
}
break;
default:
- gmx_fatal(FARGS, "Pressure coupling type %s not implemented yet",
- epcoupltype_names[ir->epct]);
+ gmx_fatal(FARGS,
+ "Pressure coupling type %s not implemented yet",
+ enumValueToString(ir->epct));
}
}
}
ir->ref_p[i][i] = dumdub[1][i];
ir->compress[i][i] = dumdub[0][i];
}
- if (ir->epct == epctANISOTROPIC)
+ if (ir->epct == PressureCouplingType::Anisotropic)
{
ir->ref_p[XX][YY] = dumdub[1][3];
ir->ref_p[XX][ZZ] = dumdub[1][4];
}
}
- if (ir->comm_mode == ecmNO)
+ if (ir->comm_mode == ComRemovalAlgorithm::No)
{
ir->nstcomm = 0;
}
opts->couple_moltype = nullptr;
if (strlen(inputrecStrings->couple_moltype) > 0)
{
- if (ir->efep != efepNO)
+ if (ir->efep != FreeEnergyPerturbationType::No)
{
opts->couple_moltype = gmx_strdup(inputrecStrings->couple_moltype);
if (opts->couple_lam0 == opts->couple_lam1)
{
warning(wi, "The lambda=0 and lambda=1 states for coupling are identical");
}
- if (ir->eI == eiMD && (opts->couple_lam0 == ecouplamNONE || opts->couple_lam1 == ecouplamNONE))
+ if (ir->eI == IntegrationAlgorithm::MD
+ && (opts->couple_lam0 == ecouplamNONE || opts->couple_lam1 == ecouplamNONE))
{
warning_note(
wi,
}
}
/* FREE ENERGY AND EXPANDED ENSEMBLE OPTIONS */
- if (ir->efep != efepNO)
+ if (ir->efep != FreeEnergyPerturbationType::No)
{
if (fep->delta_lambda != 0)
{
- ir->efep = efepSLOWGROWTH;
+ ir->efep = FreeEnergyPerturbationType::SlowGrowth;
}
}
- if (fep->edHdLPrintEnergy == edHdLPrintEnergyYES)
+ if (fep->edHdLPrintEnergy == FreeEnergyPrintEnergy::Yes)
{
- fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL;
+ fep->edHdLPrintEnergy = FreeEnergyPrintEnergy::Total;
warning_note(wi,
"Old option for dhdl-print-energy given: "
"changing \"yes\" to \"total\"\n");
}
- if (ir->bSimTemp && (fep->edHdLPrintEnergy == edHdLPrintEnergyNO))
+ if (ir->bSimTemp && (fep->edHdLPrintEnergy == FreeEnergyPrintEnergy::No))
{
/* always print out the energy to dhdl if we are doing
expanded ensemble, since we need the total energy for
we will allow that if the appropriate mdp setting has
been enabled. Otherwise, total it is:
*/
- fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL;
+ fep->edHdLPrintEnergy = FreeEnergyPrintEnergy::Total;
}
- if ((ir->efep != efepNO) || ir->bSimTemp)
+ if ((ir->efep != FreeEnergyPerturbationType::No) || ir->bSimTemp)
{
ir->bExpanded = FALSE;
- if ((ir->efep == efepEXPANDED) || ir->bSimTemp)
+ if ((ir->efep == FreeEnergyPerturbationType::Expanded) || ir->bSimTemp)
{
ir->bExpanded = TRUE;
}
* If the (advanced) user does FEP through manual topology changes,
* this check will not be triggered.
*/
- if (ir->efep != efepNO && ir->fepvals->n_lambda == 0 && ir->fepvals->sc_alpha != 0
+ if (ir->efep != FreeEnergyPerturbationType::No && ir->fepvals->n_lambda == 0
+ && ir->fepvals->sc_alpha != 0
&& (couple_lambda_has_vdw_on(opts->couple_lam0) && couple_lambda_has_vdw_on(opts->couple_lam1)))
{
warning(wi,
}
double gmx_unused canary;
- int ndeform = sscanf(inputrecStrings->deform, "%lf %lf %lf %lf %lf %lf %lf", &(dumdub[0][0]),
- &(dumdub[0][1]), &(dumdub[0][2]), &(dumdub[0][3]), &(dumdub[0][4]),
- &(dumdub[0][5]), &canary);
+ int ndeform = sscanf(inputrecStrings->deform,
+ "%lf %lf %lf %lf %lf %lf %lf",
+ &(dumdub[0][0]),
+ &(dumdub[0][1]),
+ &(dumdub[0][2]),
+ &(dumdub[0][3]),
+ &(dumdub[0][4]),
+ &(dumdub[0][5]),
+ &canary);
if (strlen(inputrecStrings->deform) > 0 && ndeform != 6)
{
ir->deform[YY][XX] = dumdub[0][3];
ir->deform[ZZ][XX] = dumdub[0][4];
ir->deform[ZZ][YY] = dumdub[0][5];
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
for (i = 0; i < 3; i++)
{
}
/* Ion/water position swapping checks */
- if (ir->eSwapCoords != eswapNO)
+ if (ir->eSwapCoords != SwapType::No)
{
if (ir->swap->nstswap < 1)
{
/* Set up MTS levels, this needs to happen before checking AWH parameters */
if (ir->useMts)
{
- setupMtsLevels(ir->mtsLevels, *ir, *opts, wi);
+ std::vector<std::string> errorMessages;
+ ir->mtsLevels = gmx::setupMtsLevels(opts->mtsOpts, &errorMessages);
+
+ for (const auto& errorMessage : errorMessages)
+ {
+ warning_error(wi, errorMessage.c_str());
+ }
}
if (ir->bDoAwh)
{
- gmx::checkAwhParams(ir->awhParams, ir, wi);
+ gmx::checkAwhParams(*ir->awhParams, *ir, wi);
}
sfree(dumstr[0]);
const int ognr = cbuf[aj];
if (ognr != NOGID)
{
- gmx_fatal(FARGS, "Atom %d in multiple %s groups (%d and %d)", aj + 1, title,
- ognr + 1, i + 1);
+ gmx_fatal(FARGS, "Atom %d in multiple %s groups (%d and %d)", aj + 1, title, ognr + 1, i + 1);
}
else
{
{
if (bVerbose)
{
- fprintf(stderr, "Making dummy/rest group for %s containing %d elements\n", title,
- natoms - ntot);
+ fprintf(stderr, "Making dummy/rest group for %s containing %d elements\n", title, natoms - ntot);
}
/* Add group name "rest" */
grps->emplace_back(restnm);
nrdf_tc[i] = 0;
}
for (gmx::index i = 0;
- i < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1; i++)
+ i < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1;
+ i++)
{
nrdf_vcm[i] = 0;
clear_ivec(dof_vcm[i]);
const t_atom& local = atomP.atom();
int i = atomP.globalAtomNumber();
nrdf2[i] = 0;
- if (local.ptype == eptAtom || local.ptype == eptNucleus)
+ if (local.ptype == ParticleType::Atom || local.ptype == ParticleType::Nucleus)
{
int g = getGroupType(groups, SimulationAtomGroupType::Freeze, i);
for (int d = 0; d < DIM; d++)
*/
int ai = as + ia[i + 1];
int aj = as + ia[i + 2];
- if (((atom[ia[i + 1]].ptype == eptNucleus) || (atom[ia[i + 1]].ptype == eptAtom))
- && ((atom[ia[i + 2]].ptype == eptNucleus) || (atom[ia[i + 2]].ptype == eptAtom)))
+ if (((atom[ia[i + 1]].ptype == ParticleType::Nucleus)
+ || (atom[ia[i + 1]].ptype == ParticleType::Atom))
+ && ((atom[ia[i + 2]].ptype == ParticleType::Nucleus)
+ || (atom[ia[i + 2]].ptype == ParticleType::Atom)))
{
if (nrdf2[ai] > 0)
{
for (int i = 0; i < pull->ncoord; i++)
{
- if (pull->coord[i].eType != epullCONSTRAINT)
+ if (pull->coord[i].eType != PullingAlgorithm::Constraint)
{
continue;
}
* Note that we do not and should not include the rest group here.
*/
for (gmx::index j = 0;
- j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]); j++)
+ j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]);
+ j++)
{
switch (ir->comm_mode)
{
- case ecmLINEAR:
- case ecmLINEAR_ACCELERATION_CORRECTION:
+ case ComRemovalAlgorithm::Linear:
+ case ComRemovalAlgorithm::LinearAccelerationCorrection:
nrdf_vcm_sub[j] = 0;
for (int d = 0; d < ndim_rm_vcm; d++)
{
}
}
break;
- case ecmANGULAR: nrdf_vcm_sub[j] = 6; break;
+ case ComRemovalAlgorithm::Angular: nrdf_vcm_sub[j] = 6; break;
default: gmx_incons("Checking comm_mode");
}
}
for (gmx::index i = 0;
- i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling]); i++)
+ i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling]);
+ i++)
{
/* Count the number of atoms of TC group i for every VCM group */
for (gmx::index j = 0;
- j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1; j++)
+ j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1;
+ j++)
{
na_vcm[j] = 0;
}
nrdf_uc = nrdf_tc[i];
nrdf_tc[i] = 0;
for (gmx::index j = 0;
- j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1; j++)
+ j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1;
+ j++)
{
if (nrdf_vcm[j] > nrdf_vcm_sub[j])
{
{
opts->nrdf[i] = 0;
}
- fprintf(stderr, "Number of degrees of freedom in T-Coupling group %s is %.2f\n",
- gnames[groups.groups[SimulationAtomGroupType::TemperatureCoupling][i]], opts->nrdf[i]);
+ fprintf(stderr,
+ "Number of degrees of freedom in T-Coupling group %s is %.2f\n",
+ gnames[groups.groups[SimulationAtomGroupType::TemperatureCoupling][i]],
+ opts->nrdf[i]);
}
sfree(nrdf2);
* But since this is much larger than STRLEN, such a line can not be parsed.
* The real maximum is the number of names that fit in a string: STRLEN/2.
*/
-#define EGP_MAX (STRLEN / 2)
int j, k, nr;
bool bSet;
j = 0;
while ((j < nr)
&& gmx_strcasecmp(
- names[2 * i].c_str(),
- *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][j]])))
+ names[2 * i].c_str(),
+ *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][j]])))
{
j++;
}
k = 0;
while ((k < nr)
&& gmx_strcasecmp(
- names[2 * i + 1].c_str(),
- *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][k]])))
+ names[2 * i + 1].c_str(),
+ *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][k]])))
{
k++;
}
/* Just a quick check here, more thorough checks are in mdrun */
- if (strcmp(swap->grp[eGrpSplit0].molname, swap->grp[eGrpSplit1].molname) == 0)
+ if (strcmp(swap->grp[static_cast<int>(SwapGroupSplittingType::Split0)].molname,
+ swap->grp[static_cast<int>(SwapGroupSplittingType::Split1)].molname)
+ == 0)
{
- gmx_fatal(FARGS, "The split groups can not both be '%s'.", swap->grp[eGrpSplit0].molname);
+ gmx_fatal(FARGS,
+ "The split groups can not both be '%s'.",
+ swap->grp[static_cast<int>(SwapGroupSplittingType::Split0)].molname);
}
/* Get the index atoms of the split0, split1, solvent, and swap groups */
if (swapg->nat > 0)
{
- fprintf(stderr, "%s group '%s' contains %d atoms.\n",
- ig < 3 ? eSwapFixedGrp_names[ig] : "Swap", swap->grp[ig].molname, swapg->nat);
+ fprintf(stderr,
+ "%s group '%s' contains %d atoms.\n",
+ ig < 3 ? enumValueToString(static_cast<SwapGroupSplittingType>(ig)) : "Swap",
+ swap->grp[ig].molname,
+ swapg->nat);
snew(swapg->ind, swapg->nat);
for (i = 0; i < swapg->nat; i++)
{
fprintf(stderr,
"Group '%s' with %d atoms can be activated for interactive molecular dynamics "
"(IMD).\n",
- IMDgname, IMDgroup->nat);
+ IMDgname,
+ IMDgroup->nat);
snew(IMDgroup->ind, IMDgroup->nat);
for (i = 0; i < IMDgroup->nat; i++)
{
"removal group(s), due to limitations in the code these still contribute to the "
"mass of the COM along frozen dimensions and therefore the COMM correction will be "
"too small.",
- numPartiallyFrozenVcmAtoms, DIM);
+ numPartiallyFrozenVcmAtoms,
+ DIM);
warning(wi, warningText.c_str());
}
if (numNonVcmAtoms > 0)
}
}
-void do_index(const char* mdparin,
- const char* ndx,
- gmx_mtop_t* mtop,
- bool bVerbose,
- const gmx::MdModulesNotifier& notifier,
- t_inputrec* ir,
- warninp_t wi)
+void do_index(const char* mdparin,
+ const char* ndx,
+ gmx_mtop_t* mtop,
+ bool bVerbose,
+ const gmx::MDModulesNotifiers& mdModulesNotifiers,
+ t_inputrec* ir,
+ warninp_t wi)
{
t_blocka* defaultIndexGroups;
int natoms;
snew(defaultIndexGroups, 1);
snew(defaultIndexGroups->index, 1);
snew(gnames, 1);
- atoms_all = gmx_mtop_global_atoms(mtop);
+ atoms_all = gmx_mtop_global_atoms(*mtop);
analyse(&atoms_all, defaultIndexGroups, &gnames, FALSE, TRUE);
done_atom(&atoms_all);
}
gmx_fatal(FARGS,
"Invalid T coupling input: %zu groups, %zu ref-t values and "
"%zu tau-t values",
- temperatureCouplingGroupNames.size(), temperatureCouplingReferenceValues.size(),
+ temperatureCouplingGroupNames.size(),
+ temperatureCouplingReferenceValues.size(),
temperatureCouplingTauValues.size());
}
const bool useReferenceTemperature = integratorHasReferenceTemperature(ir);
- do_numbering(natoms, groups, temperatureCouplingGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::TemperatureCoupling, restnm,
- useReferenceTemperature ? egrptpALL : egrptpALL_GENREST, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ temperatureCouplingGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::TemperatureCoupling,
+ restnm,
+ useReferenceTemperature ? egrptpALL : egrptpALL_GENREST,
+ bVerbose,
+ wi);
nr = groups->groups[SimulationAtomGroupType::TemperatureCoupling].size();
ir->opts.ngtc = nr;
snew(ir->opts.nrdf, nr);
snew(ir->opts.tau_t, nr);
snew(ir->opts.ref_t, nr);
- if (ir->eI == eiBD && ir->bd_fric == 0)
+ if (ir->eI == IntegrationAlgorithm::BD && ir->bd_fric == 0)
{
fprintf(stderr, "bd-fric=0, so tau-t will be used as the inverse friction constant(s)\n");
}
convertReals(wi, temperatureCouplingTauValues, "tau-t", ir->opts.tau_t);
for (i = 0; (i < nr); i++)
{
- if ((ir->eI == eiBD) && ir->opts.tau_t[i] <= 0)
+ if ((ir->eI == IntegrationAlgorithm::BD) && ir->opts.tau_t[i] <= 0)
{
- sprintf(warn_buf, "With integrator %s tau-t should be larger than 0", ei_names[ir->eI]);
+ sprintf(warn_buf,
+ "With integrator %s tau-t should be larger than 0",
+ enumValueToString(ir->eI));
warning_error(wi, warn_buf);
}
- if (ir->etc != etcVRESCALE && ir->opts.tau_t[i] == 0)
+ if (ir->etc != TemperatureCoupling::VRescale && ir->opts.tau_t[i] == 0)
{
warning_note(
wi,
tau_min = std::min(tau_min, ir->opts.tau_t[i]);
}
}
- if (ir->etc != etcNO && ir->nsttcouple == -1)
+ if (ir->etc != TemperatureCoupling::No && ir->nsttcouple == -1)
{
ir->nsttcouple = ir_optimal_nsttcouple(ir);
}
if (EI_VV(ir->eI))
{
- if ((ir->etc == etcNOSEHOOVER) && (ir->epc == epcBERENDSEN))
+ if ((ir->etc == TemperatureCoupling::NoseHoover) && (ir->epc == PressureCoupling::Berendsen))
{
gmx_fatal(FARGS,
"Cannot do Nose-Hoover temperature with Berendsen pressure control with "
"md-vv; use either vrescale temperature with berendsen pressure or "
"Nose-Hoover temperature with MTTK pressure");
}
- if (ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::Mttk)
{
- if (ir->etc != etcNOSEHOOVER)
+ if (ir->etc != TemperatureCoupling::NoseHoover)
{
gmx_fatal(FARGS,
"Cannot do MTTK pressure coupling without Nose-Hoover temperature "
sprintf(warn_buf,
"For proper integration of the %s thermostat, tau-t (%g) should be at "
"least %d times larger than nsttcouple*dt (%g)",
- ETCOUPLTYPE(ir->etc), tau_min, nstcmin, ir->nsttcouple * ir->delta_t);
+ enumValueToString(ir->etc),
+ tau_min,
+ nstcmin,
+ ir->nsttcouple * ir->delta_t);
warning(wi, warn_buf);
}
}
}
if (!simulatedAnnealingGroupNames.empty() && gmx::ssize(simulatedAnnealingGroupNames) != nr)
{
- gmx_fatal(FARGS, "Wrong number of annealing values: %zu (for %d groups)\n",
- simulatedAnnealingGroupNames.size(), nr);
+ gmx_fatal(FARGS,
+ "Wrong number of annealing values: %zu (for %d groups)\n",
+ simulatedAnnealingGroupNames.size(),
+ nr);
}
else
{
snew(ir->opts.anneal_temp, nr);
for (i = 0; i < nr; i++)
{
- ir->opts.annealing[i] = eannNO;
+ ir->opts.annealing[i] = SimulatedAnnealing::No;
ir->opts.anneal_npoints[i] = 0;
ir->opts.anneal_time[i] = nullptr;
ir->opts.anneal_temp[i] = nullptr;
{
if (gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[i], "N", 1))
{
- ir->opts.annealing[i] = eannNO;
+ ir->opts.annealing[i] = SimulatedAnnealing::No;
}
else if (gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[i], "S", 1))
{
- ir->opts.annealing[i] = eannSINGLE;
+ ir->opts.annealing[i] = SimulatedAnnealing::Single;
bAnneal = TRUE;
}
else if (gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[i], "P", 1))
{
- ir->opts.annealing[i] = eannPERIODIC;
+ ir->opts.annealing[i] = SimulatedAnnealing::Periodic;
bAnneal = TRUE;
}
}
auto simulatedAnnealingPoints = gmx::splitString(inputrecStrings->anneal_npoints);
if (simulatedAnnealingPoints.size() != simulatedAnnealingGroupNames.size())
{
- gmx_fatal(FARGS, "Found %zu annealing-npoints values for %zu groups\n",
- simulatedAnnealingPoints.size(), simulatedAnnealingGroupNames.size());
+ gmx_fatal(FARGS,
+ "Found %zu annealing-npoints values for %zu groups\n",
+ simulatedAnnealingPoints.size(),
+ simulatedAnnealingGroupNames.size());
}
convertInts(wi, simulatedAnnealingPoints, "annealing points", ir->opts.anneal_npoints);
size_t numSimulatedAnnealingFields = 0;
if (simulatedAnnealingTimes.size() != numSimulatedAnnealingFields)
{
- gmx_fatal(FARGS, "Found %zu annealing-time values, wanted %zu\n",
- simulatedAnnealingTimes.size(), numSimulatedAnnealingFields);
+ gmx_fatal(FARGS,
+ "Found %zu annealing-time values, wanted %zu\n",
+ simulatedAnnealingTimes.size(),
+ numSimulatedAnnealingFields);
}
auto simulatedAnnealingTemperatures = gmx::splitString(inputrecStrings->anneal_temp);
if (simulatedAnnealingTemperatures.size() != numSimulatedAnnealingFields)
{
- gmx_fatal(FARGS, "Found %zu annealing-temp values, wanted %zu\n",
- simulatedAnnealingTemperatures.size(), numSimulatedAnnealingFields);
+ gmx_fatal(FARGS,
+ "Found %zu annealing-temp values, wanted %zu\n",
+ simulatedAnnealingTemperatures.size(),
+ numSimulatedAnnealingFields);
}
std::vector<real> allSimulatedAnnealingTimes(numSimulatedAnnealingFields);
std::vector<real> allSimulatedAnnealingTemperatures(numSimulatedAnnealingFields);
- convertReals(wi, simulatedAnnealingTimes, "anneal-time",
- allSimulatedAnnealingTimes.data());
- convertReals(wi, simulatedAnnealingTemperatures, "anneal-temp",
+ convertReals(wi, simulatedAnnealingTimes, "anneal-time", allSimulatedAnnealingTimes.data());
+ convertReals(wi,
+ simulatedAnnealingTemperatures,
+ "anneal-temp",
allSimulatedAnnealingTemperatures.data());
for (i = 0, k = 0; i < nr; i++)
{
gmx_fatal(FARGS,
"Annealing timepoints out of order: t=%f comes after "
"t=%f\n",
- ir->opts.anneal_time[i][j], ir->opts.anneal_time[i][j - 1]);
+ ir->opts.anneal_time[i][j],
+ ir->opts.anneal_time[i][j - 1]);
}
}
if (ir->opts.anneal_temp[i][j] < 0)
{
- gmx_fatal(FARGS, "Found negative temperature in annealing: %f\n",
+ gmx_fatal(FARGS,
+ "Found negative temperature in annealing: %f\n",
ir->opts.anneal_temp[i][j]);
}
k++;
/* Print out some summary information, to make sure we got it right */
for (i = 0; i < nr; i++)
{
- if (ir->opts.annealing[i] != eannNO)
+ if (ir->opts.annealing[i] != SimulatedAnnealing::No)
{
j = groups->groups[SimulationAtomGroupType::TemperatureCoupling][i];
- fprintf(stderr, "Simulated annealing for group %s: %s, %d timepoints\n",
- *(groups->groupNames[j]), eann_names[ir->opts.annealing[i]],
+ fprintf(stderr,
+ "Simulated annealing for group %s: %s, %d timepoints\n",
+ *(groups->groupNames[j]),
+ enumValueToString(ir->opts.annealing[i]),
ir->opts.anneal_npoints[i]);
fprintf(stderr, "Time (ps) Temperature (K)\n");
/* All terms except the last one */
for (j = 0; j < (ir->opts.anneal_npoints[i] - 1); j++)
{
- fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j],
+ fprintf(stderr,
+ "%9.1f %5.1f\n",
+ ir->opts.anneal_time[i][j],
ir->opts.anneal_temp[i][j]);
}
/* Finally the last one */
j = ir->opts.anneal_npoints[i] - 1;
- if (ir->opts.annealing[i] == eannSINGLE)
+ if (ir->opts.annealing[i] == SimulatedAnnealing::Single)
{
- fprintf(stderr, "%9.1f- %5.1f\n", ir->opts.anneal_time[i][j],
+ fprintf(stderr,
+ "%9.1f- %5.1f\n",
+ ir->opts.anneal_time[i][j],
ir->opts.anneal_temp[i][j]);
}
else
{
- fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j],
+ fprintf(stderr,
+ "%9.1f %5.1f\n",
+ ir->opts.anneal_time[i][j],
ir->opts.anneal_temp[i][j]);
if (std::fabs(ir->opts.anneal_temp[i][j] - ir->opts.anneal_temp[i][0]) > GMX_REAL_EPS)
{
{
for (int i = 1; i < ir->pull->ngroup; i++)
{
- const int gid = search_string(inputrecStrings->pullGroupNames[i].c_str(),
- defaultIndexGroups->nr, gnames);
+ const int gid = search_string(
+ inputrecStrings->pullGroupNames[i].c_str(), defaultIndexGroups->nr, gnames);
GMX_ASSERT(defaultIndexGroups, "Must have initialized default index groups");
atomGroupRangeValidation(natoms, gid, *defaultIndexGroups);
}
make_rotation_groups(ir->rot, inputrecStrings->rotateGroupNames, defaultIndexGroups, gnames);
}
- if (ir->eSwapCoords != eswapNO)
+ if (ir->eSwapCoords != SwapType::No)
{
make_swap_groups(ir->swap, defaultIndexGroups, gnames);
}
gmx::IndexGroupsAndNames defaultIndexGroupsAndNames(
*defaultIndexGroups, gmx::arrayRefFromArray(gnames, defaultIndexGroups->nr));
- notifier.preProcessingNotifications_.notify(defaultIndexGroupsAndNames);
-
- auto accelerations = gmx::splitString(inputrecStrings->acc);
- auto accelerationGroupNames = gmx::splitString(inputrecStrings->accgrps);
- if (accelerationGroupNames.size() * DIM != accelerations.size())
- {
- gmx_fatal(FARGS, "Invalid Acceleration input: %zu groups and %zu acc. values",
- accelerationGroupNames.size(), accelerations.size());
- }
- do_numbering(natoms, groups, accelerationGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::Acceleration, restnm, egrptpALL_GENREST, bVerbose, wi);
- nr = groups->groups[SimulationAtomGroupType::Acceleration].size();
- snew(ir->opts.acc, nr);
- ir->opts.ngacc = nr;
-
- convertRvecs(wi, accelerations, "anneal-time", ir->opts.acc);
+ mdModulesNotifiers.preProcessingNotifier_.notify(defaultIndexGroupsAndNames);
auto freezeDims = gmx::splitString(inputrecStrings->frdim);
auto freezeGroupNames = gmx::splitString(inputrecStrings->freeze);
if (freezeDims.size() != DIM * freezeGroupNames.size())
{
- gmx_fatal(FARGS, "Invalid Freezing input: %zu groups and %zu freeze values",
- freezeGroupNames.size(), freezeDims.size());
- }
- do_numbering(natoms, groups, freezeGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::Freeze, restnm, egrptpALL_GENREST, bVerbose, wi);
+ gmx_fatal(FARGS,
+ "Invalid Freezing input: %zu groups and %zu freeze values",
+ freezeGroupNames.size(),
+ freezeDims.size());
+ }
+ do_numbering(natoms,
+ groups,
+ freezeGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::Freeze,
+ restnm,
+ egrptpALL_GENREST,
+ bVerbose,
+ wi);
nr = groups->groups[SimulationAtomGroupType::Freeze].size();
ir->opts.ngfrz = nr;
snew(ir->opts.nFreeze, nr);
}
auto energyGroupNames = gmx::splitString(inputrecStrings->energy);
- do_numbering(natoms, groups, energyGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::EnergyOutput, restnm, egrptpALL_GENREST, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ energyGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::EnergyOutput,
+ restnm,
+ egrptpALL_GENREST,
+ bVerbose,
+ wi);
add_wall_energrps(groups, ir->nwall, symtab);
ir->opts.ngener = groups->groups[SimulationAtomGroupType::EnergyOutput].size();
auto vcmGroupNames = gmx::splitString(inputrecStrings->vcm);
- do_numbering(natoms, groups, vcmGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::MassCenterVelocityRemoval, restnm,
- vcmGroupNames.empty() ? egrptpALL_GENREST : egrptpPART, bVerbose, wi);
-
- if (ir->comm_mode != ecmNO)
+ do_numbering(natoms,
+ groups,
+ vcmGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::MassCenterVelocityRemoval,
+ restnm,
+ vcmGroupNames.empty() ? egrptpALL_GENREST : egrptpPART,
+ bVerbose,
+ wi);
+
+ if (ir->comm_mode != ComRemovalAlgorithm::No)
{
checkAndUpdateVcmFreezeGroupConsistency(groups, natoms, ir->opts, wi);
}
calc_nrdf(mtop, ir, gnames);
auto user1GroupNames = gmx::splitString(inputrecStrings->user1);
- do_numbering(natoms, groups, user1GroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::User1, restnm, egrptpALL_GENREST, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ user1GroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::User1,
+ restnm,
+ egrptpALL_GENREST,
+ bVerbose,
+ wi);
auto user2GroupNames = gmx::splitString(inputrecStrings->user2);
- do_numbering(natoms, groups, user2GroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::User2, restnm, egrptpALL_GENREST, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ user2GroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::User2,
+ restnm,
+ egrptpALL_GENREST,
+ bVerbose,
+ wi);
auto compressedXGroupNames = gmx::splitString(inputrecStrings->x_compressed_groups);
- do_numbering(natoms, groups, compressedXGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::CompressedPositionOutput, restnm, egrptpONE, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ compressedXGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::CompressedPositionOutput,
+ restnm,
+ egrptpONE,
+ bVerbose,
+ wi);
auto orirefFitGroupNames = gmx::splitString(inputrecStrings->orirefitgrp);
- do_numbering(natoms, groups, orirefFitGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::OrientationRestraintsFit, restnm, egrptpALL_GENREST,
- bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ orirefFitGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::OrientationRestraintsFit,
+ restnm,
+ egrptpALL_GENREST,
+ bVerbose,
+ wi);
/* MiMiC QMMM input processing */
auto qmGroupNames = gmx::splitString(inputrecStrings->QMMM);
gmx_fatal(FARGS, "Currently, having more than one QM group in MiMiC is not supported");
}
/* group rest, if any, is always MM! */
- do_numbering(natoms, groups, qmGroupNames, defaultIndexGroups, gnames,
- SimulationAtomGroupType::QuantumMechanics, restnm, egrptpALL_GENREST, bVerbose, wi);
+ do_numbering(natoms,
+ groups,
+ qmGroupNames,
+ defaultIndexGroups,
+ gnames,
+ SimulationAtomGroupType::QuantumMechanics,
+ restnm,
+ egrptpALL_GENREST,
+ bVerbose,
+ wi);
ir->opts.ngQM = qmGroupNames.size();
/* end of MiMiC QMMM input */
snew(ir->opts.egp_flags, nr * nr);
bExcl = do_egp_flag(ir, groups, "energygrp-excl", inputrecStrings->egpexcl, EGP_EXCL);
- if (bExcl && ir->cutoff_scheme == ecutsVERLET)
+ if (bExcl && ir->cutoff_scheme == CutoffScheme::Verlet)
{
warning_error(wi, "Energy group exclusions are currently not supported");
}
}
bTable = do_egp_flag(ir, groups, "energygrp-table", inputrecStrings->egptable, EGP_TABLE);
- if (bTable && !(ir->vdwtype == evdwUSER) && !(ir->coulombtype == eelUSER)
- && !(ir->coulombtype == eelPMEUSER) && !(ir->coulombtype == eelPMEUSERSWITCH))
+ if (bTable && !(ir->vdwtype == VanDerWaalsType::User)
+ && !(ir->coulombtype == CoulombInteractionType::User)
+ && !(ir->coulombtype == CoulombInteractionType::PmeUser)
+ && !(ir->coulombtype == CoulombInteractionType::PmeUserSwitch))
{
gmx_fatal(FARGS,
"Can only have energy group pair tables in combination with user tables for VdW "
if ((ir->expandedvals->nstexpanded < 0) && ir->bSimTemp)
{
ir->expandedvals->nstexpanded = 2 * static_cast<int>(ir->opts.tau_t[0] / ir->delta_t);
- warning(wi, gmx::formatString(
- "the value for nstexpanded was not specified for "
- " expanded ensemble simulated tempering. It is set to 2*tau_t (%d) "
- "by default, but it is recommended to set it to an explicit value!",
- ir->expandedvals->nstexpanded));
+ warning(wi,
+ gmx::formatString(
+ "the value for nstexpanded was not specified for "
+ " expanded ensemble simulated tempering. It is set to 2*tau_t (%d) "
+ "by default, but it is recommended to set it to an explicit value!",
+ ir->expandedvals->nstexpanded));
}
for (i = 0; (i < defaultIndexGroups->nr); i++)
{
}
-static void check_disre(const gmx_mtop_t* mtop)
+static void check_disre(const gmx_mtop_t& mtop)
{
if (gmx_mtop_ftype_count(mtop, F_DISRES) > 0)
{
- const gmx_ffparams_t& ffparams = mtop->ffparams;
+ const gmx_ffparams_t& ffparams = mtop.ffparams;
int ndouble = 0;
int old_label = -1;
for (int i = 0; i < ffparams.numTypes(); i++)
{
BasicVector<bool> havePosres = { false, false, false };
- gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(&sys);
- int nmol;
- while (const InteractionLists* ilist = gmx_mtop_ilistloop_next(iloop, &nmol))
+ for (const auto ilists : IListRange(sys))
{
- if (nmol > 0 && (!havePosres[XX] || !havePosres[YY] || !havePosres[ZZ]))
+ const auto& posResList = ilists.list()[F_POSRES];
+ const auto& fbPosResList = ilists.list()[F_FBPOSRES];
+ if (ilists.nmol() > 0 && (!havePosres[XX] || !havePosres[YY] || !havePosres[ZZ]))
{
- for (int i = 0; i < (*ilist)[F_POSRES].size(); i += 2)
+ for (int i = 0; i < posResList.size(); i += 2)
{
- const t_iparams& pr = sys.ffparams.iparams[(*ilist)[F_POSRES].iatoms[i]];
+ const t_iparams& pr = sys.ffparams.iparams[posResList.iatoms[i]];
for (int d = 0; d < DIM; d++)
{
if (pr.posres.fcA[d] != 0)
}
}
}
- for (int i = 0; i < (*ilist)[F_FBPOSRES].size(); i += 2)
+ for (int i = 0; i < fbPosResList.size(); i += 2)
{
/* Check for flat-bottom posres */
- const t_iparams& pr = sys.ffparams.iparams[(*ilist)[F_FBPOSRES].iatoms[i]];
+ const t_iparams& pr = sys.ffparams.iparams[fbPosResList.iatoms[i]];
if (pr.fbposres.k != 0)
{
switch (pr.fbposres.geom)
gmx_fatal(FARGS,
"Invalid geometry for flat-bottom position restraint.\n"
"Expected nr between 1 and %d. Found %d\n",
- efbposresNR - 1, pr.fbposres.geom);
+ efbposresNR - 1,
+ pr.fbposres.geom);
}
}
}
return havePosres;
}
-static void check_combination_rule_differences(const gmx_mtop_t* mtop,
+static void check_combination_rule_differences(const gmx_mtop_t& mtop,
int state,
bool* bC6ParametersWorkWithGeometricRules,
bool* bC6ParametersWorkWithLBRules,
ptr = getenv("GMX_LJCOMB_TOL");
if (ptr != nullptr)
{
- double dbl;
+ double dbl;
double gmx_unused canary;
if (sscanf(ptr, "%lf%lf", &dbl, &canary) != 1)
{
- gmx_fatal(FARGS,
- "Could not parse a single floating-point number from GMX_LJCOMB_TOL (%s)", ptr);
+ gmx_fatal(
+ FARGS, "Could not parse a single floating-point number from GMX_LJCOMB_TOL (%s)", ptr);
}
tol = dbl;
}
*bC6ParametersWorkWithLBRules = TRUE;
*bC6ParametersWorkWithGeometricRules = TRUE;
bCanDoLBRules = TRUE;
- ntypes = mtop->ffparams.atnr;
+ ntypes = mtop.ffparams.atnr;
snew(typecount, ntypes);
gmx_mtop_count_atomtypes(mtop, state, typecount);
*bLBRulesPossible = TRUE;
for (tpi = 0; tpi < ntypes; ++tpi)
{
- c6i = mtop->ffparams.iparams[(ntypes + 1) * tpi].lj.c6;
- c12i = mtop->ffparams.iparams[(ntypes + 1) * tpi].lj.c12;
+ c6i = mtop.ffparams.iparams[(ntypes + 1) * tpi].lj.c6;
+ c12i = mtop.ffparams.iparams[(ntypes + 1) * tpi].lj.c12;
for (tpj = tpi; tpj < ntypes; ++tpj)
{
- c6j = mtop->ffparams.iparams[(ntypes + 1) * tpj].lj.c6;
- c12j = mtop->ffparams.iparams[(ntypes + 1) * tpj].lj.c12;
- c6 = mtop->ffparams.iparams[ntypes * tpi + tpj].lj.c6;
+ c6j = mtop.ffparams.iparams[(ntypes + 1) * tpj].lj.c6;
+ c12j = mtop.ffparams.iparams[(ntypes + 1) * tpj].lj.c12;
+ c6 = mtop.ffparams.iparams[ntypes * tpi + tpj].lj.c6;
c6_geometric = std::sqrt(c6i * c6j);
if (!gmx_numzero(c6_geometric))
{
sfree(typecount);
}
-static void check_combination_rules(const t_inputrec* ir, const gmx_mtop_t* mtop, warninp_t wi)
+static void check_combination_rules(const t_inputrec* ir, const gmx_mtop_t& mtop, warninp_t wi)
{
bool bLBRulesPossible, bC6ParametersWorkWithGeometricRules, bC6ParametersWorkWithLBRules;
- check_combination_rule_differences(mtop, 0, &bC6ParametersWorkWithGeometricRules,
- &bC6ParametersWorkWithLBRules, &bLBRulesPossible);
- if (ir->ljpme_combination_rule == eljpmeLB)
+ check_combination_rule_differences(
+ mtop, 0, &bC6ParametersWorkWithGeometricRules, &bC6ParametersWorkWithLBRules, &bLBRulesPossible);
+ if (ir->ljpme_combination_rule == LongRangeVdW::LB)
{
if (!bC6ParametersWorkWithLBRules || !bLBRulesPossible)
{
{
if (!bC6ParametersWorkWithGeometricRules)
{
- if (ir->eDispCorr != edispcNO)
+ if (ir->eDispCorr != DispersionCorrectionType::No)
{
warning_note(wi,
"You are using geometric combination rules in "
void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_t wi)
{
// Not meeting MTS requirements should have resulted in a fatal error, so we can assert here
- gmx::assertMtsRequirements(*ir);
+ GMX_ASSERT(gmx::checkMtsRequirements(*ir).empty(), "All MTS requirements should be met here");
char err_buf[STRLEN];
int i, m, c, nmol;
- bool bCharge, bAcc;
- real * mgrp, mt;
- rvec acc;
+ bool bCharge;
gmx_mtop_atomloop_block_t aloopb;
char warn_buf[STRLEN];
set_warning_line(wi, mdparin, -1);
- if (allTrue(haveAbsoluteReference(*ir)) && allTrue(havePositionRestraints(*sys)))
- if (ir->comm_mode != ecmNO && allTrue(havePositionRestraints(*sys)))
++ if (ir->comm_mode != ComRemovalAlgorithm::No && allTrue(havePositionRestraints(*sys)))
{
warning_note(wi,
"Removing center of mass motion in the presence of position restraints might "
"macro-molecule, the artifacts are usually negligible.");
}
- if (ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0 && ir->nstlist > 1
- && ((EI_MD(ir->eI) || EI_SD(ir->eI)) && (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN)))
+ if (ir->cutoff_scheme == CutoffScheme::Verlet && ir->verletbuf_tol > 0 && ir->nstlist > 1
+ && ((EI_MD(ir->eI) || EI_SD(ir->eI))
+ && (ir->etc == TemperatureCoupling::VRescale || ir->etc == TemperatureCoupling::Berendsen)))
{
/* Check if a too small Verlet buffer might potentially
* cause more drift than the thermostat can couple off.
* of errors. The factor 0.5 is because energy distributes
* equally over Ekin and Epot.
*/
- max_T_error = 0.5 * tau * ir->verletbuf_tol / (nrdf_at * BOLTZ * T);
+ max_T_error = 0.5 * tau * ir->verletbuf_tol / (nrdf_at * gmx::c_boltz * T);
if (max_T_error > T_error_warn)
{
sprintf(warn_buf,
"of %g and a tau_t of %g, your temperature might be off by up to %.1f%%. "
"To ensure the error is below %.1f%%, decrease verlet-buffer-tolerance to "
"%.0e or decrease tau_t.",
- ir->verletbuf_tol, T, tau, 100 * max_T_error, 100 * T_error_suggest,
+ ir->verletbuf_tol,
+ T,
+ tau,
+ 100 * max_T_error,
+ 100 * T_error_suggest,
ir->verletbuf_tol * T_error_suggest / max_T_error);
warning(wi, warn_buf);
}
sprintf(err_buf,
"all tau_t must be positive using Andersen temperature control, "
"tau_t[%d]=%10.6f",
- i, ir->opts.tau_t[i]);
+ i,
+ ir->opts.tau_t[i]);
CHECK(ir->opts.tau_t[i] < 0);
}
- if (ir->etc == etcANDERSENMASSIVE && ir->comm_mode != ecmNO)
+ if (ir->etc == TemperatureCoupling::AndersenMassive && ir->comm_mode != ComRemovalAlgorithm::No)
{
for (i = 0; i < ir->opts.ngtc; i++)
{
"multiple of nstcomm (%d), as velocities of atoms in coupled groups are "
"randomized every time step. The input tau_t (%8.3f) leads to %d steps per "
"randomization",
- i, etcoupl_names[ir->etc], ir->nstcomm, ir->opts.tau_t[i], nsteps);
+ i,
+ enumValueToString(ir->etc),
+ ir->nstcomm,
+ ir->opts.tau_t[i],
+ nsteps);
CHECK(nsteps % ir->nstcomm != 0);
}
}
}
- if (EI_DYNAMICS(ir->eI) && !EI_SD(ir->eI) && ir->eI != eiBD && ir->comm_mode == ecmNO
+ if (EI_DYNAMICS(ir->eI) && !EI_SD(ir->eI) && ir->eI != IntegrationAlgorithm::BD
+ && ir->comm_mode == ComRemovalAlgorithm::No
&& !(allTrue(haveAbsoluteReference(*ir)) || allTrue(havePositionRestraints(*sys)) || ir->nsteps <= 10)
&& !ETC_ANDERSEN(ir->etc))
{
"rounding errors can lead to build up of kinetic energy of the center of mass");
}
- if (ir->epc == epcPARRINELLORAHMAN && ir->etc == etcNOSEHOOVER)
+ if (ir->epc == PressureCoupling::ParrinelloRahman && ir->etc == TemperatureCoupling::NoseHoover)
{
real tau_t_max = 0;
for (int g = 0; g < ir->opts.ngtc; g++)
std::string message = gmx::formatString(
"With %s T-coupling and %s p-coupling, "
"%s (%g) should be at least twice as large as %s (%g) to avoid resonances",
- etcoupl_names[ir->etc], epcoupl_names[ir->epc], "tau-p", ir->tau_p, "tau-t",
+ enumValueToString(ir->etc),
+ enumValueToString(ir->epc),
+ "tau-p",
+ ir->tau_p,
+ "tau-t",
tau_t_max);
warning(wi, message.c_str());
}
}
/* Check for pressure coupling with absolute position restraints */
- if (ir->epc != epcNO && ir->refcoord_scaling == erscNO)
+ if (ir->epc != PressureCoupling::No && ir->refcoord_scaling == RefCoordScaling::No)
{
const BasicVector<bool> havePosres = havePositionRestraints(*sys);
{
}
bCharge = FALSE;
- aloopb = gmx_mtop_atomloop_block_init(sys);
+ aloopb = gmx_mtop_atomloop_block_init(*sys);
const t_atom* atom;
while (gmx_mtop_atomloop_block_next(aloopb, &atom, &nmol))
{
"You are using full electrostatics treatment %s for a system without charges.\n"
"This costs a lot of performance for just processing zeros, consider using %s "
"instead.\n",
- EELTYPE(ir->coulombtype), EELTYPE(eelCUT));
+ enumValueToString(ir->coulombtype),
+ enumValueToString(CoulombInteractionType::Cut));
warning(wi, err_buf);
}
}
else
{
- if (ir->coulombtype == eelCUT && ir->rcoulomb > 0)
+ if (ir->coulombtype == CoulombInteractionType::Cut && ir->rcoulomb > 0)
{
sprintf(err_buf,
"You are using a plain Coulomb cut-off, which might produce artifacts.\n"
"You might want to consider using %s electrostatics.\n",
- EELTYPE(eelPME));
+ enumValueToString(CoulombInteractionType::Pme));
warning_note(wi, err_buf);
}
}
/* Check if combination rules used in LJ-PME are the same as in the force field */
if (EVDW_PME(ir->vdwtype))
{
- check_combination_rules(ir, sys, wi);
+ check_combination_rules(ir, *sys, wi);
}
/* Generalized reaction field */
- if (ir->coulombtype == eelGRF_NOTUSED)
+ if (ir->coulombtype == CoulombInteractionType::GRFNotused)
{
warning_error(wi,
"Generalized reaction-field electrostatics is no longer supported. "
"constant by hand.");
}
- bAcc = FALSE;
- for (int i = 0; (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++)
- {
- for (m = 0; (m < DIM); m++)
- {
- if (fabs(ir->opts.acc[i][m]) > 1e-6)
- {
- bAcc = TRUE;
- }
- }
- }
- if (bAcc)
- {
- clear_rvec(acc);
- snew(mgrp, sys->groups.groups[SimulationAtomGroupType::Acceleration].size());
- for (const AtomProxy atomP : AtomRange(*sys))
- {
- const t_atom& local = atomP.atom();
- int i = atomP.globalAtomNumber();
- mgrp[getGroupType(sys->groups, SimulationAtomGroupType::Acceleration, i)] += local.m;
- }
- mt = 0.0;
- for (i = 0; (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++)
- {
- for (m = 0; (m < DIM); m++)
- {
- acc[m] += ir->opts.acc[i][m] * mgrp[i];
- }
- mt += mgrp[i];
- }
- for (m = 0; (m < DIM); m++)
- {
- if (fabs(acc[m]) > 1e-6)
- {
- const char* dim[DIM] = { "X", "Y", "Z" };
- fprintf(stderr, "Net Acceleration in %s direction, will %s be corrected\n", dim[m],
- ir->nstcomm != 0 ? "" : "not");
- if (ir->nstcomm != 0 && m < ndof_com(ir))
- {
- acc[m] /= mt;
- for (i = 0;
- (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++)
- {
- ir->opts.acc[i][m] -= acc[m];
- }
- }
- }
- }
- sfree(mgrp);
- }
-
- if (ir->efep != efepNO && ir->fepvals->sc_alpha != 0
+ if (ir->efep != FreeEnergyPerturbationType::No && ir->fepvals->sc_alpha != 0
&& !gmx_within_tol(sys->ffparams.reppow, 12.0, 10 * GMX_DOUBLE_EPS))
{
gmx_fatal(FARGS, "Soft-core interactions are only supported with VdW repulsion power 12");
bWarned = FALSE;
for (i = 0; i < ir->pull->ncoord && !bWarned; i++)
{
- if (ir->pull->coord[i].group[0] == 0 || ir->pull->coord[i].group[1] == 0)
+ if (ir->pull->coord[i].eGeom != PullGroupGeometry::Transformation
+ && (ir->pull->coord[i].group[0] == 0 || ir->pull->coord[i].group[1] == 0))
{
const auto absRef = haveAbsoluteReference(*ir);
const auto havePosres = havePositionRestraints(*sys);
{
for (m = 0; m <= i; m++)
{
- if ((ir->epc != epcNO && ir->compress[i][m] != 0) || ir->deform[i][m] != 0)
+ if ((ir->epc != PressureCoupling::No && ir->compress[i][m] != 0) || ir->deform[i][m] != 0)
{
for (c = 0; c < ir->pull->ncoord; c++)
{
- if (ir->pull->coord[c].eGeom == epullgDIRPBC && ir->pull->coord[c].vec[m] != 0)
+ if (ir->pull->coord[c].eGeom == PullGroupGeometry::DirectionPBC
+ && ir->pull->coord[c].vec[m] != 0)
{
gmx_fatal(FARGS,
"Can not have dynamic box while using pull geometry '%s' "
"(dim %c)",
- EPULLGEOM(ir->pull->coord[c].eGeom), 'x' + m);
+ enumValueToString(ir->pull->coord[c].eGeom),
+ 'x' + m);
}
}
}
}
}
- check_disre(sys);
+ check_disre(*sys);
}
void double_check(t_inputrec* ir, matrix box, bool bHasNormalConstraints, bool bHasAnyConstraints, warninp_t wi)
warning_error(wi, ptr);
}
- if (bHasNormalConstraints && ir->eConstrAlg == econtSHAKE)
+ if (bHasNormalConstraints && ir->eConstrAlg == ConstraintAlgorithm::Shake)
{
if (ir->shake_tol <= 0.0)
{
}
}
- if ((ir->eConstrAlg == econtLINCS) && bHasNormalConstraints)
+ if ((ir->eConstrAlg == ConstraintAlgorithm::Lincs) && bHasNormalConstraints)
{
/* If we have Lincs constraints: */
- if (ir->eI == eiMD && ir->etc == etcNO && ir->eConstrAlg == econtLINCS && ir->nLincsIter == 1)
+ if (ir->eI == IntegrationAlgorithm::MD && ir->etc == TemperatureCoupling::No
+ && ir->eConstrAlg == ConstraintAlgorithm::Lincs && ir->nLincsIter == 1)
{
sprintf(warn_buf,
"For energy conservation with LINCS, lincs_iter should be 2 or larger.\n");
warning_note(wi, warn_buf);
}
- if ((ir->eI == eiCG || ir->eI == eiLBFGS) && (ir->nProjOrder < 8))
+ if ((ir->eI == IntegrationAlgorithm::CG || ir->eI == IntegrationAlgorithm::LBFGS)
+ && (ir->nProjOrder < 8))
{
sprintf(warn_buf,
"For accurate %s with LINCS constraints, lincs-order should be 8 or more.",
- ei_names[ir->eI]);
+ enumValueToString(ir->eI));
warning_note(wi, warn_buf);
}
- if (ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::Mttk)
{
warning_error(wi, "MTTK not compatible with lincs -- use shake instead.");
}
}
- if (bHasAnyConstraints && ir->epc == epcMTTK)
+ if (bHasAnyConstraints && ir->epc == PressureCoupling::Mttk)
{
warning_error(wi, "Constraints are not implemented with MTTK pressure control.");
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2019,2020,2021, 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.
*/
#if GMX_DOUBLE
F77_FUNC(dsyevr, DSYEVR)
- (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, &abstol, &m, eigenvalues,
- eigenvectors, &n, isuppz, &w0, &lwork, &iw0, &liwork, &info);
+ (jobz,
+ "I",
+ "L",
+ &n,
+ a,
+ &n,
+ &vl,
+ &vu,
+ &index_lower,
+ &index_upper,
+ &abstol,
+ &m,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ isuppz,
+ &w0,
+ &lwork,
+ &iw0,
+ &liwork,
+ &info);
#else
F77_FUNC(ssyevr, SSYEVR)
- (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, &abstol, &m, eigenvalues,
- eigenvectors, &n, isuppz, &w0, &lwork, &iw0, &liwork, &info);
+ (jobz,
+ "I",
+ "L",
+ &n,
+ a,
+ &n,
+ &vl,
+ &vu,
+ &index_lower,
+ &index_upper,
+ &abstol,
+ &m,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ isuppz,
+ &w0,
+ &lwork,
+ &iw0,
+ &liwork,
+ &info);
#endif
if (info != 0)
{
sfree(isuppz);
- gmx_fatal(FARGS, "Internal errror in LAPACK diagonalization.");
+ gmx_fatal(FARGS, "Internal error in LAPACK diagonalization.");
}
lwork = static_cast<int>(w0);
#if GMX_DOUBLE
F77_FUNC(dsyevr, DSYEVR)
- (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, &abstol, &m, eigenvalues,
- eigenvectors, &n, isuppz, work, &lwork, iwork, &liwork, &info);
+ (jobz,
+ "I",
+ "L",
+ &n,
+ a,
+ &n,
+ &vl,
+ &vu,
+ &index_lower,
+ &index_upper,
+ &abstol,
+ &m,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ isuppz,
+ work,
+ &lwork,
+ iwork,
+ &liwork,
+ &info);
#else
F77_FUNC(ssyevr, SSYEVR)
- (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, &abstol, &m, eigenvalues,
- eigenvectors, &n, isuppz, work, &lwork, iwork, &liwork, &info);
+ (jobz,
+ "I",
+ "L",
+ &n,
+ a,
+ &n,
+ &vl,
+ &vu,
+ &index_lower,
+ &index_upper,
+ &abstol,
+ &m,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ isuppz,
+ work,
+ &lwork,
+ iwork,
+ &liwork,
+ &info);
#endif
sfree(isuppz);
{
# if GMX_DOUBLE
F77_FUNC(pdsaupd, PDSAUPD)
- (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork,
- workl, &lworkl, &info);
+ (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork, workl, &lworkl, &info);
# else
F77_FUNC(pssaupd, PSSAUPD)
- (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork,
- workl, &lworkl, &info);
+ (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork, workl, &lworkl, &info);
# endif
if (ido == -1 || ido == 1)
{
gmx_fatal(FARGS,
"Maximum number of iterations (%d) reached in Arnoldi\n"
"diagonalization, but only %d of %d eigenvectors converged.\n",
- maxiter, iparam[4], neig);
+ maxiter,
+ iparam[4],
+ neig);
}
else if (info != 0)
{
# if GMX_DOUBLE
F77_FUNC(pdseupd, PDSEUPD)
- (&dovec, "A", select, eigenvalues, eigenvectors, &n, NULL, "I", &n, "SA", &neig, &abstol, resid,
- &ncv, v, &n, iparam, ipntr, workd, workl, &lworkl, &info);
+ (&dovec,
+ "A",
+ select,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ NULL,
+ "I",
+ &n,
+ "SA",
+ &neig,
+ &abstol,
+ resid,
+ &ncv,
+ v,
+ &n,
+ iparam,
+ ipntr,
+ workd,
+ workl,
+ &lworkl,
+ &info);
# else
F77_FUNC(psseupd, PSSEUPD)
- (&dovec, "A", select, eigenvalues, eigenvectors, &n, NULL, "I", &n, "SA", &neig, &abstol, resid,
- &ncv, v, &n, iparam, ipntr, workd, workl, &lworkl, &info);
+ (&dovec,
+ "A",
+ select,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ NULL,
+ "I",
+ &n,
+ "SA",
+ &neig,
+ &abstol,
+ resid,
+ &ncv,
+ v,
+ &n,
+ iparam,
+ ipntr,
+ workd,
+ workl,
+ &lworkl,
+ &info);
# endif
sfree(v);
{
#if GMX_DOUBLE
F77_FUNC(dsaupd, DSAUPD)
- (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork,
- workl, &lworkl, &info);
+ (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork, workl, &lworkl, &info);
#else
F77_FUNC(ssaupd, SSAUPD)
- (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork,
- workl, &lworkl, &info);
+ (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork, workl, &lworkl, &info);
#endif
if (ido == -1 || ido == 1)
{
gmx_fatal(FARGS,
"Maximum number of iterations (%d) reached in Arnoldi\n"
"diagonalization, but only %d of %d eigenvectors converged.\n",
- maxiter, iparam[4], neig);
+ maxiter,
+ iparam[4],
+ neig);
}
else if (info != 0)
{
#if GMX_DOUBLE
F77_FUNC(dseupd, DSEUPD)
- (&dovec, "A", select, eigenvalues, eigenvectors, &n, nullptr, "I", &n, "SA", &neig, &abstol,
- resid, &ncv, v, &n, iparam, ipntr, workd, workl, &lworkl, &info);
+ (&dovec,
+ "A",
+ select,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ nullptr,
+ "I",
+ &n,
+ "SA",
+ &neig,
+ &abstol,
+ resid,
+ &ncv,
+ v,
+ &n,
+ iparam,
+ ipntr,
+ workd,
+ workl,
+ &lworkl,
+ &info);
#else
F77_FUNC(sseupd, SSEUPD)
- (&dovec, "A", select, eigenvalues, eigenvectors, &n, nullptr, "I", &n, "SA", &neig, &abstol,
- resid, &ncv, v, &n, iparam, ipntr, workd, workl, &lworkl, &info);
+ (&dovec,
+ "A",
+ select,
+ eigenvalues,
+ eigenvectors,
+ &n,
+ nullptr,
+ "I",
+ &n,
+ "SA",
+ &neig,
+ &abstol,
+ resid,
+ &ncv,
+ v,
+ &n,
+ iparam,
+ ipntr,
+ workd,
+ workl,
+ &lworkl,
+ &info);
#endif
sfree(v);
const std::string& simdString(SimdType s)
{
- static const std::map<SimdType, std::string> name = {
- { SimdType::None, "None" },
- { SimdType::Reference, "Reference" },
- { SimdType::Generic, "Generic" },
- { SimdType::X86_Sse2, "SSE2" },
- { SimdType::X86_Sse4_1, "SSE4.1" },
- { SimdType::X86_Avx128Fma, "AVX_128_FMA" },
- { SimdType::X86_Avx, "AVX_256" },
- { SimdType::X86_Avx2, "AVX2_256" },
- { SimdType::X86_Avx2_128, "AVX2_128" },
- { SimdType::X86_Avx512, "AVX_512" },
- { SimdType::X86_Avx512Knl, "AVX_512_KNL" },
- { SimdType::X86_Mic, "X86_MIC" },
- { SimdType::Arm_Neon, "ARM_NEON" },
- { SimdType::Arm_NeonAsimd, "ARM_NEON_ASIMD" },
- { SimdType::Arm_Sve, "ARM_SVE" },
- { SimdType::Ibm_Vmx, "IBM_VMX" },
- { SimdType::Ibm_Vsx, "IBM_VSX" },
- { SimdType::Fujitsu_HpcAce, "Fujitsu HPC-ACE" }
- };
+ static const std::map<SimdType, std::string> name = { { SimdType::None, "None" },
+ { SimdType::Reference, "Reference" },
+ { SimdType::Generic, "Generic" },
+ { SimdType::X86_Sse2, "SSE2" },
+ { SimdType::X86_Sse4_1, "SSE4.1" },
+ { SimdType::X86_Avx128Fma, "AVX_128_FMA" },
+ { SimdType::X86_Avx, "AVX_256" },
+ { SimdType::X86_Avx2, "AVX2_256" },
+ { SimdType::X86_Avx2_128, "AVX2_128" },
+ { SimdType::X86_Avx512, "AVX_512" },
+ { SimdType::X86_Avx512Knl, "AVX_512_KNL" },
+ { SimdType::Arm_NeonAsimd,
+ "ARM_NEON_ASIMD" },
+ { SimdType::Arm_Sve, "ARM_SVE" },
+ { SimdType::Ibm_Vsx, "IBM_VSX" } };
return name.at(s);
}
-namespace
-{
-
-
-//! Helper to detect correct AMD Zen architecture.
-bool cpuIsAmdZen1(const CpuInfo& cpuInfo)
-{
- // Both Zen/Zen+/Zen2 have family==23
- // Model numbers for Zen:
- // 1) Naples, Whitehaven, Summit ridge, and Snowy Owl
- // 17) Raven ridge
- // Model numbers for Zen+:
- // 8) Pinnacle Ridge
- // 24) Picasso
- return (cpuInfo.vendor() == gmx::CpuInfo::Vendor::Amd && cpuInfo.family() == 23
- && (cpuInfo.model() == 1 || cpuInfo.model() == 17 || cpuInfo.model() == 8
- || cpuInfo.model() == 24));
-}
-
-} // namespace
-
-
SimdType simdSuggested(const CpuInfo& c)
{
SimdType suggested = SimdType::None;
}
else if (c.feature(CpuInfo::Feature::Arm_Neon))
{
- suggested = SimdType::Arm_Neon;
+ suggested = SimdType::None;
}
break;
case CpuInfo::Vendor::Ibm:
}
else if (c.feature(CpuInfo::Feature::Ibm_Vmx))
{
- suggested = SimdType::Ibm_Vmx;
+ suggested = SimdType::None;
}
break;
case CpuInfo::Vendor::Fujitsu:
if (c.feature(CpuInfo::Feature::Fujitsu_HpcAce))
{
- suggested = SimdType::Fujitsu_HpcAce;
+ suggested = SimdType::None;
}
break;
default: break;
return SimdType::X86_Avx512Knl;
#elif GMX_SIMD_X86_AVX_512
return SimdType::X86_Avx512;
-#elif GMX_SIMD_X86_MIC
- return SimdType::X86_Mic;
#elif GMX_SIMD_X86_AVX2_256
return SimdType::X86_Avx2;
#elif GMX_SIMD_X86_AVX2_128
return SimdType::X86_Sse4_1;
#elif GMX_SIMD_X86_SSE2
return SimdType::X86_Sse2;
-#elif GMX_SIMD_ARM_NEON
- return SimdType::Arm_Neon;
#elif GMX_SIMD_ARM_NEON_ASIMD
return SimdType::Arm_NeonAsimd;
#elif GMX_SIMD_ARM_SVE
return SimdType::Arm_Sve;
-#elif GMX_SIMD_IBM_VMX
- return SimdType::Ibm_Vmx;
#elif GMX_SIMD_IBM_VSX
return SimdType::Ibm_Vsx;
-#elif GMX_SIMD_SPARC64_HPC_ACE
- return SimdType::Fujitsu_HpcAce;
#elif GMX_SIMD_REFERENCE
return SimdType::Reference;
#else
if (compiled == SimdType::X86_Avx2 && wanted == SimdType::X86_Avx512)
{
logMsg = wrapper.wrapToString(formatString(
- "Highest SIMD level requested by all nodes in run: %s\n"
+ "Highest SIMD level supported by all nodes in run: %s\n"
"SIMD instructions selected at compile time: %s\n"
"This program was compiled for different hardware than you are running on, "
"which could influence performance. This build might have been configured on "
"a login node with only a single AVX-512 FMA unit (in which case AVX2 is faster), "
"while the node you are running on has dual AVX-512 FMA units.",
- simdString(wanted).c_str(), simdString(compiled).c_str()));
+ simdString(wanted).c_str(),
+ simdString(compiled).c_str()));
warnMsg = wrapper.wrapToString(formatString(
"Compiled SIMD: %s, but for this host/run %s might be better (see log).",
- simdString(compiled).c_str(), simdString(wanted).c_str()));
+ simdString(compiled).c_str(),
+ simdString(wanted).c_str()));
}
else if (compiled == SimdType::X86_Avx512 && wanted == SimdType::X86_Avx2
&& identifyAvx512FmaUnits() == 1)
{
// The reason for explicitly checking the number of FMA units above is to avoid triggering
- // this conditional if the AVX2 SIMD was requested by some other node in a heterogeneous MPI run.
+ // this conditional if the AVX2 SIMD was supported by some other node in a heterogeneous MPI run.
logMsg = wrapper.wrapToString(formatString(
- "Highest SIMD level requested by all nodes in run: %s\n"
+ "Highest SIMD level supported by all nodes in run: %s\n"
"SIMD instructions selected at compile time: %s\n"
"This program was compiled for different hardware than you are running on, "
"which could influence performance."
"This host supports AVX-512, but since it only has 1 AVX-512"
"FMA unit, it would be faster to use AVX2 instead.",
- simdString(wanted).c_str(), simdString(compiled).c_str()));
+ simdString(wanted).c_str(),
+ simdString(compiled).c_str()));
warnMsg = wrapper.wrapToString(formatString(
"Compiled SIMD: %s, but for this host/run %s might be better (see log).",
- simdString(compiled).c_str(), simdString(wanted).c_str()));
+ simdString(compiled).c_str(),
+ simdString(wanted).c_str()));
}
else if (compiled == SimdType::X86_Avx2 && wanted == SimdType::X86_Avx2_128)
{
// the supported one, but AVX128Fma is an exception: AMD CPUs will (strongly) prefer
// AVX128Fma, but they will work fine with AVX too. Thus, make an exception for this.
logMsg = wrapper.wrapToString(
- formatString("Highest SIMD level requested by all nodes in run: %s\n"
+ formatString("Highest SIMD level supported by all nodes in run: %s\n"
"SIMD instructions selected at compile time: %s\n"
- "Compiled SIMD newer than requested; program might crash.",
+ "Compiled SIMD newer than supported; program might crash.",
- simdString(wanted).c_str(), simdString(compiled).c_str()));
+ simdString(wanted).c_str(),
+ simdString(compiled).c_str()));
warnMsg = logMsg;
}
else if (wanted != compiled)
{
// This warning will also occur if compiled is X86_Avx and wanted is X86_Avx128Fma
logMsg = wrapper.wrapToString(formatString(
- "Highest SIMD level requested by all nodes in run: %s\n"
+ "Highest SIMD level supported by all nodes in run: %s\n"
"SIMD instructions selected at compile time: %s\n"
"This program was compiled for different hardware than you are running on, "
"which could influence performance.",
- simdString(wanted).c_str(), simdString(compiled).c_str()));
+ simdString(wanted).c_str(),
+ simdString(compiled).c_str()));
warnMsg = wrapper.wrapToString(formatString(
"Compiled SIMD: %s, but for this host/run %s might be better (see log).",
- simdString(compiled).c_str(), simdString(wanted).c_str()));
+ simdString(compiled).c_str(),
+ simdString(wanted).c_str()));
#if GMX_SIMD_ARM_SVE
}
else if ((compiled == SimdType::Arm_Sve) && (svcntb() != GMX_SIMD_ARM_SVE_LENGTH_VALUE / 8))
{
logMsg = wrapper.wrapToString(formatString(
- "Longest SVE length requested by all nodes in run: %d\n"
+ "Longest SVE length supported by all nodes in run: %d\n"
"SVE length selected at compile time: %ld\n"
"This program was compiled for different hardware than you are running on, "
"which will lead to incorrect behavior.\n"
"Aborting",
- GMX_SIMD_ARM_SVE_LENGTH_VALUE, svcntb() * 8));
+ GMX_SIMD_ARM_SVE_LENGTH_VALUE,
+ svcntb() * 8));
warnMsg = wrapper.wrapToString(formatString(
"Compiled SVE Length: %d, but for this process requires %ld (see log).",
- GMX_SIMD_ARM_SVE_LENGTH_VALUE, svcntb() * 8));
+ GMX_SIMD_ARM_SVE_LENGTH_VALUE,
+ svcntb() * 8));
#endif
}
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, 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.
fprintf(stderr,
"Energy files don't match, different number of energies:\n"
" %s: %d\n %s: %d\n",
- files[f - 1].c_str(), nresav, files[f].c_str(), fr->nre);
+ files[f - 1].c_str(),
+ nresav,
+ files[f].c_str(),
+ fr->nre);
fprintf(stderr,
"\nContinue conversion using only the first %d terms (n/y)?\n"
"(you should be sure that the energy terms match)\n",
"Reads one energy file and writes another, applying the [TT]-dt[tt],",
"[TT]-offset[tt], [TT]-t0[tt] and [TT]-settime[tt] options and",
"converting to a different format if necessary (indicated by file",
- "extentions).[PAR]",
+ "extensions).[PAR]",
"[TT]-settime[tt] is applied first, then [TT]-dt[tt]/[TT]-offset[tt]",
"followed by [TT]-b[tt] and [TT]-e[tt] to select which frames to write."
};
{ "-error", FALSE, etBOOL, { &bError }, "Stop on errors in the file" }
};
- if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc,
- asize(bugs), bugs, &oenv))
+ if (!parse_common_args(
+ &argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
{
return 0;
}
if (debug)
{
- fprintf(debug, "fr->step %s, fr->t %.4f, fro->step %s fro->t %.4f, w %s\n",
- gmx_step_str(fr->step, buf), fr->t, gmx_step_str(fro->step, buf2), fro->t,
+ fprintf(debug,
+ "fr->step %s, fr->t %.4f, fro->step %s fro->t %.4f, w %s\n",
+ gmx_step_str(fr->step, buf),
+ fr->t,
+ gmx_step_str(fro->step, buf2),
+ fro->t,
gmx::boolToString(bWrite));
}
if (bNewOutput)
{
bNewOutput = FALSE;
- fprintf(stderr, "\nContinue writing frames from t=%g, step=%s\n", fro->t,
+ fprintf(stderr,
+ "\nContinue writing frames from t=%g, step=%s\n",
+ fro->t,
gmx_step_str(fro->step, buf));
}
"samples away.\n"
" Use g_energy -odh option to extract these "
"samples.\n",
- files[f].c_str(), size);
+ files[f].c_str(),
+ size);
warned_about_dh = TRUE;
break;
}
{
f--;
}
- printf("\nLast step written from %s: t %g, step %s\n", files[f].c_str(), last_t,
+ printf("\nLast step written from %s: t %g, step %s\n",
+ files[f].c_str(),
+ last_t,
gmx_step_str(laststep, buf));
lastfilestep = laststep;
}
else
{
- fprintf(stderr, "Last frame written was at step %s, time %f\n",
- gmx_step_str(fro->step, buf), fro->t);
+ fprintf(stderr, "Last frame written was at step %s, time %f\n", gmx_step_str(fro->step, buf), fro->t);
fprintf(stderr, "Wrote %d frames\n", noutfr);
}
fprintf(stderr,
"Do you REALLY want to truncate this trajectory (%s) at:\n"
"frame %d, time %g, bytes %ld ??? (type YES if so)\n",
- fn, j, t, static_cast<long int>(fpos));
+ fn,
+ j,
+ t,
+ static_cast<long int>(fpos));
if (1 != scanf("%s", yesno))
{
gmx_fatal(FARGS, "Error reading user input");
const char* fit[efNR + 1] = { nullptr, "none", "rot+trans", "rotxy+transxy",
"translation", "transxy", "progressive", nullptr };
- static gmx_bool bSeparate = FALSE, bVels = TRUE, bForce = FALSE, bCONECT = FALSE;
- static gmx_bool bCenter = FALSE;
- static int skip_nr = 1, ndec = 3, nzero = 0;
- static real tzero = 0, delta_t = 0, timestep = 0, ttrunc = -1, tdump = -1, split_t = 0;
- static rvec newbox = { 0, 0, 0 }, shift = { 0, 0, 0 }, trans = { 0, 0, 0 };
- static char* exec_command = nullptr;
- static real dropunder = 0, dropover = 0;
- static gmx_bool bRound = FALSE;
+ gmx_bool bSeparate = FALSE, bVels = TRUE, bForce = FALSE, bCONECT = FALSE;
+ gmx_bool bCenter = FALSE;
+ int skip_nr = 1, ndec = 3, nzero = 0;
+ real tzero = 0, delta_t = 0, timestep = 0, ttrunc = -1, tdump = -1, split_t = 0;
+ rvec newbox = { 0, 0, 0 }, shift = { 0, 0, 0 }, trans = { 0, 0, 0 };
+ char* exec_command = nullptr;
+ real dropunder = 0, dropover = 0;
+ gmx_bool bRound = FALSE;
t_pargs pa[] = {
{ "-skip", FALSE, etINT, { &skip_nr }, "Only write every nr-th frame" },
FALSE,
etBOOL,
{ &bCONECT },
- "Add conect records when writing [REF].pdb[ref] files. Useful "
+ "Add CONECT PDB records when writing [REF].pdb[ref] files. Useful "
"for visualization of non-standard molecules, e.g. "
"coarse grained ones" }
};
{ efXVG, "-drop", "drop", ffOPTRD } };
#define NFILE asize(fnm)
- if (!parse_common_args(&argc, argv, PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | PCA_TIME_UNIT,
- NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv))
+ if (!parse_common_args(&argc,
+ argv,
+ PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | PCA_TIME_UNIT,
+ NFILE,
+ fnm,
+ NPA,
+ pa,
+ asize(desc),
+ desc,
+ 0,
+ nullptr,
+ &oenv))
{
return 0;
}
fprintf(stderr,
"WARNING: Option for unitcell representation (-ur %s)\n"
" only has effect in combination with -pbc %s, %s or %s.\n"
- " Ignoring unitcell representation.\n\n",
- unitcell_opt[0], pbc_opt[2], pbc_opt[3], pbc_opt[4]);
+ " Ingoring unitcell representation.\n\n",
+ unitcell_opt[0],
+ pbc_opt[2],
+ pbc_opt[3],
+ pbc_opt[4]);
}
}
if (bFit && bPBC)
if (0 == top->mols.nr && (bCluster || bPBCcomMol))
{
- gmx_fatal(FARGS, "Option -pbc %s requires a .tpr file for the -s option",
- pbc_opt[pbc_enum]);
+ gmx_fatal(FARGS, "Option -pbc %s requires a .tpr file for the -s option", pbc_opt[pbc_enum]);
}
/* top_title is only used for gro and pdb,
"Index[%d] %d is larger than the number of atoms in the\n"
"trajectory file (%d). There is a mismatch in the contents\n"
"of your -f, -s and/or -n files.",
- i, index[i] + 1, natoms);
+ i,
+ index[i] + 1,
+ natoms);
}
bCopy = bCopy || (i != index[i]);
}
switch (ftp)
{
case efTNG:
- trxout = trjtools_gmx_prepare_tng_writing(
- out_file, filemode[0], trxin, nullptr, nout, mtop.get(),
- gmx::arrayRefFromArray(index, nout), grpnm);
+ trxout = trjtools_gmx_prepare_tng_writing(out_file,
+ filemode[0],
+ trxin,
+ nullptr,
+ nout,
+ mtop.get(),
+ gmx::arrayRefFromArray(index, nout),
+ grpnm);
break;
case efXTC:
case efTRR:
if (bTDump)
{
- fprintf(stderr, "\nDumping frame at t= %g %s\n",
+ fprintf(stderr,
+ "\nDumping frame at t= %g %s\n",
output_env_conv_time(oenv, frout_time),
output_env_get_time_unit(oenv).c_str());
}
else
{
/* round() is not C89 compatible, so we do this: */
- bDoIt = bRmod(std::floor(frout_time + 0.5), std::floor(tzero + 0.5),
+ bDoIt = bRmod(std::floor(frout_time + 0.5),
+ std::floor(tzero + 0.5),
std::floor(delta_t + 0.5));
}
}
/* print sometimes */
if (((outframe % SKIP) == 0) || (outframe < SKIP))
{
- fprintf(stderr, " -> frame %6d time %8.3f \r", outframe,
+ fprintf(stderr,
+ " -> frame %6d time %8.3f \r",
+ outframe,
output_env_conv_time(oenv, frout_time));
fflush(stderr);
}
put_atoms_in_triclinic_unitcell(ecenter, fr.box, positionsArrayRef);
break;
case euCompact:
- put_atoms_in_compact_unitcell(pbcType, ecenter, fr.box,
- positionsArrayRef);
+ put_atoms_in_compact_unitcell(
+ pbcType, ecenter, fr.box, positionsArrayRef);
break;
}
}
if (bPBCcomRes)
{
- put_residue_com_in_box(unitcell_enum, ecenter, natoms, atoms->atom,
- pbcType, fr.box, fr.x);
+ put_residue_com_in_box(
+ unitcell_enum, ecenter, natoms, atoms->atom, pbcType, fr.box, fr.x);
}
if (bPBCcomMol)
{
- put_molecule_com_in_box(unitcell_enum, ecenter, &top->mols, natoms,
- atoms->atom, pbcType, fr.box, fr.x);
+ put_molecule_com_in_box(
+ unitcell_enum, ecenter, &top->mols, natoms, atoms->atom, pbcType, fr.box, fr.x);
}
/* Copy the input trxframe struct to the output trxframe struct */
frout = fr;
/* round() is not C89 compatible, so we do this: */
bSplitHere = bSplit
&& bRmod(std::floor(frout.time + 0.5),
- std::floor(tzero + 0.5), std::floor(split_t + 0.5));
+ std::floor(tzero + 0.5),
+ std::floor(split_t + 0.5));
}
if (bSeparate || bSplitHere)
{
switch (ftp)
{
case efGRO:
- write_hconf_p(out, title.c_str(), &useatoms, frout.x,
- frout.bV ? frout.v : nullptr, frout.box);
+ write_hconf_p(out,
+ title.c_str(),
+ &useatoms,
+ frout.x,
+ frout.bV ? frout.v : nullptr,
+ frout.box);
break;
case efPDB:
fprintf(out, "REMARK GENERATED BY TRJCONV\n");
{
model_nr++;
}
- write_pdbfile(out, title.c_str(), &useatoms, frout.x,
- frout.pbcType, frout.box, ' ', model_nr, gc);
+ write_pdbfile(out,
+ title.c_str(),
+ &useatoms,
+ frout.x,
+ frout.pbcType,
+ frout.box,
+ ' ',
+ model_nr,
+ gc);
break;
case efG96:
const char* outputTitle = "";
{ "With a Lead Filled Snowshoe", "F. Zappa" },
{ "Right Between the Eyes", "F. Zappa" },
{ "BioBeat is Not Available In Regular Shops", "P.J. Meulenhoff" },
- { "Rub It Right Accross Your Eyes", "F. Zappa" },
+ { "Rub It Right Across Your Eyes", "F. Zappa" },
{ "Shake Yourself", "YES" },
{ "I Am a Wonderful Thing", "Kid Creole" },
{ "Way to Go Dude", "Beavis and Butthead" },
{ "Disturb the Peace of a John Q Citizen", "Urban Dance Squad" },
{ "Wicky-wicky Wa-wild West", "Will Smith" },
{ "This is Tense !", "Star Wars Episode I The Phantom Menace" },
- { "Fly to the Court of England and Unfold",
- "Macbeth, Act 3, Scene 6, William Shakespeare" },
+ { "Fly to the Court of England and Unfold", "Macbeth, Act 3, Scene 6, William Shakespeare" },
{ "Why, how now, Claudio ! Whence Comes this Restraint ?",
"Lucio in Measure for measure, Act 1, Scene 4, William Shakespeare" },
{ "In the End Science Comes Down to Praying", "P. v.d. Berg" },
{ "Nobody Never Learnt No-Nothing from No History", "Gogol Bordello" },
{ "I'd be Safe and Warm if I was in L.A.", "The Mamas and the Papas" },
{ "It's Unacceptable That Chocolate Makes You Fat", "MI 3" },
- { "My Brothers are Protons (Protons!), My Sisters are Neurons (Neurons)",
- "Gogol Bordello" },
+ { "My Brothers are Protons (Protons!), My Sisters are Neurons (Neurons)", "Gogol Bordello" },
{ "Put Me Inside SSC, Let's Test Superstring Theory, Oh Yoi Yoi Accelerate the Protons",
"Gogol Bordello" },
{ "Do You Have Sex Maniacs or Schizophrenics or Astrophysicists in Your Family?",
{ "The scientific method is an integral part of human intelligence, and when it has once "
"been set at work it can only be dismissed by dismissing the intelligence itself",
"George H. Mead" },
- { "Der Ball ist rund, das Spiel dauert 90 minuten, alles andere ist Theorie",
- "Lola rennt" },
+ { "Der Ball ist rund, das Spiel dauert 90 minuten, alles andere ist Theorie", "Lola rennt" },
{ "Life in the streets is not easy", "Marky Mark" },
{ "How will I know it's working right?", "MGMT" },
{ "There was no preconception on what to do", "Daft Punk" },
{ "All sorts of things can happen when you're open to new ideas and playing around with "
"things.",
"Stephanie Kwolek, inventor of Kevlar" },
- { "As always in life, people want a simple answer... and it's always wrong.",
- "Marie Daly" },
+ { "As always in life, people want a simple answer... and it's always wrong.", "Marie Daly" },
{ "For a research worker the unforgotten moments of his life are those rare ones which "
"come after years of plodding work, when the veil over natures secret seems suddenly to "
"lift & when what was dark & chaotic appears in a clear & beautiful light & pattern.",
"3-phosphoshikimate-carboxyvinyl transferase?' Shopkeeper: 'You mean Roundup?' "
"Scientist: 'Yeah, that's it. I can never remember that dang name!'",
"John Pickett" },
- { "It is not clear that intelligence has any long-term survival value.",
- "Stephen Hawking" },
+ { "It is not clear that intelligence has any long-term survival value.", "Stephen Hawking" },
{ "The greatest shortcoming of the human race is our inability to understand the "
"exponential function.",
"Albert Bartlett" },
"married, it never occurred to him to verify this statement by examining his wives' "
"mouths.",
"Bertrand Russell" },
- { "I had trouble with physics in college. When I signed up I thought it said psychics.",
- "Greg Tamblyn" },
{ "I don't believe in astrology; I'm a Sagittarian and we're skeptical.",
"Arthur C. Clarke" },
{ "I see they found out the universe is 80 million years older than we thought. It's also "
"attempted.",
"Anonymous" },
{ "If my PhD doesn't allow me to be right on the internet, what is it even good for?",
- "Martin Vögele" }
+ "Martin Vögele" },
+ { "A little less conversation, a little more action, please.", "Elvis Presley" },
+ { "Friends don't let friends use Berendsen!", "John Chodera (on Twitter)" }
};
if (beCool())