Made changes to propel/self. Kept all features of previous version (and tested they stayed the same), but additionally added dipole option for direction of self-propulsion. Also updated examples.

This commit is contained in:
Sam Cameron
2020-12-20 16:39:04 +00:00
parent 4c1f449350
commit 05ecf86134
20 changed files with 919 additions and 469 deletions

View File

@ -8,53 +8,117 @@ Syntax
.. parsed-literal::
fix ID group-ID propel/self mode magnitude keyword values ...
fix ID group-ID propel/self magnitude keyword values
* ID, group-ID are documented in :doc:`fix <fix>` command
* propel/self = style name of this fix command
* mode = velocity or quat
* magnitude = magnitude of the active force
* one or more keyword/value pairs may be appended to args
* keyword = *types*
* magnitude = magnitude of self-propulsion force
* one (and only one) keyword/value pair must be appended to args
* keyword = *dipole* or *velocity* or *quat*
.. parsed-literal::
*dipole* value = none = apply force along dipole direction
*velocity* value = none = apply force along velocity direction
*quat* values = direction vector *sx* and *sy* and *sz*
*sx* = x component of force direction in ellipsoid frame
*sy* = y component of force direction in ellipsoid frame
*sz* = z component of force direction in ellipsoid frame
*types* values = one or more atom types
Examples
""""""""
.. code-block:: LAMMPS
fix active_group all propel/self velocity 1.0
fix constant_velocity all viscous 1.0
fix active_group all propel/self quat 1.0
fix active all propel/self quat 1.0 types 1 2 4
fix propel/self all 40.0 dipole
fix propel/self all 10.0 velocity
fix propel/self all 15.7 quat 1.0 0.0 0.0
Description
"""""""""""
Adds a force of a constant magnitude to each atom in the group. The nature in
which the force is added depends on the mode.
Add a force to each atom in the group due to a self-propulsion force. The
force is given by
For *mode* = *velocity*, the active force acts along the velocity vector of
each atom. This can be interpreted as a velocity-dependent friction,
such as proposed by :ref:`(Erdmann) <Erdmann>`.
.. math::
For *mode* = *quat* the force is applied along the axis obtained
by rotating the x-axis along the atom's quaternion. In other words, the
force is along the x-axis in the atom's body frame. This mode requires
all atoms in the group to have a quaternion, so atom_style should
either be ellipsoid or body. In combination with Langevin thermostat
for translation and rotation in the overdamped regime, the quaternion
mode corresponds to the active Brownian particle model introduced by
:ref:`(Henkes) <Henkes>`, :ref:`(Bialke) <Bialke>` and :ref:`(Fily)
<Fily>`.
F_i = f_P e_i
By default, this fix is applied to all atoms in the group. You can
override this behavior by specifying the atom types the fix should work
on through the *types* keyword.
where *i* is the particle the force is being applied to, :math:`f_P`
is the magnitude of the force, and :math:`e_i` is the vector direction
of the force. The specification of :math:`e_i` is based on which of the
three keywords (*dipole* or *velocity* or *quat*) one selects.
For keyword *dipole*, :math:`e_i` is just equal to
the dipole vectors of the atoms in the group. Therefore, if the dipoles
are not unit vectors, the :math:`e_i` will not be unit vectors.
.. note::
If another command changes the magnitude of the dipole, this force will
change accordingly (since :math:`|e_i|` will change, which is physically
equivalent to re-scaling :math:`f_P` while keeping :math:`|e_i|` constant),
and no warning will be provided by LAMMPS. This is almost never what you
want, so ensure you aren't changing dipole magnitudes with another LAMMPS
fix or pair style. Furthermore, self-propulsion forces (almost) always
set :math:`e_i` to be a unit vector for all times, so it's best to set
all the dipole magnitudes to 1.0 unless you have a good reason not to
(see the :doc:`set <set>` command on how to do this).
For keyword *velocity*, :math:`e_i` points in the direction
of the current velocity (a unit-vector). This can be interpreted as a
velocity-dependent friction, as proposed by e.g. :ref:`(Erdmann) <Erdmann1>`.
For keyword *quat*, :math:`e_i` points in the direction of the unit
vector defined by its arguments *sx*, *sy*, and *sz*, which are
themselves defined within the coordinate frame of the atom's
ellipsoid. For instance, for an ellipsoid with long axis along
its x-direction, if one wanted the self-propulsion force to also
be along this axis, set *sx* equal to 1 and *sy*, *sz* both equal
to zero. For *quat*, :math:`e_i` will always be a unit vector,
so multiplying all three arguments *sx*, *sy*, and *sz* by a
positive scalar will not change the self-propulsion force
(multiplying by a negative scalar will change the sign of the
force).
Along with adding a force contribution, this fix can also
contribute to the virial (pressure) of the system, defined as
:math:`f_P \sum_i <e_i . r_i>/(d V)`, where :math:`r_i` is the
*unwrapped* coordinate of particle i in the case of periodic
boundary conditions. See :ref:`(Winkler) <Winkler1>` for a
discussion of this active pressure contribution.
For keywords *dipole* and *quat*, this fix is by default
included in pressure computations.
For keyword *velocity*, this fix is by default not included
in pressure computations.
.. note::
In contrast to equilibrium systems, pressure of active systems
in general depends on the geometry of the container.
The active pressure contribution as calculated in this fix
is only valid for certain boundary conditions (spherical
walls, rectangular walls, or periodic boundary conditions).
For other geometries, the pressure must be measured via
explicit calculation of the force per unit area on a wall,
and so one must not calculate it using this fix.
(Use :doc:`fix_modify <fix_modify>` as described below
to turn off the virial contribution of this fix). Again,
see :ref:`(Winkler) <Winkler1>` for discussion of why this
is the case.
Furthermore, when dealing with active systems, the temperature
is no longer well defined. Therefore, one should ensure that
the *virial* flag is used in the
:doc:`compute pressure <compute_pressure>` command (turning
off temperature contributions).
----------
Restart, fix_modify, output, run start/stop, minimize info
@ -62,40 +126,48 @@ Restart, fix_modify, output, run start/stop, minimize info
No information about this fix is written to :doc:`binary restart files <restart>`.
This fix is not imposed during minimization.
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 yes* for keywords *dipole* and *quat*. The
default is *virial no* for keyword *velocity*.
No parameter of this fix can be used with the *start/stop* keywords of
the :doc:`run <run>` command.
Restrictions
""""""""""""
In quat mode, this fix makes use of per-atom quaternions to take
into account the fact that the orientation can rotate and hence the
direction of the active force can change. The quat mode
of this fix only works with atom_style ellipsoid.
With keyword *dipole*, this fix only works when the DIPOLE package is enabled.
See the :doc:`Build package <Build_package>` doc page for more info.
This fix is part of the USER-BROWNIAN package. It is only enabled if
LAMMPS was built with that package. See the :doc:`Build package <Build_package>`
doc page for more info.
Related commands
""""""""""""""""
:doc:`fix setforce <fix_setforce>`, :doc:`fix addforce <fix_addforce>`
.. _Erdmann:
**(Erdmann)** U. Erdmann , W. Ebeling, L. Schimansky-Geier, and F. Schweitzer,
Eur. Phys. J. B 15, 105-113, 2000.
.. _Henkes:
**(Henkes)** Henkes, S, Fily, Y., and Marchetti, M. C. Phys. Rev. E, 84, 040301(R), 2011.
.. _Bialke:
**(Bialke)** J. Bialke, T. Speck, and H Loewen, Phys. Rev. Lett. 108, 168301, 2012.
.. _Fily:
**(Fily)** Y. Fily and M.C. Marchetti, Phys. Rev. Lett. 108, 235702, 2012.
:doc:`fix efield <fix_efield>` , :doc:`fix setforce <fix_setforce>`,
:doc:`fix addforce <fix_addforce>`
Default
"""""""
types
none
----------
.. _Erdmann1:
**(Erdmann)** U. Erdmann , W. Ebeling, L. Schimansky-Geier, and F. Schweitzer,
Eur. Phys. J. B 15, 105-113, 2000.
.. _Winkler1:
**(Winkler)** Winkler, Wysocki, and Gompper, Soft Matter, 11, 6680 (2015).

