Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add expanded gaussian pair for hpmc #1817

Merged
merged 34 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
52a2063
Update CMake lists
josephburkhart Jun 12, 2024
866db90
Create PairPotentialExpandedGaussian.cc
josephburkhart Jun 12, 2024
13bcab1
Create PairPotentialExpandedGaussian.h
josephburkhart Jun 12, 2024
8383b84
Create expanded_gaussian.py
josephburkhart Jun 12, 2024
9659523
Create test_pair_expanded_gaussian.py
josephburkhart Jun 12, 2024
891b730
Replace Lennard-Jones variable names and text with Expanded Gaussian
josephburkhart Jun 13, 2024
5cac99a
Update C++ class header params to match EG definition
josephburkhart Jun 13, 2024
b684f33
Update C++ class energy method to match EG definition
josephburkhart Jun 13, 2024
a24f6e4
Update python class docstring
josephburkhart Jun 13, 2024
b8ac72e
Update python class params to match EG definition
josephburkhart Jun 13, 2024
32238db
Remove duplicate test
josephburkhart Jun 13, 2024
4321731
Update invalid params for tests
josephburkhart Jun 13, 2024
35e1ae8
Update tests' energy calculation to match EG definition
josephburkhart Jun 13, 2024
494e0ed
Update test params to suit EG definition
josephburkhart Jun 13, 2024
40a4117
Add EG import to __init__.py
josephburkhart Jun 13, 2024
a0600c1
Add EG to documentation
josephburkhart Jun 13, 2024
6452645
Add missing auxiliary function
josephburkhart Jun 13, 2024
edfca6e
Add missing export
josephburkhart Jun 13, 2024
6a42b65
Fix missing export
josephburkhart Jun 13, 2024
1d33032
Add missing parameter in test
josephburkhart Jun 13, 2024
c1dac23
Add missing parameter to test
josephburkhart Jun 13, 2024
61ebd04
Refactor pre-computed class attributes to match LJ
josephburkhart Jun 13, 2024
6f6c04d
Refactor energy calculation to match MD
josephburkhart Jun 13, 2024
120e78c
Fix typo in single pair potential test
josephburkhart Jun 13, 2024
b8df89d
Revise multi-potential test to match EG definition
josephburkhart Jun 13, 2024
0d11fdb
Fix variable scoping error
josephburkhart Jun 13, 2024
91495a1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 13, 2024
05a0f84
Reformat docstrings to match line length restrictions
josephburkhart Jun 13, 2024
f20215f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 13, 2024
65645aa
Shorten interaction parameters in test to satisfy MPI requirements
josephburkhart Jun 14, 2024
3fed0c7
Save expected results to variables
josephburkhart Jul 10, 2024
0b7ded8
Merge branch 'trunk-minor' into Feature/Expanded-Gaussian-For-HPMC
josephburkhart Jul 11, 2024
05f5a32
Merge branch 'trunk-minor' into Feature/Expanded-Gaussian-For-HPMC
joaander Jul 11, 2024
bcb6d68
Ensure that sigma is positive.
joaander Jul 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions hoomd/hpmc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ set(_hpmc_sources module.cc
ExternalPotentialLinear.cc
PairPotential.cc
PairPotentialLennardJones.cc
PairPotentialExpandedGaussian.cc
PairPotentialStep.cc
PairPotentialUnion.cc
PairPotentialAngularStep.cc
Expand Down Expand Up @@ -85,6 +86,7 @@ set(_hpmc_headers
OBBTree.h
PairPotential.h
PairPotentialLennardJones.h
PairPotentialExpandedGaussian.h
PairPotentialStep.h
PairPotentialUnion.h
PairPotentialAngularStep.h
Expand Down
98 changes: 98 additions & 0 deletions hoomd/hpmc/PairPotentialExpandedGaussian.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright (c) 2009-2024 The Regents of the University of Michigan.
// Part of HOOMD-blue, released under the BSD 3-Clause License.

#include "PairPotentialExpandedGaussian.h"

namespace hoomd
{
namespace hpmc
{

PairPotentialExpandedGaussian::PairPotentialExpandedGaussian(
std::shared_ptr<SystemDefinition> sysdef)
: PairPotential(sysdef), m_params(m_type_param_index.getNumElements())
{
}

LongReal PairPotentialExpandedGaussian::energy(const LongReal r_squared,
const vec3<LongReal>& r_ij,
const unsigned int type_i,
const quat<LongReal>& q_i,
const LongReal charge_i,
const unsigned int type_j,
const quat<LongReal>& q_j,
const LongReal charge_j) const
{
unsigned int param_index = m_type_param_index(type_i, type_j);
const auto& param = m_params[param_index];

LongReal r = fast::sqrt(r_squared);
LongReal rmd_2 = (r - param.delta) * (r - param.delta);
LongReal rmd_over_sigma_2 = rmd_2 / param.sigma_2;
LongReal exp_val = fast::exp(-LongReal(1.0) / LongReal(2.0) * rmd_over_sigma_2);
LongReal energy = param.epsilon * exp_val;

if (m_mode == shift || (m_mode == xplor && param.r_on_squared >= param.r_cut_squared))
{
LongReal r_cut = fast::sqrt(param.r_cut_squared);
LongReal rcutmd_2 = (r_cut - param.delta) * (r_cut - param.delta);
LongReal rcutmd_over_sigma_2 = rcutmd_2 / param.sigma_2;
energy -= param.epsilon * fast::exp(-LongReal(1.0) / LongReal(2.0) * rcutmd_over_sigma_2);
}

if (m_mode == xplor && r_squared > param.r_on_squared)
{
LongReal a = param.r_cut_squared - param.r_on_squared;
LongReal denominator = a * a * a;

LongReal b = param.r_cut_squared - r_squared;
LongReal numerator = b * b
* (param.r_cut_squared + LongReal(2.0) * r_squared
- LongReal(3.0) * param.r_on_squared);
energy *= numerator / denominator;
}

return energy;
}

void PairPotentialExpandedGaussian::setParamsPython(pybind11::tuple typ, pybind11::dict params)
{
auto pdata = m_sysdef->getParticleData();
auto type_i = pdata->getTypeByName(typ[0].cast<std::string>());
auto type_j = pdata->getTypeByName(typ[1].cast<std::string>());
unsigned int param_index_1 = m_type_param_index(type_i, type_j);
m_params[param_index_1] = ParamType(params);
unsigned int param_index_2 = m_type_param_index(type_j, type_i);
m_params[param_index_2] = ParamType(params);

notifyRCutChanged();
}

pybind11::dict PairPotentialExpandedGaussian::getParamsPython(pybind11::tuple typ)
{
auto pdata = m_sysdef->getParticleData();
auto type_i = pdata->getTypeByName(typ[0].cast<std::string>());
auto type_j = pdata->getTypeByName(typ[1].cast<std::string>());
unsigned int param_index = m_type_param_index(type_i, type_j);
return m_params[param_index].asDict();
}

namespace detail
{
void exportPairPotentialExpandedGaussian(pybind11::module& m)
{
pybind11::class_<PairPotentialExpandedGaussian,
PairPotential,
std::shared_ptr<PairPotentialExpandedGaussian>>(
m,
"PairPotentialExpandedGaussian")
.def(pybind11::init<std::shared_ptr<SystemDefinition>>())
.def("setParams", &PairPotentialExpandedGaussian::setParamsPython)
.def("getParams", &PairPotentialExpandedGaussian::getParamsPython)
.def_property("mode",
&PairPotentialExpandedGaussian::getMode,
&PairPotentialExpandedGaussian::setMode);
}
} // end namespace detail
} // end namespace hpmc
} // end namespace hoomd
141 changes: 141 additions & 0 deletions hoomd/hpmc/PairPotentialExpandedGaussian.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Copyright (c) 2009-2024 The Regents of the University of Michigan.
// Part of HOOMD-blue, released under the BSD 3-Clause License.

#pragma once

#include "PairPotential.h"

namespace hoomd
{
namespace hpmc
{

/*** Compute Expanded Gaussian energy between two particles.

For use with HPMC simulations.
*/
class PairPotentialExpandedGaussian : public hpmc::PairPotential
{
public:
PairPotentialExpandedGaussian(std::shared_ptr<SystemDefinition> sysdef);
virtual ~PairPotentialExpandedGaussian() { }

virtual LongReal energy(const LongReal r_squared,
const vec3<LongReal>& r_ij,
const unsigned int type_i,
const quat<LongReal>& q_i,
const LongReal charge_i,
const unsigned int type_j,
const quat<LongReal>& q_j,
const LongReal charge_j) const;

/// Compute the non-additive cuttoff radius
virtual LongReal computeRCutNonAdditive(unsigned int type_i, unsigned int type_j) const
{
unsigned int param_index = m_type_param_index(type_i, type_j);
return slow::sqrt(m_params[param_index].r_cut_squared);
}

/// Set type pair dependent parameters to the potential.
void setParamsPython(pybind11::tuple typ, pybind11::dict params);

/// Get type pair dependent parameters.
pybind11::dict getParamsPython(pybind11::tuple typ);

void setMode(const std::string& mode_str)
{
if (mode_str == "none")
{
m_mode = no_shift;
}
else if (mode_str == "shift")
{
m_mode = shift;
}
else if (mode_str == "xplor")
{
m_mode = xplor;
}
else
{
throw std::domain_error("Invalid mode " + mode_str);
}
}

std::string getMode()
{
std::string result = "none";

if (m_mode == shift)
{
result = "shift";
}
if (m_mode == xplor)
{
result = "xplor";
}

return result;
}

protected:
/// Shifting modes that can be applied to the energy
enum EnergyShiftMode
{
no_shift = 0,
shift,
xplor
};

/// Type pair parameters of EG potential
struct ParamType
{
ParamType()
{
sigma_2 = 0;
epsilon = 0;
delta = 0;
r_cut_squared = 0;
r_on_squared = 0;
}

ParamType(pybind11::dict v)
{
auto sigma(v["sigma"].cast<LongReal>());
auto r_cut(v["r_cut"].cast<LongReal>());
auto r_on(v["r_on"].cast<LongReal>());

sigma_2 = sigma * sigma;
epsilon = v["epsilon"].cast<LongReal>();
delta = v["delta"].cast<LongReal>();
r_cut_squared = r_cut * r_cut;
r_on_squared = r_on * r_on;
}

pybind11::dict asDict()
{
pybind11::dict result;

result["sigma"] = pow(sigma_2, 1. / 2.);
result["epsilon"] = epsilon;
result["delta"] = delta;
result["r_cut"] = slow::sqrt(r_cut_squared);
result["r_on"] = slow::sqrt(r_on_squared);

return result;
}

LongReal sigma_2;
LongReal epsilon;
LongReal delta;
LongReal r_cut_squared;
LongReal r_on_squared;
};

std::vector<ParamType> m_params;

EnergyShiftMode m_mode = no_shift;
};

} // end namespace hpmc
} // end namespace hoomd
3 changes: 3 additions & 0 deletions hoomd/hpmc/module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ void exportPairPotential(pybind11::module& m);

void exportPairPotentialLennardJones(pybind11::module& m);

void exportPairPotentialExpandedGaussian(pybind11::module& m);

void exportPairPotentialAngularStep(pybind11::module& m);

void exportPairPotentialStep(pybind11::module& m);
Expand Down Expand Up @@ -154,6 +156,7 @@ PYBIND11_MODULE(_hpmc, m)

exportPairPotential(m);
exportPairPotentialLennardJones(m);
exportPairPotentialExpandedGaussian(m);
exportPairPotentialAngularStep(m);
exportPairPotentialStep(m);
exportPairPotentialUnion(m);
Expand Down
1 change: 1 addition & 0 deletions hoomd/hpmc/pair/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
set(files __init__.py
lennard_jones.py
expanded_gaussian.py
pair.py
step.py
union.py
Expand Down
1 change: 1 addition & 0 deletions hoomd/hpmc/pair/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from . import user
from .pair import Pair
from .lennard_jones import LennardJones
from .expanded_gaussian import ExpandedGaussian
from .union import Union
from .angular_step import AngularStep
from .step import Step
107 changes: 107 additions & 0 deletions hoomd/hpmc/pair/expanded_gaussian.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Copyright (c) 2009-2024 The Regents of the University of Michigan.
# Part of HOOMD-blue, released under the BSD 3-Clause License.

"""Expanded Gaussian pair potential.

.. invisible-code-block: python

simulation = hoomd.util.make_example_simulation()
sphere = hoomd.hpmc.integrate.Sphere()
sphere.shape['A'] = dict(diameter=0.0)
simulation.operations.integrator = sphere
"""

import hoomd

from .pair import Pair
joaander marked this conversation as resolved.
Show resolved Hide resolved
from hoomd.data.typeconverter import positive_real


@hoomd.logging.modify_namespace(('hpmc', 'pair', 'ExpandedGaussian'))
class ExpandedGaussian(Pair):
"""Expanded Gaussian pair potential (HPMC).

Args:
default_r_cut (float): Default cutoff radius :math:`[\\mathrm{length}]`.
default_r_on (float): Default XPLOR on radius
:math:`[\\mathrm{length}]`.
mode (str): Energy shifting/smoothing mode.

`ExpandedGaussian` computes the Expanded Gaussian pair potential between
every pair of particles in the simulation state. The functional form of the
potential, including its behavior under shifting modes, is identical to that
in the MD pair potential `hoomd.md.pair.ExpandedGaussian`.

See Also:
`hoomd.md.pair.ExpandedGaussian`

`hoomd.md.pair`

.. rubric:: Example

.. code-block:: python

expanded_gaussian = hoomd.hpmc.pair.ExpandedGaussian()
expanded_gaussian.params[('A', 'A')] = dict(epsilon=1.0,
sigma=1.0,
delta=1.0,
r_cut=2.5)
simulation.operations.integrator.pair_potentials = [expanded_gaussian]

.. py:attribute:: params

The potential parameters. The dictionary has the following keys:

* ``epsilon`` (`float`, **required**) -
Energy well depth :math:`\\varepsilon` :math:`[\\mathrm{energy}]`.
* ``sigma`` (`float`, **required**) -
Characteristic length scale :math:`\\sigma`
:math:`[\\mathrm{length}]`.
* ``delta`` (`float`, **required**) -
Characteristic length scale :math:`\\delta`
:math:`[\\mathrm{length}]`.
* ``r_cut`` (`float`): Cutoff radius :math:`[\\mathrm{length}]`.
Defaults to the value given in ``default_r_cut`` on construction.
* ``r_on`` (`float`): XPLOR on radius :math:`[\\mathrm{length}]`.
Defaults to the value given in ``default_r_on`` on construction.

Type: `TypeParameter` [`tuple` [``particle_type``, ``particle_type``],
`dict`]

.. py:attribute:: mode

The energy shifting/smoothing mode: Possible values are:
``"none"``, ``"shift"``, and ``"xplor"``.

.. rubric:: Example

.. code-block:: python

expanded_gaussian.mode = 'shift'

Type: `str`
"""
_cpp_class_name = "PairPotentialExpandedGaussian"

def __init__(self, default_r_cut=None, default_r_on=0.0, mode='none'):
if default_r_cut is None:
default_r_cut = float
else:
default_r_cut = float(default_r_cut)

params = hoomd.data.typeparam.TypeParameter(
'params', 'particle_types',
hoomd.data.parameterdicts.TypeParameterDict(
epsilon=float,
sigma=positive_real,
delta=float,
r_cut=default_r_cut,
r_on=float(default_r_on),
len_keys=2))
self._add_typeparam(params)

self._param_dict.update(
hoomd.data.parameterdicts.ParameterDict(
mode=hoomd.data.typeconverter.OnlyFrom(("none", "shift",
"xplor"))))
self.mode = mode
Loading