Merge branch 'master' into kim_fix

This commit is contained in:
Axel Kohlmeyer
2020-07-20 20:27:41 -04:00
51 changed files with 21877 additions and 505 deletions

View File

@ -72,7 +72,7 @@ endif()
# we require C++11 without extensions
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_EXTENSIONS OFF CACHE BOOL "Use compiler extensions")
########################################################################
# User input options #

View File

@ -52,26 +52,26 @@ add_library(GTest::GTest UNKNOWN IMPORTED)
set_target_properties(GTest::GTest PROPERTIES
IMPORTED_LOCATION ${GTEST_LIBRARY_PATH}
INTERFACE_INCLUDE_DIRECTORIES ${GTEST_INCLUDE_DIR}
IMPORTED_LINK_INTERFACE_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
INTERFACE_LINK_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
add_dependencies(GTest::GTest googletest)
add_library(GTest::GMock UNKNOWN IMPORTED)
set_target_properties(GTest::GMock PROPERTIES
IMPORTED_LOCATION ${GMOCK_LIBRARY_PATH}
INTERFACE_INCLUDE_DIRECTORIES ${GMOCK_INCLUDE_DIR}
IMPORTED_LINK_INTERFACE_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
INTERFACE_LINK_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
add_dependencies(GTest::GMock googletest)
add_library(GTest::GTestMain UNKNOWN IMPORTED)
set_target_properties(GTest::GTestMain PROPERTIES
IMPORTED_LOCATION ${GTEST_MAIN_LIBRARY_PATH}
INTERFACE_INCLUDE_DIRECTORIES ${GTEST_INCLUDE_DIR}
IMPORTED_LINK_INTERFACE_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
INTERFACE_LINK_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
add_dependencies(GTest::GTestMain googletest)
add_library(GTest::GMockMain UNKNOWN IMPORTED)
set_target_properties(GTest::GMockMain PROPERTIES
IMPORTED_LOCATION ${GMOCK_MAIN_LIBRARY_PATH}
INTERFACE_INCLUDE_DIRECTORIES ${GMOCK_INCLUDE_DIR}
IMPORTED_LINK_INTERFACE_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
INTERFACE_LINK_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
add_dependencies(GTest::GMockMain googletest)

View File

@ -244,3 +244,4 @@ OPT.
* :doc:`wall/region <fix_wall_region>`
* :doc:`wall/region/ees <fix_wall_ees>`
* :doc:`wall/srd <fix_wall_srd>`
* :doc:`widom <fix_widom>`

View File

@ -387,6 +387,7 @@ accelerated styles exist.
* :doc:`wall/region <fix_wall_region>` - use region surface as wall
* :doc:`wall/region/ees <fix_wall_ees>` - use region surface as wall for ellipsoidal particles
* :doc:`wall/srd <fix_wall_srd>` - slip/no-slip wall for SRD particles
* :doc:`widom <fix_widom>` - Widom insertions of atoms or molecules
Restrictions
""""""""""""

View File

@ -68,7 +68,7 @@ Description
This fix performs grand canonical Monte Carlo (GCMC) exchanges of
atoms or molecules with an imaginary ideal gas
reservoir at the specified T and chemical potential (mu) as discussed
in :ref:`(Frenkel) <Frenkel>`. It also
in :ref:`(Frenkel) <Frenkel2>`. It also
attempts Monte Carlo (MC) moves (translations and molecule
rotations) within the simulation cell or
region. If used with the :doc:`fix nvt <fix_nh>`
@ -481,7 +481,7 @@ listed above.
----------
.. _Frenkel:
.. _Frenkel2:
**(Frenkel)** Frenkel and Smit, Understanding Molecular Simulation,
Academic Press, London, 2002.

227
doc/src/fix_widom.rst Normal file
View File

@ -0,0 +1,227 @@
.. index:: fix widom
fix widom command
=================
Syntax
""""""
.. parsed-literal::
fix ID group-ID widom N M type seed T keyword values ...
* ID, group-ID are documented in :doc:`fix <fix>` command
* widom = style name of this fix command
* N = invoke this fix every N steps
* M = number of Widom insertions to attempt every N steps
* type = atom type for inserted atoms (must be 0 if mol keyword used)
* seed = random # seed (positive integer)
* T = temperature of the system (temperature units)
* zero or more keyword/value pairs may be appended to args
.. parsed-literal::
keyword = *mol*\ , *region*\ , *full_energy*, *charge*\ , *intra_energy*
*mol* value = template-ID
template-ID = ID of molecule template specified in a separate :doc:`molecule <molecule>` command
*region* value = region-ID
region-ID = ID of region where Widom insertions are allowed
*full_energy* = compute the entire system energy when performing Widom insertions
*charge* value = charge of inserted atoms (charge units)
*intra_energy* value = intramolecular energy (energy units)
Examples
""""""""
.. code-block:: LAMMPS
fix 2 gas widom 1 50000 1 19494 2.0
fix 3 water widom 1000 100 0 29494 300.0 mol h2omol full_energy
Description
"""""""""""
This fix performs Widom insertions of atoms or molecules at the given
temperature as discussed in :ref:`(Frenkel) <Frenkel1>`. Specific uses
include computation of Henry constants of small molecules in microporous
materials or amorphous systems.
Every N timesteps the fix attempts M number of Widom insertions of atoms
or molecules.
If the *mol* keyword is used, only molecule insertions are performed.
Conversely, if the *mol* keyword is not used, only atom insertions are
performed.
This command may optionally use the *region* keyword to define an
insertion volume. The specified region must have been previously
defined with a :doc:`region <region>` command. It must be defined with
side = *in*\ . Insertion attempts occur only within the specified
region. For non-rectangular regions, random trial points are generated
within the rectangular bounding box until a point is found that lies
inside the region. If no valid point is generated after 1000 trials, no
insertion is performed. If an attempted insertion places the atom or
molecule center-of-mass outside the specified region, a new attempted
insertion is generated. This process is repeated until the atom or
molecule center-of-mass is inside the specified region.
Note that neighbor lists are re-built every timestep that this fix is
invoked, so you should not set N to be too small. See the :doc:`neighbor
<neighbor>` command for details.
When an atom or molecule is to be inserted, its coordinates are chosen
at a random position within the current simulation cell or region.
Relative coordinates for atoms in a molecule are taken from the
template molecule provided by the user. The center of mass of the
molecule is placed at the insertion point. The orientation of the
molecule is chosen at random by rotating about this point.
Individual atoms are inserted, unless the *mol* keyword is used. It
specifies a *template-ID* previously defined using the :doc:`molecule
<molecule>` command, which reads a file that defines the molecule. The
coordinates, atom types, charges, etc., as well as any bonding and
special neighbor information for the molecule can be specified in the
molecule file. See the :doc:`molecule <molecule>` command for details.
The only settings required to be in this file are the coordinates and
types of atoms in the molecule.
If you wish to insert molecules via the *mol* keyword, that will have
their bonds or angles constrained via SHAKE, use the *shake* keyword,
specifying as its value the ID of a separate :doc:`fix shake
<fix_shake>` command which also appears in your input script.
Note that fix widom does not use configurational bias MC or any other
kind of sampling of intramolecular degrees of freedom. Inserted
molecules can have different orientations, but they will all have the
same intramolecular configuration, which was specified in the molecule
command input.
For atoms, inserted particles have the specified atom type. For
molecules, they use the same atom types as in the template molecule
supplied by the user.
The excess chemical potential mu_ex is defined as:
.. math::
\mu_{ex} = -kT \ln(<\exp(-(U_{N+1}-U_{N})/{kT})>)
where *k* is Boltzman's constant, *T* is the user-specified temperature,
U_N and U_{N+1} is the potential energy of the system with N and N+1
particles.
The *full_energy* option means that the fix calculates the total
potential energy of the entire simulated system, instead of just the
energy of the part that is changed. By default, this option is off, in
which case only partial energies are computed to determine the energy
difference due to the proposed change.
The *full_energy* option is needed for systems with complicated
potential energy calculations, including the following:
* long-range electrostatics (kspace)
* many-body pair styles
* hybrid pair styles
* eam pair styles
* tail corrections
* need to include potential energy contributions from other fixes
In these cases, LAMMPS will automatically apply the *full_energy*
keyword and issue a warning message.
When the *mol* keyword is used, the *full_energy* option also includes
the intramolecular energy of inserted and deleted molecules, whereas
this energy is not included when *full_energy* is not used. If this is
not desired, the *intra_energy* keyword can be used to define an amount
of energy that is subtracted from the final energy when a molecule is
inserted, and subtracted from the initial energy when a molecule is
deleted. For molecules that have a non-zero intramolecular energy, this
will ensure roughly the same behavior whether or not the *full_energy*
option is used.
Some fixes have an associated potential energy. Examples of such fixes
include: :doc:`efield <fix_efield>`, :doc:`gravity <fix_gravity>`,
:doc:`addforce <fix_addforce>`, :doc:`restrain <fix_restrain>`, and
:doc:`wall fixes <fix_wall>`. For that energy to be included in the
total potential energy of the system (the quantity used when performing
Widom insertions), you MUST enable the :doc:`fix_modify <fix_modify>`
*energy* option for that fix. The doc pages for individual :doc:`fix
<fix>` commands specify if this should be done.
Use the *charge* option to insert atoms with a user-specified point
charge. Note that doing so will cause the system to become non-neutral.
LAMMPS issues a warning when using long-range electrostatics (kspace)
with non-neutral systems. See the :doc:`compute group/group
<compute_group_group>` documentation for more details about simulating
non-neutral systems with kspace on.
**Restart, fix_modify, output, run start/stop, minimize info:**
This fix writes the state of the fix to :doc:`binary restart files
<restart>`. This includes information about the random number generator
seed, the next timestep for Widom insertions etc. See the
:doc:`read_restart <read_restart>` command for info on how to re-specify
a fix in an input script that reads a restart file, so that the
operation of the fix continues in an uninterrupted fashion.
.. note::
For this to work correctly, the timestep must **not** be changed
after reading the restart with :doc:`reset_timestep
<reset_timestep>`. The fix will try to detect it and stop with an
error.
None of the :doc:`fix_modify <fix_modify>` options are relevant to this
fix.
This fix computes a global vector of length 3, which can be accessed by
various :doc:`output commands <Howto_output>`. The vector values are
the following global cumulative quantities:
* 1 = average excess chemical potential on each timestep
* 2 = average difference in potential energy on each timestep
* 3 = volume of the insertion region
The vector values calculated by this fix are "extensive".
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 is part of the MC package. It is only enabled if LAMMPS was
built with that package. See the :doc:`Build package <Build_package>`
doc page for more info.
Do not set "neigh_modify once yes" or else this fix will never be
called. Reneighboring is **required**.
Can be run in parallel, but aspects of the GCMC part will not scale well
in parallel. Only usable for 3D simulations.
Related commands
""""""""""""""""
:doc:`fix gcmc <fix_gcmc>`
:doc:`fix atom/swap <fix_atom_swap>`,
:doc:`neighbor <neighbor>`,
:doc:`fix deposit <fix_deposit>`, :doc:`fix evaporate <fix_evaporate>`,
Default
"""""""
The option defaults are mol = no, intra_energy = 0.0 and full_energy =
no, except for the situations where full_energy is required, as listed
above.
----------
.. _Frenkel1:
**(Frenkel)** Frenkel and Smit, Understanding Molecular Simulation,
Academic Press, London, 2002.

View File

@ -3250,6 +3250,8 @@ whitesmoke
whitespace
Wi
Wicaksono
Widom
widom
Wijk
Wikipedia
wildcard

View File

@ -75,7 +75,7 @@ eim: NaCl using the EIM potential
ellipse: ellipsoidal particles in spherical solvent, 2d system
flow: Couette and Poiseuille flow in a 2d channel
friction: frictional contact of spherical asperities between 2d surfaces
gcmc: Grand Canonical Monte Carlo (GCMC) via the fix gcmc command
gcmc: Grand Canonical MC with fix gcmc, Widom insertion with fix widom
gjf: use of fix langevin Gronbech-Jensen/Farago option
granregion: use of fix wall/region/gran as boundary on granular particles
hugoniostat: Hugoniostat shock dynamics

17322
examples/gcmc/data.spce Normal file

File diff suppressed because it is too large Load Diff

2019
examples/gcmc/data.widom.lj Normal file

File diff suppressed because it is too large Load Diff

28
examples/gcmc/in.widom.lj Normal file
View File

@ -0,0 +1,28 @@
# Kob and Andersen model Phys. Rev. E 51, 4626 (1995)
units lj
atom_style atomic
pair_style lj/cut 2.5
pair_modify shift yes
read_data data.widom.lj
pair_coeff 1 1 1.0 1.0 2.5
pair_coeff 1 2 1.5 0.8 2.0
pair_coeff 2 2 0.5 0.88 2.2
neighbor 0.3 bin
neigh_modify delay 0 every 5 check yes
fix mywidom all widom 10 100000 2 29494 0.75
fix 1 all langevin 0.75 0.75 0.1 48279 zero yes
fix 2 all nve
timestep 0.002
thermo_style custom step temp pe etotal press vol density f_mywidom[1] f_mywidom[2] f_mywidom[3]
thermo 10
run 100

View File

@ -0,0 +1,38 @@
units real
dimension 3
boundary p p p
atom_style full
pair_style lj/cut/coul/long 10.0
bond_style harmonic
angle_style harmonic
read_data data.spce
molecule h2omol H2O.txt
### Flexible SPC/E Potential Parameters ###
### Zhang et al., Fluid Phase Equilibria, 262 (2007) 210-216 ###
pair_coeff 1 1 0.1502629 3.1169
pair_coeff 1 2 0.0341116368 2.04845
pair_coeff 2 2 0.00774378 0.98
bond_coeff 1 176.864 0.9611
angle_coeff 1 42.1845 109.4712
kspace_style pppm 1.0e-4
fix mywidom all widom 10 20 0 29494 298 mol h2omol
fix 2 all nvt temp 298.0 298.0 100.0
neighbor 2.0 bin
neigh_modify delay 10 every 2 check yes
#run variables
timestep 0.5
thermo 10
thermo_style custom step etotal pe temp press vol density f_mywidom[1] f_mywidom[2] f_mywidom[3]
run 100

View File

@ -0,0 +1,89 @@
LAMMPS (30 Jun 2020)
using 1 OpenMP thread(s) per MPI task
# Kob and Andersen model Phys. Rev. E 51, 4626 (1995)
units lj
atom_style atomic
pair_style lj/cut 2.5
pair_modify shift yes
read_data data.widom.lj
orthogonal box = (0.0000000 0.0000000 0.0000000) to (9.4000000 9.4000000 9.4000000)
1 by 1 by 1 MPI processor grid
reading atoms ...
1000 atoms
reading velocities ...
1000 velocities
read_data CPU = 0.003 seconds
pair_coeff 1 1 1.0 1.0 2.5
pair_coeff 1 2 1.5 0.8 2.0
pair_coeff 2 2 0.5 0.88 2.2
neighbor 0.3 bin
neigh_modify delay 0 every 5 check yes
fix mywidom all widom 10 100000 2 29494 0.75
fix 1 all langevin 0.75 0.75 0.1 48279 zero yes
fix 2 all nve
timestep 0.002
thermo_style custom step temp pe etotal press vol density f_mywidom[1] f_mywidom[2] f_mywidom[3]
thermo 10
run 100
Neighbor list info ...
update every 5 steps, delay 0 steps, check yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 2.8
ghost atom cutoff = 2.8
binsize = 1.4, bins = 7 7 7
1 neighbor lists, perpetual/occasional/extra = 1 0 0
(1) pair lj/cut, perpetual
attributes: half, newton on
pair build: half/bin/atomonly/newton
stencil: half/bin/3d/newton
bin: standard
Per MPI rank memory allocation (min/avg/max) = 3.181 | 3.181 | 3.181 Mbytes
Step Temp PotEng TotEng Press Volume Density f_mywidom[1] f_mywidom[2] f_mywidom[3]
0 0.75021245 -6.4204308 -5.2962374 7.2962696 830.584 1.2039721 0 0 830.584
10 0.7358936 -6.4405082 -5.3377717 7.1699962 830.584 1.2039721 -3.8577501 171.3429 830.584
20 0.75426414 -6.4267946 -5.2965298 7.2833985 830.584 1.2039721 -4.0708206 227.63895 830.584
30 0.72947489 -6.4064078 -5.3132896 7.3872583 830.584 1.2039721 -4.4304803 367.7146 830.584
40 0.73504751 -6.4248725 -5.3234038 7.2927069 830.584 1.2039721 -4.1904189 266.99373 830.584
50 0.76497439 -6.4352472 -5.2889331 7.3046861 830.584 1.2039721 -3.8628472 172.51133 830.584
60 0.75752861 -6.4147051 -5.2795485 7.4416 830.584 1.2039721 -3.5355467 111.5042 830.584
70 0.77775078 -6.4210798 -5.2556202 7.4473703 830.584 1.2039721 -3.4754802 102.92223 830.584
80 0.80937104 -6.4320008 -5.2191583 7.4121087 830.584 1.2039721 -3.9287513 188.35625 830.584
90 0.76321255 -6.4203633 -5.2766893 7.4307727 830.584 1.2039721 -4.2257529 279.87337 830.584
100 0.74561743 -6.4010576 -5.2837499 7.52907 830.584 1.2039721 -3.6817835 135.5099 830.584
Loop time of 25.8264 on 1 procs for 100 steps with 1000 atoms
Performance: 669.082 tau/day, 3.872 timesteps/s
99.8% 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.08186 | 0.08186 | 0.08186 | 0.0 | 0.32
Neigh | 0.023613 | 0.023613 | 0.023613 | 0.0 | 0.09
Comm | 0.0053532 | 0.0053532 | 0.0053532 | 0.0 | 0.02
Output | 0.00037837 | 0.00037837 | 0.00037837 | 0.0 | 0.00
Modify | 25.715 | 25.715 | 25.715 | 0.0 | 99.57
Other | | 0.0005643 | | | 0.00
Nlocal: 1000.00 ave 1000 max 1000 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost: 3049.00 ave 3049 max 3049 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs: 46176.0 ave 46176 max 46176 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Total # of neighbors = 46176
Ave neighs/atom = 46.176000
Neighbor list builds = 10
Dangerous builds = 0
Total wall time: 0:00:25

View File

@ -0,0 +1,89 @@
LAMMPS (30 Jun 2020)
using 1 OpenMP thread(s) per MPI task
# Kob and Andersen model Phys. Rev. E 51, 4626 (1995)
units lj
atom_style atomic
pair_style lj/cut 2.5
pair_modify shift yes
read_data data.widom.lj
orthogonal box = (0.0000000 0.0000000 0.0000000) to (9.4000000 9.4000000 9.4000000)
1 by 2 by 2 MPI processor grid
reading atoms ...
1000 atoms
reading velocities ...
1000 velocities
read_data CPU = 0.002 seconds
pair_coeff 1 1 1.0 1.0 2.5
pair_coeff 1 2 1.5 0.8 2.0
pair_coeff 2 2 0.5 0.88 2.2
neighbor 0.3 bin
neigh_modify delay 0 every 5 check yes
fix mywidom all widom 10 100000 2 29494 0.75
fix 1 all langevin 0.75 0.75 0.1 48279 zero yes
fix 2 all nve
timestep 0.002
thermo_style custom step temp pe etotal press vol density f_mywidom[1] f_mywidom[2] f_mywidom[3]
thermo 10
run 100
Neighbor list info ...
update every 5 steps, delay 0 steps, check yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 2.8
ghost atom cutoff = 2.8
binsize = 1.4, bins = 7 7 7
1 neighbor lists, perpetual/occasional/extra = 1 0 0
(1) pair lj/cut, perpetual
attributes: half, newton on
pair build: half/bin/atomonly/newton
stencil: half/bin/3d/newton
bin: standard
Per MPI rank memory allocation (min/avg/max) = 3.13 | 3.13 | 3.131 Mbytes
Step Temp PotEng TotEng Press Volume Density f_mywidom[1] f_mywidom[2] f_mywidom[3]
0 0.75021245 -6.4204308 -5.2962374 7.2962696 830.584 1.2039721 0 0 830.584
10 0.74279259 -6.4332442 -5.3201696 7.2071344 830.584 1.2039721 -3.4462258 98.984938 830.584
20 0.73016272 -6.4222911 -5.3281423 7.2714238 830.584 1.2039721 -4.4887329 397.41346 830.584
30 0.74416342 -6.429139 -5.3140101 7.2713375 830.584 1.2039721 -4.3313574 322.19056 830.584
40 0.73295457 -6.4370942 -5.3387618 7.227091 830.584 1.2039721 -4.7419281 557.00309 830.584
50 0.76914235 -6.4473959 -5.2948361 7.2179148 830.584 1.2039721 -3.1794069 69.352982 830.584
60 0.74099083 -6.4433012 -5.3329265 7.204973 830.584 1.2039721 -3.5231065 109.66994 830.584
70 0.74514671 -6.4288463 -5.312244 7.2771269 830.584 1.2039721 -1.0154832 3.8727995 830.584
80 0.72787097 -6.4457574 -5.3550427 7.1130709 830.584 1.2039721 -3.6691709 133.2501 830.584
90 0.78452846 -6.5034376 -5.3278217 6.8238659 830.584 1.2039721 -2.0798339 16.008373 830.584
100 0.77188499 -6.487313 -5.3306433 6.9133194 830.584 1.2039721 -2.066579 15.727938 830.584
Loop time of 3.37748 on 4 procs for 100 steps with 1000 atoms
Performance: 5116.239 tau/day, 29.608 timesteps/s
98.7% 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.02025 | 0.020952 | 0.021322 | 0.3 | 0.62
Neigh | 0.0059071 | 0.0060568 | 0.0061543 | 0.1 | 0.18
Comm | 0.016558 | 0.059554 | 0.094282 | 12.2 | 1.76
Output | 0.00022173 | 0.00042927 | 0.0010471 | 0.0 | 0.01
Modify | 3.2552 | 3.2902 | 3.3335 | 1.7 | 97.42
Other | | 0.0003003 | | | 0.01
Nlocal: 250.000 ave 256 max 242 min
Histogram: 1 0 0 0 1 0 0 0 1 1
Nghost: 1666.00 ave 1670 max 1659 min
Histogram: 1 0 0 0 0 0 1 0 0 2
Neighs: 11538.0 ave 11832 max 11091 min
Histogram: 1 0 0 0 0 0 1 1 0 1
Total # of neighbors = 46152
Ave neighs/atom = 46.152000
Neighbor list builds = 10
Dangerous builds = 0
Total wall time: 0:00:03

View File

@ -0,0 +1,133 @@
LAMMPS (30 Jun 2020)
using 1 OpenMP thread(s) per MPI task
units real
dimension 3
boundary p p p
atom_style full
pair_style lj/cut/coul/long 10.0
bond_style harmonic
angle_style harmonic
read_data data.spce
orthogonal box = (-0.031613 -0.023523 -0.085255) to (43.234352 44.939753 42.306533)
1 by 1 by 1 MPI processor grid
reading atoms ...
8640 atoms
scanning bonds ...
2 = max bonds/atom
scanning angles ...
1 = max angles/atom
reading bonds ...
5760 bonds
reading angles ...
2880 angles
2 = max # of 1-2 neighbors
1 = max # of 1-3 neighbors
1 = max # of 1-4 neighbors
2 = max # of special neighbors
special bonds CPU = 0.008 seconds
read_data CPU = 0.028 seconds
molecule h2omol H2O.txt
Read molecule template h2omol:
1 molecules
3 atoms with max type 2
2 bonds with max type 1
1 angles with max type 1
0 dihedrals with max type 0
0 impropers with max type 0
### Flexible SPC/E Potential Parameters ###
### Zhang et al., Fluid Phase Equilibria, 262 (2007) 210-216 ###
pair_coeff 1 1 0.1502629 3.1169
pair_coeff 1 2 0.0341116368 2.04845
pair_coeff 2 2 0.00774378 0.98
bond_coeff 1 176.864 0.9611
angle_coeff 1 42.1845 109.4712
kspace_style pppm 1.0e-4
fix mywidom all widom 10 20 0 29494 298 mol h2omol
fix 2 all nvt temp 298.0 298.0 100.0
neighbor 2.0 bin
neigh_modify delay 10 every 2 check yes
#run variables
timestep 0.5
thermo 10
thermo_style custom step etotal pe temp press vol density f_mywidom[1] f_mywidom[2] f_mywidom[3]
run 100
PPPM initialization ...
using 12-bit tables for long-range coulomb (src/kspace.cpp:330)
G vector (1/distance) = 0.2690183
grid = 24 24 24
stencil order = 5
estimated absolute RMS force accuracy = 0.024843102
estimated relative force accuracy = 7.4814263e-05
using double precision FFTW3
3d grid and FFT values/proc = 29791 13824
WARNING: Fix Widom using full_energy option (src/MC/fix_widom.cpp:297)
0 atoms in group FixWidom:widom_exclusion_group:mywidom
0 atoms in group FixWidom:rotation_gas_atoms:mywidom
WARNING: Neighbor exclusions used with KSpace solver may give inconsistent Coulombic energies (src/neighbor.cpp:487)
Neighbor list info ...
update every 2 steps, delay 10 steps, check yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 12
ghost atom cutoff = 12
binsize = 6, bins = 8 8 8
1 neighbor lists, perpetual/occasional/extra = 1 0 0
(1) pair lj/cut/coul/long, perpetual
attributes: half, newton on
pair build: half/bin/newton
stencil: half/bin/3d/newton
bin: standard
Per MPI rank memory allocation (min/avg/max) = 29.66 | 29.66 | 29.66 Mbytes
Step TotEng PotEng Temp Press Volume Density f_mywidom[1] f_mywidom[2] f_mywidom[3]
0 -29703.973 -29703.973 0 -4764.5901 82468.116 1.9140713 0 0 82468.116
10 -29712.131 -31110.041 54.285179 -3154.4423 82468.116 1.9140713 241.93348 3.7366217e-178 82468.116
20 -29711.939 -32614.429 112.71273 -4216.1592 82468.116 1.9140713 16.095006 1.5716469e-12 82468.116
30 -29688.142 -32368.506 104.08688 -4093.6515 82468.116 1.9140713 5.7862327 5.7086352e-05 82468.116
40 -29662.343 -32252.144 100.57005 -1458.5339 82468.116 1.9140713 126.68071 1.2467216e-93 82468.116
50 -29646.78 -32837.635 123.91081 -4607.1155 82468.116 1.9140713 74.622397 1.8790479e-55 82468.116
60 -29628.968 -33001.229 130.9554 -4589.5296 82468.116 1.9140713 3.6575433 0.0020780497 82468.116
70 -29602.78 -32816.28 124.79023 -3082.1133 82468.116 1.9140713 13.983097 5.561247e-11 82468.116
80 -29577.552 -33141.454 138.39742 -6332.8138 82468.116 1.9140713 41.98931 1.6075608e-31 82468.116
90 -29550.865 -33792.115 164.70094 -4607.6419 82468.116 1.9140713 68.690681 4.2082269e-51 82468.116
100 -29515.107 -34052.782 176.21207 -3609.5709 82468.116 1.9140713 41.090597 7.3326206e-31 82468.116
Loop time of 163.407 on 1 procs for 100 steps with 8640 atoms
Performance: 0.026 ns/day, 907.819 hours/ns, 0.612 timesteps/s
99.8% CPU use with 1 MPI tasks x 1 OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 8.5495 | 8.5495 | 8.5495 | 0.0 | 5.23
Bond | 0.031981 | 0.031981 | 0.031981 | 0.0 | 0.02
Kspace | 2.3995 | 2.3995 | 2.3995 | 0.0 | 1.47
Neigh | 5.0542 | 5.0542 | 5.0542 | 0.0 | 3.09
Comm | 0.051965 | 0.051965 | 0.051965 | 0.0 | 0.03
Output | 0.0018802 | 0.0018802 | 0.0018802 | 0.0 | 0.00
Modify | 147.31 | 147.31 | 147.31 | 0.0 | 90.15
Other | | 0.003614 | | | 0.00
Nlocal: 8640.00 ave 8640 max 8640 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost: 23499.0 ave 23499 max 23499 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs: 3.27380e+06 ave 3.2738e+06 max 3.2738e+06 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Total # of neighbors = 3273800
Ave neighs/atom = 378.91204
Ave special neighs/atom = 2.0000000
Neighbor list builds = 220
Dangerous builds = 0
Total wall time: 0:02:44

View File

@ -41,7 +41,7 @@ FixGravityKokkos<DeviceType>::FixGravityKokkos(LAMMPS *lmp, int narg, char **arg
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void FixGravityKokkos<DeviceType>::post_force(int vflag)
void FixGravityKokkos<DeviceType>::post_force(int /*vflag*/)
{
// update gravity due to variables

View File

@ -137,7 +137,7 @@ void FixLangevinKokkos<DeviceType>::grow_arrays(int nmax)
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void FixLangevinKokkos<DeviceType>::initial_integrate(int vflag)
void FixLangevinKokkos<DeviceType>::initial_integrate(int /*vflag*/)
{
atomKK->sync(execution_space,datamask_read);
atomKK->modified(execution_space,datamask_modify);

View File

@ -73,7 +73,7 @@ void FixSetForceKokkos<DeviceType>::init()
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void FixSetForceKokkos<DeviceType>::post_force(int vflag)
void FixSetForceKokkos<DeviceType>::post_force(int /*vflag*/)
{
atomKK->sync(execution_space, X_MASK | F_MASK | MASK_MASK);

View File

@ -23,6 +23,7 @@
#include "comm.h"
#include "update.h"
#include "force.h"
#include "info.h"
#include "kspace.h"
#include "pair.h"
#include "error.h"
@ -45,7 +46,8 @@ using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixTuneKspace::FixTuneKspace(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
Fix(lmp, narg, arg),
acc_str(""), kspace_style(""), pair_style(""), base_pair_style("")
{
if (narg < 3) error->all(FLERR,"Illegal fix tune/kspace command");
@ -98,10 +100,9 @@ void FixTuneKspace::init()
if (force->kspace->dipoleflag)
error->all(FLERR,"Cannot use fix tune/kspace with dipole long-range solver");
store_old_kspace_settings();
double old_acc = force->kspace->accuracy/force->kspace->two_charge_force;
char old_acc_str[16];
snprintf(old_acc_str,16,"%g",old_acc);
strncpy(new_acc_str,old_acc_str,16);
acc_str = std::to_string(old_acc);
int itmp;
double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp);
@ -120,34 +121,35 @@ void FixTuneKspace::pre_exchange()
if (next_reneighbor != update->ntimestep) return;
next_reneighbor = update->ntimestep + nevery;
Info *info = new Info(lmp);
bool has_msm = info->has_style("pair", base_pair_style + "/msm");
delete info;
double time = get_timing_info();
if (strcmp(force->kspace_style,"ewald") == 0) ewald_time = time;
if (strcmp(force->kspace_style,"pppm") == 0) pppm_time = time;
if (strcmp(force->kspace_style,"msm") == 0) msm_time = time;
if (utils::strmatch(force->kspace_style,"^ewald")) ewald_time = time;
if (utils::strmatch(force->kspace_style,"^pppm")) pppm_time = time;
if (utils::strmatch(force->kspace_style,"^msm")) msm_time = time;
niter++;
if (niter == 1) {
// test Ewald
store_old_kspace_settings();
strcpy(new_kspace_style,"ewald");
snprintf(new_pair_style,64,"%s/long",base_pair_style);
update_pair_style(new_pair_style,pair_cut_coul);
update_kspace_style(new_kspace_style,new_acc_str);
pair_style = base_pair_style + "/long";
update_pair_style(pair_style,pair_cut_coul);
update_kspace_style("ewald",acc_str);
} else if (niter == 2) {
// test PPPM
store_old_kspace_settings();
strcpy(new_kspace_style,"pppm");
snprintf(new_pair_style,64,"%s/long",base_pair_style);
update_pair_style(new_pair_style,pair_cut_coul);
update_kspace_style(new_kspace_style,new_acc_str);
} else if (niter == 3) {
pair_style = base_pair_style + "/long";
update_pair_style(pair_style,pair_cut_coul);
update_kspace_style("pppm",acc_str);
} else if (has_msm && (niter == 3)) {
// test MSM
store_old_kspace_settings();
strcpy(new_kspace_style,"msm");
snprintf(new_pair_style,64,"%s/msm",base_pair_style);
update_pair_style(new_pair_style,pair_cut_coul);
update_kspace_style(new_kspace_style,new_acc_str);
pair_style = base_pair_style + "/msm";
update_pair_style(pair_style,pair_cut_coul);
update_kspace_style("msm",acc_str);
} else if (niter == 4) {
store_old_kspace_settings();
if (comm->me == 0)
@ -156,16 +158,17 @@ void FixTuneKspace::pre_exchange()
"msm_time = {}\n",
ewald_time, pppm_time, msm_time));
// switch to fastest one
strcpy(new_kspace_style,"ewald");
snprintf(new_pair_style,64,"%s/long",base_pair_style);
if (msm_time == 0.0) msm_time = 1.0e300;
kspace_style = "ewald";
pair_style = base_pair_style + "/long";
if (pppm_time < ewald_time && pppm_time < msm_time)
strcpy(new_kspace_style,"pppm");
kspace_style = "pppm";
else if (msm_time < pppm_time && msm_time < ewald_time) {
strcpy(new_kspace_style,"msm");
snprintf(new_pair_style,64,"%s/msm",base_pair_style);
kspace_style = "msm";
pair_style = base_pair_style + "/msm";
}
update_pair_style(new_pair_style,pair_cut_coul);
update_kspace_style(new_kspace_style,new_acc_str);
update_pair_style(pair_style,pair_cut_coul);
update_kspace_style(kspace_style,acc_str);
} else {
adjust_rcut(time);
}
@ -207,30 +210,26 @@ double FixTuneKspace::get_timing_info()
void FixTuneKspace::store_old_kspace_settings()
{
int n = strlen(force->kspace_style) + 1;
char *old_kspace_style = new char[n];
strcpy(old_kspace_style,force->kspace_style);
strcpy(new_kspace_style,old_kspace_style);
double old_acc = force->kspace->accuracy_relative;
char old_acc_str[16];
snprintf(old_acc_str,16,"%g",old_acc);
strcpy(new_pair_style,force->pair_style);
strcpy(base_pair_style,force->pair_style);
char *trunc;
if ((trunc = strstr(base_pair_style, "/long")) != NULL) *trunc = '\0';
if ((trunc = strstr(base_pair_style, "/msm" )) != NULL) *trunc = '\0';
kspace_style = force->kspace_style;
pair_style = force->pair_style;
std::size_t found;
if (std::string::npos != (found = pair_style.rfind("/long")))
base_pair_style = pair_style.substr(0,found);
else if (std::string::npos != (found = pair_style.rfind("/msm")))
base_pair_style = pair_style.substr(0,found);
else base_pair_style = pair_style;
old_differentiation_flag = force->kspace->differentiation_flag;
old_slabflag = force->kspace->slabflag;
old_slab_volfactor = force->kspace->slab_volfactor;
delete[] old_kspace_style;
}
/* ----------------------------------------------------------------------
update the pair style if necessary, preserving the settings
------------------------------------------------------------------------- */
void FixTuneKspace::update_pair_style(char *new_pair_style,
void FixTuneKspace::update_pair_style(const std::string &new_pair_style,
double pair_cut_coul)
{
int itmp;
@ -238,7 +237,7 @@ void FixTuneKspace::update_pair_style(char *new_pair_style,
*p_cutoff = pair_cut_coul;
// check to see if we need to change pair styles
if (strcmp(new_pair_style,force->pair_style) == 0) return;
if (new_pair_style == force->pair_style) return;
// create a temporary file to store current pair settings
FILE *p_pair_settings_file;
@ -247,8 +246,9 @@ void FixTuneKspace::update_pair_style(char *new_pair_style,
rewind(p_pair_settings_file);
if (comm->me == 0)
utils::logmesg(lmp,fmt::format("Creating new pair style: {}\n",new_pair_style));
// delete old pair style and create new one
force->create_pair(new_pair_style,1);
force->create_pair(new_pair_style.c_str(),1);
// restore current pair settings from temporary file
force->pair->read_restart(p_pair_settings_file);
@ -267,26 +267,14 @@ void FixTuneKspace::update_pair_style(char *new_pair_style,
update the kspace style if necessary
------------------------------------------------------------------------- */
void FixTuneKspace::update_kspace_style(char *new_kspace_style,
char *new_acc_str)
void FixTuneKspace::update_kspace_style(const std::string &new_kspace_style,
const std::string &new_acc_str)
{
// create kspace style char string
int narg = 2;
char **arg;
arg = NULL;
int maxarg = 100;
arg = (char **) memory->srealloc(arg,maxarg*sizeof(char *),"tune/kspace:arg");
int n = 12;
arg[0] = new char[n];
strcpy(arg[0],new_kspace_style);
arg[1] = new char[n];
strcpy(arg[1],new_acc_str);
// delete old kspace style and create new one
force->create_kspace(arg[0],1);
force->kspace->settings(narg-1,&arg[1]);
char *tmp_acc_str = (char *)new_acc_str.c_str();
force->create_kspace(new_kspace_style.c_str(),1);
force->kspace->settings(1,&tmp_acc_str);
force->kspace->differentiation_flag = old_differentiation_flag;
force->kspace->slabflag = old_slabflag;
force->kspace->slab_volfactor = old_slab_volfactor;
@ -305,8 +293,6 @@ void FixTuneKspace::update_kspace_style(char *new_kspace_style,
// Re-init computes to update pointers to virials, etc.
for (int i = 0; i < modify->ncompute; i++) modify->compute[i]->init();
memory->sfree(arg);
}
/* ----------------------------------------------------------------------
@ -315,7 +301,7 @@ void FixTuneKspace::update_kspace_style(char *new_kspace_style,
void FixTuneKspace::adjust_rcut(double time)
{
if (strcmp(force->kspace_style,"msm") == 0) return;
if (utils::strmatch(force->kspace_style,"^msm")) return;
if (converged) return;
double temp;
@ -401,8 +387,8 @@ void FixTuneKspace::adjust_rcut(double time)
utils::logmesg(lmp,fmt::format("Adjusted Coulomb cutoff for real space: {}\n", current_cutoff));
store_old_kspace_settings();
update_pair_style(new_pair_style,pair_cut_coul);
update_kspace_style(new_kspace_style,new_acc_str);
update_pair_style(pair_style,pair_cut_coul);
update_kspace_style(kspace_style,acc_str);
}
/* ----------------------------------------------------------------------

View File

@ -21,6 +21,7 @@ FixStyle(tune/kspace,FixTuneKspace)
#define LMP_FIX_TUNE_KSPACE_H
#include "fix.h"
#include <string>
namespace LAMMPS_NS {
@ -33,8 +34,8 @@ class FixTuneKspace : public Fix {
void pre_exchange();
double get_timing_info();
void store_old_kspace_settings();
void update_pair_style(char *, double);
void update_kspace_style(char *, char *);
void update_pair_style(const std::string &, double);
void update_kspace_style(const std::string &, const std::string &);
void adjust_rcut(double);
void mnbrak();
void brent0();
@ -51,10 +52,10 @@ class FixTuneKspace : public Fix {
double ewald_time,pppm_time,msm_time;
double pair_cut_coul;
char new_acc_str[16];
char new_kspace_style[64];
char new_pair_style[64];
char base_pair_style[64];
std::string acc_str;
std::string kspace_style;
std::string pair_style;
std::string base_pair_style;
int old_differentiation_flag;
int old_slabflag;

View File

@ -34,13 +34,8 @@ FixBondCreateAngle::FixBondCreateAngle(LAMMPS *lmp, int narg, char **arg) :
int FixBondCreateAngle::constrain(int i, int j, double amin, double amax)
{
double **x = atom->x;
tagint *tag = atom->tag;
tagint **bond_atom = atom->bond_atom;
int *num_bond = atom->num_bond;
int **nspecial = atom->nspecial;
tagint **special = atom->special;
int *mask = atom->mask;
int *type = atom->type;
double v1x = 0.0;
double v1y = 0.0;

View File

@ -493,11 +493,7 @@ void FixGCMC::init()
}
}
if (full_flag) {
char *id_pe = (char *) "thermo_pe";
int ipe = modify->find_compute(id_pe);
c_pe = modify->compute[ipe];
}
if (full_flag) c_pe = modify->compute[modify->find_compute("thermo_pe")];
int *type = atom->type;
@ -580,18 +576,12 @@ void FixGCMC::init()
// skip if already exists from previous init()
if (full_flag && !exclusion_group_bit) {
char **group_arg = new char*[4];
// create unique group name for atoms to be excluded
int len = strlen(id) + 30;
group_arg[0] = new char[len];
sprintf(group_arg[0],"FixGCMC:gcmc_exclusion_group:%s",id);
group_arg[1] = (char *) "subtract";
group_arg[2] = (char *) "all";
group_arg[3] = (char *) "all";
group->assign(4,group_arg);
exclusion_group = group->find(group_arg[0]);
auto group_id = std::string("FixGCMC:gcmc_exclusion_group:") + id;
group->assign(group_id + " subtract all all");
exclusion_group = group->find(group_id);
if (exclusion_group == -1)
error->all(FLERR,"Could not find fix gcmc exclusion group ID");
exclusion_group_bit = group->bitmask[exclusion_group];
@ -603,34 +593,25 @@ void FixGCMC::init()
char **arg = new char*[narg];;
arg[0] = (char *) "exclude";
arg[1] = (char *) "group";
arg[2] = group_arg[0];
arg[2] = (char *) group_id.c_str();
arg[3] = (char *) "all";
neighbor->modify_params(narg,arg);
delete [] group_arg[0];
delete [] group_arg;
delete [] arg;
}
// create a new group for temporary use with selected molecules
if (exchmode == EXCHMOL || movemode == MOVEMOL) {
char **group_arg = new char*[3];
// create unique group name for atoms to be rotated
int len = strlen(id) + 30;
group_arg[0] = new char[len];
sprintf(group_arg[0],"FixGCMC:rotation_gas_atoms:%s",id);
group_arg[1] = (char *) "molecule";
char digits[12];
sprintf(digits,"%d",-1);
group_arg[2] = digits;
group->assign(3,group_arg);
molecule_group = group->find(group_arg[0]);
auto group_id = std::string("FixGCMC:rotation_gas_atoms:") + id;
group->assign(group_id + " molecule -1");
molecule_group = group->find(group_id);
if (molecule_group == -1)
error->all(FLERR,"Could not find fix gcmc rotation group ID");
molecule_group_bit = group->bitmask[molecule_group];
molecule_group_inversebit = molecule_group_bit ^ ~0;
delete [] group_arg[0];
delete [] group_arg;
}
// get all of the needed molecule data if exchanging

1227
src/MC/fix_widom.cpp Normal file

File diff suppressed because it is too large Load Diff

257
src/MC/fix_widom.h Normal file
View File

@ -0,0 +1,257 @@
/* -*- 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(widom,FixWidom)
#else
#ifndef LMP_FIX_WIDOM_H
#define LMP_FIX_WIDOM_H
#include <cstdio>
#include "fix.h"
namespace LAMMPS_NS {
class FixWidom : public Fix {
public:
FixWidom(class LAMMPS *, int, char **);
~FixWidom();
int setmask();
void init();
void pre_exchange();
void attempt_atomic_insertion();
void attempt_molecule_insertion();
void attempt_atomic_insertion_full();
void attempt_molecule_insertion_full();
double energy(int, int, tagint, double *);
double molecule_energy(tagint);
double energy_full();
void update_gas_atoms_list();
double compute_vector(int);
double memory_usage();
void write_restart(FILE *);
void restart(char *);
void grow_molecule_arrays(int);
private:
int molecule_group,molecule_group_bit;
int molecule_group_inversebit;
int exclusion_group,exclusion_group_bit;
int nwidom_type,nevery,seed;
int ninsertions;
int ngas; // # of gas atoms on all procs
int ngas_local; // # of gas atoms on this proc
int exchmode; // exchange ATOM or MOLECULE
int movemode; // move ATOM or MOLECULE
int regionflag; // 0 = anywhere in box, 1 = specific region
int iregion; // widom region
char *idregion; // widom region id
bool charge_flag; // true if user specified atomic charge
bool full_flag; // true if doing full system energy calculations
int natoms_per_molecule; // number of atoms in each inserted molecule
int nmaxmolatoms; // number of atoms allocated for molecule arrays
double ave_widom_chemical_potential;
int widom_nmax;
int max_region_attempts;
double gas_mass;
double insertion_temperature;
double beta,sigma,volume;
double charge;
double xlo,xhi,ylo,yhi,zlo,zhi;
double region_xlo,region_xhi,region_ylo,region_yhi,region_zlo,region_zhi;
double region_volume;
double energy_stored; // full energy of old/current configuration
double *sublo,*subhi;
int *local_gas_list;
double **cutsq;
double **molcoords;
double *molq;
imageint *molimage;
imageint imagezero;
double energy_intra;
class Pair *pair;
class RanPark *random_equal;
class Atom *model_atom;
class Molecule **onemols;
int imol,nmol;
int triclinic; // 0 = orthog box, 1 = triclinic
class Compute *c_pe;
void options(int, char **);
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... 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.
E: Fix Widom does not (yet) work with atom_style template
Self-explanatory.
E: Fix Widom region does not support a bounding box
Not all regions represent bounded volumes. You cannot use
such a region with the fix Widom command.
E: Fix Widom region cannot be dynamic
Only static regions can be used with fix Widom.
E: Fix Widom region extends outside simulation box
Self-explanatory.
E: Fix Widom molecule must have coordinates
The defined molecule does not specify coordinates.
E: Fix Widom molecule must have atom types
The defined molecule does not specify atom types.
E: Atom type must be zero in fix Widom mol command
Self-explanatory.
E: Fix Widom molecule has charges, but atom style does not
Self-explanatory.
E: Fix Widom molecule template ID must be same as atom_style template ID
When using atom_style template, you cannot insert molecules that are
not in that template.
E: Fix Widom atom has charge, but atom style does not
Self-explanatory.
UNDOCUMENTED
E: Molecule template ID for fix Widom does not exist
Self-explanatory.
W: Molecule template for fix Widom has multiple molecules
The fix Widom command will only create molecules of a single type,
i.e. the first molecule in the template.
E: Region ID for fix Widom does not exist
Self-explanatory.
W: Fix Widom using full_energy option
Fix Widom has automatically turned on the full_energy option since it
is required for systems like the one specified by the user. User input
included one or more of the following: kspace, a hybrid
pair style, an eam pair style, tail correction,
or no "single" function for the pair style.
E: Invalid atom type in fix Widom command
The atom type specified in the Widom command does not exist.
E: Fix Widom cannot exchange individual atoms belonging to a molecule
This is an error since you should not delete only one atom of a
molecule. The user has specified atomic (non-molecular) gas
exchanges, but an atom belonging to a molecule could be deleted.
E: All mol IDs should be set for fix Widom group atoms
The molecule flag is on, yet not all molecule ids in the fix group
have been set to non-zero positive values by the user. This is an
error since all atoms in the fix Widom group are eligible for deletion,
rotation, and translation and therefore must have valid molecule ids.
E: Fix Widom molecule command requires that atoms have molecule attributes
Should not choose the Widom molecule feature if no molecules are being
simulated. The general molecule flag is off, but Widom's molecule flag
is on.
E: Cannot use fix Widom in a 2d simulation
Fix Widom is set up to run in 3d only. No 2d simulations with fix Widom
are allowed.
E: Could not find fix Widom exclusion group ID
Self-explanatory.
E: Illegal fix Widom gas mass <= 0
The computed mass of the designated gas molecule or atom type was less
than or equal to zero.
E: Cannot do Widom on atoms in atom_modify first group
This is a restriction due to the way atoms are organized in a list to
enable the atom_modify first command.
W: Fix Widom is being applied to the default group all
This is allowed, but it will result in Monte Carlo moves
being performed on all the atoms in the system, which is
often not what is intended.
E: Could not find specified fix Widom group ID
Self-explanatory.
E: fix Widom does currently not support full_energy option with molecules on more than 1 MPI process.
UNDOCUMENTED
E: Fix Widom put atom outside box
This should not normally happen. Contact the developers.
E: Fix Widom ran out of available molecule IDs
See the setting for tagint in the src/lmptype.h file.
E: Fix Widom ran out of available atom IDs
See the setting for tagint in the src/lmptype.h file.
E: Too many total atoms
See the setting for bigint in the src/lmptype.h file.
*/

View File

@ -247,11 +247,9 @@ void ComputeMLIAP::compute_array()
for (int ielem = 0; ielem < data->nelements; ielem++) {
const int elemoffset = data->nparams*ielem;
for (int jparam = 0; jparam < data->nparams; jparam++) {
int irow = 1;
for (int i = 0; i < ntotal; i++) {
double *gradforcei = data->gradforce[i]+elemoffset;
int iglobal = atom->tag[i];
int irow = 3*(iglobal-1)+1;
tagint irow = 3*(atom->tag[i]-1)+1;
mliaparray[irow][jparam+elemoffset] += gradforcei[jparam];
mliaparray[irow+1][jparam+elemoffset] += gradforcei[jparam+data->yoffset];
mliaparray[irow+2][jparam+elemoffset] += gradforcei[jparam+data->zoffset];

View File

@ -32,16 +32,14 @@
using namespace LAMMPS_NS;
MLIAPData::MLIAPData(LAMMPS *lmp,
int gradgradflag_in, int *map_in, class MLIAPModel* model_in,
class MLIAPDescriptor* descriptor_in, class PairMLIAP* pairmliap_in) :
Pointers(lmp),
list(NULL),
gradforce(NULL),
betas(NULL), descriptors(NULL), gamma_row_index(NULL), gamma_col_index(NULL),
gamma(NULL), egradient(NULL), model(NULL), descriptor(NULL),
iatoms(NULL), ielems(NULL), numneighs(NULL),
jatoms(NULL), jelems(NULL), rij(NULL), graddesc(NULL)
MLIAPData::MLIAPData(LAMMPS *lmp, int gradgradflag_in, int *map_in,
class MLIAPModel* model_in,
class MLIAPDescriptor* descriptor_in,
class PairMLIAP* pairmliap_in) :
Pointers(lmp), gradforce(NULL), betas(NULL), descriptors(NULL), gamma(NULL),
gamma_row_index(NULL), gamma_col_index(NULL), egradient(NULL),
numneighs(NULL), iatoms(NULL), ielems(NULL), jatoms(NULL), jelems(NULL),
rij(NULL), graddesc(NULL), model(NULL), descriptor(NULL), list(NULL)
{
gradgradflag = gradgradflag_in;
map = map_in;

View File

@ -68,8 +68,8 @@ class MLIAPData : protected Pointers {
class PairMLIAP *pairmliap; // access to pair tally functions
private:
class MLIAPModel* model;
class MLIAPDescriptor* descriptor;
class MLIAPModel *model;
class MLIAPDescriptor *descriptor;
int nmax;
class NeighList *list; // LAMMPS neighbor list

View File

@ -76,12 +76,8 @@ MLIAPDescriptorSNAP::~MLIAPDescriptorSNAP()
void MLIAPDescriptorSNAP::compute_descriptors(class MLIAPData* data)
{
double **x = atom->x;
int ij = 0;
for (int ii = 0; ii < data->natoms; ii++) {
const int i = data->iatoms[ii];
const int ielem = data->ielems[ii];
// insure rij, inside, wj, and rcutij are of size jnum
@ -130,8 +126,6 @@ void MLIAPDescriptorSNAP::compute_descriptors(class MLIAPData* data)
void MLIAPDescriptorSNAP::compute_forces(class MLIAPData* data)
{
double fij[3];
double **x = atom->x;
double **f = atom->f;
int ij = 0;
@ -208,8 +202,6 @@ void MLIAPDescriptorSNAP::compute_forces(class MLIAPData* data)
void MLIAPDescriptorSNAP::compute_force_gradients(class MLIAPData* data)
{
double **x = atom->x;
int ij = 0;
for (int ii = 0; ii < data->natoms; ii++) {
const int i = data->iatoms[ii];
@ -285,11 +277,8 @@ void MLIAPDescriptorSNAP::compute_force_gradients(class MLIAPData* data)
void MLIAPDescriptorSNAP::compute_descriptor_gradients(class MLIAPData* data)
{
double **x = atom->x;
int ij = 0;
for (int ii = 0; ii < data->natoms; ii++) {
const int i = data->iatoms[ii];
const int ielem = data->ielems[ii];
// insure rij, inside, wj, and rcutij are of size jnum
@ -328,8 +317,6 @@ void MLIAPDescriptorSNAP::compute_descriptor_gradients(class MLIAPData* data)
ij = ij0;
for (int jj = 0; jj < ninside; jj++) {
const int j = snaptr->inside[jj];
if(chemflag)
snaptr->compute_duidrj(snaptr->rij[jj], snaptr->wj[jj],
snaptr->rcutij[jj],jj, snaptr->element[jj]);

View File

@ -102,7 +102,6 @@ void MLIAPModelLinear::compute_gradgrads(class MLIAPData* data)
data->egradient[l] = 0.0;
for (int ii = 0; ii < data->natoms; ii++) {
const int i = data->iatoms[ii];
const int ielem = data->ielems[ii];
const int elemoffset = data->nparams*ielem;
@ -145,8 +144,6 @@ void MLIAPModelLinear::compute_force_gradients(class MLIAPData* data)
for (int jj = 0; jj < data->numneighs[ii]; jj++) {
const int j = data->jatoms[ij];
const int jelem = data->ielems[ij];
int l = elemoffset+1;
for (int icoeff = 0; icoeff < data->ndescriptors; icoeff++) {
data->gradforce[i][l] += data->graddesc[ij][icoeff][0];

View File

@ -127,7 +127,6 @@ void MLIAPModelQuadratic::compute_gradgrads(class MLIAPData* data)
data->egradient[l] = 0.0;
for (int ii = 0; ii < data->natoms; ii++) {
const int i = data->iatoms[ii];
const int ielem = data->ielems[ii];
const int elemoffset = data->nparams*ielem;
@ -216,9 +215,6 @@ void MLIAPModelQuadratic::compute_force_gradients(class MLIAPData* data) {
for (int jj = 0; jj < data->numneighs[ii]; jj++) {
const int j = data->jatoms[ij];
const int jelem = data->ielems[ij];
const int ij0 = ij;
int l = elemoffset+1;
for (int icoeff = 0; icoeff < data->ndescriptors; icoeff++) {
data->gradforce[i][l] += data->graddesc[ij][icoeff][0];

View File

@ -310,7 +310,7 @@ void DihedralCharmm::allocate()
int n = atom->ndihedraltypes;
memory->create(k,n+1,"dihedral:k");
memory->create(multiplicity,n+1,"dihedral:k");
memory->create(multiplicity,n+1,"dihedral:multiplicity");
memory->create(shift,n+1,"dihedral:shift");
memory->create(cos_shift,n+1,"dihedral:cos_shift");
memory->create(sin_shift,n+1,"dihedral:sin_shift");

View File

@ -328,7 +328,7 @@ void DihedralCharmmfsw::allocate()
int n = atom->ndihedraltypes;
memory->create(k,n+1,"dihedral:k");
memory->create(multiplicity,n+1,"dihedral:k");
memory->create(multiplicity,n+1,"dihedral:multiplicity");
memory->create(shift,n+1,"dihedral:shift");
memory->create(cos_shift,n+1,"dihedral:cos_shift");
memory->create(sin_shift,n+1,"dihedral:sin_shift");

View File

@ -410,7 +410,7 @@ int PythonImpl::create_entry(char *name)
if (!format && ninput+noutput)
error->all(FLERR,"Invalid python command");
else if (format && strlen(format) != ninput+noutput)
else if (format && ((int) strlen(format) != ninput+noutput))
error->all(FLERR,"Invalid python command");
// process inputs as values or variables

View File

@ -156,11 +156,11 @@ void AngleCosineShift::allocate()
allocated = 1;
int n = atom->nangletypes;
memory->create(k ,n+1,"Angle:k");
memory->create(ksint ,n+1,"Angle:ksint");
memory->create(kcost ,n+1,"Angle:kcost");
memory->create(theta ,n+1,"Angle:theta");
memory->create(setflag,n+1, "Angle:setflag");
memory->create(k,n+1,"angle:k");
memory->create(ksint,n+1,"angle:ksint");
memory->create(kcost,n+1,"angle:kcost");
memory->create(theta,n+1,"angle:theta");
memory->create(setflag,n+1,"angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}

View File

@ -110,9 +110,9 @@ void BondHarmonicShift::allocate()
allocated = 1;
int n = atom->nbondtypes;
memory->create(k , n+1,"bond:k");
memory->create(r0, n+1,"bond:r0");
memory->create(r1, n+1,"bond:r1");
memory->create(k,n+1,"bond:k");
memory->create(r0,n+1,"bond:r0");
memory->create(r1,n+1,"bond:r1");
memory->create(setflag,n+1,"bond:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;

View File

@ -511,7 +511,7 @@ void ComputeVoronoi::processCell(voronoicell_neighbor &c, int i)
c.face_areas(narea);
have_narea = true;
voro[i][1] = 0.0;
for (j=0; j<narea.size(); ++j)
for (j=0; j < (int)narea.size(); ++j)
if (narea[j] > fthresh) voro[i][1] += 1.0;
} else {
// unthresholded face count
@ -526,7 +526,7 @@ void ComputeVoronoi::processCell(voronoicell_neighbor &c, int i)
voro[i][2] = 0.0;
// each entry in neigh should correspond to an entry in narea
if (neighs != narea.size())
if (neighs != (int)narea.size())
error->one(FLERR,"Voro++ error: narea and neigh have a different size");
// loop over all faces (neighbors) and check if they are in the surface group
@ -587,7 +587,7 @@ void ComputeVoronoi::processCell(voronoicell_neighbor &c, int i)
if (!have_narea) c.face_areas(narea);
if (neighs != narea.size())
if (neighs != (int)narea.size())
error->one(FLERR,"Voro++ error: narea and neigh have a different size");
tagint itag, jtag;
tagint *tag = atom->tag;

View File

@ -74,7 +74,7 @@
#endif
#if __cplusplus == 201103L || __cplusplus == 201402L
# if defined(__clang__)
# if defined(__clang__) && !defined(__INTEL_COMPILER)
# define FMT_FALLTHROUGH [[clang::fallthrough]]
# elif FMT_GCC_VERSION >= 700 && !defined(__PGI) && !defined(__INTEL_COMPILER)
# define FMT_FALLTHROUGH [[gnu::fallthrough]]

View File

@ -584,10 +584,10 @@ void Group::create(char *name, int *flag)
return group index if name matches existing group, -1 if no such group
------------------------------------------------------------------------- */
int Group::find(const char *name)
int Group::find(const std::string &name)
{
for (int igroup = 0; igroup < MAX_GROUP; igroup++)
if (names[igroup] && strcmp(name,names[igroup]) == 0) return igroup;
if (names[igroup] && (name == names[igroup])) return igroup;
return -1;
}

View File

@ -33,7 +33,7 @@ class Group : protected Pointers {
void assign(int, char **); // assign atoms to a group
void assign(const std::string &); // convenience function
void create(char *, int *); // add flagged atoms to a group
int find(const char *); // lookup name in list of groups
int find(const std::string &); // lookup name in list of groups
int find_or_create(const char *); // lookup name or create new group
void write_restart(FILE *);
void read_restart(FILE *);

View File

@ -265,7 +265,7 @@ void Info::command(int narg, char **arg)
fputs("\nInfo-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info\n",out);
time_t now = time(NULL);
fprintf(out,"Printed on %s\n",ctime(&now));
fmt::print(out,"Printed on {}\n",ctime(&now));
if (flags & CONFIG) {
fmt::print(out,"\nLAMMPS version: {} / {}\n",
@ -302,17 +302,15 @@ void Info::command(int narg, char **arg)
fputs("-DLAMMPS_SMALLSMALL\n",out);
#endif
const char *pkg;
int ncword, ncline = 0;
fputs("\nInstalled packages:\n\n",out);
for (int i = 0; NULL != (pkg = lmp->installed_packages[i]); ++i) {
ncword = strlen(pkg);
for (const char **pkg = lmp->installed_packages; *pkg != nullptr; ++pkg) {
ncword = strlen(*pkg);
if (ncline + ncword > 78) {
ncline = 0;
fputs("\n",out);
}
fprintf(out,"%s ",pkg);
fmt::print(out,"{} ",*pkg);
ncline += ncword + 1;
}
fputs("\n",out);
@ -320,7 +318,7 @@ void Info::command(int narg, char **arg)
if (flags & MEMORY) {
fprintf(out,"\nMemory allocation information (MPI rank 0):\n\n");
fputs("\nMemory allocation information (MPI rank 0):\n\n",out);
bigint bytes = 0;
bytes += atom->memory_usage();
@ -332,26 +330,26 @@ void Info::command(int narg, char **arg)
for (int i = 0; i < output->ndump; i++)
bytes += output->dump[i]->memory_usage();
double mbytes = bytes/1024.0/1024.0;
fprintf(out,"Total dynamically allocated memory: %.4g Mbyte\n",mbytes);
fmt::print(out,"Total dynamically allocated memory: {:.4} Mbyte\n",mbytes);
#if defined(_WIN32)
HANDLE phandle = GetCurrentProcess();
PROCESS_MEMORY_COUNTERS_EX pmc;
GetProcessMemoryInfo(phandle,(PROCESS_MEMORY_COUNTERS *)&pmc,sizeof(pmc));
fprintf(out,"Non-shared memory use: %.4g Mbyte\n",
fmt::print(out,"Non-shared memory use: {:.4} Mbyte\n",
(double)pmc.PrivateUsage/1048576.0);
fprintf(out,"Maximum working set size: %.4g Mbyte\n",
fmt::print(out,"Maximum working set size: {:.4} Mbyte\n",
(double)pmc.PeakWorkingSetSize/1048576.0);
#else
#if defined(__linux__)
struct mallinfo mi;
mi = mallinfo();
fprintf(out,"Current reserved memory pool size: %.4g Mbyte\n",
fmt::print(out,"Current reserved memory pool size: {:.4} Mbyte\n",
(double)mi.uordblks/1048576.0+(double)mi.hblkhd/1048576.0);
#endif
struct rusage ru;
if (getrusage(RUSAGE_SELF, &ru) == 0) {
fprintf(out,"Maximum resident set size: %.4g Mbyte\n",
fmt::print(out,"Maximum resident set size: {:.4} Mbyte\n",
(double)ru.ru_maxrss/1024.0);
}
#endif
@ -376,85 +374,84 @@ void Info::command(int narg, char **arg)
comm->get_comm_cutoff());
if (comm->mode == 1) {
fprintf(out,"Communication mode = multi\n");
fputs("Communication mode = multi\n",out);
double cut;
for (int i=1; i <= atom->ntypes && neighbor->cuttype; ++i) {
cut = neighbor->cuttype[i];
if (comm->cutusermulti) cut = MAX(cut,comm->cutusermulti[i]);
fprintf(out,"Communication cutoff for type %d = %g\n", i, cut);
fmt::print(out,"Communication cutoff for type {} = {:.8}\n", i, cut);
}
}
fprintf(out,"Nprocs = %d, Nthreads = %d\n",
comm->nprocs, comm->nthreads);
fmt::print(out,"Nprocs = {}, Nthreads = {}\n",comm->nprocs,comm->nthreads);
if (domain->box_exist)
fprintf(out,"Processor grid = %d x %d x %d\n",comm->procgrid[0],
fmt::print(out,"Processor grid = {} x {} x {}\n",comm->procgrid[0],
comm->procgrid[1], comm->procgrid[2]);
}
if (flags & SYSTEM) {
fprintf(out,"\nSystem information:\n");
fprintf(out,"Units = %s\n", update->unit_style);
fprintf(out,"Atom style = %s\n", atom->atom_style);
fprintf(out,"Atom map = %s\n", mapstyles[atom->map_style]);
fputs("\nSystem information:\n",out);
fmt::print(out,"Units = {}\n", update->unit_style);
fmt::print(out,"Atom style = {}\n", atom->atom_style);
fmt::print(out,"Atom map = {}\n", mapstyles[atom->map_style]);
if (atom->molecular > 0) {
const char *msg;
msg = (atom->molecular == 2) ? "template" : "standard";
fprintf(out,"Molecule type = %s\n",msg);
fmt::print(out,"Molecule type = {}\n",msg);
}
fprintf(out,"Atoms = " BIGINT_FORMAT ", types = %d, style = %s\n",
fmt::print(out,"Atoms = {:12}, types = {:8d}, style = {}\n",
atom->natoms, atom->ntypes, force->pair_style);
if (force->pair && utils::strmatch(force->pair_style,"^hybrid")) {
PairHybrid *hybrid = (PairHybrid *)force->pair;
fprintf(out,"Hybrid sub-styles:");
fmt::print(out,"Hybrid sub-styles:");
for (int i=0; i < hybrid->nstyles; ++i)
fprintf(out," %s", hybrid->keywords[i]);
fmt::print(out," {}", hybrid->keywords[i]);
fputc('\n',out);
}
if (atom->molecular > 0) {
const char *msg;
msg = force->bond_style ? force->bond_style : "none";
fprintf(out,"Bonds = " BIGINT_FORMAT ", types = %d, style = %s\n",
fmt::print(out,"Bonds = {:12}, types = {:8}, style = {}\n",
atom->nbonds, atom->nbondtypes, msg);
msg = force->angle_style ? force->angle_style : "none";
fprintf(out,"Angles = " BIGINT_FORMAT ", types = %d, style = %s\n",
fmt::print(out,"Angles = {:12}, types = {:8}, style = {}\n",
atom->nangles, atom->nangletypes, msg);
msg = force->dihedral_style ? force->dihedral_style : "none";
fprintf(out,"Dihedrals = " BIGINT_FORMAT ", types = %d, style = %s\n",
fmt::print(out,"Dihedrals = {:12}, types = {:8}, style = {}\n",
atom->ndihedrals, atom->ndihedraltypes, msg);
msg = force->improper_style ? force->improper_style : "none";
fprintf(out,"Impropers = " BIGINT_FORMAT ", types = %d, style = %s\n",
fmt::print(out,"Impropers = {:12}, types = {:8}, style = {}\n",
atom->nimpropers, atom->nimpropertypes, msg);
const double * const special_lj = force->special_lj;
const double * const special_coul = force->special_coul;
fprintf(out,"Special bond factors lj = %-10g %-10g %-10g\n"
"Special bond factors coul = %-10g %-10g %-10g\n",
fmt::print(out,"Special bond factors lj = {:<8} {:<8} {:<8}\n"
"Special bond factors coul = {:<8} {:<8} {:<8}\n",
special_lj[1],special_lj[2],special_lj[3],
special_coul[1],special_coul[2],special_coul[3]);
}
fprintf(out,"Kspace style = %s\n",
fmt::print(out,"Kspace style = {}\n",
force->kspace ? force->kspace_style : "none");
if (domain->box_exist) {
fprintf(out,"\nDimensions = %d\n",domain->dimension);
fprintf(out,"%s box = %g x %g x %g\n",
fmt::print(out,"\nDimensions = {}\n",domain->dimension);
fmt::print(out,"{} box = {:.8} x {:.8} x {:.8}\n",
domain->triclinic ? "Triclinic" : "Orthogonal",
domain->xprd, domain->yprd, domain->zprd);
fprintf(out,"Boundaries = %c,%c %c,%c %c,%c\n",
fmt::print(out,"Boundaries = {},{} {},{} {},{}\n",
bstyles[domain->boundary[0][0]],bstyles[domain->boundary[0][1]],
bstyles[domain->boundary[1][0]],bstyles[domain->boundary[1][1]],
bstyles[domain->boundary[2][0]],bstyles[domain->boundary[2][1]]);
fprintf(out,"xlo, xhi = %g, %g\n", domain->boxlo[0], domain->boxhi[0]);
fprintf(out,"ylo, yhi = %g, %g\n", domain->boxlo[1], domain->boxhi[1]);
fprintf(out,"zlo, zhi = %g, %g\n", domain->boxlo[2], domain->boxhi[2]);
fmt::print(out,"xlo, xhi = {:.8}, {:.8}\n", domain->boxlo[0], domain->boxhi[0]);
fmt::print(out,"ylo, yhi = {:.8}, {:.8}\n", domain->boxlo[1], domain->boxhi[1]);
fmt::print(out,"zlo, zhi = {:.8}, {:.8}\n", domain->boxlo[2], domain->boxhi[2]);
if (domain->triclinic)
fprintf(out,"Xy, xz, yz = %g, %g, %g\n",
fmt::print(out,"Xy, xz, yz = {:.8}, {:.8}, {:.8}\n",
domain->xy, domain->xz, domain->yz);
} else {
fputs("\nBox has not yet been created\n",out);
@ -464,23 +461,23 @@ void Info::command(int narg, char **arg)
if (domain->box_exist && (flags & COEFFS)) {
Pair *pair=force->pair;
fprintf(out,"\nCoeff information:\n");
fputs("\nCoeff status information:\n",out);
if (pair) {
fprintf(out,"Pair Coeffs:\n");
fputs("\nPair Coeffs:\n",out);
for (int i=1; i <= atom->ntypes; ++i)
for (int j=i; j <= atom->ntypes; ++j) {
fprintf(out,"%3d %3d :",i,j);
fmt::print(out,"{:6d} {:6d}:",i,j);
if (pair->allocated && pair->setflag[i][j]) fputs(" is set\n",out);
else fputs (" is not set\n",out);
else fputs(" is not set\n",out);
}
}
if (force->bond) {
Bond *bond=force->bond;
if (bond) {
fprintf(out,"Bond Coeffs:\n");
fputs("\nBond Coeffs:\n",out);
for (int i=1; i <= atom->nbondtypes; ++i) {
fprintf(out,"%3d :",i);
fmt::print(out,"{:6d}:",i);
if (bond->allocated && bond->setflag[i]) fputs(" is set\n",out);
else fputs (" is not set\n",out);
}
@ -490,9 +487,9 @@ void Info::command(int narg, char **arg)
Angle *angle=force->angle;
if (angle) {
fprintf(out,"Angle Coeffs:\n");
fputs("\nAngle Coeffs:\n",out);
for (int i=1; i <= atom->nangletypes; ++i) {
fprintf(out,"%3d :",i);
fmt::print(out,"{:6d}:",i);
if (angle->allocated && angle->setflag[i]) fputs(" is set\n",out);
else fputs (" is not set\n",out);
}
@ -502,9 +499,9 @@ void Info::command(int narg, char **arg)
Dihedral *dihedral=force->dihedral;
if (dihedral) {
fprintf(out,"Dihedral Coeffs:\n");
fputs("\nDihedral Coeffs:\n",out);
for (int i=1; i <= atom->ndihedraltypes; ++i) {
fprintf(out,"%3d :",i);
fmt::print(out,"{:6d}:",i);
if (dihedral->allocated && dihedral->setflag[i]) fputs(" is set\n",out);
else fputs (" is not set\n",out);
}
@ -514,9 +511,9 @@ void Info::command(int narg, char **arg)
Improper *b=force->improper;
if (b) {
fprintf(out,"Improper Coeffs:\n");
fputs("\nImproper Coeffs:\n",out);
for (int i=1; i <= atom->nimpropertypes; ++i) {
fprintf(out,"%3d :",i);
fmt::print(out,"{:6d}:",i);
if (b->allocated && b->setflag[i]) fputs(" is set\n",out);
else fputs (" is not set\n",out);
}
@ -528,10 +525,10 @@ void Info::command(int narg, char **arg)
int ngroup = group->ngroup;
char **names = group->names;
int *dynamic = group->dynamic;
fprintf(out,"\nGroup information:\n");
fputs("\nGroup information:\n",out);
for (int i=0; i < ngroup; ++i) {
if (names[i])
fprintf(out,"Group[%2d]: %s (%s)\n",
fmt::print(out,"Group[{:2d}]: {:16} ({})\n",
i, names[i], dynamic[i] ? "dynamic" : "static");
}
}
@ -539,17 +536,18 @@ void Info::command(int narg, char **arg)
if (flags & REGIONS) {
int nreg = domain->nregion;
Region **regs = domain->regions;
fprintf(out,"\nRegion information:\n");
fputs("\nRegion information:\n",out);
for (int i=0; i < nreg; ++i) {
fprintf(out,"Region[%3d]: %s, style = %s, side = %s\n",
i, regs[i]->id, regs[i]->style,
fmt::print(out,"Region[{:3d}]: {:16} style = {:16} side = {}\n",
i, std::string(regs[i]->id)+',',
std::string(regs[i]->style)+',',
regs[i]->interior ? "in" : "out");
if (regs[i]->bboxflag)
fprintf(out," Boundary: lo %g %g %g hi %g %g %g\n",
fmt::print(out," Boundary: lo {:.8} {:.8} {:.8} hi {:.8} {:.8} {:.8}\n",
regs[i]->extent_xlo, regs[i]->extent_ylo,
regs[i]->extent_zlo, regs[i]->extent_xhi,
regs[i]->extent_yhi, regs[i]->extent_zhi);
else fprintf(out," No Boundary\n");
else fputs(" No Boundary\n",out);
}
}
@ -557,10 +555,11 @@ void Info::command(int narg, char **arg)
int ncompute = modify->ncompute;
Compute **compute = modify->compute;
char **names = group->names;
fprintf(out,"\nCompute information:\n");
fputs("\nCompute information:\n",out);
for (int i=0; i < ncompute; ++i) {
fprintf(out,"Compute[%3d]: %s, style = %s, group = %s\n",
i, compute[i]->id, compute[i]->style,
fmt::print(out,"Compute[{:3d}]: {:16} style = {:16} group = {}\n",
i, std::string(compute[i]->id)+',',
std::string(compute[i]->style)+',',
names[compute[i]->igroup]);
}
}
@ -571,15 +570,17 @@ void Info::command(int narg, char **arg)
int *nevery = output->every_dump; \
char **vnames = output->var_dump;
char **names = group->names;
fprintf(out,"\nDump information:\n");
fputs("\nDump information:\n",out);
for (int i=0; i < ndump; ++i) {
fprintf(out,"Dump[%3d]: %s, file = %s, style = %s, group = %s, ",
i, dump[i]->id, dump[i]->filename,
dump[i]->style, names[dump[i]->igroup]);
fmt::print(out,"Dump[{:3d}]: {:16} file = {:16} style = {:16} group = {:16} ",
i, std::string(dump[i]->id)+',',
std::string(dump[i]->filename)+',',
std::string(dump[i]->style)+',',
std::string(names[dump[i]->igroup])+',');
if (nevery[i]) {
fprintf(out,"every = %d\n", nevery[i]);
fmt::print(out,"every = {}\n", nevery[i]);
} else {
fprintf(out,"every = %s\n", vnames[i]);
fmt::print(out,"every = {}\n", vnames[i]);
}
}
}
@ -588,10 +589,12 @@ void Info::command(int narg, char **arg)
int nfix = modify->nfix;
Fix **fix = modify->fix;
char **names = group->names;
fprintf(out,"\nFix information:\n");
fputs("\nFix information:\n",out);
for (int i=0; i < nfix; ++i) {
fprintf(out,"Fix[%3d]: %s, style = %s, group = %s\n",
i, fix[i]->id, fix[i]->style, names[fix[i]->igroup]);
fmt::print(out, "Fix[{:3d}]: {:16} style = {:16} group = {}\n",
i,std::string(fix[i]->id)+',',
std::string(fix[i]->style)+',',
names[fix[i]->igroup]);
}
}
@ -600,19 +603,20 @@ void Info::command(int narg, char **arg)
int *style = input->variable->style;
char **names = input->variable->names;
char ***data = input->variable->data;
fprintf(out,"\nVariable information:\n");
fputs("\nVariable information:\n",out);
for (int i=0; i < nvar; ++i) {
int ndata = 1;
fprintf(out,"Variable[%3d]: %-10s, style = %-10s, def =",
i,names[i],varstyles[style[i]]);
fmt::print(out,"Variable[{:3d}]: {:16} style = {:16} def =",
i,std::string(names[i])+',',
std::string(varstyles[style[i]])+',');
if (style[i] == INTERNAL) {
fprintf(out,"%g\n",input->variable->dvalue[i]);
fmt::print(out,"{:.8}\n",input->variable->dvalue[i]);
continue;
}
if ((style[i] != LOOP) && (style[i] != ULOOP))
ndata = input->variable->num[i];
for (int j=0; j < ndata; ++j)
fprintf(out," %s",data[i][j]);
fmt::print(out," {}",data[i][j]);
fputs("\n",out);
}
}
@ -646,9 +650,9 @@ void Info::command(int narg, char **arg)
wallclock = (wallclock - walls) / 60.0;
wallm = fmod(wallclock,60.0);
wallh = (wallclock - wallm) / 60.0;
fprintf(out,"\nTotal time information (MPI rank 0):\n"
" CPU time: %4d:%02d:%02d\n"
" Wall time: %4d:%02d:%02d\n",
fmt::print(out,"\nTotal time information (MPI rank 0):\n"
" CPU time: {:4d}:{:02d}:{:02d}\n"
" Wall time: {:4d}:{:02d}:{:02d}\n",
cpuh,cpum,cpus,wallh,wallm,walls);
}
@ -663,11 +667,10 @@ void Info::command(int narg, char **arg)
fclose(out);
}
void Info::available_styles(FILE * out, int flags)
{
fprintf(out,"\nStyles information:\n");
fputs("\nStyles information:\n",out);
if(flags & ATOM_STYLES) atom_styles(out);
if(flags & INTEGRATE_STYLES) integrate_styles(out);
@ -685,102 +688,102 @@ void Info::available_styles(FILE * out, int flags)
if(flags & COMMAND_STYLES) command_styles(out);
}
void Info::atom_styles(FILE * out)
void Info::atom_styles(FILE *out)
{
fprintf(out, "\nAtom styles:\n");
fputs("\nAtom styles:\n",out);
print_columns(out, atom->avec_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}
void Info::integrate_styles(FILE * out)
void Info::integrate_styles(FILE *out)
{
fprintf(out, "\nIntegrate styles:\n");
fputs("\nIntegrate styles:\n",out);
print_columns(out, update->integrate_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}
void Info::minimize_styles(FILE * out)
void Info::minimize_styles(FILE *out)
{
fprintf(out, "\nMinimize styles:\n");
fputs("\nMinimize styles:\n",out);
print_columns(out, update->minimize_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}
void Info::pair_styles(FILE * out)
void Info::pair_styles(FILE *out)
{
fprintf(out, "\nPair styles:\n");
fputs("\nPair styles:\n",out);
print_columns(out, force->pair_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}
void Info::bond_styles(FILE * out)
void Info::bond_styles(FILE *out)
{
fprintf(out, "\nBond styles:\n");
fputs("\nBond styles:\n",out);
print_columns(out, force->bond_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}
void Info::angle_styles(FILE * out)
void Info::angle_styles(FILE *out)
{
fprintf(out, "\nAngle styles:\n");
fputs("\nAngle styles:\n",out);
print_columns(out, force->angle_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}
void Info::dihedral_styles(FILE * out)
void Info::dihedral_styles(FILE *out)
{
fprintf(out, "\nDihedral styles:\n");
fputs("\nDihedral styles:\n",out);
print_columns(out, force->dihedral_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}
void Info::improper_styles(FILE * out)
void Info::improper_styles(FILE *out)
{
fprintf(out, "\nImproper styles:\n");
fputs("\nImproper styles:\n",out);
print_columns(out, force->improper_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}
void Info::kspace_styles(FILE * out)
void Info::kspace_styles(FILE *out)
{
fprintf(out, "\nKSpace styles:\n");
fputs("\nKSpace styles:\n",out);
print_columns(out, force->kspace_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}
void Info::fix_styles(FILE * out)
void Info::fix_styles(FILE *out)
{
fprintf(out, "\nFix styles:\n");
fputs("\nFix styles:\n",out);
print_columns(out, modify->fix_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}
void Info::compute_styles(FILE * out)
void Info::compute_styles(FILE *out)
{
fprintf(out, "\nCompute styles:\n");
fputs("\nCompute styles:\n",out);
print_columns(out, modify->compute_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}
void Info::region_styles(FILE * out)
void Info::region_styles(FILE *out)
{
fprintf(out, "\nRegion styles:\n");
fputs("\nRegion styles:\n",out);
print_columns(out, domain->region_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}
void Info::dump_styles(FILE * out)
void Info::dump_styles(FILE *out)
{
fprintf(out, "\nDump styles:\n");
print_columns(out, output->dump_map);
fprintf(out, "\n\n\n");
fputs("\nDump styles:\n",out);
print_columns(out,output->dump_map);
fputs("\n\n\n",out);
}
void Info::command_styles(FILE * out)
void Info::command_styles(FILE *out)
{
fprintf(out, "\nCommand styles (add-on input script commands):\n");
fputs("\nCommand styles (add-on input script commands):\n",out);
print_columns(out, input->command_map);
fprintf(out, "\n\n\n");
fputs("\n\n\n",out);
}

View File

@ -198,7 +198,7 @@ class KSpace : protected Pointers {
void pair_check();
void ev_init(int eflag, int vflag, int alloc = 1) {
if (eflag||vflag) ev_setup(eflag, vflag, alloc);
else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0;
else evflag = evflag_atom = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0;
}
void ev_setup(int, int, int alloc = 1);
double estimate_table_accuracy(double, double);

View File

@ -26,11 +26,13 @@ using namespace LAMMPS_NS;
NBin::NBin(LAMMPS *lmp) : Pointers(lmp)
{
last_bin = -1;
maxbin = maxatom = 0;
mbins = maxbin = maxatom = 0;
binhead = NULL;
bins = NULL;
atom2bin = NULL;
neighbor->last_setup_bins = -1;
// geometry settings
dimension = domain->dimension;

View File

@ -2078,6 +2078,7 @@ void Neighbor::build(int topoflag)
// leading to errors or even a crash
if (style != Neighbor::NSQ) {
if (last_setup_bins < 0) setup_bins();
for (int i = 0; i < nbin; i++) {
neigh_bin[i]->bin_atoms_setup(nall);
neigh_bin[i]->bin_atoms();

View File

@ -4222,13 +4222,14 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
if (eval_in_progress[ivar])
print_var_error(FLERR,"Variable has circular dependency",ivar);
if ((method == AVE) && (nvec == 0))
print_var_error(FLERR,"Cannot compute average of empty vector",ivar);
double *vec;
nvec = compute_vector(ivar,&vec);
nstride = 1;
if ((method == AVE) && (nvec == 0))
print_var_error(FLERR,"Cannot compute average of empty vector",ivar);
} else print_var_error(FLERR,"Invalid special function in "
"variable formula",ivar);

View File

@ -24,6 +24,7 @@ class Variable : protected Pointers {
public:
Variable(class LAMMPS *);
~Variable();
void set(const std::string &);
void set(int, char **);
void set(const std::string &);
void set(char *, int, char **);

View File

@ -9,6 +9,7 @@ From: fedora:32
ccache gcc-c++ gcc-gfortran gdb valgrind eigen3-devel openblas-devel \
openmpi-devel mpich-devel fftw-devel voro++-devel gsl-devel hdf5-devel \
netcdf-devel netcdf-cxx-devel netcdf-mpich-devel netcdf-openmpi-devel \
python3-pyyaml \
mingw-filesystem-base mingw32-nsis mingw-binutils-generic \
mingw32-filesystem mingw32-pkg-config \
mingw64-filesystem mingw64-pkg-config \

View File

@ -1,5 +1,5 @@
BootStrap: docker
From: rocm/dev-ubuntu-18.04
From: ubuntu:18.04
%environment
export PATH=/usr/lib/ccache:/usr/local/cuda-10.2/bin:${PATH}:/opt/rocm/bin:/opt/rocm/profiler/bin:/opt/rocm/opencl/bin/x86_64
@ -11,6 +11,22 @@ From: rocm/dev-ubuntu-18.04
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get upgrade --no-install-recommends -y
apt-get install -y --no-install-recommends curl libnuma-dev gnupg
curl -sL http://repo.radeon.com/rocm/apt/debian/rocm.gpg.key | apt-key add -
printf "deb [arch=amd64] http://repo.radeon.com/rocm/apt/debian/ xenial main" > /etc/apt/sources.list.d/rocm.list
apt-get update
apt-get install --no-install-recommends -y \
kmod \
file \
sudo \
libelf1 \
rocm-dev \
rocm-libs \
build-essential
apt-get install --no-install-recommends -y software-properties-common
apt-get install --no-install-recommends -y \
bc \
@ -57,7 +73,6 @@ From: rocm/dev-ubuntu-18.04
python3-pkg-resources \
python3-setuptools \
python3-virtualenv \
rocm-libs \
rsync \
ssh \
vim-nox \
@ -86,10 +101,10 @@ From: rocm/dev-ubuntu-18.04
libcublas-dev
export PATH=$PATH:/opt/rocm/bin:/opt/rocm/profiler/bin:/opt/rocm/opencl/bin/x86_64
git clone -b master-rocm-3.3 https://github.com/ROCmSoftwarePlatform/hipCUB.git
git clone -b master-rocm-3.5 https://github.com/ROCmSoftwarePlatform/hipCUB.git
mkdir hipCUB/build
cd hipCUB/build
CXX=hcc cmake -D BUILD_TEST=off ..
CXX=hipcc cmake -D BUILD_TEST=off ..
make -j4
make package
make install

View File

@ -28,6 +28,12 @@
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
#if defined(OMPI_MAJOR_VERSION)
const bool have_openmpi = true;
#else
const bool have_openmpi = false;
#endif
using LAMMPS_NS::utils::split_words;
namespace LAMMPS_NS {
@ -35,11 +41,19 @@ using ::testing::MatchesRegex;
#define GETIDX(i) lmp->atom->map(i)
#define TEST_FAILURE(...) \
#define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \
::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} else { \
if (!have_openmpi) { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} \
}
#define STRINGIFY(val) XSTR(val)
@ -454,51 +468,26 @@ TEST_F(ResetIDsTest, DeleteAdd)
TEST_F(ResetIDsTest, DeathTests)
{
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_mol_ids"););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal reset_mol_ids command.*"));
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", lmp->input->one("reset_mol_ids"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all offset 1 1"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all offset -2"););
TEST_FAILURE(".*ERROR on proc 0: Expected integer.*",
lmp->input->one("reset_mol_ids all offset xxx"););
TEST_FAILURE(".*ERROR on proc 0: Expected integer.*",
lmp->input->one("reset_mol_ids all compress yes single no offset xxx"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all offset"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all compress"););
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_mol_ids all offset 1 1"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal reset_mol_ids command.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_mol_ids all offset -2"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal reset_mol_ids command.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_mol_ids all offset xxx"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR on proc 0: Expected integer.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_mol_ids all compress yes single no offset xxx"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR on proc 0: Expected integer.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_mol_ids all offset"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal reset_mol_ids command.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_mol_ids all compress"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal reset_mol_ids command.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_mol_ids all compress xxx"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal reset_mol_ids command.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_mol_ids all single"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal reset_mol_ids command.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_mol_ids all single xxx"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal reset_mol_ids command.*"));
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all compress xxx"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all single"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all single xxx"););
}
TEST(ResetMolIds, CMDFail)
@ -511,26 +500,23 @@ TEST(ResetMolIds, CMDFail)
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
if (!verbose) ::testing::internal::GetCapturedStdout();
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_mol_ids all"););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Reset_mol_ids command before.*"));
TEST_FAILURE(".*ERROR: Reset_mol_ids command before simulation box is.*",
lmp->input->one("reset_mol_ids all"););
::testing::internal::CaptureStdout();
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("atom_modify id no");
lmp->input->one("region box block 0 1 0 1 0 1");
lmp->input->one("create_box 1 box");
TEST_FAILURE(lmp->input->one("reset_mol_ids all"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Cannot use reset_mol_ids unl.*"));
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Cannot use reset_mol_ids unless.*",
lmp->input->one("reset_mol_ids all"););
::testing::internal::CaptureStdout();
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("region box block 0 1 0 1 0 1");
lmp->input->one("create_box 1 box");
TEST_FAILURE(lmp->input->one("reset_mol_ids all"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Can only use reset_mol_ids.*"));
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Can only use reset_mol_ids.*", lmp->input->one("reset_mol_ids all"););
if (!verbose) ::testing::internal::CaptureStdout();
delete lmp;
@ -544,6 +530,10 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (have_openmpi && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";
// handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = split_words(var);

View File

@ -30,6 +30,12 @@
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
#if defined(OMPI_MAJOR_VERSION)
const bool have_openmpi = true;
#else
const bool have_openmpi = false;
#endif
using LAMMPS_NS::utils::split_words;
namespace LAMMPS_NS {
@ -37,11 +43,19 @@ using ::testing::ExitedWithCode;
using ::testing::MatchesRegex;
using ::testing::StrEq;
#define TEST_FAILURE(...) \
#define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \
::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} else { \
if (!have_openmpi) { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} \
}
class SimpleCommandsTest : public ::testing::Test {
@ -68,10 +82,7 @@ protected:
TEST_F(SimpleCommandsTest, UnknownCommand)
{
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("XXX one two three"););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Unknown command.*"));
TEST_FAILURE(".*ERROR: Unknown command.*", lmp->input->one("XXX one two"););
}
TEST_F(SimpleCommandsTest, Echo)
@ -103,15 +114,8 @@ TEST_F(SimpleCommandsTest, Echo)
ASSERT_EQ(lmp->input->echo_screen, 0);
ASSERT_EQ(lmp->input->echo_log, 1);
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("echo"););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex("^ERROR: Illegal echo command.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("echo xxx"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex("^ERROR: Illegal echo command.*"));
TEST_FAILURE(".*ERROR: Illegal echo command.*", lmp->input->one("echo"););
TEST_FAILURE(".*ERROR: Illegal echo command.*", lmp->input->one("echo xxx"););
}
TEST_F(SimpleCommandsTest, Log)
@ -154,24 +158,20 @@ TEST_F(SimpleCommandsTest, Log)
in.close();
remove("simple_command_test.log");
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("log"););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal log command.*"));
TEST_FAILURE(".*ERROR: Illegal log command.*", lmp->input->one("log"););
}
TEST_F(SimpleCommandsTest, Quit)
{
::testing::internal::CaptureStdout();
lmp->input->one("echo none");
TEST_FAILURE(lmp->input->one("quit xxx"););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Expected integer .*"));
::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Expected integer .*", lmp->input->one("quit xxx"););
#if !defined(OMPI_MAJOR_VERSION) // this stalls with OpenMPI. skip.
// the following tests must be skipped with OpenMPI due to using threads
if (have_openmpi) GTEST_SKIP();
ASSERT_EXIT(lmp->input->one("quit"), ExitedWithCode(0), "");
ASSERT_EXIT(lmp->input->one("quit 9"), ExitedWithCode(9), "");
#endif
}
TEST_F(SimpleCommandsTest, ResetTimestep)
@ -188,25 +188,10 @@ TEST_F(SimpleCommandsTest, ResetTimestep)
if (!verbose) ::testing::internal::GetCapturedStdout();
ASSERT_EQ(lmp->update->ntimestep, 0);
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_timestep -10"););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Timestep must be >= 0.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_timestep"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal reset_timestep .*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_timestep 10 10"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal reset_timestep .*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("reset_timestep xxx"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Expected integer .*"));
TEST_FAILURE(".*ERROR: Timestep must be >= 0.*", lmp->input->one("reset_timestep -10"););
TEST_FAILURE(".*ERROR: Illegal reset_timestep .*", lmp->input->one("reset_timestep"););
TEST_FAILURE(".*ERROR: Illegal reset_timestep .*", lmp->input->one("reset_timestep 10 10"););
TEST_FAILURE(".*ERROR: Expected integer .*", lmp->input->one("reset_timestep xxx"););
}
TEST_F(SimpleCommandsTest, Suffix)
@ -215,10 +200,8 @@ TEST_F(SimpleCommandsTest, Suffix)
ASSERT_EQ(lmp->suffix, nullptr);
ASSERT_EQ(lmp->suffix2, nullptr);
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("suffix on"););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: May only enable suffixes after defining one.*"));
TEST_FAILURE(".*ERROR: May only enable suffixes after defining one.*",
lmp->input->one("suffix on"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("suffix one");
@ -247,20 +230,9 @@ TEST_F(SimpleCommandsTest, Suffix)
if (!verbose) ::testing::internal::GetCapturedStdout();
ASSERT_EQ(lmp->suffix_enable, 1);
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("suffix"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal suffix command.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("suffix hybrid"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal suffix command.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("suffix hybrid one"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal suffix command.*"));
TEST_FAILURE(".*ERROR: Illegal suffix command.*", lmp->input->one("suffix"););
TEST_FAILURE(".*ERROR: Illegal suffix command.*", lmp->input->one("suffix hybrid"););
TEST_FAILURE(".*ERROR: Illegal suffix command.*", lmp->input->one("suffix hybrid one"););
}
TEST_F(SimpleCommandsTest, Thermo)
@ -284,20 +256,9 @@ TEST_F(SimpleCommandsTest, Thermo)
ASSERT_EQ(lmp->output->thermo_every, 10);
ASSERT_EQ(lmp->output->var_thermo, nullptr);
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("thermo"););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal thermo command.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("thermo -1"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal thermo command.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("thermo xxx"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Expected integer.*"));
TEST_FAILURE(".*ERROR: Illegal thermo command.*", lmp->input->one("thermo"););
TEST_FAILURE(".*ERROR: Illegal thermo command.*", lmp->input->one("thermo -1"););
TEST_FAILURE(".*ERROR: Expected integer.*", lmp->input->one("thermo xxx"););
}
TEST_F(SimpleCommandsTest, TimeStep)
@ -324,15 +285,8 @@ TEST_F(SimpleCommandsTest, TimeStep)
if (!verbose) ::testing::internal::GetCapturedStdout();
ASSERT_EQ(lmp->update->dt, -0.1);
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("timestep"););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal timestep command.*"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("timestep xxx"););
mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Expected floating point.*"));
TEST_FAILURE(".*ERROR: Illegal timestep command.*", lmp->input->one("timestep"););
TEST_FAILURE(".*ERROR: Expected floating point.*", lmp->input->one("timestep xxx"););
}
TEST_F(SimpleCommandsTest, Units)
@ -343,7 +297,7 @@ TEST_F(SimpleCommandsTest, Units)
ASSERT_EQ(num, sizeof(dt) / sizeof(double));
ASSERT_THAT(lmp->update->unit_style, StrEq("lj"));
for (int i = 0; i < num; ++i) {
for (std::size_t i = 0; i < num; ++i) {
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one(fmt::format("units {}", names[i]));
if (!verbose) ::testing::internal::GetCapturedStdout();
@ -356,10 +310,7 @@ TEST_F(SimpleCommandsTest, Units)
if (!verbose) ::testing::internal::GetCapturedStdout();
ASSERT_THAT(lmp->update->unit_style, StrEq("lj"));
::testing::internal::CaptureStdout();
TEST_FAILURE(lmp->input->one("units unknown"););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR: Illegal units command.*"));
TEST_FAILURE(".*ERROR: Illegal units command.*", lmp->input->one("units unknown"););
}
} // namespace LAMMPS_NS
@ -368,6 +319,10 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (have_openmpi && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";
// handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = split_words(var);

View File

@ -23,17 +23,33 @@
#include <string>
using namespace LAMMPS_NS;
using testing::StartsWith;
using testing::MatchesRegex;
using testing::StrEq;
using utils::sfgets;
using utils::sfread;
using utils::split_words;
#define TEST_FAILURE(...) \
#if defined(OMPI_MAJOR_VERSION)
const bool have_openmpi = true;
#else
const bool have_openmpi = false;
#endif
#define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \
::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} else { \
if (!have_openmpi) { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} \
}
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
@ -99,13 +115,10 @@ TEST_F(FileOperationsTest, safe_fgets)
ASSERT_THAT(buf, StrEq("newline"));
memset(buf, 0, MAX_BUF_SIZE);
::testing::internal::CaptureStdout();
TEST_FAILURE(
".*ERROR on proc 0: Unexpected end of file while "
"reading file 'safe_file_read_test.txt'.*",
utils::sfgets(FLERR, buf, MAX_BUF_SIZE, fp, "safe_file_read_test.txt", lmp->error););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, StartsWith("ERROR on proc 0: Unexpected end of file while "
"reading file 'safe_file_read_test.txt'"));
fclose(fp);
}
@ -125,11 +138,9 @@ TEST_F(FileOperationsTest, safe_fread)
utils::sfread(FLERR, buf, 1, 10, fp, "safe_file_read_test.txt", nullptr);
ASSERT_THAT(buf, StrEq("two_lines\n"));
::testing::internal::CaptureStdout();
TEST_FAILURE(utils::sfread(FLERR, buf, 1, 100, fp, "safe_file_read_test.txt", lmp->error););
auto mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, StartsWith("ERROR on proc 0: Unexpected end of file while "
"reading file 'safe_file_read_test.txt'"));
TEST_FAILURE(".*ERROR on proc 0: Unexpected end of file while "
"reading file 'safe_file_read_test.txt'.*",
utils::sfread(FLERR, buf, 1, 100, fp, "safe_file_read_test.txt", lmp->error););
// short read but no error triggered due to passing a NULL pointer
memset(buf, 0, MAX_BUF_SIZE);
@ -166,6 +177,10 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (have_openmpi && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";
// handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = split_words(var);

View File

@ -35,15 +35,29 @@
#include <cstring>
#include <mpi.h>
#if defined(OMPI_MAJOR_VERSION)
const bool have_openmpi = true;
#else
const bool have_openmpi = false;
#endif
using namespace LAMMPS_NS;
using ::testing::MatchesRegex;
using utils::split_words;
#define TEST_FAILURE(...) \
#define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \
::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} else { \
if (!have_openmpi) { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} \
}
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
@ -116,10 +130,8 @@ TEST_F(PotentialFileReaderTest, Sw_noconv)
lmp->input->one("units real");
if (!verbose) ::testing::internal::GetCapturedStdout();
::testing::internal::CaptureStdout();
TEST_FAILURE(PotentialFileReader reader(lmp, "Si.sw", "Stillinger-Weber", utils::REAL2METAL););
std::string mesg = ::testing::internal::GetCapturedStdout();
ASSERT_THAT(mesg, MatchesRegex(".*ERROR on proc.*potential.*requires metal units but real.*"));
TEST_FAILURE(".*ERROR on proc.*potential.*requires metal units but real.*",
PotentialFileReader reader(lmp, "Si.sw", "Stillinger-Weber", utils::REAL2METAL););
}
TEST_F(PotentialFileReaderTest, Comb)
@ -291,6 +303,10 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (have_openmpi && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";
// handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = split_words(var);