View File

@ -0,0 +1,70 @@
# 2D overdamped active brownian particle dynamics (ABP)
# with WCA potential
variable gamma_t equal 1.0
variable gamma_r equal 1.0
variable D_t equal 1.0
variable D_r equal 3.0
variable seed equal 1974019
variable fp equal 4.0
variable params string ${gamma_t}_${gamma_r}_${D_t}_${D_r}_${fp}
log log_WCA_${params}_2d.lammps.log
units lj
atom_style hybrid dipole sphere
dimension 2
newton off
lattice sq 0.4
region box block -16 16 -16 16 -0.2 0.2
create_box 1 box
create_atoms 1 box
mass * 1.0
set type * dipole/random ${seed} 1.0
velocity all create 1.0 1 loop geom
# more careful with neighbors since higher diffusion in abps
neighbor 1.0 bin
neigh_modify every 1 delay 1 check yes
# WCA potential (purely repulsive)
pair_style lj/cut 2.5
pair_coeff * * 1.0 1.0 1.1224
pair_modify shift yes
# overdamped brownian dynamics time-step
fix step all brownian/sphere ${gamma_t} ${gamma_r} ${D_t} ${D_r} ${seed} dipole
# self-propulsion force along the dipole direction
fix activity all propel/self ${fp} dipole
fix 2 all enforce2d
compute press all pressure NULL virial
thermo_style custom step temp epair c_press
#equilibration
timestep 0.0000000001
thermo 50001
run 50000
reset_timestep 0
# MSD
compute msd all msd
thermo_style custom step temp epair c_msd[*] c_press
timestep 0.00001
thermo 10000
# main run
run 200000

View File

