29#include "thermostat.hpp"
46#ifdef ESPRESSO_THERMOSTAT_PER_PARTICLE
52 gamma = brownian_gamma;
55#ifdef ESPRESSO_PARTICLE_ANISOTROPY
57 auto const aniso_flag = (gamma[0] != gamma[1]) || (gamma[1] != gamma[2]);
61 auto const delta_pos_body = hadamard_division(force_body * dt, gamma);
67 for (
unsigned int j = 0; j < 3; j++) {
70#ifdef ESPRESSO_PARTICLE_ANISOTROPY
73 position[j] = delta_pos_lab[j];
77 position[j] = p.
force()[j] * dt / gamma[j];
82 position[j] = p.
force()[j] * dt / gamma;
99#ifdef ESPRESSO_THERMOSTAT_PER_PARTICLE
105 gamma = brownian_gamma;
108#ifdef ESPRESSO_PARTICLE_ANISOTROPY
110 auto const aniso_flag = (gamma[0] != gamma[1]) || (gamma[1] != gamma[2]);
114 auto const vel_body = hadamard_division(force_body, gamma);
120 for (
unsigned int j = 0; j < 3; j++) {
124#ifdef ESPRESSO_PARTICLE_ANISOTROPY
152 [[maybe_unused]]
double kT) {
154#ifdef ESPRESSO_THERMOSTAT_PER_PARTICLE
168 auto const noise = Random::noise_gaussian<RNGSalt::BROWNIAN_WALK>(
170 for (
unsigned int j = 0; j < 3; j++) {
172#ifndef ESPRESSO_PARTICLE_ANISOTROPY
173 if (sigma_pos > 0.0) {
174 delta_pos_body[j] = sigma_pos * sqrt(dt) * noise[j];
176 delta_pos_body[j] = 0.0;
179 if (sigma_pos[j] > 0.0) {
180 delta_pos_body[j] = sigma_pos[j] * sqrt(dt) * noise[j];
182 delta_pos_body[j] = 0.0;
188#ifdef ESPRESSO_PARTICLE_ANISOTROPY
190 auto const aniso_flag =
191 (sigma_pos[0] != sigma_pos[1]) || (sigma_pos[1] != sigma_pos[2]);
199 for (
unsigned int j = 0; j < 3; j++) {
201#ifdef ESPRESSO_PARTICLE_ANISOTROPY
202 position[j] += aniso_flag ? delta_pos_lab[j] : delta_pos_body[j];
204 position[j] += delta_pos_body[j];
218 auto const noise = Random::noise_gaussian<RNGSalt::BROWNIAN_INC>(
221 for (
unsigned int j = 0; j < 3; j++) {
236#ifdef ESPRESSO_ROTATION
249#ifdef ESPRESSO_THERMOSTAT_PER_PARTICLE
255 gamma = brownian_gamma_rotation;
259 for (
unsigned int j = 0; j < 3; j++) {
262#ifndef ESPRESSO_PARTICLE_ANISOTROPY
263 dphi[j] = p.
torque()[j] * dt / gamma;
265 dphi[j] = p.
torque()[j] * dt / gamma[j];
270 double dphi_m = dphi.
norm();
272 auto const dphi_u = dphi / dphi_m;
288#ifdef ESPRESSO_THERMOSTAT_PER_PARTICLE
294 gamma = brownian_gamma_rotation;
298 for (
unsigned int j = 0; j < 3; j++) {
300#ifdef ESPRESSO_PARTICLE_ANISOTROPY
301 omega[j] = p.
torque()[j] / gamma[j];
303 omega[j] = p.
torque()[j] / gamma;
319 double dt,
double kT) {
322#ifdef ESPRESSO_THERMOSTAT_PER_PARTICLE
334 auto const noise = Random::noise_gaussian<RNGSalt::BROWNIAN_ROT_INC>(
336 for (
unsigned int j = 0; j < 3; j++) {
338#ifndef ESPRESSO_PARTICLE_ANISOTROPY
339 if (sigma_pos > 0.0) {
340 dphi[j] = noise[j] * sigma_pos * sqrt(dt);
343 if (sigma_pos[j] > 0.0) {
344 dphi[j] = noise[j] * sigma_pos[j] * sqrt(dt);
351 double dphi_m = dphi.
norm();
353 auto const dphi_u = dphi / dphi_m;
369 auto const noise = Random::noise_gaussian<RNGSalt::BROWNIAN_ROT_WALK>(
371 for (
unsigned int j = 0; j < 3; j++) {
373 domega[j] = sigma_vel * noise[j] / sqrt(p.
rinertia()[j]);
Vector implementation and trait types for boost qvm interoperability.
Random number generation using Philox.
static Utils::Vector3d velocity(Particle const &p_ref, Particle const &p_vs)
Velocity of the virtual site.
This file contains all subroutines required to process rotational motion.
Utils::Vector3d convert_vector_body_to_space(const Particle &p, const Utils::Vector3d &vec)
Utils::Vector3d convert_vector_space_to_body(const Particle &p, const Utils::Vector3d &v)
Utils::Quaternion< double > local_rotate_particle_body(Particle const &p, const Utils::Vector3d &axis_body_frame, const double phi)
Rotate the particle p around the body-frame defined NORMALIZED axis aBodyFrame by amount phi.
uint64_t rng_counter() const
Get current value of the RNG.
uint32_t rng_seed() const
Thermostat for Brownian dynamics.
GammaType sigma_pos
Translational noise standard deviation.
double sigma_vel_rotation
Angular velocity noise standard deviation.
double sigma_vel
Translational velocity noise standard deviation.
GammaType sigma_pos_rotation
Rotational noise standard deviation.
static GammaType sigma(double kT, GammaType const &gamma)
Calculate the noise prefactor.
Struct holding all information for one particle.
auto const & rinertia() const
auto const & mass() const
auto const & quat() const
auto const & rotation() const
auto const & gamma() const
bool can_rotate_around(unsigned int const axis) const
auto const & gamma_rot() const
auto const & torque() const
bool is_fixed_along(unsigned int const axis) const
auto const & force() const
Quaternion representation.
Utils::Vector3d bd_random_walk_vel_rot(BrownianThermostat const &brownian, Particle const &p)
Determine the angular velocities: random walk part.
Utils::Quaternion< double > bd_drag_rot(Thermostat::GammaType const &brownian_gamma_rotation, Particle &p, double dt)
Determine quaternions: viscous drag driven by conservative torques.
Utils::Vector3d bd_random_walk(BrownianThermostat const &brownian, Particle const &p, double dt, double kT)
Determine the positions: random walk part.
Utils::Vector3d bd_drag_vel(Thermostat::GammaType const &brownian_gamma, Particle const &p)
Set the terminal velocity driven by the conservative forces drag.
Utils::Vector3d bd_random_walk_vel(BrownianThermostat const &brownian, Particle const &p)
Determine the velocities: random walk part.
Utils::Quaternion< double > bd_random_walk_rot(BrownianThermostat const &brownian, Particle const &p, double dt, double kT)
Determine the quaternions: random walk part.
Utils::Vector3d bd_drag(Thermostat::GammaType const &brownian_gamma, Particle const &p, double dt)
Determine position: viscous drag driven by conservative forces.
Utils::Vector3d bd_drag_vel_rot(Thermostat::GammaType const &brownian_gamma_rotation, Particle const &p)
Set the terminal angular velocity driven by the conservative torques drag.