Added bd integrator for ellipsoidal particles as well.

This commit is contained in:
Sam Cameron
2020-12-16 16:14:13 +00:00
parent 86ebe0a9d3
commit f2e7f5263e
9 changed files with 876 additions and 2 deletions

View File

@ -40,6 +40,7 @@ OPT.
* :doc:`aveforce <fix_aveforce>`
* :doc:`balance <fix_balance>`
* :doc:`bd/sphere <fix_bd_sphere>`
* :doc:`bd/asphere <fix_bd_asphere>`
* :doc:`bocs <fix_bocs>`
* :doc:`bond/break <fix_bond_break>`
* :doc:`bond/create <fix_bond_create>`

View File

@ -181,8 +181,9 @@ accelerated styles exist.
* :doc:`ave/histo/weight <fix_ave_histo>` - weighted version of fix ave/histo
* :doc:`ave/time <fix_ave_time>` - compute/output global time-averaged quantities
* :doc:`aveforce <fix_aveforce>` - add an averaged force to each atom
* :doc:`bd/sphere <fix_bd_sphere>` - overdamped translational and rotational brownian dynamics
* :doc:`balance <fix_balance>` - perform dynamic load-balancing
* :doc:`bd/asphere <fix_bd_asphere>` - integrate positions and orientations in overdamped motion
* :doc:`bd/sphere <fix_bd_sphere>` - overdamped translational and rotational brownian dynamics
* :doc:`bocs <fix_bocs>` - NPT style time integration with pressure correction
* :doc:`bond/break <fix_bond_break>` - break bonds on the fly
* :doc:`bond/create <fix_bond_create>` - create bonds on the fly

149
doc/src/fix_bd_asphere.rst Normal file
View File