@ -0,0 +1,74 @@
# 3D overdamped active brownian dynamics with no interactions
variable gamma_t equal 1.0
variable gamma_r equal 1.0
variable D_t equal 1.0
variable D_r equal 3.0
variable seed equal 1974019
variable fp equal 4.0
variable params string ${gamma_t}_${gamma_r}_${D_t}_${D_r}_${fp}
log log_ideal_${params}_3d.lammps.log
units lj
atom_style hybrid dipole sphere
dimension 3
newton off
lattice sc 0.4
region box block -8 8 -8 8 -8 8
create_box 1 box
create_atoms 1 box
mass * 1.0
set type * dipole/random ${seed} 1.0
velocity all create 1.0 1 loop geom
pair_style none
# overdamped brownian dynamics time-step
fix step all brownian/sphere ${gamma_t} ${gamma_r} ${D_t} ${D_r} ${seed} dipole
# self-propulsion force along the dipole direction
fix activity all propel/self ${fp} dipole
compute press all pressure NULL virial
thermo_style custom step temp epair c_press
#equilibration
timestep 0.0000000001
thermo 50001
run 50000
reset_timestep 0
# MSD to demonstrate expected diffusive behaviour for ideal active
# brownian motion, which is
#
# MSD = (2*d*D_t + 2*fp**2/(gamma_t**2*(d-1)*D_r))*t
#
# with d being simulation dimension
compute msd all msd
thermo_style custom step temp epair c_msd[*] c_press
timestep 0.00001
thermo 10000
# main run
run 120000
# if you want to check that rotational diffusion is behaving as expected,
# uncomment next three lines for dump output and then plot <e(t).e(0)>,
# which should decay exponentially with timescale (d-1)*D_r (with d
# being simulation dimension)
#dump 1 all custom 2000 dump_ideal_${params}_3d.lammpstrj id type &
# x y xu yu mux muy muz fx fy fz
#dump_modify 1 first yes sort id
#run 120000

View File

@ -0,0 +1,163 @@
units lj
atom_style hybrid dipole sphere
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)
dimension 2
newton off
lattice sq 0.4
Lattice spacing in x,y,z = 1.5811388 1.5811388 1.5811388
region box block -16 16 -16 16 -0.2 0.2
create_box 1 box
Created orthogonal box = (-25.298221 -25.298221 -0.31622777) to (25.298221 25.298221 0.31622777)
2 by 2 by 1 MPI processor grid
create_atoms 1 box
Created 1024 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 ...
1024 settings made for dipole/random
velocity all create 1.0 1 loop geom
# more careful with neighbors since higher diffusion in abps
neighbor 1.0 bin
neigh_modify every 1 delay 1 check yes
# WCA potential (purely repulsive)
pair_style lj/cut 2.5
pair_coeff * * 1.0 1.0 1.1224
pair_modify shift yes
# overdamped brownian dynamics time-step
fix step all brownian/sphere ${gamma_t} ${gamma_r} ${D_t} ${D_r} ${seed} dipole
fix step all brownian/sphere 1 ${gamma_r} ${D_t} ${D_r} ${seed} dipole
fix step all brownian/sphere 1 1 ${D_t} ${D_r} ${seed} dipole
fix step all brownian/sphere 1 1 1 ${D_r} ${seed} dipole
fix step all brownian/sphere 1 1 1 3 ${seed} dipole
fix step all brownian/sphere 1 1 1 3 1974019 dipole
# self-propulsion force along the dipole direction
fix activity all propel/self ${fp} dipole
fix activity all propel/self 4 dipole
fix 2 all enforce2d
compute press all pressure NULL virial
thermo_style custom step temp epair c_press
#equilibration
timestep 0.0000000001
thermo 50001
run 50000
Neighbor list info ...
update every 1 steps, delay 1 steps, check yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 2.1224
ghost atom cutoff = 2.1224
binsize = 1.0612, bins = 48 48 1
1 neighbor lists, perpetual/occasional/extra = 1 0 0
(1) pair lj/cut, perpetual
attributes: half, newton off
pair build: half/bin/newtoff
stencil: half/bin/2d/newtoff
bin: standard
Per MPI rank memory allocation (min/avg/max) = 5.052 | 5.052 | 5.052 Mbytes
Step Temp E_pair c_press
0 1 0 -0.53979198
50000 1.0371295e+10 0 -0.542818
Loop time of 2.25396 on 4 procs for 50000 steps with 1024 atoms
Performance: 0.192 tau/day, 22183.200 timesteps/s
99.8% CPU use with 4 MPI tasks x 1 OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0.1034 | 0.10382 | 0.10438 | 0.1 | 4.61
Neigh | 0 | 0 | 0 | 0.0 | 0.00
Comm | 0.26698 | 0.26833 | 0.26924 | 0.2 | 11.90
Output | 2.2284e-05 | 2.4926e-05 | 3.2332e-05 | 0.0 | 0.00
Modify | 1.7222 | 1.7237 | 1.727 | 0.1 | 76.48
Other | | 0.1581 | | | 7.01
Nlocal: 256.000 ave 256 max 256 min
Histogram: 4 0 0 0 0 0 0 0 0 0
Nghost: 105.000 ave 105 max 105 min
Histogram: 4 0 0 0 0 0 0 0 0 0
Neighs: 544.000 ave 544 max 544 min
Histogram: 4 0 0 0 0 0 0 0 0 0
Total # of neighbors = 2176
Ave neighs/atom = 2.1250000
Neighbor list builds = 0
Dangerous builds = 0
reset_timestep 0
# MSD
compute msd all msd
thermo_style custom step temp epair c_msd[*] c_press
timestep 0.00001
thermo 10000
# main run
run 200000
Per MPI rank memory allocation (min/avg/max) = 5.427 | 5.427 | 5.427 Mbytes
Step Temp E_pair c_msd[1] c_msd[2] c_msd[3] c_msd[4] c_press
0 1.0371295e+10 0 0 0 0 0 -0.542818
10000 107356.09 0.079828495 0.19584264 0.19679822 0 0.39264086 0.00078740793
20000 101692.44 0.11317533 0.40847364 0.42097802 0 0.82945167 0.74111888
30000 105763.55 0.10261852 0.68303669 0.66125751 0 1.3442942 0.71112533
40000 105127.29 0.12371743 0.97990144 0.94005552 0 1.919957 1.0574552
50000 101579.58 0.12771813 1.3059069 1.2364468 0 2.5423537 1.059263
60000 104914.36 0.12055843 1.6215593 1.525488 0 3.1470473 0.79873537
70000 106629.18 0.1278745 1.9639958 1.8682794 0 3.8322752 0.91950208
80000 103286.54 0.13927689 2.3201565 2.2373383 0 4.5574948 1.1875034
90000 106451.61 0.093479681 2.6287902 2.5753347 0 5.2041249 1.0861163
100000 102199.72 0.13269425 2.9127976 2.9369237 0 5.8497214 1.4841998
110000 105229.73 0.10594209 3.1798718 3.3495317 0 6.5294035 1.5444784
120000 106262.36 0.11902575 3.6267452 3.7188125 0 7.3455578 1.3366518
130000 109388.12 0.10562576 3.929973 4.0226942 0 7.9526672 1.324534
140000 107697.35 0.13028752 4.231893 4.3780995 0 8.6099925 1.7406167
150000 103928.72 0.12278994 4.5826286 4.7578662 0 9.3404948 1.3024003
160000 103370.23 0.11391216 4.8767011 5.1181189 0 9.99482 1.4325241
170000 103821.53 0.11163256 5.153318 5.3785963 0 10.531914 1.4569115
180000 106824.99 0.13225083 5.4080929 5.7399804 0 11.148073 1.334984
190000 101794.6 0.10632938 5.7384925 6.080955 0 11.819448 0.81285422
200000 102128.67 0.13703498 6.0414673 6.4511058 0 12.492573 0.42904128
Loop time of 9.60419 on 4 procs for 200000 steps with 1024 atoms
Performance: 17992.140 tau/day, 20824.236 timesteps/s
100.0% CPU use with 4 MPI tasks x 1 OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0.71756 | 0.75121 | 0.79008 | 3.0 | 7.82
Neigh | 0.018158 | 0.018773 | 0.019357 | 0.3 | 0.20
Comm | 1.0469 | 1.0597 | 1.0738 | 1.2 | 11.03
Output | 0.00051435 | 0.00057078 | 0.00070838 | 0.0 | 0.01
Modify | 6.8012 | 6.9883 | 7.1513 | 4.9 | 72.76
Other | | 0.7857 | | | 8.18
Nlocal: 256.000 ave 265 max 240 min
Histogram: 1 0 0 0 0 0 1 0 0 2
Nghost: 88.5000 ave 91 max 87 min
Histogram: 1 0 2 0 0 0 0 0 0 1
Neighs: 678.500 ave 713 max 597 min
Histogram: 1 0 0 0 0 0 0 0 1 2
Total # of neighbors = 2714
Ave neighs/atom = 2.6503906
Neighbor list builds = 241
Dangerous builds = 0
Total wall time: 0:00:11

