/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 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.
#include <algorithm>
#include <vector>
-#include "gromacs/mdtypes/mdatom.h"
#include "gromacs/utility/arrayref.h"
namespace gmx
DensityFittingAmplitudeLookupImpl(const DensityFittingAmplitudeLookupImpl&) = default;
virtual ~DensityFittingAmplitudeLookupImpl() = default;
- virtual const std::vector<real>& operator()(const t_mdatoms& atoms, ArrayRef<const int> localIndex) = 0;
- virtual std::unique_ptr<DensityFittingAmplitudeLookupImpl> clone() = 0;
+ virtual const std::vector<real>& operator()(ArrayRef<const real> /*chargeA*/,
+ ArrayRef<const real> /*massT*/,
+ ArrayRef<const int> localIndex) = 0;
+ virtual std::unique_ptr<DensityFittingAmplitudeLookupImpl> clone() = 0;
};
namespace
UnitAmplitudes(const UnitAmplitudes&) = default;
~UnitAmplitudes() override = default;
std::unique_ptr<DensityFittingAmplitudeLookupImpl> clone() override;
- const std::vector<real>& operator()(const t_mdatoms& atoms, ArrayRef<const int> localIndex) override;
+ const std::vector<real>& operator()(ArrayRef<const real> /*chargeA*/,
+ ArrayRef<const real> /*massT*/,
+ ArrayRef<const int> localIndex) override;
private:
std::vector<real> amplitude_;
return std::make_unique<UnitAmplitudes>(*this);
};
-const std::vector<real>& UnitAmplitudes::operator()(const t_mdatoms& /*atoms*/, ArrayRef<const int> localIndex)
+const std::vector<real>& UnitAmplitudes::operator()(ArrayRef<const real> /*chargeA*/,
+ ArrayRef<const real> /*massT*/,
+ ArrayRef<const int> localIndex)
{
if (amplitude_.size() != localIndex.size())
{
ChargesAsAmplitudes(const ChargesAsAmplitudes&) = default;
~ChargesAsAmplitudes() override = default;
std::unique_ptr<DensityFittingAmplitudeLookupImpl> clone() override;
- const std::vector<real>& operator()(const t_mdatoms& atoms, ArrayRef<const int> localIndex) override;
+ const std::vector<real>& operator()(ArrayRef<const real> chargeA,
+ ArrayRef<const real> /*massT*/,
+ ArrayRef<const int> localIndex) override;
private:
std::vector<real> amplitude_;
return std::make_unique<ChargesAsAmplitudes>(*this);
};
-const std::vector<real>& ChargesAsAmplitudes::operator()(const t_mdatoms& atoms, ArrayRef<const int> localIndex)
+const std::vector<real>& ChargesAsAmplitudes::operator()(ArrayRef<const real> chargeA,
+ ArrayRef<const real> /*massT*/,
+ ArrayRef<const int> localIndex)
{
if (amplitude_.size() != localIndex.size())
{
std::transform(std::begin(localIndex),
std::end(localIndex),
std::begin(amplitude_),
- [&atoms](gmx::index index) { return atoms.chargeA[index]; });
+ [&chargeA](gmx::index index) { return chargeA[index]; });
return amplitude_;
}
MassesAsAmplitudes(const MassesAsAmplitudes&) = default;
~MassesAsAmplitudes() override = default;
std::unique_ptr<DensityFittingAmplitudeLookupImpl> clone() override;
- const std::vector<real>& operator()(const t_mdatoms& atoms, ArrayRef<const int> localIndex) override;
+ const std::vector<real>& operator()(ArrayRef<const real> /*chargeA*/,
+ ArrayRef<const real> massT,
+ ArrayRef<const int> localIndex) override;
private:
std::vector<real> amplitude_;
return std::make_unique<MassesAsAmplitudes>(*this);
};
-const std::vector<real>& MassesAsAmplitudes::operator()(const t_mdatoms& atoms, ArrayRef<const int> localIndex)
+const std::vector<real>& MassesAsAmplitudes::operator()(ArrayRef<const real> /*chargeA*/,
+ ArrayRef<const real> massT,
+ ArrayRef<const int> localIndex)
{
if (amplitude_.size() != localIndex.size())
{
std::transform(std::begin(localIndex),
std::end(localIndex),
std::begin(amplitude_),
- [&atoms](gmx::index index) { return atoms.massT[index]; });
+ [&massT](gmx::index index) { return massT[index]; });
return amplitude_;
}
}
}
-const std::vector<real>& DensityFittingAmplitudeLookup::operator()(const t_mdatoms& atoms,
- ArrayRef<const int> localIndex)
+const std::vector<real>& DensityFittingAmplitudeLookup::operator()(ArrayRef<const real> chargeA,
+ ArrayRef<const real> massT,
+ ArrayRef<const int> localIndex)
{
- return (*impl_)(atoms, localIndex);
+ return (*impl_)(chargeA, massT, localIndex);
}
DensityFittingAmplitudeLookup::~DensityFittingAmplitudeLookup() = default;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 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.
#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/real.h"
-struct t_mdatoms;
-
namespace gmx
{
//! Move assignment
DensityFittingAmplitudeLookup& operator=(DensityFittingAmplitudeLookup&& other) noexcept;
/*! \brief Return the amplitudes for spreading atoms of a given local index.
- * \param[in] atoms the atom information
+ * \param[in] chargeA Atom charges
+ * \param[in] massT Atom masses.
* \param[in] localIndex the local atom indices
* \returns amplitudes
*/
- const std::vector<real>& operator()(const t_mdatoms& atoms, ArrayRef<const int> localIndex);
+ const std::vector<real>& operator()(ArrayRef<const real> chargeA,
+ ArrayRef<const real> massT,
+ ArrayRef<const int> localIndex);
private:
std::unique_ptr<DensityFittingAmplitudeLookupImpl> impl_;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 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.
// spread atoms on grid
gaussTransform_.setZero();
- std::vector<real> amplitudes =
- amplitudeLookup_(forceProviderInput.mdatoms_, localAtomSet_.localIndex());
+ std::vector<real> amplitudes = amplitudeLookup_(
+ forceProviderInput.chargeA_, forceProviderInput.massT_, localAtomSet_.localIndex());
if (parameters_.normalizeDensities_)
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 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.
class DensityFittingAmplitudeLookupTest : public ::testing::Test
{
-public:
- DensityFittingAmplitudeLookupTest()
- {
- atoms_.nr = numberOfAtoms_;
- atoms_.massT = masses_.data();
- atoms_.chargeA = charges_.data();
- }
-
protected:
int numberOfAtoms_ = 3;
std::vector<real> masses_ = { 2, 3, 4 };
TEST_F(DensityFittingAmplitudeLookupTest, Unity)
{
DensityFittingAmplitudeLookup lookup(DensityFittingAmplitudeMethod::Unity);
- const auto lookupResult = lookup(atoms_, lookupIndices_);
+ const auto lookupResult = lookup(charges_, masses_, lookupIndices_);
EXPECT_EQ(lookupResult[0], 1);
EXPECT_EQ(lookupResult[1], 1);
}
TEST_F(DensityFittingAmplitudeLookupTest, Charge)
{
DensityFittingAmplitudeLookup lookup(DensityFittingAmplitudeMethod::Charge);
- const auto lookupResult = lookup(atoms_, lookupIndices_);
+ const auto lookupResult = lookup(charges_, masses_, lookupIndices_);
EXPECT_EQ(lookupResult[0], 30);
EXPECT_EQ(lookupResult[1], 40);
}
TEST_F(DensityFittingAmplitudeLookupTest, Masses)
{
DensityFittingAmplitudeLookup lookup(DensityFittingAmplitudeMethod::Mass);
- const auto lookupResult = lookup(atoms_, lookupIndices_);
+ const auto lookupResult = lookup(charges_, masses_, lookupIndices_);
EXPECT_EQ(lookupResult[0], 3);
EXPECT_EQ(lookupResult[1], 4);
}
{
DensityFittingAmplitudeLookup lookup(DensityFittingAmplitudeMethod::Unity);
DensityFittingAmplitudeLookup lookupCopied = lookup;
- const auto lookupResult = lookupCopied(atoms_, lookupIndices_);
+ const auto lookupResult = lookupCopied(charges_, masses_, lookupIndices_);
EXPECT_EQ(lookupResult[0], 1);
EXPECT_EQ(lookupResult[1], 1);
}
{
DensityFittingAmplitudeLookup lookup(DensityFittingAmplitudeMethod::Unity);
DensityFittingAmplitudeLookup lookupCopied(lookup);
- const auto lookupResult = lookupCopied(atoms_, lookupIndices_);
+ const auto lookupResult = lookupCopied(charges_, masses_, lookupIndices_);
EXPECT_EQ(lookupResult[0], 1);
EXPECT_EQ(lookupResult[1], 1);
}
{
DensityFittingAmplitudeLookup lookup(DensityFittingAmplitudeMethod::Unity);
DensityFittingAmplitudeLookup lookupCopied = std::move(lookup);
- const auto lookupResult = lookupCopied(atoms_, lookupIndices_);
+ const auto lookupResult = lookupCopied(charges_, masses_, lookupIndices_);
EXPECT_EQ(lookupResult[0], 1);
EXPECT_EQ(lookupResult[1], 1);
}
{
DensityFittingAmplitudeLookup lookup(DensityFittingAmplitudeMethod::Unity);
DensityFittingAmplitudeLookup lookupCopied(std::move(lookup));
- const auto lookupResult = lookupCopied(atoms_, lookupIndices_);
+ const auto lookupResult = lookupCopied(charges_, masses_, lookupIndices_);
EXPECT_EQ(lookupResult[0], 1);
EXPECT_EQ(lookupResult[1], 1);
}
#include "gromacs/mdtypes/imdmodule.h"
#include "gromacs/mdtypes/imdoutputprovider.h"
#include "gromacs/mdtypes/imdpoptionprovider.h"
-#include "gromacs/mdtypes/mdatom.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/ioptionscontainerwithsections.h"
#include "gromacs/options/optionsection.h"
{
if (isActive())
{
- const t_mdatoms& mdatoms = forceProviderInput.mdatoms_;
- const double t = forceProviderInput.t_;
- const t_commrec& cr = forceProviderInput.cr_;
+ const double t = forceProviderInput.t_;
+ const t_commrec& cr = forceProviderInput.cr_;
// NOTE: The non-conservative electric field does not have a virial
ArrayRef<RVec> f = forceProviderOutput->forceWithVirial_.force_;
+ auto chargeA = forceProviderInput.chargeA_;
for (int m = 0; (m < DIM); m++)
{
const real fieldStrength = gmx::c_fieldfac * field(m, t);
if (fieldStrength != 0)
{
// TODO: Check parallellism
- for (int i = 0; i < mdatoms.homenr; ++i)
+ for (int i = 0; i < forceProviderInput.homenr_; ++i)
{
// NOTE: Not correct with perturbed charges
- f[i][m] += mdatoms.chargeA[i] * fieldStrength;
+ f[i][m] += chargeA[i] * fieldStrength;
}
}
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,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.
}
// Prepare a ForceProviderInput
- t_mdatoms md;
- std::vector<real> chargeA{ 1 };
- md.homenr = ssize(chargeA);
- md.chargeA = chargeA.data();
+ std::vector<real> chargeA{ 1 };
t_commrec cr;
matrix boxDummy = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
- ForceProviderInput forceProviderInput({}, md, 0.0, boxDummy, cr);
+ ForceProviderInput forceProviderInput({}, ssize(chargeA), chargeA, {}, 0.0, boxDummy, cr);
// Prepare a ForceProviderOutput
PaddedVector<RVec> f = { { 0, 0, 0 } };
*/
if (stepWork.computeForces)
{
- gmx::ForceProviderInput forceProviderInput(x, *mdatoms, t, box, *cr);
+ gmx::ForceProviderInput forceProviderInput(
+ x,
+ mdatoms->homenr,
+ gmx::arrayRefFromArray(mdatoms->chargeA, mdatoms->homenr),
+ gmx::arrayRefFromArray(mdatoms->massT, mdatoms->homenr),
+ t,
+ box,
+ *cr);
gmx::ForceProviderOutput forceProviderOutput(forceWithVirialMtsLevel0, enerd);
/* Collect forces from modules */
struct gmx_enerdata_t;
struct t_commrec;
struct t_forcerec;
-struct t_mdatoms;
namespace gmx
{
public:
/*! \brief Constructor assembles all necessary force provider input data
*
- * \param[in] x Atomic positions
- * \param[in] cr Communication record structure
- * \param[in] box The simulation box
- * \param[in] time The current time in the simulation
- * \param[in] mdatoms The atomic data
+ * \param[in] x Atomic positions.
+ * \param[in] homenr Number of atoms on the domain.
+ * \param[in] chargeA Atomic charges for atoms on the domain.
+ * \param[in] massT Atomic masses for atoms on the domain.
+ * \param[in] time The current time in the simulation.
+ * \param[in] box The simulation box.
+ * \param[in] cr Communication record structure.
*/
ForceProviderInput(ArrayRef<const RVec> x,
- const t_mdatoms& mdatoms,
+ int homenr,
+ ArrayRef<const real> chargeA,
+ ArrayRef<const real> massT,
double time,
const matrix box,
const t_commrec& cr) :
x_(x),
- mdatoms_(mdatoms),
+ homenr_(homenr),
+ chargeA_(chargeA),
+ massT_(massT),
t_(time),
cr_(cr)
{
copy_mat(box, box_);
}
- ArrayRef<const RVec> x_; //!< The atomic positions
- const t_mdatoms& mdatoms_; //!< Atomic data
- double t_; //!< The current time in the simulation
+ ArrayRef<const RVec> x_; //!< The atomic positions
+ int homenr_;
+ ArrayRef<const real> chargeA_;
+ ArrayRef<const real> massT_;
+ double t_; //!< The current time in the simulation
matrix box_ = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; //!< The simulation box
const t_commrec& cr_; //!< Communication record structure
};
/*
* 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.
{
GMX_ASSERT(restraint_, "Restraint must be initialized.");
- const auto& mdatoms = forceProviderInput.mdatoms_;
- GMX_ASSERT(mdatoms.homenr >= 0, "number of home atoms must be non-negative.");
+ const int homenr = forceProviderInput.homenr_;
+ GMX_ASSERT(homenr >= 0, "number of home atoms must be non-negative.");
const auto& box = forceProviderInput.box_;
GMX_ASSERT(check_box(PbcType::Unset, box) == nullptr, "Invalid box.");
const auto& cr = forceProviderInput.cr_;
const auto& t = forceProviderInput.t_;
// Cooperatively get Cartesian coordinates for center of mass of each site
- RVec r1 = sites_[0].centerOfMass(cr, static_cast<size_t>(mdatoms.homenr), x, t);
+ RVec r1 = sites_[0].centerOfMass(cr, static_cast<size_t>(homenr), x, t);
// r2 is to be constructed as
// r2 = (site[N] - site[N-1]) + (site_{N-1} - site_{N-2}) + ... + (site_2 - site_1) + site_1
// where the minimum image convention is applied to each path but not to the overall sum.
// a big molecule in a small box.
for (size_t i = 0; i < sites_.size() - 1; ++i)
{
- RVec a = sites_[i].centerOfMass(cr, static_cast<size_t>(mdatoms.homenr), x, t);
- RVec b = sites_[i + 1].centerOfMass(cr, static_cast<size_t>(mdatoms.homenr), x, t);
+ RVec a = sites_[i].centerOfMass(cr, static_cast<size_t>(homenr), x, t);
+ RVec b = sites_[i + 1].centerOfMass(cr, static_cast<size_t>(homenr), x, t);
// dr = minimum_image_vector(b - a)
pbc_dx(&pbc, b, a, dr);
r2[0] += dr[0];