@ -0,0 +1,149 @@
.. index:: fix bd/asphere
fix bd/asphere command
======================
Syntax
""""""
.. parsed-literal::
fix ID group-ID bd/asphere gamma_t gamma_r diff_t diff_r seed keyword args
* ID, group-ID are documented in :doc:`fix <fix>` command
* bd/asphere = style name of this fix command
* gamma_t = translational friction coefficient
* gamma_r = rotational friction coefficient
* diff_t = translational diffusion coefficient
* diff_r = rotational diffusion coefficient
* zero or more keyword/value pairs may be appended
* keyword = *rng* or *dipole*
.. parsed-literal::
*rng* value = *uniform* or *gaussian* or *none*
*uniform* = use uniform random number generator
*gaussian* = use gaussian random number generator
*none* = turn off noise
*dipole* value = none = update orientation of dipoles during integration
Examples
""""""""
.. code-block:: LAMMPS
fix 1 all bd/asphere 1.0 1.0 1.0 1.0 1294019
fix 1 all bd/asphere 1.0 1.0 1.0 1.0 19581092 rng none dipole
fix 1 all bd/asphere 1.0 1.0 1.0 1.0 19581092 rng uniform
fix 1 all bd/asphere 1.0 1.0 1.0 1.0 19581092 dipole rng gaussian
Description
"""""""""""
Perform Brownian Dynamics integration to update position, velocity,
angular velocity, particle orientation, and dipole moment for
finite-size elipsoidal particles in the group each timestep.
Brownian Dynamics uses Newton's laws of
motion in the limit that inertial forces are negligible compared to
viscous forces. The stochastic equations of motion are
.. math::
dr = \frac{F}{\gamma_t}dt+\sqrt{2D_t}dW_t, \\
d\Omega = \frac{T}{\gamma_r}dt + \sqrt{2D_r}dW_r,
where :math:`d\Omega` is an infinitesimal rotation vector (see e.g.
Chapter 4 of :ref:`(Goldstein) <GoldsteinCM1>`), :math:`dW_t` and
:math:`dW_r` are Wiener processes (see e.g. :ref:`(Gardiner) <GardinerC1>`).
The quaternions :math:`q` of the ellipsoid are updated each timestep from
the angular velocity vector.
See :doc:`fix bd/sphere <fix_bd_sphere>` for discussion on the
values of :math:`\gamma_t`, :math:`\gamma_r`, :math:`D_t`,
and :math:`D_r` when simulating equilibrium systems.
If the *rng* keyword is used with the *uniform* value, then the noise
is generated from a uniform distribution (see
:ref:`(Dunweg) <Dunweg7>` for why this works). This is the same method
of noise generation as used in :doc:`fix_langevin <fix_langevin>`.
If the *rng* keyword is used with the *gaussian* value, then the noise
is generated from a gaussian distribution. Typically this added
complexity is unnecessary, and one should be fine using the *uniform*
value for reasons argued in :ref:`(Dunweg) <Dunweg7>`.
If the *rng* keyword is used with the *none* value, then the noise
terms are set to zero.
If the *dipole* keyword is used, then the dipole moments of the particles
are updated by setting them along the x axis of the ellipsoidal frames of
reference.
----------
.. include:: accel_styles.rst
----------
Restart, fix_modify, output, run start/stop, minimize info
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
No information about this fix is written to :doc:`binary restart files <restart>`.
No global or per-atom quantities are stored
by this fix for access by various :doc:`output commands <Howto_output>`.
The :doc:`fix_modify <fix_modify>` *virial* option is supported by this
fix to add the contribution due to the added forces on atoms to the
system's virial as part of :doc:`thermodynamic output <thermo_style>`.
The default is *virial no*.
No parameter of this fix can be used with the *start/stop* keywords of
the :doc:`run <run>` command. This fix is not invoked during
:doc:`energy minimization <minimize>`.
Restrictions
""""""""""""
This fix requires that atoms store torque and angular velocity (omega)
as defined by the :doc:`atom_style sphere <atom_style>` command, as well
as atoms which have a definite orientation as defined by the
:doc:`atom_style ellipsoid <atom_style>` command.
Optionally, they can also store a dipole moment as defined by the
:doc:`atom_style dipole <atom_style>` command.
This fix is part of the USER-MISC package. It is only enabled if
LAMMPS was built with that package. See the :doc:`Build package <Build_package>`
doc page for more info.
All particles in the group must be finite-size ellipsoids. They cannot
be point particles.
Related commands
""""""""""""""""
:doc:`fix bd/sphere <fix_bd_sphere>`, :doc:`fix langevin <fix_langevin>`,
:doc:`fix nve/asphere <fix_nve_asphere>`, :doc:`atom style <atom_style>`
Default
"""""""
The default for *rng* is *uniform*.
----------
.. _GoldsteinCM1:
**(Goldstein)** Goldstein, Poole, and Safko, Classical Mechanics, 3rd Ed. (2001).
.. _GardinerC1:
**(Gardiner)** Gardiner, A Handbook for the Natural and Social Sciences 4th Ed. (2009).
.. _Dunweg7:
**(Dunweg)** Dunweg and Paul, Int J of Modern Physics C, 2, 817-27 (1991).

View File

@ -0,0 +1,2 @@
The input file in2d.bd demonstrates how to run a 2d simulation
of ellipsoidal particles undergoing overdamped brownian motion.

View File

@ -0,0 +1,71 @@
# 3d overdamped brownian dynamics
variable rng string gaussian
variable gamma_t equal 4.0
variable gamma_r equal 1.0
variable D_t equal 7.0
variable D_r equal 13.0
variable seed equal 1974019
variable params string ${rng}_${gamma_t}_${gamma_r}_${D_t}_${D_r}
log log_${params}_3d.lammps.log
units lj
atom_style hybrid dipole sphere ellipsoid
dimension 3
newton off
lattice sc 0.4
region box block -4 4 -4 4 -4 4
create_box 1 box
create_atoms 1 box
mass * 1.0
set type * dipole/random ${seed} 1.0
set type * shape 1 1 1
set type * quat/random ${seed}
velocity all create 1.0 1 loop geom
neighbor 1.0 bin
neigh_modify every 1 delay 1 check yes
pair_style none
fix 1 all bd/asphere ${gamma_t} ${gamma_r} ${D_t} ${D_r} ${seed} rng ${rng} dipole
compute press all pressure NULL virial
thermo_style custom step temp epair c_press
#equilibration
timestep 0.0000000001
thermo 50000
run 50000
reset_timestep 0
#initialisation for the main run
# MSD
compute msd all msd
thermo_style custom step temp epair c_msd[*] c_press
# write trajectory and thermo in a log-scale frequency
#dump 1 all custom 1000 dump_${params}_3d.lammpstrj id type &
# x y xu yu mux muy muz fx fy fz
#dump_modify 1 first yes sort id
timestep 0.00001
thermo 10000
# main run
run 120000