View File

@ -0,0 +1,150 @@
units lj
atom_style hybrid dipole sphere
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)
dimension 3
newton off
lattice sc 0.4
Lattice spacing in x,y,z = 1.3572088 1.3572088 1.3572088
region box block -8 8 -8 8 -8 8
create_box 1 box
Created orthogonal box = (-10.857670 -10.857670 -10.857670) to (10.857670 10.857670 10.857670)
2 by 1 by 2 MPI processor grid
create_atoms 1 box
Created 4096 atoms
create_atoms CPU = 0.002 seconds
mass * 1.0
set type * dipole/random ${seed} 1.0
set type * dipole/random 1974019 1.0
Setting atom values ...
4096 settings made for dipole/random
velocity all create 1.0 1 loop geom
pair_style none
# overdamped brownian dynamics time-step
fix step all brownian/sphere ${gamma_t} ${gamma_r} ${D_t} ${D_r} ${seed} dipole
fix step all brownian/sphere 1 ${gamma_r} ${D_t} ${D_r} ${seed} dipole
fix step all brownian/sphere 1 1 ${D_t} ${D_r} ${seed} dipole
fix step all brownian/sphere 1 1 1 ${D_r} ${seed} dipole
fix step all brownian/sphere 1 1 1 3 ${seed} dipole
fix step all brownian/sphere 1 1 1 3 1974019 dipole
# self-propulsion force along the dipole direction
fix activity all propel/self ${fp} dipole
fix activity all propel/self 4 dipole
compute press all pressure NULL virial
thermo_style custom step temp epair c_press
#equilibration
timestep 0.0000000001
thermo 50001
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) = 4.319 | 4.319 | 4.319 Mbytes
Step Temp E_pair c_press
0 1 0 0.068021726
50000 1.046425e+10 0 0.067505633
Loop time of 7.83903 on 4 procs for 50000 steps with 4096 atoms
Performance: 0.055 tau/day, 6378.340 timesteps/s
97.9% CPU use with 4 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.50238 | 0.51891 | 0.53617 | 1.7 | 6.62
Output | 2.6343e-05 | 3.6075e-05 | 4.6997e-05 | 0.0 | 0.00
Modify | 6.9536 | 6.9732 | 7.0105 | 0.8 | 88.95
Other | | 0.3469 | | | 4.43
Nlocal: 1024.00 ave 1024 max 1024 min
Histogram: 4 0 0 0 0 0 0 0 0 0
Nghost: 353.000 ave 353 max 353 min
Histogram: 4 0 0 0 0 0 0 0 0 0
Neighs: 0.00000 ave 0 max 0 min
Histogram: 4 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
# MSD to demonstrate expected diffusive behaviour for ideal active
# brownian motion, which is
#
# MSD = (2*d*D_t + 2*fp**2/(gamma_t**2*(d-1)*D_r))*t
#
# with d being simulation dimension
compute msd all msd
thermo_style custom step temp epair c_msd[*] c_press
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) = 4.694 | 4.694 | 4.694 Mbytes
Step Temp E_pair c_msd[1] c_msd[2] c_msd[3] c_msd[4] c_press
0 1.046425e+10 0 0 0 0 0 0.067505633
10000 106340.56 0 0.2469318 0.23662295 0.2441413 0.72769605 0.19939966
20000 104620.27 0 0.55429324 0.5231436 0.54976641 1.6272032 0.26601423
30000 106130.45 0 0.87562668 0.84813496 0.89321299 2.6169746 0.30836996
40000 105773.31 0 1.2262635 1.1899278 1.2626926 3.6788838 0.35392219
50000 103804.88 0 1.5851624 1.5645815 1.6434185 4.7931624 0.33326997
60000 105746.45 0 1.9928016 1.9347072 1.9837329 5.9112417 0.2550878
70000 104500.3 0 2.3269429 2.2774077 2.3368821 6.9412326 0.25218225
80000 105381.46 0 2.7114959 2.6937299 2.7171132 8.122339 0.36940892
90000 104542.79 0 3.0828648 3.084417 3.0783207 9.2456025 0.36106481
100000 104246.75 0 3.4635513 3.5105066 3.4545226 10.42858 0.3712313
110000 103099.55 0 3.8471061 3.9389997 3.8220676 11.608173 0.38466185
120000 103098.45 0 4.2014598 4.3456831 4.1888659 12.736009 0.36710217
Loop time of 22.8893 on 4 procs for 120000 steps with 4096 atoms
Performance: 4529.619 tau/day, 5242.615 timesteps/s
100.0% CPU use with 4 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.0049489 | 0.0050479 | 0.0050978 | 0.1 | 0.02
Comm | 0.082752 | 0.084491 | 0.085332 | 0.4 | 0.37
Output | 0.00054352 | 0.0006034 | 0.00064793 | 0.0 | 0.00
Modify | 21.069 | 21.521 | 21.964 | 7.0 | 94.02
Other | | 1.278 | | | 5.58
Nlocal: 1024.00 ave 1050 max 1010 min
Histogram: 2 0 0 1 0 0 0 0 0 1
Nghost: 0.00000 ave 0 max 0 min
Histogram: 4 0 0 0 0 0 0 0 0 0
Neighs: 0.00000 ave 0 max 0 min
Histogram: 4 0 0 0 0 0 0 0 0 0
Total # of neighbors = 0
Ave neighs/atom = 0.0000000
Neighbor list builds = 2169
Dangerous builds = 0
# if you want to check that rotational diffusion is behaving as expected,
# uncomment next three lines for dump output and then plot <e(t).e(0)>,
# which should decay exponentially with timescale (d-1)*D_r (with d
# being simulation dimension)
#dump 1 all custom 2000 dump_ideal_${params}_3d.lammpstrj id type # x y xu yu mux muy muz fx fy fz
#dump_modify 1 first yes sort id
#run 120000
Total wall time: 0:00:30

