Skip to content

Commit eb25c1e

Browse files
authored
Merge branch 'refactor/flow' into refactor/integrator
2 parents 5541e45 + 8f121b7 commit eb25c1e

18 files changed

+855
-332
lines changed

.ruff.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ ignore = [
3232

3333
"__init__.py" = ["F401", # __init__.py import submodules for use by the package importer.
3434
]
35+
"*/pytest/*.py" = ["PLR2004", # allow "magic numbers" in tests
36+
]
3537

3638
[lint.pydocstyle]
3739
convention = "google"

src/BondEvaluatorDoubleWell.h

Lines changed: 79 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -2,151 +2,133 @@
22
// Copyright (c) 2021-2024, Auburn University
33
// Part of azplugins, released under the BSD 3-Clause License.
44

5-
/*! \file BondEvaluatorDoubleWell.h
6-
\brief Defines the bond evaluator class for a double well potential
7-
*/
8-
95
#ifndef AZPLUGINS_BOND_EVALUATOR_DOUBLE_WELL_H_
106
#define AZPLUGINS_BOND_EVALUATOR_DOUBLE_WELL_H_
117

12-
#ifndef NVCC
8+
#ifndef __HIPCC__
139
#include <string>
1410
#endif
1511

16-
#include "hoomd/HOOMDMath.h"
12+
#include "BondEvaluator.h"
1713

18-
#ifdef NVCC
14+
#ifdef __HIPCC__
1915
#define DEVICE __device__
2016
#else
2117
#define DEVICE
2218
#endif
2319

20+
namespace hoomd
21+
{
2422
namespace azplugins
2523
{
2624
namespace detail
2725
{
2826

29-
//! Class for evaluating the double well bond potential
30-
/*!
31-
This bond potential follows the functional form
32-
\f{eqnarray*}
33-
34-
V_{\rm{DW}}(r) = \frac{V_{max}-c/2}{b^4} \left[ \left( r - a/2 \right)^2 -b^2 \right]^2 +
35-
\frac{c}{2b}\left(r-a/2\right)+c/2
36-
37-
\f}
38-
which has two minima at r = (a/2 +/- b), seperated by a maximum at a/2 of height V_max when c is set
39-
to zero.
40-
41-
The parameter a tunes the location of the maximal value and the parameter b tunes the distance of
42-
the two maxima from each other. This potential is useful to model bonds which can be either
43-
mechanically or thermally "activated" into a effectively longer state. The value of V_max can be
44-
used to tune the height of the energy barrier in between the two states.
45-
46-
If c is non zero, the relative energy of the minima can be tuned, where c is the energy of the
47-
second minima, the first minima value is at zero. This causes a small shift in the location of the
48-
minima and the maxima, because of the added linear term.
49-
50-
The parameters are:
51-
- \a V_max (params.x) potential difference between the the first minima and maxima
52-
- \a a (params.y) shift for the location of the V_max, the maximum is at approx. a/2
53-
- \a b (params.z) scaling for the distance of the two minima at approx. (a/2 +/- b)
54-
- \a c (params.w) potential difference between the two minima, default is c=0
55-
56-
*/
57-
class BondEvaluatorDoubleWell
27+
//! Parameters of double well bond potential
28+
struct BondParametersDoubleWell : public BondParameters
5829
{
59-
public:
60-
//! Define the parameter type used by this bond potential evaluator
61-
62-
typedef Scalar4 param_type;
30+
#ifndef __HIPCC__
31+
BondParametersDoubleWell() : r_1(0), r_diff(1.0), U_1(0), U_tilt(0) { }
6332

64-
//! Constructs the pair potential evaluator
65-
/*!
66-
* \param _rsq Squared distance beteen the particles
67-
* \param _params Per type bond parameters of this potential as given above
68-
*/
69-
DEVICE BondEvaluatorDoubleWell(Scalar _rsq, const param_type& _params)
70-
: rsq(_rsq), V_max(_params.x), a(_params.y), b(_params.z), c(_params.w)
33+
BondParametersDoubleWell(pybind11::dict v)
7134
{
35+
r_1 = v["r_1"].cast<Scalar>();
36+
r_diff = r_1 - v["r_0"].cast<Scalar>();
37+
U_1 = v["U_1"].cast<Scalar>();
38+
U_tilt = v["U_tilt"].cast<Scalar>();
7239
}
7340

74-
//! This evaluator doesn't use diameter information
75-
DEVICE static bool needsDiameter()
41+
pybind11::dict asDict()
7642
{
77-
return false;
43+
pybind11::dict v;
44+
v["r_0"] = r_1 - r_diff;
45+
v["r_1"] = r_1;
46+
v["U_1"] = U_1;
47+
v["U_tilt"] = U_tilt;
48+
return v;
7849
}
50+
#endif
51+
52+
Scalar r_1; //!< location of the potential local maximum
53+
Scalar r_diff; //!< difference between r_1 and r_0 (location of first minimum)
54+
Scalar U_1; //!< Potential Potential maximum energy barrier between minima
55+
Scalar U_tilt; //!< tunes the energy offset (tilt) between minima
56+
}
57+
#if HOOMD_LONGREAL_SIZE == 32
58+
__attribute__((aligned(16)));
59+
#else
60+
__attribute__((aligned(32)));
61+
#endif
7962

80-
//! Accept the optional diameter values
81-
/*!
82-
* \param da Diameter of particle a
83-
* \param db Diameter of particle b
84-
*/
85-
DEVICE void setDiameter(Scalar da, Scalar db) { }
63+
//! Class for evaluating the double well bond potential
64+
/*!
65+
* This bond potential follows the functional form
66+
* \f{eqnarray*}
67+
*
68+
* U(r) = U_1\left[\frac{\left((r-r_1)^2-(r_1-r_0)^2\right)^2}{\left(r_1-r_0\right)^4}\right]
69+
* +
70+
* U_{\rm{tilt}}\left[1+\frac{r-r_1}{r_1-r_0}-\frac{\left((r-r_1)^2-(r_1-r_0)^2\right)^2}{\left(r_1-r_0\right)^4}\right]
71+
*
72+
* \f}
73+
* which has two minima at r = r_0 and r = 2 * r_1 - r_0, seperated by a maximum
74+
* at r_1 of height U_1 when U_tilt is set to zero.
75+
*
76+
* The parameter r_1 tunes the location of the maximal value and the parameter r_0 tunes the
77+
* distance of the two minima from each other. This potential is useful to model bonds which can be
78+
* either mechanically or thermally "activated" into a effectively longer state. The value of U_1
79+
* can be used to tune the height of the energy barrier in between the two states.
80+
*
81+
* If U_tilt is non zero, the relative energy of the minima can be tuned, where 2 * U_tilt
82+
* is the energy of the second minima, the first minima value is at zero. This causes a
83+
* small shift in the location of the minima and the maxima, because of the added linear term.
84+
*/
85+
class BondEvaluatorDoubleWell : public BondEvaluator
86+
{
87+
public:
88+
typedef BondParametersDoubleWell param_type;
8689

87-
//! This evaluator doesn't use charge
88-
DEVICE static bool needsCharge()
90+
DEVICE BondEvaluatorDoubleWell(Scalar _rsq, const param_type& _params)
91+
: BondEvaluator(_rsq), r_1(_params.r_1), r_diff(_params.r_diff), U_1(_params.U_1),
92+
U_tilt(_params.U_tilt)
8993
{
90-
return false;
9194
}
9295

93-
//! Accept the optional charge values
94-
/*!
95-
* \param qa Charge of particle a
96-
* \param qb Charge of particle b
97-
*/
98-
DEVICE void setCharge(Scalar qa, Scalar qb) { }
99-
100-
//! Evaluate the force and energy
101-
/*!
102-
* \param force_divr Output parameter to write the computed force divided by r.
103-
* \param bond_eng Output parameter to write the computed bond energy
104-
*
105-
* \return True if they are evaluated or false if the bond energy is not defined.
106-
*/
10796
DEVICE bool evalForceAndEnergy(Scalar& force_divr, Scalar& bond_eng)
10897
{
10998
bond_eng = 0;
11099
force_divr = 0;
111-
112-
// check for invalid parameters
113-
if (b == Scalar(0.0))
100+
// check for invalid parameters r0 = r1
101+
if (r_diff == Scalar(0.0))
114102
return false;
115103

116-
Scalar c_half = Scalar(0.5) * c;
117-
Scalar r = fast::sqrt(rsq);
118-
Scalar r_min_half_a = r - Scalar(0.5) * a;
119-
Scalar b_sq = b * b;
120-
Scalar d = r_min_half_a * r_min_half_a - b_sq;
121-
122-
bond_eng = ((V_max - c_half) / (b_sq * b_sq)) * d * d + c_half / b * r_min_half_a + c_half;
123-
force_divr = -(4 * (V_max - c_half) / (b_sq * b_sq) * d * r_min_half_a + c_half / b) / r;
104+
const Scalar r = fast::sqrt(rsq);
105+
const Scalar x = (r_1 - r) / r_diff;
106+
const Scalar x2 = x * x;
107+
const Scalar y = Scalar(1.0) - x2;
108+
const Scalar y2 = y * y;
124109

110+
bond_eng = U_1 * y2 + U_tilt * (Scalar(1.0) - x - y2);
111+
force_divr = (Scalar(4.0) * x * y * (U_tilt - U_1) - U_tilt) / (r_diff * r);
125112
return true;
126113
}
127114

128-
#ifndef NVCC
129-
//! Get the name of this potential
130-
/*!
131-
* \returns The potential name. Must be short and all lowercase, as this is the name energies
132-
* will be logged as via analyze.log.
133-
*/
115+
#ifndef __HIPCC__
134116
static std::string getName()
135117
{
136-
return std::string("doublewell");
118+
return std::string("DoubleWell");
137119
}
138120
#endif
139121

140-
protected:
141-
Scalar rsq; //!< Stored rsq from the constructor
142-
Scalar V_max; //!< V_max parameter
143-
Scalar a; //!< a parameter
144-
Scalar b; //!< b parameter
145-
Scalar c; //!< c parameter
122+
private:
123+
Scalar r_1; //!< r_1 parameter
124+
Scalar r_diff; //!< r_diff parameter
125+
Scalar U_1; //!< U_1 parameter
126+
Scalar U_tilt; //!< U_tilt parameter
146127
};
147128

148129
} // end namespace detail
149130
} // end namespace azplugins
131+
} // end namespace hoomd
150132

151133
#undef DEVICE
152134

src/CMakeLists.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ set(COMPONENT_NAME azplugins)
33

44
# TODO: List all host C++ source code files in _${COMPONENT_NAME}_sources.
55
set(_${COMPONENT_NAME}_sources
6+
ConstantFlow.cc
67
GroupVelocityCompute.cc
78
module.cc
9+
ParabolicFlow.cc
810
)
911

1012
# TODO: List all GPU C++ source code files in _${COMPONENT_NAME}_cu_sources.
@@ -14,16 +16,22 @@ set(_${COMPONENT_NAME}_cu_sources
1416
# TODO: List all Python modules in python_files.
1517
set(python_files
1618
__init__.py
19+
conftest.py
1720
bond.py
1821
flow.py
1922
pair.py
2023
)
2124

2225
# TODO: Add names of all bond evaluators
23-
set(_bond_evaluators )
26+
set(_bond_evaluators
27+
DoubleWell
28+
)
2429

2530
# TODO: Add names of all pair evaluators`
26-
set(_pair_evaluators Hertz)
31+
set(_pair_evaluators
32+
Hertz
33+
PerturbedLennardJones
34+
)
2735

2836
# TODO: Add names of all anisotropic pair evaluators
2937
set(_aniso_pair_evaluators )

src/ConstantFlow.cc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) 2018-2020, Michael P. Howard
2+
// Copyright (c) 2021-2024, Auburn University
3+
// Part of azplugins, released under the BSD 3-Clause License.
4+
5+
#include "ConstantFlow.h"
6+
7+
namespace hoomd
8+
{
9+
namespace azplugins
10+
{
11+
namespace detail
12+
{
13+
void export_ConstantFlow(pybind11::module& m)
14+
{
15+
namespace py = pybind11;
16+
py::class_<ConstantFlow, std::shared_ptr<ConstantFlow>>(m, "ConstantFlow")
17+
.def(py::init<Scalar3>())
18+
.def_property(
19+
"velocity",
20+
[](const ConstantFlow& U)
21+
{
22+
const auto field = U.getVelocity();
23+
return pybind11::make_tuple(field.x, field.y, field.z);
24+
},
25+
[](ConstantFlow& U, const pybind11::tuple& field)
26+
{
27+
U.setVelocity(make_scalar3(pybind11::cast<Scalar>(field[0]),
28+
pybind11::cast<Scalar>(field[1]),
29+
pybind11::cast<Scalar>(field[2])));
30+
});
31+
}
32+
} // end namespace detail
33+
} // end namespace azplugins
34+
} // end namespace hoomd

src/ConstantFlow.h

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,40 @@
55
#ifndef AZPLUGINS_CONSTANT_FLOW_H_
66
#define AZPLUGINS_CONSTANT_FLOW_H_
77

8+
#ifndef __HIPCC__
9+
#include <pybind11/pybind11.h>
10+
#endif
11+
812
#include "hoomd/HOOMDMath.h"
913

10-
#ifdef __HIPCC__
14+
#ifndef __HIPCC__
1115
#define HOSTDEVICE __host__ __device__
1216
#else
1317
#define HOSTDEVICE
14-
#include <pybind11/pybind11.h>
18+
#endif // __HIPCC__
19+
20+
#ifndef PYBIND11_EXPORT
21+
#define PYBIND11_EXPORT __attribute__((visibility("default")))
1522
#endif
23+
1624
namespace hoomd
1725
{
1826
namespace azplugins
1927
{
2028

2129
//! Position-independent flow along a vector
22-
class ConstantFlow
30+
class PYBIND11_EXPORT ConstantFlow
2331
{
2432
public:
2533
//! Constructor
2634
/*!
2735
*\param U_ Flow field
2836
*/
29-
ConstantFlow(Scalar3 U_) : U(U_) { }
37+
ConstantFlow(Scalar3 velocity)
38+
{
39+
setVelocity(velocity);
40+
}
41+
3042
//! Evaluate the flow field
3143
/*!
3244
* \param r position to evaluate flow
@@ -52,32 +64,10 @@ class ConstantFlow
5264
Scalar3 U; //!< Flow field
5365
};
5466

55-
namespace detail
56-
{
57-
void export_ConstantFlow(pybind11::module& m)
58-
{
59-
namespace py = pybind11;
60-
py::class_<ConstantFlow, std::shared_ptr<ConstantFlow>>(m, "ConstantFlow")
61-
.def(py::init<Scalar3>())
62-
.def_property(
63-
"mean_velocity",
64-
[](const ConstantFlow& U)
65-
{
66-
const auto field = U.getVelocity();
67-
return pybind11::make_tuple(field.x, field.y, field.z);
68-
},
69-
[](ConstantFlow& U, const pybind11::tuple& field)
70-
{
71-
U.setVelocity(make_scalar3(pybind11::cast<Scalar>(field[0]),
72-
pybind11::cast<Scalar>(field[1]),
73-
pybind11::cast<Scalar>(field[2])));
74-
});
75-
}
76-
} // end namespace detail
77-
7867
} // namespace azplugins
7968
} // namespace hoomd
8069

8170
#undef HOSTDEVICE
71+
#undef PYBIND11_EXPORT
8272

8373
#endif // AZPLUGINS_CONSTANT_FLOW_H_

0 commit comments

Comments
 (0)