View File

@ -0,0 +1,154 @@
units lj
atom_style hybrid dipole sphere ellipsoid
WARNING: Atom_style hybrid defines both pertype and peratom masses - both must be set, only peratom masses will be used (src/atom_vec_hybrid.cpp:157)
WARNING: Peratom rmass is in multiple sub-styles - must be used consistently (src/atom_vec_hybrid.cpp:219)
dimension 3
newton off
lattice sc 0.4
Lattice spacing in x,y,z = 1.3572088 1.3572088 1.3572088
region box block -4 4 -4 4 -4 4
create_box 1 box
Created orthogonal box = (-5.4288352 -5.4288352 -5.4288352) to (5.4288352 5.4288352 5.4288352)
1 by 1 by 1 MPI processor grid
create_atoms 1 box
Created 512 atoms
create_atoms CPU = 0.001 seconds
mass * 1.0
set type * dipole/random ${seed} 1.0
set type * dipole/random 1974019 1.0
Setting atom values ...
512 settings made for dipole/random
set type * shape 1 1 1
Setting atom values ...
512 settings made for shape
set type * quat/random ${seed}
set type * quat/random 1974019
Setting atom values ...
512 settings made for quat/random
velocity all create 1.0 1 loop geom
neighbor 1.0 bin
neigh_modify every 1 delay 1 check yes
pair_style none
fix 1 all bd/asphere ${gamma_t} ${gamma_r} ${D_t} ${D_r} ${seed} rng ${rng} dipole
fix 1 all bd/asphere 4 ${gamma_r} ${D_t} ${D_r} ${seed} rng ${rng} dipole
fix 1 all bd/asphere 4 1 ${D_t} ${D_r} ${seed} rng ${rng} dipole
fix 1 all bd/asphere 4 1 7 ${D_r} ${seed} rng ${rng} dipole
fix 1 all bd/asphere 4 1 7 13 ${seed} rng ${rng} dipole
fix 1 all bd/asphere 4 1 7 13 1974019 rng ${rng} dipole
fix 1 all bd/asphere 4 1 7 13 1974019 rng gaussian dipole
compute press all pressure NULL virial
thermo_style custom step temp epair c_press
#equilibration
timestep 0.0000000001
thermo 50000
run 50000
WARNING: No pairwise cutoff or binsize set. Atom sorting therefore disabled. (src/atom.cpp:2118)
WARNING: Communication cutoff is 0.0. No ghost atoms will be generated. Atoms may get lost. (src/comm_brick.cpp:167)
Per MPI rank memory allocation (min/avg/max) = 5.379 | 5.379 | 5.379 Mbytes
Step Temp E_pair c_press
0 1 0 0
50000 1.3923773e+11 0 0
Loop time of 5.68636 on 1 procs for 50000 steps with 512 atoms
Performance: 0.076 tau/day, 8792.977 timesteps/s
100.0% CPU use with 1 MPI tasks x 1 OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0 | 0 | 0 | 0.0 | 0.00
Neigh | 0 | 0 | 0 | 0.0 | 0.00
Comm | 0.11589 | 0.11589 | 0.11589 | 0.0 | 2.04
Output | 2.1155e-05 | 2.1155e-05 | 2.1155e-05 | 0.0 | 0.00
Modify | 5.4911 | 5.4911 | 5.4911 | 0.0 | 96.57
Other | | 0.07936 | | | 1.40
Nlocal: 512.000 ave 512 max 512 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost: 217.000 ave 217 max 217 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs: 0.00000 ave 0 max 0 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Total # of neighbors = 0
Ave neighs/atom = 0.0000000
Neighbor list builds = 0
Dangerous builds = 0
reset_timestep 0
#initialisation for the main run
# MSD
compute msd all msd
thermo_style custom step temp epair c_msd[*] c_press
# write trajectory and thermo in a log-scale frequency
dump 1 all custom 1000 dump_${params}_2d.lammpstrj id type x y xu yu mux muy muz fx fy fz
dump 1 all custom 1000 dump_gaussian_4_1_7_13_2d.lammpstrj id type x y xu yu mux muy muz fx fy fz
dump_modify 1 first yes sort id
timestep 0.00001
thermo 10000
# main run
run 120000
WARNING: Communication cutoff is 0.0. No ghost atoms will be generated. Atoms may get lost. (src/comm_brick.cpp:167)
Per MPI rank memory allocation (min/avg/max) = 7.103 | 7.103 | 7.103 Mbytes
Step Temp E_pair c_msd[1] c_msd[2] c_msd[3] c_msd[4] c_press
0 1.3923773e+11 0 0 0 0 0 0
10000 1413805.2 0 1.3943053 1.4055827 1.4346505 4.2345385 0
20000 1380788.4 0 2.8560158 2.6537192 2.698195 8.2079299 0
30000 1368735.7 0 4.2694087 4.1286924 3.9635117 12.361613 0
40000 1349446 0 5.4328386 6.0271243 5.3571941 16.817157 0
50000 1366690 0 7.0372792 7.3342977 6.7676981 21.139275 0
60000 1413212.4 0 8.6092241 8.3859529 8.3650987 25.360276 0
70000 1401310 0 10.085131 9.4972009 9.7949174 29.377249 0
80000 1419160.7 0 11.413946 10.964643 11.007284 33.385873 0
90000 1298713.5 0 12.556318 12.457196 12.055966 37.06948 0
100000 1430838.3 0 14.104796 13.817001 13.596538 41.518335 0
110000 1364246.8 0 15.382464 15.09201 15.017312 45.491785 0
120000 1389237.6 0 16.632972 16.343173 16.015748 48.991892 0
Loop time of 13.595 on 1 procs for 120000 steps with 512 atoms
Performance: 7626.329 tau/day, 8826.770 timesteps/s
100.0% CPU use with 1 MPI tasks x 1 OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0 | 0 | 0 | 0.0 | 0.00
Neigh | 0.00079148 | 0.00079148 | 0.00079148 | 0.0 | 0.01
Comm | 0.029132 | 0.029132 | 0.029132 | 0.0 | 0.21
Output | 0.15178 | 0.15178 | 0.15178 | 0.0 | 1.12
Modify | 13.222 | 13.222 | 13.222 | 0.0 | 97.25
Other | | 0.1916 | | | 1.41
Nlocal: 512.000 ave 512 max 512 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost: 0.00000 ave 0 max 0 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs: 0.00000 ave 0 max 0 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Total # of neighbors = 0
Ave neighs/atom = 0.0000000
Neighbor list builds = 1110
Dangerous builds = 0
Total wall time: 0:00:19