View File

@ -1,54 +0,0 @@
dimension 2
boundary p p p
variable L equal 20
region total block -$L $L -$L $L -0.5 0.5
lattice hex 0.3
create_box 2 total
create_atoms 1 box
# Set random fraction to passive:
set type 1 type/fraction 2 0.5 1337
# Purely repulsive particles:
variable rc equal "2^(1.0/6.0)"
pair_style lj/cut ${rc}
pair_coeff * * 1.0 1.0
pair_modify shift yes
mass * 1.0
fix step all nve
fix temp all langevin 1.0 1.0 1.0 13
fix twod all enforce2d
neighbor 0.6 bin
dump traj all custom 250 2d_active.dump.bin id type x y z
thermo_style custom time step pe ke etotal temp
thermo 1000
run 5000
group one type 1
group two type 2
compute ke1 one ke
compute ke2 two ke
thermo_style custom step pe ke etotal temp c_ke1 c_ke2
fix active all propel/self velocity 1.0
# With active force there is more motion so increase bin size:
neighbor 1.0 bin
run 10000
# Only make type 1 active:
fix active all propel/self velocity 1.0 types 1
# With active force there is more motion so increase bin size:
neighbor 1.0 bin
run 10000

View File

@ -1,37 +0,0 @@
dimension 2
boundary p p p
variable L equal 20
region total block -$L $L -$L $L -0.5 0.5
lattice hex 0.3
create_box 2 total
create_atoms 1 box
# Set random fraction to passive:
set type 1 type/fraction 2 0.5 1337
# Purely repulsive particles:
variable rc equal "2^(1.0/6.0)"
pair_style lj/cut ${rc}
pair_coeff * * 1.0 1.0
pair_modify shift yes
mass * 1.0
fix step all nve
fix twod all enforce2d
neighbor 0.6 bin
dump traj all custom 250 2d_active.dump.bin id type x y z
thermo_style custom step pe ke etotal temp
thermo 1000
run 10000
fix active all propel/self velocity 1.0
fix fric all viscous 1.0
# With active force there is more motion so increase bin size:
neighbor 1.0 bin
run 10000

