diff --git a/src/ConstantFlow.h b/src/ConstantFlow.h index bff9340a..4c484bea 100644 --- a/src/ConstantFlow.h +++ b/src/ConstantFlow.h @@ -18,7 +18,9 @@ #endif // __HIPCC__ #ifndef PYBIND11_EXPORT -#define PYBIND11_EXPORT __attribute__((visibility("default"))) +#define _PYBIND11_EXPORT __attribute__((visibility("default"))) +#else +#define _PYBIND11_EXPORT PYBIND11_EXPORT #endif namespace hoomd @@ -27,7 +29,7 @@ namespace azplugins { //! Position-independent flow along a vector -class PYBIND11_EXPORT ConstantFlow +class _PYBIND11_EXPORT ConstantFlow { public: //! Constructor @@ -68,6 +70,6 @@ class PYBIND11_EXPORT ConstantFlow } // namespace hoomd #undef HOSTDEVICE -#undef PYBIND11_EXPORT +#undef _PYBIND11_EXPORT #endif // AZPLUGINS_CONSTANT_FLOW_H_ diff --git a/src/ParabolicFlow.h b/src/ParabolicFlow.h index b925bf01..47c741d2 100644 --- a/src/ParabolicFlow.h +++ b/src/ParabolicFlow.h @@ -23,7 +23,9 @@ #endif // __HIPCC__ #ifndef PYBIND11_EXPORT -#define PYBIND11_EXPORT __attribute__((visibility("default"))) +#define _PYBIND11_EXPORT __attribute__((visibility("default"))) +#else +#define _PYBIND11_EXPORT PYBIND11_EXPORT #endif namespace hoomd @@ -48,7 +50,7 @@ namespace azplugins * \note The user must properly establish no flux of particles through the channel * walls through an appropriate wall potential. */ -class PYBIND11_EXPORT ParabolicFlow +class _PYBIND11_EXPORT ParabolicFlow { public: //! Construct parabolic flow profile @@ -101,6 +103,6 @@ class PYBIND11_EXPORT ParabolicFlow } // namespace hoomd #undef HOSTDEVICE -#undef PYBIND11_EXPORT +#undef _PYBIND11_EXPORT #endif // AZPLUGINS_PARABOLIC_FLOW_H_ diff --git a/src/RNGIdentifiers.h b/src/RNGIdentifiers.h index 8e2c7c1f..dd28d486 100644 --- a/src/RNGIdentifiers.h +++ b/src/RNGIdentifiers.h @@ -10,18 +10,23 @@ #ifndef AZPLUGINS_RNG_IDENTIFIERS_H_ #define AZPLUGINS_RNG_IDENTIFIERS_H_ +#include + +namespace hoomd + { namespace azplugins { - +namespace detail + { struct RNGIdentifier { - // hoomd's identifiers, changed by +/- 1 - static const uint32_t DPDEvaluatorGeneralWeight = 0x4a84f5d1; - static const uint32_t TwoStepBrownianFlow = 0x431287fe; - static const uint32_t TwoStepLangevinFlow = 0x89abcdee; - static const uint32_t ParticleEvaporator = 0x3eb8536f; + static const uint8_t DPDEvaluatorGeneralWeight = 200; + static const uint8_t TwoStepBrownianFlow = 201; + static const uint8_t TwoStepLangevinFlow = 202; + static const uint8_t ParticleEvaporator = 203; }; - + } // end namespace detail } // end namespace azplugins + } // end namespace hoomd #endif // AZPLUGINS_RNG_IDENTIFIERS_H_ diff --git a/src/TwoStepBrownianFlow.h b/src/TwoStepBrownianFlow.h index c9f12f54..adaaac26 100644 --- a/src/TwoStepBrownianFlow.h +++ b/src/TwoStepBrownianFlow.h @@ -10,16 +10,17 @@ #ifndef AZPLUGINS_TWO_STEP_BROWNIAN_FLOW_H_ #define AZPLUGINS_TWO_STEP_BROWNIAN_FLOW_H_ -#ifdef NVCC +#ifdef __HIPCC__ #error This header cannot be compiled by nvcc #endif #include "hoomd/RandomNumbers.h" -#include "hoomd/extern/pybind/include/pybind11/pybind11.h" #include "hoomd/md/TwoStepLangevinBase.h" +#include #include "RNGIdentifiers.h" - +namespace hoomd + { namespace azplugins { @@ -27,7 +28,7 @@ namespace azplugins /*! * \note Only translational motion is supported by this integrator. */ -template class PYBIND11_EXPORT TwoStepBrownianFlow : public TwoStepLangevinBase +template class PYBIND11_EXPORT TwoStepBrownianFlow : public md::TwoStepLangevinBase { public: //! Constructor @@ -35,17 +36,13 @@ template class PYBIND11_EXPORT TwoStepBrownianFlow : public Two std::shared_ptr group, std::shared_ptr T, std::shared_ptr flow_field, - unsigned int seed, - bool use_lambda, - Scalar lambda, bool noiseless) - : TwoStepLangevinBase(sysdef, group, T, seed, use_lambda, lambda), m_flow_field(flow_field), + : md::TwoStepLangevinBase(sysdef, group, T), m_flow_field(flow_field), m_noiseless(noiseless) { m_exec_conf->msg->notice(5) << "Constructing TwoStepBrownianFlow" << std::endl; if (m_sysdef->getNDimensions() < 3) { - m_exec_conf->msg->error() << "flow.brownian is only supported in 3D" << std::endl; throw std::runtime_error("Brownian dynamics in flow is only supported in 3D"); } } @@ -75,10 +72,6 @@ template class PYBIND11_EXPORT TwoStepBrownianFlow : public Two /*! * \param flow_field New flow field to apply */ - void setFlowField(std::shared_ptr flow_field) - { - m_flow_field = flow_field; - } //! Get the flag for if noise is applied to the motion bool getNoiseless() const @@ -105,13 +98,8 @@ void TwoStepBrownianFlow::integrateStepOne(unsigned int timestep) { if (m_aniso) { - m_exec_conf->msg->error() << "azplugins.integrate: anisotropic particles are not supported " - "with brownian flow integrators." - << std::endl; throw std::runtime_error("Anisotropic integration not supported with brownian flow"); } - if (m_prof) - m_prof->push("Brownian step"); ArrayHandle h_pos(m_pdata->getPositions(), access_location::host, @@ -121,16 +109,15 @@ void TwoStepBrownianFlow::integrateStepOne(unsigned int timestep) ArrayHandle h_net_force(m_pdata->getNetForce(), access_location::host, access_mode::read); - ArrayHandle h_diameter(m_pdata->getDiameters(), - access_location::host, - access_mode::read); ArrayHandle h_gamma(m_gamma, access_location::host, access_mode::read); - const Scalar currentTemp = m_T->getValue(timestep); + const Scalar currentTemp = (*m_T)(timestep); const FlowField& flow_field = *m_flow_field; const BoxDim& box = m_pdata->getBox(); + uint16_t seed = m_sysdef->getSeed(); + // perform the first half step of velocity verlet unsigned int group_size = m_group->getNumMembers(); for (unsigned int group_idx = 0; group_idx < group_size; group_idx++) @@ -141,13 +128,7 @@ void TwoStepBrownianFlow::integrateStepOne(unsigned int timestep) const Scalar4 postype = h_pos.data[idx]; Scalar3 pos = make_scalar3(postype.x, postype.y, postype.z); const unsigned int type = __scalar_as_int(postype.w); - Scalar gamma; - if (m_use_lambda) - gamma = m_lambda * h_diameter.data[idx]; - else - { - gamma = h_gamma.data[type]; - } + const Scalar gamma = h_gamma.data[type]; // get the flow velocity at the current position const Scalar3 flow_vel = flow_field(pos); @@ -158,10 +139,11 @@ void TwoStepBrownianFlow::integrateStepOne(unsigned int timestep) coeff = Scalar(0.0); // draw random force - hoomd::RandomGenerator rng(azplugins::RNGIdentifier::TwoStepBrownianFlow, - m_seed, - h_tag.data[idx], - timestep); + hoomd::RandomGenerator rng( + hoomd::Seed(hoomd::azplugins::detail::RNGIdentifier::TwoStepBrownianFlow, + timestep, + seed), + hoomd::Counter(h_tag.data[idx])); hoomd::UniformDistribution uniform(-coeff, coeff); const Scalar3 random_force = make_scalar3(uniform(rng), uniform(rng), uniform(rng)); @@ -176,9 +158,6 @@ void TwoStepBrownianFlow::integrateStepOne(unsigned int timestep) // write out the position h_pos.data[idx] = make_scalar4(pos.x, pos.y, pos.z, type); } - - if (m_prof) - m_prof->pop(); } namespace detail @@ -190,21 +169,19 @@ void export_TwoStepBrownianFlow(pybind11::module& m, const std::string& name) namespace py = pybind11; typedef TwoStepBrownianFlow BrownianFlow; - py::class_>(m, - name.c_str(), - py::base()) + py::class_>( + m, + name.c_str(), + py::base()) .def(py::init, std::shared_ptr, std::shared_ptr, std::shared_ptr, - unsigned int, - bool, - Scalar, bool>()) - .def("setFlowField", &BrownianFlow::setFlowField) - .def("setNoiseless", &BrownianFlow::setNoiseless); + .def_property_readonly("flow_field", &BrownianFlow::getFlowField) + .def_property("noiseless", &BrownianFlow::getNoiseless, &BrownianFlow::setNoiseless); } - } // end namespace detail - } // end namespace azplugins - + } // end namespace detail + } // end namespace azplugins + } // end namespace hoomd #endif // AZPLUGINS_TWO_STEP_BROWNIAN_FLOW_H_ diff --git a/src/TwoStepLangevinFlow.h b/src/TwoStepLangevinFlow.h index d0cd9764..7fdcb015 100644 --- a/src/TwoStepLangevinFlow.h +++ b/src/TwoStepLangevinFlow.h @@ -10,16 +10,17 @@ #ifndef AZPLUGINS_TWO_STEP_LANGEVIN_FLOW_H_ #define AZPLUGINS_TWO_STEP_LANGEVIN_FLOW_H_ -#ifdef NVCC +#ifdef __HIPCC__ #error This header cannot be compiled by nvcc #endif #include "hoomd/RandomNumbers.h" -#include "hoomd/extern/pybind/include/pybind11/pybind11.h" #include "hoomd/md/TwoStepLangevinBase.h" +#include #include "RNGIdentifiers.h" - +namespace hoomd + { namespace azplugins { @@ -27,7 +28,8 @@ namespace azplugins /*! * \note Only translational motion is supported by this integrator. */ -template class PYBIND11_EXPORT TwoStepLangevinFlow : public TwoStepLangevinBase +template +class PYBIND11_EXPORT TwoStepLangevinFlow : public hoomd::md::TwoStepLangevinBase { public: //! Constructor @@ -35,17 +37,12 @@ template class PYBIND11_EXPORT TwoStepLangevinFlow : public Two std::shared_ptr group, std::shared_ptr T, std::shared_ptr flow_field, - unsigned int seed, - bool use_lambda, - Scalar lambda, bool noiseless) - : TwoStepLangevinBase(sysdef, group, T, seed, use_lambda, lambda), m_flow_field(flow_field), - m_noiseless(noiseless) + : TwoStepLangevinBase(sysdef, group, T), m_flow_field(flow_field), m_noiseless(noiseless) { m_exec_conf->msg->notice(5) << "Constructing TwoStepLangevinFlow" << std::endl; if (m_sysdef->getNDimensions() < 3) { - m_exec_conf->msg->error() << "flow.langevin is only supported in 3D" << std::endl; throw std::runtime_error("Langevin dynamics in flow is only supported in 3D"); } } @@ -72,10 +69,6 @@ template class PYBIND11_EXPORT TwoStepLangevinFlow : public Two /*! * \param flow_field New flow field to apply */ - void setFlowField(std::shared_ptr flow_field) - { - m_flow_field = flow_field; - } //! Get the flag for if noise is applied to the motion bool getNoiseless() const @@ -102,13 +95,8 @@ void TwoStepLangevinFlow::integrateStepOne(unsigned int timestep) { if (m_aniso) { - m_exec_conf->msg->error() << "azplugins.integrate: anisotropic particles are not supported " - "with langevin flow integrators." - << std::endl; throw std::runtime_error("Anisotropic integration not supported with langevin flow"); } - if (m_prof) - m_prof->push("Langevin step 1"); ArrayHandle h_pos(m_pdata->getPositions(), access_location::host, @@ -151,9 +139,6 @@ void TwoStepLangevinFlow::integrateStepOne(unsigned int timestep) h_pos.data[idx] = make_scalar4(pos.x, pos.y, pos.z, __int_as_scalar(type)); h_vel.data[idx] = make_scalar4(vel.x, vel.y, vel.z, mass); } - - if (m_prof) - m_prof->pop(); } template @@ -166,8 +151,6 @@ void TwoStepLangevinFlow::integrateStepTwo(unsigned int timestep) << std::endl; throw std::runtime_error("Anisotropic integration not supported with langevin flow"); } - if (m_prof) - m_prof->push("Langevin step 2"); ArrayHandle h_vel(m_pdata->getVelocities(), access_location::host, @@ -181,31 +164,21 @@ void TwoStepLangevinFlow::integrateStepTwo(unsigned int timestep) ArrayHandle h_net_force(m_pdata->getNetForce(), access_location::host, access_mode::read); - ArrayHandle h_diameter(m_pdata->getDiameters(), - access_location::host, - access_mode::read); ArrayHandle h_gamma(m_gamma, access_location::host, access_mode::read); - const Scalar currentTemp = m_T->getValue(timestep); + const Scalar currentTemp = (*m_T)(timestep); const FlowField& flow_field = *m_flow_field; + uint16_t seed = m_sysdef->getSeed(); // second step of velocity verlet while modifying accelerations unsigned int group_size = m_group->getNumMembers(); for (unsigned int group_idx = 0; group_idx < group_size; group_idx++) { unsigned int idx = m_group->getMemberIndex(group_idx); - // get the friction coefficient const Scalar4 postype = h_pos.data[idx]; - Scalar gamma; - if (m_use_lambda) - gamma = m_lambda * h_diameter.data[idx]; - else - { - unsigned int type = __scalar_as_int(postype.w); - gamma = h_gamma.data[type]; - } - + unsigned int type = __scalar_as_int(postype.w); + const Scalar gamma = h_gamma.data[type]; // get the flow velocity at the current position const Scalar3 flow_vel = flow_field(make_scalar3(postype.x, postype.y, postype.z)); @@ -213,10 +186,11 @@ void TwoStepLangevinFlow::integrateStepTwo(unsigned int timestep) Scalar coeff = fast::sqrt(Scalar(6.0) * gamma * currentTemp / m_deltaT); if (m_noiseless) coeff = Scalar(0.0); - hoomd::RandomGenerator rng(azplugins::RNGIdentifier::TwoStepLangevinFlow, - m_seed, - h_tag.data[idx], - timestep); + hoomd::RandomGenerator rng( + hoomd::Seed(hoomd::azplugins::detail::RNGIdentifier::TwoStepBrownianFlow, + timestep, + seed), + hoomd::Counter(h_tag.data[idx])); hoomd::UniformDistribution uniform(-coeff, coeff); const Scalar3 random = make_scalar3(uniform(rng), uniform(rng), uniform(rng)); @@ -243,9 +217,6 @@ void TwoStepLangevinFlow::integrateStepTwo(unsigned int timestep) h_vel.data[idx] = make_scalar4(vel.x, vel.y, vel.z, mass); h_accel.data[idx] = accel; } - - if (m_prof) - m_prof->pop(); } namespace detail @@ -257,21 +228,20 @@ void export_TwoStepLangevinFlow(pybind11::module& m, const std::string& name) namespace py = pybind11; typedef TwoStepLangevinFlow LangevinFlow; - py::class_>(m, - name.c_str(), - py::base()) + py::class_>( + m, + name.c_str(), + py::base()) .def(py::init, std::shared_ptr, std::shared_ptr, std::shared_ptr, - unsigned int, - bool, - Scalar, bool>()) - .def("setFlowField", &LangevinFlow::setFlowField) - .def("setNoiseless", &LangevinFlow::setNoiseless); + .def_property_readonly("flow_field", &LangevinFlow::getFlowField) + .def_property("noiseless", &LangevinFlow::getNoiseless, &LangevinFlow::setNoiseless); } } // end namespace detail } // end namespace azplugins + } // end namespace hoomd #endif // AZPLUGINS_TWO_STEP_LANGEVIN_FLOW_H_ diff --git a/src/flow.py b/src/flow.py index 13a6828c..a377c6e1 100644 --- a/src/flow.py +++ b/src/flow.py @@ -53,7 +53,8 @@ class ParabolicFlow(FlowField): Args: mean_velocity (float): Mean velocity. - separation (float): Separation between parallel plates defining the flow field. + separation (float): Separation between parallel plates defining the + flow field. This flow field generates the parabolic flow profile in a slit geomtry: diff --git a/src/module.cc b/src/module.cc index d9483378..150e1419 100644 --- a/src/module.cc +++ b/src/module.cc @@ -4,6 +4,11 @@ #include +#include "ConstantFlow.h" +#include "ParabolicFlow.h" +#include "TwoStepBrownianFlow.h" +#include "TwoStepLangevinFlow.h" + namespace hoomd { //! Plugins for soft matter @@ -72,10 +77,9 @@ void export_PotentialPairColloidGPU(pybind11::module&); void export_PotentialPairHertzGPU(pybind11::module&); void export_PotentialPairPerturbedLennardJonesGPU(pybind11::module&); #endif // ENABLE_HIP - - } // namespace detail - } // namespace azplugins - } // namespace hoomd + } // namespace detail + } // namespace azplugins + } // namespace hoomd // python module PYBIND11_MODULE(_azplugins, m) @@ -88,6 +92,10 @@ PYBIND11_MODULE(_azplugins, m) // flow export_ConstantFlow(m); export_ParabolicFlow(m); + export_TwoStepBrownianFlow(m, "BrownianConstantFlow"); + export_TwoStepBrownianFlow(m, "BrownianParabolicFlow"); + export_TwoStepLangevinFlow(m, "LangevinConstantFlow"); + export_TwoStepLangevinFlow(m, "LangevinParabolicFlow"); // pair export_AnisoPotentialPairTwoPatchMorse(m);