View File

@ -53,7 +53,8 @@ dihedral_style table/cut, Mike Salerno, ksalerno@pha.jhu.edu, 11 May 18
fix accelerate/cos, Zheng Gong (ENS de Lyon), z.gong@outlook.com, 24 Apr 20
fix addtorque, Laurent Joly (U Lyon), ljoly.ulyon at gmail.com, 8 Aug 11
fix ave/correlate/long, Jorge Ramirez (UPM Madrid), jorge.ramirez at upm.es, 21 Oct 2015
fix bd/sphere, Sam Cameron (U of Bristol), samuel.j.m.cameron at gmail.com, 10 Dec 2020
fix bd/sphere, Sam Cameron (U of Bristol), samuel.j.m.cameron at gmail.com, 13 Dec 2020
fix bd/asphere, Sam Cameron (U of Bristol), samuel.j.m.cameron at gmail.com, 13 Dec 2020
fix electron/stopping/fit, James Stewart (SNL), jstewa .at. sandia.gov, 23 Sep 2020
fix electron/stopping, Konstantin Avchaciov, k.avchachov at gmail.com, 26 Feb 2019
fix ffl, David Wilkins (EPFL Lausanne), david.wilkins @ epfl.ch, 28 Sep 2018

View File

@ -0,0 +1,392 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Originally modified from USER-CGDNA/fix_nve_dotc_langevin.cpp.
Contributing author: Sam Cameron (University of Bristol)
------------------------------------------------------------------------- */
#include "fix_bd_asphere.h"
#include <cmath>
#include <cstring>
#include "math_extra.h"
#include "atom.h"
#include "atom_vec_ellipsoid.h"
#include "force.h"
#include "update.h"
#include "comm.h"
#include "domain.h"
#include "random_mars.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
#define SMALL 1e-14
enum{NODIPOLE,DIPOLE};
/* ---------------------------------------------------------------------- */
FixBdAsphere::FixBdAsphere(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
virial_flag = 1;
time_integrate = 1;
dipole_flag = NODIPOLE;
if (narg > 11 || narg < 8 )
error->all(FLERR,"Illegal fix bd/asphere command.");
if (!atom->sphere_flag)
error->all(FLERR,"Fix bd/asphere requires atom style sphere");
gamma_t = utils::numeric(FLERR,arg[3],false,lmp);
if (gamma_t <= 0.0)
error->all(FLERR,"Fix bd/asphere translational viscous drag "
"coefficient must be > 0.");
gamma_r = utils::numeric(FLERR,arg[4],false,lmp);
if (gamma_t <= 0.0)
error->all(FLERR,"Fix bd/asphere rotational viscous drag "
"coefficient must be > 0.");
diff_t = utils::numeric(FLERR,arg[5],false,lmp);
if (diff_t <= 0.0)
error->all(FLERR,"Fix bd/asphere translational diffusion "
"coefficient must be > 0.");
diff_r = utils::numeric(FLERR,arg[6],false,lmp);
if (diff_r <= 0.0)
error->all(FLERR,"Fix bd/asphere rotational diffusion "
"coefficient must be > 0.");
seed = utils::inumeric(FLERR,arg[7],false,lmp);
if (seed <= 0) error->all(FLERR,"Fix bd/asphere seed must be > 0.");
noise_flag = 1;
gaussian_noise_flag = 0;
int iarg = 8;
while (iarg < narg) {
if (strcmp(arg[iarg],"rng") == 0) {
if (narg == iarg + 1) {
error->all(FLERR,"Illegal fix/bd/asphere command.");
}
if (strcmp(arg[iarg + 1],"uniform") == 0) {
noise_flag = 1;
} else if (strcmp(arg[iarg + 1],"gaussian") == 0) {
noise_flag = 1;
gaussian_noise_flag = 1;
} else if (strcmp(arg[iarg + 1],"none") == 0) {
noise_flag = 0;
} else {
error->all(FLERR,"Illegal fix/bd/asphere command.");
}
iarg = iarg + 2;
} else if (strcmp(arg[iarg],"dipole") == 0) {
dipole_flag = DIPOLE;
iarg = iarg + 1;
} else {
error->all(FLERR,"Illegal fix/bd/asphere command.");
}
}
if (dipole_flag == DIPOLE && !atom->mu_flag)
error->all(FLERR,"Fix bd/asphere dipole requires atom attribute mu");
// initialize Marsaglia RNG with processor-unique seed
random = new RanMars(lmp,seed + comm->me);
}
/* ---------------------------------------------------------------------- */
int FixBdAsphere::setmask()
{
int mask = 0;
mask |= INITIAL_INTEGRATE;
mask |= POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
FixBdAsphere::~FixBdAsphere()
{
delete random;
}
/* ---------------------------------------------------------------------- */
void FixBdAsphere::init()
{
avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
if (!avec)
error->all(FLERR,"Compute bd/asphere requires "
"atom style ellipsoid");
// check that all particles are finite-size ellipsoids
// no point particles allowed, spherical is OK
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
if (ellipsoid[i] < 0)
error->one(FLERR,"Fix bd/asphere requires extended particles");
if (dipole_flag == DIPOLE) {
double f_act[3] = { 1.0, 0.0, 0.0 };
double f_rot[3];
double *quat;
int *ellipsoid = atom->ellipsoid;
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
double Q[3][3];
double **mu = atom->mu;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
quat = bonus[ellipsoid[i]].quat;
MathExtra::quat_to_mat( quat, Q );
MathExtra::matvec( Q, f_act, f_rot );
mu[i][0] = f_rot[0];
mu[i][1] = f_rot[1];
mu[i][2] = f_rot[2];
}
}
}
g1 = force->ftm2v/gamma_t;
g3 = force->ftm2v/gamma_r;
if (noise_flag == 0) {
g2 = 0;
g4 = 0;
rng_func = &RanMars::zero_rng;
} else if (gaussian_noise_flag == 1) {
g2 = gamma_t*sqrt(2 * diff_t)/force->ftm2v;
g4 = gamma_r*sqrt(2 * diff_r)/force->ftm2v;
rng_func = &RanMars::gaussian;
} else {
g2 = gamma_t*sqrt( 24 * diff_t)/force->ftm2v;
g4 = gamma_r*sqrt( 24 * diff_r )/force->ftm2v;
rng_func = &RanMars::uniform_middle;
}
dt = update->dt;
sqrtdt = sqrt(dt);
}
void FixBdAsphere::setup(int vflag)
{
post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixBdAsphere::initial_integrate(int /* vflag */)
{
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega;
double **torque = atom->torque;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (igroup == atom->firstgroup) nlocal = atom->nfirst;
int d3rot; // whether to compute angular momentum in xy plane
if (domain->dimension==2) {
d3rot = 0;
} else {
d3rot = 1;
}
if (dipole_flag == DIPOLE) {
// if dipole is being tracked, then update it along with
// quaternions accordingly along with angular velocity
double wq[4];
double *quat;
int *ellipsoid = atom->ellipsoid;
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
// project dipole along x axis of quat
double f_act[3] = { 1.0, 0.0, 0.0 };
double f_rot[3];
double Q[3][3];
double **mu = atom->mu;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
update_x_and_omega(x[i],v[i],omega[i],f[i],torque[i],d3rot);
quat = bonus[ellipsoid[i]].quat;
MathExtra::vecquat(omega[i],quat,wq);
quat[0] = quat[0] + 0.5*dt*wq[0];
quat[1] = quat[1] + 0.5*dt*wq[1];
quat[2] = quat[2] + 0.5*dt*wq[2];
quat[3] = quat[3] + 0.5*dt*wq[3];
MathExtra::qnormalize(quat);
MathExtra::quat_to_mat( quat, Q );
MathExtra::matvec( Q, f_act, f_rot );
mu[i][0] = f_rot[0];
mu[i][1] = f_rot[1];
mu[i][2] = f_rot[2];
}
}
} else {
// if no dipole, just update quaternions and
// angular velocity
double wq[4];
double *quat;
int *ellipsoid = atom->ellipsoid;
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
update_x_and_omega(x[i],v[i],omega[i],f[i],torque[i],d3rot);
quat = bonus[ellipsoid[i]].quat;
MathExtra::vecquat(omega[i],quat,wq);
quat[0] = quat[0] + 0.5*dt*wq[0];
quat[1] = quat[1] + 0.5*dt*wq[1];
quat[2] = quat[2] + 0.5*dt*wq[2];
quat[3] = quat[3] + 0.5*dt*wq[3];
MathExtra::qnormalize(quat);
}
}
}
return;
}
void FixBdAsphere::update_x_and_omega(double *x, double *v, double *omega,
double *f, double *torque, int d3rot)
{
double dx, dy, dz;
dx = dt * g1 * f[0];
x[0] += dx;
v[0] = dx/dt;
dy = dt * g1 * f[1];
x[1] += dy;
v[1] = dy/dt;
dz = dt * g1 * f[2];
x[2] += dz;
v[2] = dz/dt;
omega[0] = d3rot * g3* torque[0];
omega[1] = d3rot * g3* torque[1];
omega[2] = g3* torque[2];
return;
}
/* ----------------------------------------------------------------------
apply random force, stolen from MISC/fix_efield.cpp
------------------------------------------------------------------------- */
void FixBdAsphere::post_force(int vflag)
{
double **f = atom->f;
double **x = atom->x;
double **torque = atom->torque;
int *mask = atom->mask;
imageint *image = atom->image;
int nlocal = atom->nlocal;
// virial setup
if (vflag) v_setup(vflag);
else evflag = 0;
double fx,fy,fz;
double v[6];
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
fx = g2 * (random->*rng_func)()/sqrtdt;
fy = g2 * (random->*rng_func)()/sqrtdt;
fz = g2 * (random->*rng_func)()/sqrtdt;
f[i][0] += fx;
f[i][1] += fy;
f[i][2] += fz;
torque[i][0] = g4*(random->*rng_func)()/sqrtdt;
torque[i][1] = g4*(random->*rng_func)()/sqrtdt;
torque[i][2] = g4*(random->*rng_func)()/sqrtdt;
if (evflag) {
v[0] = fx*x[i][0];
v[1] = fy*x[i][1];
v[2] = fz*x[i][2];
v[3] = fx*x[i][1];
v[4] = fx*x[i][2];
v[5] = fy*x[i][2];
v_tally(i, v);
}
}
}
void FixBdAsphere::reset_dt()
{
dt = update->dt;
sqrtdt = sqrt(dt);
}