View File

@ -1,40 +0,0 @@
dimension 3
boundary p p p
atom_style ellipsoid
variable L equal 20
region total block -$L $L -$L $L -$L $L
lattice sc 0.1
create_box 2 total
create_atoms 1 box
# Set random fraction to passive:
set type 1 type/fraction 2 0.5 1337
# Purely repulsive particles:
variable rc equal "2^(1.0/6.0)"
pair_style lj/cut ${rc}
pair_coeff * * 1.0 1.0
pair_modify shift yes
# mass * 1.0
set type * shape 1.0 1.0 1.0
set type * density 1.9098593171027443
set type * quat 0 0 1 0
fix step all nve/asphere
fix temp all langevin 1.0 1.0 1.0 13 angmom 3.333333333
neighbor 0.6 bin
dump traj all custom 100 3d_active.dump.bin id type x y z fx fy fz
thermo_style custom step pe ke etotal temp
thermo 100
run 500
fix active all propel/self quat 1.0
# With active force there is more motion so increase bin size:
neighbor 1.0 bin
run 500

View File

@ -0,0 +1,312 @@
/* ----------------------------------------------------------------------
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.
------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------
Contributed by Stefan Paquay @ Brandeis University
Thanks to Liesbeth Janssen @ Eindhoven University for useful discussions!
Current maintainer: Sam Cameron @ University of Bristol
----------------------------------------------------------------------- */
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "fix_propel_self.h"
#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 "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
enum{DIPOLE,VELOCITY,QUAT};
#define TOL 1e-14
/* ---------------------------------------------------------------------- */
FixPropelSelf::FixPropelSelf(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
virial_flag = 1;
if (narg < 5)
error->all(FLERR,"Illegal fix propel/self command");
magnitude = utils::numeric(FLERR,arg[3],false,lmp);
if (strcmp(arg[4],"velocity") == 0) {
mode = VELOCITY;
thermo_virial = 0;
if (narg != 5) {
error->all(FLERR,"Illegal fix propel/self command");
}
} else if (strcmp(arg[4],"dipole") == 0) {
mode = DIPOLE;
thermo_virial = 1;
if (narg != 5) {
error->all(FLERR,"Illegal fix propel/self command");
}
} else if (strcmp(arg[4],"quat") == 0) {
mode = QUAT;
thermo_virial = 1;
if (narg != 8) {
error->all(FLERR,"Illegal fix propel/self command");
} else {
sx = utils::numeric(FLERR,arg[5],false,lmp);
sy = utils::numeric(FLERR,arg[6],false,lmp);
sz = utils::numeric(FLERR,arg[7],false,lmp);
double qnorm = sqrt(sx*sx + sy*sy + sz*sz);
sx = sx/qnorm;
sy = sy/qnorm;
sz = sz/qnorm;
}
} else {
error->all(FLERR,"Illegal fix propel/self command");
}
}
/* ---------------------------------------------------------------------- */
int FixPropelSelf::setmask()
{
int mask = 0;
mask |= POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
FixPropelSelf::~FixPropelSelf()
{
}
/* ---------------------------------------------------------------------- */
void FixPropelSelf::init()
{
if (mode == DIPOLE && !atom->mu_flag)
error->all(FLERR,"Fix propel/self requires atom attribute mu "
"with option dipole.");
if (mode == QUAT) {
avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
if (!avec)
error->all(FLERR,"Fix propel/self requires "
"atom style ellipsoid with option quat.");
// 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 propel/self requires extended particles "
"with option quat.");
}
}
void FixPropelSelf::setup(int vflag)
{
post_force(vflag);
}
void FixPropelSelf::post_force(int vflag)
{
if (mode == DIPOLE)
post_force_dipole(vflag);
else if (mode == VELOCITY)
post_force_velocity(vflag);
else if (mode == QUAT)
post_force_quaternion(vflag);
}
void FixPropelSelf::post_force_dipole(int vflag)
{
double **f = atom->f;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double **x = atom->x;
double **mu = atom->mu;
double fx,fy,fz;
// energy and virial setup
double vi[6];
if (vflag) v_setup(vflag);
else evflag = 0;
// if domain has PBC, need to unwrap for virial
double unwrap[3];
imageint *image = atom->image;
// Add the active force to the atom force:
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
fx = magnitude*mu[i][0];
fy = magnitude*mu[i][1];
fz = magnitude*mu[i][2];
f[i][0] += fx;
f[i][1] += fy;
f[i][2] += fz;
if (evflag) {
domain->unmap(x[i],image[i],unwrap);
vi[0] = fx*unwrap[0];
vi[1] = fy*unwrap[1];
vi[2] = fz*unwrap[2];
vi[3] = fx*unwrap[1];
vi[4] = fx*unwrap[2];
vi[5] = fy*unwrap[2];
v_tally(i, vi);
}
}
}
void FixPropelSelf::post_force_velocity(int vflag)
{
double **f = atom->f;
double **v = atom->v;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int *type = atom->type;
double nv2,fnorm,fx,fy,fz;
// energy and virial setup
double vi[6];
if (vflag) v_setup(vflag);
else evflag = 0;
// if domain has PBC, need to unwrap for virial
double unwrap[3];
imageint *image = atom->image;
// Add the active force to the atom force:
for(int i = 0; i < nlocal; ++i) {
if( mask[i] & groupbit ){
nv2 = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2];
fnorm = 0.0;
if (nv2 > TOL) {
// Without this check you can run into numerical
// issues because fnorm will blow up.
fnorm = magnitude / sqrt(nv2);
}
fx = fnorm * v[i][0];
fy = fnorm * v[i][1];
fz = fnorm * v[i][2];
f[i][0] += fx;
f[i][1] += fy;
f[i][2] += fz;
if (evflag) {
domain->unmap(x[i],image[i],unwrap);
vi[0] = fx*unwrap[0];
vi[1] = fy*unwrap[1];
vi[2] = fz*unwrap[2];
vi[3] = fx*unwrap[1];
vi[4] = fx*unwrap[2];
vi[5] = fy*unwrap[2];
v_tally(i, vi);
}
}
}
}
void FixPropelSelf::post_force_quaternion(int vflag)
{
double **f = atom->f;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int *type = atom->type;
int* ellipsoid = atom->ellipsoid;
// ellipsoidal properties
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
double f_act[3] = { sx, sy, sz };
double f_rot[3];
double *quat;
double Q[3][3];
double fx,fy,fz;
// energy and virial setup
double vi[6];
if (vflag) v_setup(vflag);
else evflag = 0;
// if domain has PBC, need to unwrap for virial
double unwrap[3];
imageint *image = atom->image;
// Add the active force to the atom force:
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 );
fx = magnitude*f_rot[0];
fy = magnitude*f_rot[1];
fz = magnitude*f_rot[2];
f[i][0] += fx;
f[i][1] += fy;
f[i][2] += fz;
if (evflag) {
domain->unmap(x[i],image[i],unwrap);
vi[0] = fx*unwrap[0];
vi[1] = fy*unwrap[1];
vi[2] = fz*unwrap[2];
vi[3] = fx*unwrap[1];
vi[4] = fx*unwrap[2];
vi[5] = fy*unwrap[2];
v_tally(i, vi);
}
}
}
}

