diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index a109f50be4..869f6982e9 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -122,7 +122,7 @@ jobs: submodules: true - name: Create Python Environment - uses: mamba-org/setup-micromamba@617811f69075e3fd3ae68ca64220ad065877f246 # v2.0.0 + uses: mamba-org/setup-micromamba@06375d89d211a1232ef63355742e9e2e564bc7f7 # v2.0.2 with: micromamba-version: '2.0.2-2' environment-name: test @@ -219,7 +219,7 @@ jobs: path: code - name: Create Python Environment - uses: mamba-org/setup-micromamba@617811f69075e3fd3ae68ca64220ad065877f246 # v2.0.0 + uses: mamba-org/setup-micromamba@06375d89d211a1232ef63355742e9e2e564bc7f7 # v2.0.2 with: micromamba-version: '2.0.2-2' environment-name: test diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 7c9085c6a8..e1ad37c190 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -86,7 +86,7 @@ jobs: name: release - name: Create release - uses: softprops/action-gh-release@e7a8f85e1c67a31e6ed99a94b41bd0b71bbee6b8 # v2.0.9 + uses: softprops/action-gh-release@01570a1f39cb168c169c802c3bceb9e93fb10974 # v2.1.0 if: startsWith(github.ref, 'refs/tags/v') with: files: "*.tar.*" diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 66851357f7..a10151710f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,18 @@ Change Log 5.x --- +*Added* +* Wang-Frenkel potential + +5.0.1 (not yet released) +^^^^^^^^^^^^^^^^^^^^^^^^ + +*Fixed* + +* Prevent ``missing 1 required positional argument: 'kT'`` errors when using NEC integrators + (`#1965 `__) + + 5.0.0 (2024-12-02) ^^^^^^^^^^^^^^^^^^ diff --git a/hoomd/HOOMDMath.h b/hoomd/HOOMDMath.h index c2f5cfc890..6aa7f1ef37 100644 --- a/hoomd/HOOMDMath.h +++ b/hoomd/HOOMDMath.h @@ -349,6 +349,50 @@ inline HOSTDEVICE double pow(double x, double y) return ::exp(y * log(x)); } +//! Compute the pow of x,y in double precision when y is an integer using squaring +inline HOSTDEVICE double pow(double x, unsigned int y){ + double result = 1.0; + for(;;){ + if(y & 1) + result *= x; + y >>= 1; + if(!y) + break; + x *= x; + } + return result; + } + +inline HOSTDEVICE double pow(double x, int y){ + unsigned int _y = abs(y); + if(y < 0) + return 1.0 / pow(x, _y); + else + return pow(x,_y); + } + +//! Compute the pow of x,y in single precision when y is an integer using squaring +inline HOSTDEVICE float pow(float x, unsigned int y){ + float result = 1.0f; + for(;;){ + if(y & 1) + result *= x; + y >>= 1; + if(!y) + break; + x *= x; + } + return result; + } + +inline HOSTDEVICE float pow(float x, int y){ + unsigned int _y = abs(y); + if(y < 0) + return 1.0f / pow(x, _y); + else + return pow(x,_y); + } + //! Compute the exp of x inline HOSTDEVICE float exp(float x) { diff --git a/hoomd/hpmc/IntegratorHPMCMonoNEC.h b/hoomd/hpmc/IntegratorHPMCMonoNEC.h index c15a45fcd5..e0c6a33ae7 100644 --- a/hoomd/hpmc/IntegratorHPMCMonoNEC.h +++ b/hoomd/hpmc/IntegratorHPMCMonoNEC.h @@ -275,17 +275,12 @@ template void IntegratorHPMCMonoNEC::update(uint64_t timeste this->m_exec_conf->msg->notice(10) << "HPMCMonoEC update: " << timestep << std::endl; IntegratorHPMC::update(timestep); - // get needed vars - ArrayHandle h_counters(this->m_count_total, - access_location::host, - access_mode::readwrite); - hpmc_counters_t& counters = h_counters.data[0]; - - ArrayHandle h_nec_counters(m_nec_count_total, - access_location::host, - access_mode::readwrite); - hpmc_nec_counters_t& nec_counters = h_nec_counters.data[0]; - m_nec_count_step_start = h_nec_counters.data[0]; + { + ArrayHandle h_nec_counters(m_nec_count_total, + access_location::host, + access_mode::readwrite); + m_nec_count_step_start = h_nec_counters.data[0]; + } const BoxDim& box = this->m_pdata->getBox(); unsigned int ndim = this->m_sysdef->getNDimensions(); @@ -294,29 +289,6 @@ template void IntegratorHPMCMonoNEC::update(uint64_t timeste count_pressurevirial = 0.0; count_movelength = 0.0; - // access interaction matrix - ArrayHandle h_overlaps(this->m_overlaps, - access_location::host, - access_mode::read); - ArrayHandle h_image(this->m_pdata->getImages(), - access_location::host, - access_mode::readwrite); - - // access particle data - ArrayHandle h_postype(this->m_pdata->getPositions(), - access_location::host, - access_mode::readwrite); - ArrayHandle h_velocities(this->m_pdata->getVelocities(), - access_location::host, - access_mode::readwrite); - ArrayHandle h_orientation(this->m_pdata->getOrientationArray(), - access_location::host, - access_mode::readwrite); - - // access move sizes - ArrayHandle h_d(this->m_d, access_location::host, access_mode::read); - ArrayHandle h_a(this->m_a, access_location::host, access_mode::read); - uint16_t seed = this->m_sysdef->getSeed(); // loop over local particles nselect times @@ -333,6 +305,40 @@ template void IntegratorHPMCMonoNEC::update(uint64_t timeste // update the image list this->updateImageList(); + // get needed vars + ArrayHandle h_counters(this->m_count_total, + access_location::host, + access_mode::readwrite); + hpmc_counters_t& counters = h_counters.data[0]; + + ArrayHandle h_nec_counters(m_nec_count_total, + access_location::host, + access_mode::readwrite); + hpmc_nec_counters_t& nec_counters = h_nec_counters.data[0]; + + // access interaction matrix + ArrayHandle h_overlaps(this->m_overlaps, + access_location::host, + access_mode::read); + ArrayHandle h_image(this->m_pdata->getImages(), + access_location::host, + access_mode::readwrite); + + // access particle data + ArrayHandle h_postype(this->m_pdata->getPositions(), + access_location::host, + access_mode::readwrite); + ArrayHandle h_velocities(this->m_pdata->getVelocities(), + access_location::host, + access_mode::readwrite); + ArrayHandle h_orientation(this->m_pdata->getOrientationArray(), + access_location::host, + access_mode::readwrite); + + // access move sizes + ArrayHandle h_d(this->m_d, access_location::host, access_mode::read); + ArrayHandle h_a(this->m_a, access_location::host, access_mode::read); + // loop through N particles in a shuffled order for (unsigned int cur_chain = 0; cur_chain < this->m_pdata->getN() * m_update_fraction; cur_chain++) diff --git a/hoomd/hpmc/compute.py b/hoomd/hpmc/compute.py index b1361aefdf..fede9c0b37 100644 --- a/hoomd/hpmc/compute.py +++ b/hoomd/hpmc/compute.py @@ -7,8 +7,6 @@ particles and `SDF` samples the pressure. """ -from __future__ import print_function - from hoomd import _hoomd from hoomd.operation import Compute from hoomd.hpmc import _hpmc diff --git a/hoomd/hpmc/nec/integrate.py b/hoomd/hpmc/nec/integrate.py index 4e6a6ab324..bbec925d40 100644 --- a/hoomd/hpmc/nec/integrate.py +++ b/hoomd/hpmc/nec/integrate.py @@ -72,7 +72,7 @@ def __init__( nselect=1, ): # initialize base class - super().__init__(default_d, default_a, 0.5, nselect) + super().__init__(default_d, default_a, 0.5, nselect, 1.0) # Set base parameter dict for hpmc chain integrators param_dict = ParameterDict( diff --git a/hoomd/hpmc/pytest/CMakeLists.txt b/hoomd/hpmc/pytest/CMakeLists.txt index 1c1f9ac70c..abecd740b0 100644 --- a/hoomd/hpmc/pytest/CMakeLists.txt +++ b/hoomd/hpmc/pytest/CMakeLists.txt @@ -13,9 +13,10 @@ set(files __init__.py test_shape_updater.py test_shape_utils.py test_move_size_tuner.py + test_nec.py test_pair_lennard_jones.py test_pair_expanded_gaussian.py - test_pair_lj_gauss.py + test_pair_lj_gauss.py test_pair_opp.py test_pair_step.py test_pair_union.py diff --git a/hoomd/hpmc/pytest/test_nec.py b/hoomd/hpmc/pytest/test_nec.py new file mode 100644 index 0000000000..c8f2b5ac30 --- /dev/null +++ b/hoomd/hpmc/pytest/test_nec.py @@ -0,0 +1,15 @@ +# Copyright (c) 2009-2024 The Regents of the University of Michigan. +# Part of HOOMD-blue, released under the BSD 3-Clause License. + +import hoomd +import pytest + + +@pytest.mark.serial +def test_nec(simulation_factory, lattice_snapshot_factory): + snap = lattice_snapshot_factory(particle_types=["A"]) + simulation = simulation_factory(snap) + sphere = hoomd.hpmc.nec.integrate.Sphere() + sphere.shape["A"] = {"diameter": 1.0} + simulation.operations.integrator = sphere + simulation.run(10) diff --git a/hoomd/md/CMakeLists.txt b/hoomd/md/CMakeLists.txt index e44ec847f5..1ef7afd842 100644 --- a/hoomd/md/CMakeLists.txt +++ b/hoomd/md/CMakeLists.txt @@ -126,6 +126,7 @@ set(_md_headers ActiveForceComputeGPU.h EvaluatorPairTable.h EvaluatorPairTWF.h EvaluatorPairYukawa.h + EvaluatorPairWangFrenkel.h EvaluatorPairZBL.h EvaluatorTersoff.h EvaluatorWalls.h @@ -556,7 +557,8 @@ set(_pair_evaluators Buckingham LJGauss ForceShiftedLJ Table - ExpandedGaussian) + ExpandedGaussian + WangFrenkel) foreach(_evaluator ${_pair_evaluators}) diff --git a/hoomd/md/EvaluatorPairWangFrenkel.h b/hoomd/md/EvaluatorPairWangFrenkel.h new file mode 100644 index 0000000000..3ecac68cb0 --- /dev/null +++ b/hoomd/md/EvaluatorPairWangFrenkel.h @@ -0,0 +1,213 @@ +// Copyright (c) 2009-2024 The Regents of the University of Michigan. +// Part of HOOMD-blue, released under the BSD 3-Clause License. + +#ifndef __PAIR_EVALUATOR_WANGFRENKEL_H__ +#define __PAIR_EVALUATOR_WANGFRENKEL_H__ + +#ifndef __HIPCC__ +#include +#endif + +#include "hoomd/HOOMDMath.h" + +/*! \file EvaluatorPairWangFrenkel.h + \brief Defines the pair evaluator class for Wang-Frenkel potentials + \details As the prototypical example of a MD pair potential, this also serves as the primary + documentation and base reference for the implementation of pair evaluators. +*/ + +// need to declare these class methods with __device__ qualifiers when building in nvcc +// DEVICE is __host__ __device__ when included in nvcc and blank when included into the host +// compiler +#ifdef __HIPCC__ +#define DEVICE __device__ +#define HOSTDEVICE __host__ __device__ +#else +#define DEVICE +#define HOSTDEVICE +#endif + +namespace hoomd + { +namespace md + { +//! Class for evaluating the Wang-Frenkel pair potential +/*! General Overview + + See EvaluatorPairLJ. + + Wang-Frenkel specifics + + EvaluatorPairWang-Frenkel evaluates the function: + \f[ \epsilon \alpha \left( \left[\frac{\sigma}{r}\right]^{2\mu} -1\right)\left(\left[\frac{R}{r}\right]^{2\mu} -1 \left)^{2\nu} \f] +*/ +class EvaluatorPairWangFrenkel + { + public: + //! Define the parameter type used by this pair potential evaluator + struct param_type + { + Scalar prefactor; + Scalar sigma_pow_2m; + Scalar R_pow_2m; + int mu; + int nu; + + DEVICE void load_shared(char*& ptr, unsigned int& available_bytes) { } + + HOSTDEVICE void allocate_shared(char*& ptr, unsigned int& available_bytes) const { } + +#ifdef ENABLE_HIP + // set CUDA memory hints + void set_memory_hint() const { } +#endif + +#ifndef __HIPCC__ + param_type() : prefactor(0.0), sigma_pow_2m(0.0), R_pow_2m(0.0), mu(0.0), nu(0.0) { } + + param_type(pybind11::dict v, bool managed = false) + { + // should probably send a warning if exponents are large (eg >256) + mu = v["mu"].cast(); + nu = v["nu"].cast(); + + if(nu == 0 || mu == 0) + throw std::invalid_argument("Cannot set exponents nu or mu to zero"); + + Scalar epsilon = v["epsilon"].cast(); + Scalar sigma = v["sigma"].cast(); + Scalar sigma_sq = sigma * sigma; + Scalar rcut = v["R"].cast(); + Scalar rcutsq = rcut * rcut; + Scalar left = (1 + 2 * nu) / (2* nu * (fast::pow(rcutsq / sigma_sq, mu) - 1)); + Scalar alpha = 2 * nu * fast::pow(rcutsq / sigma_sq, mu) * fast::pow(left, 2*nu + 1); + + prefactor = epsilon * alpha; + R_pow_2m = fast::pow(rcutsq, mu); + sigma_pow_2m = fast::pow(sigma_sq, mu); + } + + pybind11::dict asDict() + { + pybind11::dict v; + v["mu"] = mu; + v["nu"] = nu; + Scalar sigma = fast::pow(sigma_pow_2m, 1.0 / (2.0*Scalar(mu))); + v["sigma"] = sigma; + Scalar sigma_sq = sigma * sigma; + v["R"] = fast::pow(R_pow_2m, 1/Scalar(2*mu)); + Scalar rcutsq = fast::pow(R_pow_2m, 1/Scalar(mu)); + Scalar left = (1 + 2 * nu) / (2* nu * (fast::pow(rcutsq / sigma_sq, mu) - 1)); + Scalar alpha = 2 * nu * fast::pow(rcutsq / sigma_sq, mu) * fast::pow(left, 2*nu + 1); + + v["epsilon"] = prefactor / alpha; + + return v; + } +#endif + } __attribute__((aligned(16))); + + //! Constructs the pair potential evaluator + /*! \param _rsq Squared distance between the particles + \param _rcutsq Squared distance at which the potential goes to 0 + \param _params Per type pair parameters of this potential + */ + DEVICE EvaluatorPairWangFrenkel(Scalar _rsq, Scalar _rcutsq, const param_type& _params) + : rsq(_rsq), rcutsq(_rcutsq), prefactor(_params.prefactor), + sigma_pow_2m(_params.sigma_pow_2m), R_pow_2m(_params.R_pow_2m), mu(_params.mu), nu(_params.nu) + { + } + + //! Mie doesn't use charge + DEVICE static bool needsCharge() + { + return false; + } + //! Accept the optional charge values. + /*! \param qi Charge of particle i + \param qj Charge of particle j + */ + DEVICE void setCharge(Scalar qi, Scalar qj) { } + + //! Evaluate the force and energy + /*! \param force_divr Output parameter to write the computed force divided by r. + \param pair_eng Output parameter to write the computed pair energy + \param energy_shift If true, the potential must be shifted so that V(r) is continuous at the + cutoff \note There is no need to check if rsq < rcutsq in this method. Cutoff tests are + performed in PotentialPair. + + \return True if they are evaluated or false if they are not because we are beyond the cutoff + */ + DEVICE bool evalForceAndEnergy(Scalar& force_divr, Scalar& pair_eng, bool energy_shift) + { + // compute the force divided by r in force_divr + if (rsq < rcutsq && prefactor != 0) + { + Scalar r2inv = Scalar(1.0) / rsq; + Scalar rinv_pow_2m = fast::pow(r2inv, mu); + Scalar sigma_over_r_pow_2m = sigma_pow_2m * rinv_pow_2m; + Scalar R_over_r_pow_2m = R_pow_2m * rinv_pow_2m; + + Scalar sigma_term = sigma_over_r_pow_2m - 1; + Scalar R_term = R_over_r_pow_2m - 1; + + Scalar R_term_2num1 = fast::pow(R_term, 2*nu - 1); + Scalar R_term_2nu = R_term_2num1 * R_term; + + pair_eng = prefactor * sigma_term * R_term_2nu; + force_divr = 2 * prefactor * mu * R_term_2num1 * (2 * nu * R_over_r_pow_2m * sigma_term + R_term * sigma_over_r_pow_2m) * r2inv; + + if(energy_shift) + { + Scalar rcinv_pow_2m = fast::pow(Scalar(1.0) / rcutsq, mu); + Scalar sigma_over_rc_pow_2m = sigma_pow_2m * rcinv_pow_2m; + Scalar R_over_rc_pow_2m = R_pow_2m * rcinv_pow_2m; + Scalar rc_R_term_2nu = fast::pow(R_over_rc_pow_2m - 1, 2*nu); + pair_eng -= prefactor * (sigma_over_rc_pow_2m - 1) * rc_R_term_2nu; + } + return true; + } + else + return false; + } + + DEVICE Scalar evalPressureLRCIntegral() + { + return 0; + } + + DEVICE Scalar evalEnergyLRCIntegral() + { + return 0; + } + +#ifndef __HIPCC__ + //! Get the name of this potential + /*! \returns The potential name. + */ + static std::string getName() + { + return std::string("wangfrenkel"); + } + + std::string getShapeSpec() const + { + throw std::runtime_error("Shape definition not supported for this pair potential."); + } +#endif + + protected: + Scalar rsq; //!< Stored rsq from the constructor + Scalar rcutsq; //!< Stored rcutsq from the constructor + + Scalar prefactor; //!< Prefactor (epsilon * alpha) + Scalar sigma_pow_2m; //!< sigma^(2m) stored + Scalar R_pow_2m; //!< R^(2m) stored + unsigned int mu; //!< mu exponent + unsigned int nu; //!< nu exponent + }; + + } // end namespace md + } // end namespace hoomd + +#endif // __PAIR_EVALUATOR_WANGFRENKEL_H__ diff --git a/hoomd/md/module-md.cc b/hoomd/md/module-md.cc index bb00f7e68e..946ad22129 100644 --- a/hoomd/md/module-md.cc +++ b/hoomd/md/module-md.cc @@ -66,6 +66,7 @@ void export_PotentialPairTWF(pybind11::module& m); void export_PotentialPairLJGauss(pybind11::module& m); void export_PotentialPairForceShiftedLJ(pybind11::module& m); void export_PotentialPairTable(pybind11::module& m); +void export_PotentialPairWangFrenkel(pybind11::module& m); void export_AnisoPotentialPairALJ2D(pybind11::module& m); void export_AnisoPotentialPairALJ3D(pybind11::module& m); @@ -221,6 +222,7 @@ void export_PotentialPairDLVOGPU(pybind11::module& m); void export_PotentialPairFourierGPU(pybind11::module& m); void export_PotentialPairOPPGPU(pybind11::module& m); void export_PotentialPairTWFGPU(pybind11::module& m); +void export_PotentialPairWangFrenkelGPU(pybind11::module&); void export_PotentialPairLJGaussGPU(pybind11::module& m); void export_PotentialPairForceShiftedLJGPU(pybind11::module& m); void export_PotentialPairTableGPU(pybind11::module& m); @@ -364,6 +366,7 @@ PYBIND11_MODULE(_md, m) export_PotentialPairLJGauss(m); export_PotentialPairForceShiftedLJ(m); export_PotentialPairTable(m); + export_PotentialPairWangFrenkel(m); export_AlchemicalMDParticles(m); @@ -461,6 +464,7 @@ PYBIND11_MODULE(_md, m) export_PotentialPairLJGaussGPU(m); export_PotentialPairForceShiftedLJGPU(m); export_PotentialPairTableGPU(m); + export_PotentialPairWangFrenkelGPU(m); export_PotentialPairConservativeDPDGPU(m); export_PotentialTersoffGPU(m); diff --git a/hoomd/md/pair/__init__.py b/hoomd/md/pair/__init__.py index c5de16f215..80e4963e44 100644 --- a/hoomd/md/pair/__init__.py +++ b/hoomd/md/pair/__init__.py @@ -158,6 +158,7 @@ Table, TWF, LJGauss, + WangFrenkel, ) __all__ = [ @@ -186,6 +187,7 @@ "Pair", "ReactionField", "Table", + "WangFrenkel", "Yukawa", "aniso", ] diff --git a/hoomd/md/pair/pair.py b/hoomd/md/pair/pair.py index 8b7ce9e33c..f03a781b5a 100644 --- a/hoomd/md/pair/pair.py +++ b/hoomd/md/pair/pair.py @@ -2020,3 +2020,77 @@ def __init__(self, nlist, default_r_cut=None, default_r_on=0.0, mode="none"): TypeParameterDict(epsilon=float, sigma=positive_real, r0=float, len_keys=2), ) self._add_typeparam(params) + +class WangFrenkel(Pair): + r"""Wang-Frenkel pair potential. + + Args: + nlist (hoomd.md.nlist.NeighborList): Neighbor list + default_r_cut (float): Default cutoff radius :math:`[\mathrm{length}]`. + default_r_on (float): Default turn-on radius :math:`[\mathrm{length}]`. + mode (str): Energy shifting/smoothing mode. + + `WangFrenkel` computes the Wang-Frenkel pair force on every particle + in the simulation state: + + .. math:: + U(r) = \epsilon \alpha \left( \left[\frac{\sigma}{r}\right]^{2\mu} -1\right) + \left(\left[\frac{R}{r}\right]^{2\mu} -1 \right)^{2\nu} + + .. math:: + \alpha = 2 \nu \left(\frac{R}{\sigma}\right)^{2\mu} + \left(\frac{2 \nu + 1}{2\nu \left(\left(\frac{R}{\sigma}\right)^{2\mu} - 1\right)}\right)^{2\nu + 1} + + The potential was introduced in `Xipeng Wang et al. 2020`_. + + .. _Xipeng Wang et al. 2020: + https://dx.doi.org/10.1039/c9cp05445f + + Note: + In the original paper, the parameter `R` is explicitly equal to the cutoff. + + Example:: + + nl = nlist.Cell() + WangFrenkel = pair.WangFrenkel(nlist=nl, default_r_cut=3.0) + WangFrenkel.params[("A", "A")] = dict(epsilon=1.0, sigma=1.0, R = 2**(1/6), mu=12, nu=6) + WangFrenkel.r_cut[("A", "A")] = 2 ** (1.0 / 6.0) + WangFrenkel.params[(["A", "B"], ["C", "D"])] = dict(epsilon=1.5, sigma=2.0, R = 2.5, mu=2, nu=2) + + {inherited} + + ---------- + + **Members defined in** `WangFrenkel`: + + .. py:attribute:: params + + The potential parameters. The dictionary has the following keys: + + * ``epsilon`` (`float`, **required**) - :math:`\varepsilon` + :math:`[\mathrm{energy}]` + * ``sigma`` (`float`, **required**) - :math:`\sigma` + :math:`[\mathrm{length}]` + * ``R`` (`float`, **required**) - :math:`R` + :math:`[\mathrm{length}]` + * ``mu`` (`int`, **required**) - :math:`\mu` + :math:`[\mathrm{dimensionless}]` + * ``nu`` (`int`, **required**) - :math:`\nu` + :math:`[\mathrm{dimensionless}]` + + Type: `TypeParameter` [`tuple` [``particle_type``, ``particle_type``], + `dict`] + """ + + _cpp_class_name = "PotentialPairWangFrenkel" + __doc__ = __doc__.replace("{inherited}", Pair._doc_inherited) + + def __init__(self, nlist, default_r_cut=None, default_r_on=0.0, mode="none"): + super().__init__(nlist, default_r_cut, default_r_on, mode) + params = TypeParameter( + "params", + "particle_types", + TypeParameterDict(epsilon=float, sigma=float, R=float, mu=int, nu=int, len_keys=2), + ) + + self._add_typeparam(params) diff --git a/hoomd/md/pytest/forces_and_energies.json b/hoomd/md/pytest/forces_and_energies.json index 4453651488..215ff125d7 100644 --- a/hoomd/md/pytest/forces_and_energies.json +++ b/hoomd/md/pytest/forces_and_energies.json @@ -1254,5 +1254,13 @@ 0.0454898 ] ] + }, + "WangFrenkel":{ + "params": [ + {"epsilon": 1.0, "sigma": 1.1, "R": 2.0, "mu": 1, "nu": 1}, + {"epsilon": 1.2, "sigma": 1.0, "R": 1.8, "mu": 2, "nu": 2} + ], + "forces": [[-875.5552722562251, 2.312692536680880], [-137331.43889608214, 0.042311562285607264]], + "energies": [[78.24912701572178, -0.508960147129286],[4608.71203066914, -0.002121340078925938]] } } diff --git a/hoomd/md/pytest/test_potential.py b/hoomd/md/pytest/test_potential.py index 5aa74a8899..a3e75657c1 100644 --- a/hoomd/md/pytest/test_potential.py +++ b/hoomd/md/pytest/test_potential.py @@ -341,6 +341,12 @@ def _invalid_params(): _make_invalid_params(table_invalid_dicts, hoomd.md.pair.Table, {}) ) + wangfrenkel_valid_dict = {"sigma": 1.0, "epsilon": 1.0, "R":2.0, "mu": 1, "nu": 1} + wangfrenkel_invalid_dicts = _make_invalid_param_dict(wangfrenkel_valid_dict) + invalid_params_list.extend( + _make_invalid_params(wangfrenkel_invalid_dicts, hoomd.md.pair.WangFrenkel, {}) + ) + tersoff_valid_dict = { "cutoff_thickness": 1.0, "magnitudes": (5.0, 2.0), diff --git a/sphinx-doc/hoomd/md/module-pair.rst b/sphinx-doc/hoomd/md/module-pair.rst index 54daf4f4ba..a572f7f2af 100644 --- a/sphinx-doc/hoomd/md/module-pair.rst +++ b/sphinx-doc/hoomd/md/module-pair.rst @@ -3,7 +3,7 @@ pair .. automodule:: hoomd.md.pair :members: - :exclude-members: Buckingham,DLVO,DPD,DPDConservative,DPDLJ,Ewald,ExpandedGaussian,ExpandedLJ,ExpandedMie,ForceShiftedLJ,Fourier,Gaussian,LJ,LJ0804,LJ1208,LJGauss,Mie,Moliere,Morse,OPP,Pair,ReactionField,TWF,Table,Yukawa,ZBL + :exclude-members: Buckingham,DLVO,DPD,DPDConservative,DPDLJ,Ewald,ExpandedGaussian,ExpandedLJ,ExpandedMie,ForceShiftedLJ,Fourier,Gaussian,LJ,LJ0804,LJ1208,LJGauss,Mie,Moliere,Morse,OPP,Pair,ReactionField,TWF,Table,WangFrenkel,Yukawa,ZBL .. rubric:: Modules @@ -41,5 +41,6 @@ pair pair/reactionfield pair/twf pair/table + pair/wangfrenkel pair/yukawa pair/zbl diff --git a/sphinx-doc/hoomd/md/pair/wangfrenkel.rst b/sphinx-doc/hoomd/md/pair/wangfrenkel.rst new file mode 100644 index 0000000000..8ebeb9ec94 --- /dev/null +++ b/sphinx-doc/hoomd/md/pair/wangfrenkel.rst @@ -0,0 +1,8 @@ +WangFrenkel +=========== + +.. py:currentmodule:: hoomd.md.pair + +.. autoclass:: WangFrenkel + :members: + :show-inheritance: diff --git a/sphinx-doc/requirements.in b/sphinx-doc/requirements.in index 3f1d22cfd3..91204b307e 100644 --- a/sphinx-doc/requirements.in +++ b/sphinx-doc/requirements.in @@ -1,7 +1,7 @@ -ipython==8.29.0 +ipython==8.30.0 nbconvert==7.16.4 nbsphinx==0.9.5 -numpy==2.1.2 +numpy==2.1.3 pandoc==2.4 sphinx==8.1.3 furo==2024.8.6 diff --git a/sphinx-doc/requirements.txt b/sphinx-doc/requirements.txt index cd162186e3..9d0dab8c78 100644 --- a/sphinx-doc/requirements.txt +++ b/sphinx-doc/requirements.txt @@ -37,13 +37,13 @@ executing==2.0.1 fastjsonschema==2.19.1 # via nbformat furo==2024.8.6 - # via -r requirements.in + # via -r sphinx-doc/requirements.in idna==3.7 # via requests imagesize==1.4.1 # via sphinx -ipython==8.29.0 - # via -r requirements.in +ipython==8.30.0 + # via -r sphinx-doc/requirements.in jedi==0.19.1 # via ipython jinja2==3.1.4 @@ -77,7 +77,7 @@ nbclient==0.10.0 # via nbconvert nbconvert==7.16.4 # via - # -r requirements.in + # -r sphinx-doc/requirements.in # nbsphinx nbformat==5.10.4 # via @@ -85,15 +85,15 @@ nbformat==5.10.4 # nbconvert # nbsphinx nbsphinx==0.9.5 - # via -r requirements.in -numpy==2.1.2 - # via -r requirements.in + # via -r sphinx-doc/requirements.in +numpy==2.1.3 + # via -r sphinx-doc/requirements.in packaging==24.0 # via # nbconvert # sphinx pandoc==2.4 - # via -r requirements.in + # via -r sphinx-doc/requirements.in pandocfilters==1.5.1 # via nbconvert parso==0.8.4 @@ -143,7 +143,7 @@ soupsieve==2.5 # via beautifulsoup4 sphinx==8.1.3 # via - # -r requirements.in + # -r sphinx-doc/requirements.in # furo # nbsphinx # sphinx-basic-ng @@ -152,13 +152,13 @@ sphinx==8.1.3 sphinx-basic-ng==1.0.0b2 # via furo sphinx-copybutton==0.5.2 - # via -r requirements.in + # via -r sphinx-doc/requirements.in sphinxcontrib-applehelp==1.0.8 # via sphinx sphinxcontrib-devhelp==1.0.6 # via sphinx sphinxcontrib-googleanalytics==0.4 - # via -r requirements.in + # via -r sphinx-doc/requirements.in sphinxcontrib-htmlhelp==2.1.0 # via sphinx sphinxcontrib-jsmath==1.0.1 @@ -173,7 +173,7 @@ tinycss2==1.3.0 # via nbconvert tornado==6.4.2 # via - # -r requirements.in + # -r sphinx-doc/requirements.in # jupyter-client traitlets==5.14.3 # via