View File

@ -0,0 +1,103 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
FixStyle(bd/asphere,FixBdAsphere)
#else
#ifndef LMP_FIX_BD_ASPHERE_H
#define LMP_FIX_BD_ASPHERE_H
#include "fix.h"
namespace LAMMPS_NS {
class FixBdAsphere : public Fix {
public:
FixBdAsphere(class LAMMPS *, int, char **);
virtual ~FixBdAsphere();
void init();
void initial_integrate(int);
void setup(int);
void post_force(int);
int setmask();
void reset_dt();
void update_x_and_omega(double *, double *, double *,
double *, double *, int );
private:
int seed; // RNG seed
int dipole_flag; // set if dipole is used
double dt, sqrtdt; // time step interval and its sqrt
double gamma_t,gamma_r; // translational and rotational damping params
double diff_t,diff_r; // translational and rotational diffusion coeffs
double g1,g2, g3, g4; // prefactors in time stepping
int noise_flag; // 0/1 for noise off/on
int gaussian_noise_flag; // 0/1 for uniform/gaussian noise
class AtomVecEllipsoid *avec;
protected:
class RanMars *random;
typedef double (RanMars::*rng_member)();
rng_member rng_func; // placeholder for RNG function
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal fix bd/asphere command.
Wrong number/type of input arguments.
E: Compute bd/asphere requires atom style sphere
Self-explanatory.
E: Compute bd/asphere requires atom style ellipsoid
Self-explanatory.
E: Compute bd/asphere dipole requires atom attribute mu
Self-explanatory.
E: Fix bd/asphere translational viscous drag coefficient must be > 0.
Self-explanatory.
E: Fix bd/asphere rotational viscous drag coefficient must be > 0.
Self-explanatory.
E: Fix bd/asphere translational diffusion coefficient must be > 0.
Self-explanatory.
E: Fix bd/asphere rotational diffusion coefficient must be > 0.
Self-explanatory.
E: Fix bd/asphere seed must be > 0.
*/