View File

@ -21,51 +21,50 @@ FixStyle(propel/self,FixPropelSelf)
#define LMP_FIX_PROPEL_SELF_H
#include "fix.h"
namespace LAMMPS_NS {
class FixPropelSelf : public Fix {
public:
FixPropelSelf(class LAMMPS *, int, char **);
virtual ~FixPropelSelf();
virtual int setmask();
virtual void post_force(int);
void init();
void post_force(int);
void setup(int);
int setmask();
double memory_usage();
protected:
enum operation_modes {
VELOCITY = 0,
QUATERNION = 1
};
private:
private:
double magnitude;
double sx,sy,sz;
int mode;
// If 0, apply fix to everything in group. If > 0, apply only to those
// types i for which i <= n_types_filter _and_ apply_to_type[i] == 1:
int n_types_filter;
int *apply_to_type; //< Specifies, per type, if the fix applies to it or not.
void post_force_dipole(int);
void post_force_velocity(int);
void post_force_quaternion(int);
class AtomVecEllipsoid *avec;
int atoms_have_quaternion();
template <int filter_by_type> void post_force_velocity(int);
template <int filter_by_type> void post_force_quaternion(int);
};
}
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
E: Illegal fix propel/self command.
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
Wrong number/type of input arguments.
E: Fix propel/self requires atom attribute mu with option dipole.
Self-explanatory.
E: Fix propel/self requires atom style ellipsoid with option quat.
Self-explanatory.
Fix propel/self requires extended particles with option quat.
Self-explanatory.
*/

View File

@ -68,7 +68,6 @@ fix nvk, Efrem Braun (UC Berkeley), efrem.braun at gmail.com, https://github.com
fix orient/eco Adrian A. Schratt and Volker Mohles (Ruhr-Uni Bochum), volker.mohles at rub.de, 6 Jun 2020
fix pafi, Thomas Swinburne (CNRS), swinburne at cinam.univ-mrs.fr, 1st Sep 2020
fix pimd, Yuxing Peng (U Chicago), yuxing at uchicago.edu, 24 Nov 2014
fix propel/self, Stefan Paquay (Brandeis U), stefanpaquay at gmail.com, 20 Jan 2020
fix rhok, Ulf Pedersen (Roskilde U), ulf at urp.dk, 25 Sep 2017
fix smd, Axel Kohlmeyer, akohlmey at gmail.com, 19 May 2008
fix ti/spring, Rodrigo Freitas (Unicamp/Brazil), rodrigohb at gmail.com, 7 Nov 2013

View File

@ -1,258 +0,0 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://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.
------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------
Contributed by Stefan Paquay @ Brandeis University
Thanks to Liesbeth Janssen @ Eindhoven University for useful discussions!
----------------------------------------------------------------------- */
#include "fix_propel_self.h"
#include "atom.h"
#include "atom_vec_ellipsoid.h"
#include "error.h"
#include "math_const.h"
#include "math_extra.h"
#include <cctype>
#include <cmath>
#include <cstring>
using namespace LAMMPS_NS;
using namespace FixConst;
using namespace MathConst;
#define PRINT_DEBUG_OUTPUT 0
/* ---------------------------------------------------------------------- */
FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv )
: Fix(lmp, narg, argv), magnitude(0.0),
mode(VELOCITY), n_types_filter(0), apply_to_type(nullptr)
{
if (narg < 5) error->all(FLERR, "Illegal fix propel/self command");
// The fix is to support the following cases:
// 1. Simple atoms, in which case the force points along the velocity
// 2. Aspherical particles with an orientation.
// The first argument (mode) is used to differentiate between these.
// args: fix ID all propel/self mode magnitude
// Optional args are
const char *mode_str = argv[3];
if (strcmp(mode_str, "velocity") == 0) {
mode = VELOCITY;
} else if (strcmp(mode_str, "quat") == 0) {
// This mode should only be supported if the atom style has
// a quaternion (and if all atoms in the group have it)
if (!atoms_have_quaternion()) {
error->all(FLERR, "All fix atoms need to be extended particles");
}
mode = QUATERNION;
} else {
char msg[2048];
sprintf(msg, "Illegal mode \"%s\" for fix propel/self", mode_str);
error->all(FLERR, msg);
}
magnitude = utils::numeric( FLERR, argv[4] ,false,lmp);
// Handle rest of args:
int iarg = 5;
while (iarg < narg) {
if (strcmp(argv[iarg],"types") == 0) {
apply_to_type = new int[atom->ntypes+1];
memset(apply_to_type, 0, atom->ntypes * sizeof(int));
// consume all following numerical arguments as types
iarg++;
int flag=0;
while (iarg < narg) {
if (isdigit(argv[iarg][0])) {
int thistype = utils::inumeric(FLERR,argv[iarg],false,lmp);
if ((thistype < 1) || (thistype > atom->ntypes))
error->all(FLERR,"Illegal atom type to types keyword");
apply_to_type[thistype] = 1;
flag = 1;
iarg++;
} else break;
}
if (!flag)
error->all(FLERR,"'types' keyword requires at least one type");
else
n_types_filter = 1;
} else {
error->all(FLERR,"Illegal fix propel/self command.");
}
}
}
/* ---------------------------------------------------------------------- */
FixPropelSelf::~FixPropelSelf()
{
delete[] apply_to_type;
}
/* ---------------------------------------------------------------------- */
int FixPropelSelf::setmask()
{
int mask = 0;
mask |= POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
double FixPropelSelf::memory_usage()
{
// magnitude + thermostat_orient + mode + n_types_filter + apply_to_type
double bytes = sizeof(double) + 3*sizeof(int) + sizeof(int*);
bytes += sizeof(int)*atom->ntypes*n_types_filter;
return bytes;
}
/* ---------------------------------------------------------------------- */
void FixPropelSelf::post_force(int vflag )
{
switch(mode) {
case QUATERNION:
if (n_types_filter) post_force_quaternion<1>(vflag);
else post_force_quaternion<0>(vflag);
break;
case VELOCITY:
if (n_types_filter) post_force_velocity<1>(vflag);
else post_force_velocity<0>(vflag);
break;
default:
;
}
}
/* ---------------------------------------------------------------------- */
template <int filter_by_type>
void FixPropelSelf::post_force_quaternion(int /* vflag */ )
{
double **f = atom->f;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int *type = atom->type;
int* ellipsoid = atom->ellipsoid;
AtomVecEllipsoid *av = static_cast<AtomVecEllipsoid*>(atom->style_match("ellipsoid"));
AtomVecEllipsoid::Bonus *bonus = av->bonus;
// Add the active force to the atom force:
for( int i = 0; i < nlocal; ++i ){
if( mask[i] & groupbit ){
if (filter_by_type && !apply_to_type[type[i]]) {
continue;
}
double f_act[3] = { 1.0, 0.0, 0.0 };
double f_rot[3];
double *quat = bonus[ellipsoid[i]].quat;
double Q[3][3];
MathExtra::quat_to_mat( quat, Q );
MathExtra::matvec( Q, f_act, f_rot );
f[i][0] += magnitude * f_rot[0];
f[i][1] += magnitude * f_rot[1];
f[i][2] += magnitude * f_rot[2];
}
}
}
/* ---------------------------------------------------------------------- */
template <int filter_by_type>
void FixPropelSelf::post_force_velocity(int /*vflag*/)
{
double **f = atom->f;
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int *type = atom->type;
// Add the active force to the atom force:
for(int i = 0; i < nlocal; ++i) {
if( mask[i] & groupbit ){
if (filter_by_type && !apply_to_type[type[i]]) {
continue;
}
const double *vi = v[i];
double f_act[3] = { vi[0], vi[1], vi[2] };
double nv2 = vi[0]*vi[0] + vi[1]*vi[1] + vi[2]*vi[2];
double fnorm = 0.0;
const double TOL = 1e-14;
if (nv2 > TOL) {
// Without this check you can run into numerical
// issues because fnorm will blow up.
fnorm = magnitude / sqrt(nv2);
}
f[i][0] += fnorm * f_act[0];
f[i][1] += fnorm * f_act[1];
f[i][2] += fnorm * f_act[2];
}
}
}
/* ---------------------------------------------------------------------- */
int FixPropelSelf::atoms_have_quaternion()
{
if (!atom->ellipsoid_flag) {
error->all(FLERR, "Mode 'quat' requires atom style ellipsoid");
return 0;
}
int *mask = atom->mask;
int flag=0,flagall=0;
// Make sure all atoms have ellipsoid data:
for (int i = 0; i < atom->nlocal; ++i)
if (mask[i] & groupbit)
if (atom->ellipsoid[i] < 0) ++flag;
MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
if (flagall > 0) return 0;
return 1;
}