Merge remote-tracking branch 'github/develop' into python_computes
This commit is contained in:
1
.github/workflows/coverity.yml
vendored
1
.github/workflows/coverity.yml
vendored
@ -67,7 +67,6 @@ jobs:
|
||||
-D PKG_MANIFOLD=on \
|
||||
-D PKG_MDI=on \
|
||||
-D PKG_MGPT=on \
|
||||
-D PKG_ML-PACE=on \
|
||||
-D PKG_ML-RANN=on \
|
||||
-D PKG_MOLFILE=on \
|
||||
-D PKG_NETCDF=on \
|
||||
|
||||
53
.github/workflows/lammps-gui-flatpak.yml
vendored
Normal file
53
.github/workflows/lammps-gui-flatpak.yml
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
# GitHub action to build LAMMPS-GUI as a flatpak bundle
|
||||
name: "Build LAMMPS-GUI as flatpak bundle"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.event_name }}-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{github.event_name == 'pull_request'}}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: LAMMPS-GUI flatpak build
|
||||
if: ${{ github.repository == 'lammps/lammps' }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Install extra packages
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ccache \
|
||||
libeigen3-dev \
|
||||
libcurl4-openssl-dev \
|
||||
mold \
|
||||
ninja-build \
|
||||
python3-dev \
|
||||
flatpak \
|
||||
flatpak-builder
|
||||
|
||||
- name: Set up access to flatpak repo
|
||||
run: flatpak --user remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
|
||||
- name: Build flatpak
|
||||
run: |
|
||||
mkdir flatpack-state
|
||||
sed -i -e 's/branch:.*/branch: develop/' tools/lammps-gui/org.lammps.lammps-gui.yml
|
||||
flatpak-builder --force-clean --verbose --repo=flatpak-repo \
|
||||
--install-deps-from=flathub --state-dir=flatpak-state \
|
||||
--user --ccache --default-branch=${{ github.ref_name }} \
|
||||
flatpak-build tools/lammps-gui/org.lammps.lammps-gui.yml
|
||||
flatpak build-bundle --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo \
|
||||
--verbose flatpak-repo LAMMPS-Linux-x86_64-GUI.flatpak \
|
||||
org.lammps.lammps-gui ${{ github.ref_name }}
|
||||
flatpak install -y -v --user LAMMPS-Linux-x86_64-GUI.flatpak
|
||||
@ -605,6 +605,16 @@ foreach(PKG_WITH_INCL KSPACE PYTHON ML-IAP VORONOI COLVARS ML-HDNNP MDI MOLFILE
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# settings for misc packages and styles
|
||||
if(PKG_MISC)
|
||||
option(LAMMPS_ASYNC_IMD "Asynchronous IMD processing" OFF)
|
||||
mark_as_advanced(LAMMPS_ASYNC_IMD)
|
||||
if(LAMMPS_ASYNC_IMD)
|
||||
target_compile_definitions(lammps PRIVATE -DLAMMPS_ASYNC_IMD)
|
||||
message(STATUS "Using IMD in asynchronous mode")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# optionally enable building script wrappers using swig
|
||||
option(WITH_SWIG "Build scripting language wrappers with SWIG" OFF)
|
||||
if(WITH_SWIG)
|
||||
|
||||
@ -48,6 +48,7 @@ This is the list of packages that may require additional steps.
|
||||
* :ref:`LEPTON <lepton>`
|
||||
* :ref:`MACHDYN <machdyn>`
|
||||
* :ref:`MDI <mdi>`
|
||||
* :ref:`MISC <misc>`
|
||||
* :ref:`ML-HDNNP <ml-hdnnp>`
|
||||
* :ref:`ML-IAP <mliap>`
|
||||
* :ref:`ML-PACE <ml-pace>`
|
||||
@ -2031,7 +2032,7 @@ TBB and MKL.
|
||||
.. _mdi:
|
||||
|
||||
MDI package
|
||||
-----------------------------
|
||||
-----------
|
||||
|
||||
.. tabs::
|
||||
|
||||
@ -2058,6 +2059,37 @@ MDI package
|
||||
|
||||
----------
|
||||
|
||||
.. _misc:
|
||||
|
||||
MISC package
|
||||
------------
|
||||
|
||||
The :doc:`fix imd <fix_imd>` style in this package can be run either
|
||||
synchronously (communication with IMD clients is done in the main
|
||||
process) or asynchronously (the fix spawns a separate thread that can
|
||||
communicate with IMD clients concurrently to the LAMMPS execution).
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. tab:: CMake build
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
-D LAMMPS_ASYNC_IMD=value # Run IMD server asynchronously
|
||||
# value = no (default) or yes
|
||||
|
||||
.. tab:: Traditional make
|
||||
|
||||
To enable asynchronous mode the ``-DLAMMPS_ASYNC_IMD`` define
|
||||
needs to be added to the ``LMP_INC`` variable in the
|
||||
``Makefile.machine`` you are using. For example:
|
||||
|
||||
.. code-block:: make
|
||||
|
||||
LMP_INC = -DLAMMPS_ASYNC_IMD -DLAMMPS_MEMALIGN=64
|
||||
|
||||
----------
|
||||
|
||||
.. _molfile:
|
||||
|
||||
MOLFILE package
|
||||
|
||||
@ -49,6 +49,7 @@ packages:
|
||||
* :ref:`LEPTON <lepton>`
|
||||
* :ref:`MACHDYN <machdyn>`
|
||||
* :ref:`MDI <mdi>`
|
||||
* :ref:`MISC <misc>`
|
||||
* :ref:`ML-HDNNP <ml-hdnnp>`
|
||||
* :ref:`ML-IAP <mliap>`
|
||||
* :ref:`ML-PACE <ml-pace>`
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
Removed commands and packages
|
||||
=============================
|
||||
|
||||
.. contents::
|
||||
|
||||
------
|
||||
|
||||
This page lists LAMMPS commands and packages that have been removed from
|
||||
the distribution and provides suggestions for alternatives or
|
||||
replacements. LAMMPS has special dummy styles implemented, that will
|
||||
@ -8,47 +12,60 @@ stop LAMMPS and print a suitable error message in most cases, when a
|
||||
style/command is used that has been removed or will replace the command
|
||||
with the direct alternative (if available) and print a warning.
|
||||
|
||||
restart2data tool
|
||||
-----------------
|
||||
LAMMPS shell
|
||||
------------
|
||||
|
||||
.. versionchanged:: 23Nov2013
|
||||
.. versionchanged:: 29Aug2024
|
||||
|
||||
The functionality of the restart2data tool has been folded into the
|
||||
LAMMPS executable directly instead of having a separate tool. A
|
||||
combination of the commands :doc:`read_restart <read_restart>` and
|
||||
:doc:`write_data <write_data>` can be used to the same effect. For
|
||||
added convenience this conversion can also be triggered by
|
||||
:doc:`command-line flags <Run_options>`
|
||||
The LAMMPS shell has been removed from the LAMMPS distribution. Users
|
||||
are encouraged to use the :ref:`LAMMPS-GUI <lammps_gui>` tool instead.
|
||||
|
||||
Fix ave/spatial and fix ave/spatial/sphere
|
||||
------------------------------------------
|
||||
i-PI tool
|
||||
---------
|
||||
|
||||
.. deprecated:: 11Dec2015
|
||||
.. versionchanged:: 27Jun2024
|
||||
|
||||
The fixes ave/spatial and ave/spatial/sphere have been removed from LAMMPS
|
||||
since they were superseded by the more general and extensible "chunk
|
||||
infrastructure". Here the system is partitioned in one of many possible
|
||||
ways through the :doc:`compute chunk/atom <compute_chunk_atom>` command
|
||||
and then averaging is done using :doc:`fix ave/chunk <fix_ave_chunk>`.
|
||||
Please refer to the :doc:`chunk HOWTO <Howto_chunk>` section for an overview.
|
||||
The i-PI tool has been removed from the LAMMPS distribution. Instead,
|
||||
instructions to install i-PI from PyPI via pip are provided.
|
||||
|
||||
Box command
|
||||
-----------
|
||||
USER-REAXC package
|
||||
------------------
|
||||
|
||||
.. deprecated:: 22Dec2022
|
||||
.. deprecated:: 7Feb2024
|
||||
|
||||
The *box* command has been removed and the LAMMPS code changed so it won't
|
||||
be needed. If present, LAMMPS will ignore the command and print a warning.
|
||||
The USER-REAXC package has been renamed to :ref:`REAXFF <PKG-REAXFF>`.
|
||||
In the process also the pair style and related fixes were renamed to use
|
||||
the "reaxff" string instead of "reax/c". For a while LAMMPS was maintaining
|
||||
backward compatibility by providing aliases for the styles. These have
|
||||
been removed, so using "reaxff" is now *required*.
|
||||
|
||||
Reset_ids, reset_atom_ids, reset_mol_ids commands
|
||||
-------------------------------------------------
|
||||
MPIIO package
|
||||
-------------
|
||||
|
||||
.. deprecated:: 22Dec2022
|
||||
.. deprecated:: 21Nov2023
|
||||
|
||||
The *reset_ids*, *reset_atom_ids*, and *reset_mol_ids* commands have
|
||||
been folded into the :doc:`reset_atoms <reset_atoms>` command. If
|
||||
present, LAMMPS will replace the commands accordingly and print a
|
||||
warning.
|
||||
The MPIIO package has been removed from LAMMPS since it was unmaintained
|
||||
for many years and thus not updated to incorporate required changes that
|
||||
had been applied to the corresponding non-MPIIO commands. As a
|
||||
consequence the MPIIO commands had become unreliable and sometimes
|
||||
crashing LAMMPS or corrupting data. Similar functionality is available
|
||||
through the :ref:`ADIOS package <PKG-ADIOS>` and the :ref:`NETCDF
|
||||
package <PKG-NETCDF>`. Also, the :doc:`dump_modify nfile or dump_modify
|
||||
fileper <dump_modify>` keywords may be used for an efficient way of
|
||||
writing out dump files when running on large numbers of processors.
|
||||
Similarly, the "nfile" and "fileper" keywords exist for restarts:
|
||||
see :doc:`restart <restart>`, :doc:`read_restart <read_restart>`,
|
||||
:doc:`write_restart <write_restart>`.
|
||||
|
||||
MSCG package
|
||||
------------
|
||||
|
||||
.. deprecated:: 21Nov2023
|
||||
|
||||
The MSCG package has been removed from LAMMPS since it was unmaintained
|
||||
for many years and instead superseded by the `OpenMSCG software
|
||||
<https://software.rcc.uchicago.edu/mscg/>`_ of the Voth group at the
|
||||
University of Chicago, which can be used independent from LAMMPS.
|
||||
|
||||
LATTE package
|
||||
-------------
|
||||
@ -64,18 +81,6 @@ packages, including LATTE. See the ``examples/QUANTUM`` dir and the
|
||||
with LATTE as a plugin library (similar to the way fix latte worked), as
|
||||
well as on a different set of MPI processors.
|
||||
|
||||
MEAM package
|
||||
------------
|
||||
|
||||
The MEAM package in Fortran has been replaced by a C++ implementation.
|
||||
The code in the :ref:`MEAM package <PKG-MEAM>` is a translation of the
|
||||
Fortran code of MEAM into C++, which removes several restrictions
|
||||
(e.g. there can be multiple instances in hybrid pair styles) and allows
|
||||
for some optimizations leading to better performance. The pair style
|
||||
:doc:`meam <pair_meam>` has the exact same syntax. For a transition
|
||||
period the C++ version of MEAM was called USER-MEAMC so it could
|
||||
coexist with the Fortran version.
|
||||
|
||||
Minimize style fire/old
|
||||
-----------------------
|
||||
|
||||
@ -97,38 +102,38 @@ The same functionality is available through
|
||||
:doc:`bond style mesocnt <bond_mesocnt>` and
|
||||
:doc:`angle style mesocnt <angle_mesocnt>`.
|
||||
|
||||
MPIIO package
|
||||
-------------
|
||||
Box command
|
||||
-----------
|
||||
|
||||
.. deprecated:: 21Nov2023
|
||||
.. deprecated:: 22Dec2022
|
||||
|
||||
The MPIIO package has been removed from LAMMPS since it was unmaintained
|
||||
for many years and thus not updated to incorporate required changes that
|
||||
had been applied to the corresponding non-MPIIO commands. As a
|
||||
consequence the MPIIO commands had become unreliable and sometimes
|
||||
crashing LAMMPS or corrupting data. Similar functionality is available
|
||||
through the :ref:`ADIOS package <PKG-ADIOS>` and the :ref:`NETCDF
|
||||
package <PKG-NETCDF>`. Also, the :doc:`dump_modify nfile or dump_modify
|
||||
fileper <dump_modify>` keywords may be used for an efficient way of
|
||||
writing out dump files when running on large numbers of processors.
|
||||
Similarly, the "nfile" and "fileper" keywords exist for restarts:
|
||||
see :doc:`restart <restart>`, :doc:`read_restart <read_restart>`,
|
||||
:doc:`write_restart <write_restart>`.
|
||||
The *box* command has been removed and the LAMMPS code changed so it won't
|
||||
be needed. If present, LAMMPS will ignore the command and print a warning.
|
||||
|
||||
Reset_ids, reset_atom_ids, reset_mol_ids commands
|
||||
-------------------------------------------------
|
||||
|
||||
MSCG package
|
||||
------------
|
||||
.. deprecated:: 22Dec2022
|
||||
|
||||
.. deprecated:: 21Nov2023
|
||||
The *reset_ids*, *reset_atom_ids*, and *reset_mol_ids* commands have
|
||||
been folded into the :doc:`reset_atoms <reset_atoms>` command. If
|
||||
present, LAMMPS will replace the commands accordingly and print a
|
||||
warning.
|
||||
|
||||
The MSCG package has been removed from LAMMPS since it was unmaintained
|
||||
for many years and instead superseded by the `OpenMSCG software
|
||||
<https://software.rcc.uchicago.edu/mscg/>`_ of the Voth group at the
|
||||
University of Chicago, which can be used independent from LAMMPS.
|
||||
MESSAGE package
|
||||
---------------
|
||||
|
||||
.. deprecated:: 4May2022
|
||||
|
||||
The MESSAGE package has been removed since it was superseded by the
|
||||
:ref:`MDI package <PKG-MDI>`. MDI implements the same functionality
|
||||
and in a more general way with direct support for more applications.
|
||||
|
||||
REAX package
|
||||
------------
|
||||
|
||||
.. deprecated:: 4Jan2019
|
||||
|
||||
The REAX package has been removed since it was superseded by the
|
||||
:ref:`REAXFF package <PKG-REAXFF>`. The REAXFF package has been tested
|
||||
to yield equivalent results to the REAX package, offers better
|
||||
@ -138,20 +143,25 @@ syntax compatible with the removed reax pair style, so input files will
|
||||
have to be adapted. The REAXFF package was originally called
|
||||
USER-REAXC.
|
||||
|
||||
USER-REAXC package
|
||||
------------------
|
||||
MEAM package
|
||||
------------
|
||||
|
||||
.. deprecated:: 7Feb2024
|
||||
.. deprecated:: 4Jan2019
|
||||
|
||||
The USER-REAXC package has been renamed to :ref:`REAXFF <PKG-REAXFF>`.
|
||||
In the process also the pair style and related fixes were renamed to use
|
||||
the "reaxff" string instead of "reax/c". For a while LAMMPS was maintaining
|
||||
backward compatibility by providing aliases for the styles. These have
|
||||
been removed, so using "reaxff" is now *required*.
|
||||
The MEAM package in Fortran has been replaced by a C++ implementation.
|
||||
The code in the :ref:`MEAM package <PKG-MEAM>` is a translation of the
|
||||
Fortran code of MEAM into C++, which removes several restrictions
|
||||
(e.g. there can be multiple instances in hybrid pair styles) and allows
|
||||
for some optimizations leading to better performance. The pair style
|
||||
:doc:`meam <pair_meam>` has the exact same syntax. For a transition
|
||||
period the C++ version of MEAM was called USER-MEAMC so it could
|
||||
coexist with the Fortran version.
|
||||
|
||||
USER-CUDA package
|
||||
-----------------
|
||||
|
||||
.. deprecated:: 31May2016
|
||||
|
||||
The USER-CUDA package had been removed, since it had been unmaintained
|
||||
for a long time and had known bugs and problems. Significant parts of
|
||||
the design were transferred to the
|
||||
@ -160,19 +170,27 @@ performance characteristics on NVIDIA GPUs. Both, the KOKKOS
|
||||
and the :ref:`GPU package <PKG-GPU>` are maintained
|
||||
and allow running LAMMPS with GPU acceleration.
|
||||
|
||||
i-PI tool
|
||||
---------
|
||||
Fix ave/spatial and fix ave/spatial/sphere
|
||||
------------------------------------------
|
||||
|
||||
.. versionchanged:: 27Jun2024
|
||||
.. deprecated:: 11Dec2015
|
||||
|
||||
The i-PI tool has been removed from the LAMMPS distribution. Instead,
|
||||
instructions to install i-PI from PyPI via pip are provided.
|
||||
The fixes ave/spatial and ave/spatial/sphere have been removed from LAMMPS
|
||||
since they were superseded by the more general and extensible "chunk
|
||||
infrastructure". Here the system is partitioned in one of many possible
|
||||
ways through the :doc:`compute chunk/atom <compute_chunk_atom>` command
|
||||
and then averaging is done using :doc:`fix ave/chunk <fix_ave_chunk>`.
|
||||
Please refer to the :doc:`chunk HOWTO <Howto_chunk>` section for an overview.
|
||||
|
||||
LAMMPS shell
|
||||
------------
|
||||
restart2data tool
|
||||
-----------------
|
||||
|
||||
.. versionchanged:: 29Aug2024
|
||||
.. deprecated:: 23Nov2013
|
||||
|
||||
The LAMMPS shell has been removed from the LAMMPS distribution. Users
|
||||
are encouraged to use the :ref:`LAMMPS-GUI <lammps_gui>` tool instead.
|
||||
The functionality of the restart2data tool has been folded into the
|
||||
LAMMPS executable directly instead of having a separate tool. A
|
||||
combination of the commands :doc:`read_restart <read_restart>` and
|
||||
:doc:`write_data <write_data>` can be used to the same effect. For
|
||||
added convenience this conversion can also be triggered by
|
||||
:doc:`command-line flags <Run_options>`
|
||||
|
||||
|
||||
@ -321,6 +321,8 @@ of the contents of the :f:mod:`LIBLAMMPS` Fortran interface to LAMMPS.
|
||||
:ftype set_string_variable: subroutine
|
||||
:f set_internal_variable: :f:subr:`set_internal_variable`
|
||||
:ftype set_internal_variable: subroutine
|
||||
:f eval: :f:func:`eval`
|
||||
:ftype eval: function
|
||||
:f gather_atoms: :f:subr:`gather_atoms`
|
||||
:ftype gather_atoms: subroutine
|
||||
:f gather_atoms_concat: :f:subr:`gather_atoms_concat`
|
||||
|
||||
@ -64,13 +64,18 @@ simple LAMMPS simulations. It is very suitable for tutorials on LAMMPS
|
||||
since you only need to learn how to use a single program for most tasks
|
||||
and thus time can be saved and people can focus on learning LAMMPS.
|
||||
The tutorials at https://lammpstutorials.github.io/ are specifically
|
||||
updated for use with LAMMPS-GUI.
|
||||
updated for use with LAMMPS-GUI and can their tutorial materials can
|
||||
be downloaded and loaded directly from the GUI.
|
||||
|
||||
Another design goal is to keep the barrier low when replacing part of
|
||||
the functionality of LAMMPS-GUI with external tools. That said, LAMMPS-GUI
|
||||
has some unique functionality that is not found elsewhere:
|
||||
|
||||
- auto-adapting to features available in the integrated LAMMPS library
|
||||
- auto-completion for LAMMPS commands and options
|
||||
- context-sensitive online help
|
||||
- start and stop of simulations via mouse or keyboard
|
||||
- monitoring of simulation progress
|
||||
- interactive visualization using the :doc:`dump image <dump_image>`
|
||||
command with the option to copy-paste the resulting settings
|
||||
- automatic slide show generation from dump image out at runtime
|
||||
|
||||
@ -7,6 +7,7 @@ This section documents the following functions:
|
||||
- :cpp:func:`lammps_command`
|
||||
- :cpp:func:`lammps_commands_list`
|
||||
- :cpp:func:`lammps_commands_string`
|
||||
- :cpp:func:`lammps_expand`
|
||||
|
||||
--------------------
|
||||
|
||||
@ -79,3 +80,8 @@ Below is a short example using some of these functions.
|
||||
.. doxygenfunction:: lammps_commands_string
|
||||
:project: progguide
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_expand
|
||||
:project: progguide
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
Compute, fixes, variables
|
||||
=========================
|
||||
Computes, fixes, variables
|
||||
==========================
|
||||
|
||||
This section documents accessing or modifying data stored by computes,
|
||||
fixes, or variables in LAMMPS using the following functions:
|
||||
@ -12,6 +12,7 @@ fixes, or variables in LAMMPS using the following functions:
|
||||
- :cpp:func:`lammps_set_string_variable`
|
||||
- :cpp:func:`lammps_set_internal_variable`
|
||||
- :cpp:func:`lammps_variable_info`
|
||||
- :cpp:func:`lammps_eval`
|
||||
|
||||
-----------------------
|
||||
|
||||
@ -55,6 +56,11 @@ fixes, or variables in LAMMPS using the following functions:
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_eval
|
||||
:project: progguide
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenenum:: _LMP_DATATYPE_CONST
|
||||
|
||||
.. doxygenenum:: _LMP_STYLE_CONST
|
||||
|
||||
@ -26,6 +26,29 @@ Syntax
|
||||
*nowait* arg = *on* or *off*
|
||||
off = LAMMPS waits to be connected to an IMD client before continuing (default)
|
||||
on = LAMMPS listens for an IMD client, but continues with the run
|
||||
*version* arg = *2* or *3*
|
||||
2 = use IMD protocol version 2 (default)
|
||||
3 = use IMD protocol version 3.
|
||||
|
||||
The following keywords are only supported for IMD protocol version 3.
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
*time* arg = *on* or *off*
|
||||
off = simulation time is not transmitted (default)
|
||||
on = simulation time is transmitted.
|
||||
*box* arg = *on* or *off*
|
||||
off = simulation box data is not transmitted (default)
|
||||
on = simulation box data is transmitted.
|
||||
*coordinates* arg = *on* or *off*
|
||||
off = atomic coordinates are not transmitted (default)
|
||||
on = atomic coordinates are transmitted.
|
||||
*velocities* arg = *on* or *off*
|
||||
off = atomic velocities are not transmitted (default)
|
||||
on = atomic velocities are transmitted.
|
||||
*forces* arg = *on* or *off*
|
||||
off = atomic forces are not transmitted (default)
|
||||
on = atomic forces are transmitted.
|
||||
|
||||
Examples
|
||||
""""""""
|
||||
@ -40,16 +63,19 @@ Description
|
||||
|
||||
This fix implements the "Interactive MD" (IMD) protocol which allows
|
||||
realtime visualization and manipulation of MD simulations through the
|
||||
IMD protocol, as initially implemented in VMD and NAMD. Specifically
|
||||
it allows LAMMPS to connect an IMD client, for example the `VMD visualization program <VMD_>`_, so that it can monitor the progress of the
|
||||
simulation and interactively apply forces to selected atoms.
|
||||
IMD protocol, as initially implemented in VMD and NAMD. Specifically it
|
||||
allows LAMMPS to connect an IMD client, for example the `VMD
|
||||
visualization program <VMD_>`_ (currently only supports IMDv2) or the
|
||||
`Python IMDClient <IMDClient_>`_ (supports both IMDv2 and IMDv3), so
|
||||
that it can monitor the progress of the simulation and interactively
|
||||
apply forces to selected atoms.
|
||||
|
||||
If LAMMPS is compiled with the pre-processor flag -DLAMMPS_ASYNC_IMD
|
||||
then fix imd will use POSIX threads to spawn a IMD communication
|
||||
thread on MPI rank 0 in order to offload data reading and writing
|
||||
from the main execution thread and potentially lower the inferred
|
||||
latencies for slow communication links. This feature has only been
|
||||
tested under linux.
|
||||
If LAMMPS is compiled with the pre-processor flag
|
||||
:ref:`-DLAMMPS_ASYNC_IMD <misc>` then fix imd will use POSIX threads to
|
||||
spawn an IMD communication thread on MPI rank 0 in order to offload data
|
||||
exchange with the IMD client from the main execution thread and
|
||||
potentially lower the inferred latencies for slow communication
|
||||
links. This feature has only been tested under linux.
|
||||
|
||||
The source code for this fix includes code developed by the Theoretical
|
||||
and Computational Biophysics Group in the Beckman Institute for Advanced
|
||||
@ -94,6 +120,15 @@ with different units or as a measure to tweak the forces generated by
|
||||
the manipulation of the IMD client, this option allows to make
|
||||
adjustments.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
In `IMDv3 <IMDv3_>`_, the IMD protocol has been extended to allow for
|
||||
the transmission of simulation time, box dimensions, atomic coordinates,
|
||||
velocities, and forces. The *version* keyword allows to select the
|
||||
version of the protocol to be used. The *time*, *box*, *coordinates*,
|
||||
*velocities*, and *forces* keywords allow to select which data is
|
||||
transmitted to the IMD client. The default is to transmit all data.
|
||||
|
||||
To connect VMD to a listening LAMMPS simulation on the same machine
|
||||
with fix imd enabled, one needs to start VMD and load a coordinate or
|
||||
topology file that matches the fix group. When the VMD command
|
||||
@ -129,6 +164,10 @@ screen output is active.
|
||||
|
||||
.. _imdvmd: https://www.ks.uiuc.edu/Research/vmd/imd/
|
||||
|
||||
.. _IMDClient: https://github.com/Becksteinlab/imdclient/tree/main/imdclient
|
||||
|
||||
.. _IMDv3: https://imdclient.readthedocs.io/en/latest/protocol_v3.html
|
||||
|
||||
Restart, fix_modify, output, run start/stop, minimize info
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
@ -147,14 +186,14 @@ This fix is part of the MISC package. It is only enabled if LAMMPS was
|
||||
built with that package. See the :doc:`Build package <Build_package>`
|
||||
page for more info.
|
||||
|
||||
When used in combination with VMD, a topology or coordinate file has
|
||||
to be loaded, which matches (in number and ordering of atoms) the
|
||||
group the fix is applied to. The fix internally sorts atom IDs by
|
||||
ascending integer value; in VMD (and thus the IMD protocol) those will
|
||||
be assigned 0-based consecutive index numbers.
|
||||
When used in combination with VMD, a topology or coordinate file has to
|
||||
be loaded, which matches (in number and ordering of atoms) the group the
|
||||
fix is applied to. The fix internally sorts atom IDs by ascending
|
||||
integer value; in VMD (and thus the IMD protocol) those will be assigned
|
||||
0-based consecutive index numbers.
|
||||
|
||||
When using multiple active IMD connections at the same time, each
|
||||
needs to use a different port number.
|
||||
fix instance needs to use a different port number.
|
||||
|
||||
Related commands
|
||||
""""""""""""""""
|
||||
|
||||
@ -117,6 +117,7 @@ liblammpsplugin_t *liblammpsplugin_load(const char *lib)
|
||||
ADDSYM(set_string_variable);
|
||||
ADDSYM(set_internal_variable);
|
||||
ADDSYM(variable_info);
|
||||
ADDSYM(eval);
|
||||
|
||||
ADDSYM(gather_atoms);
|
||||
ADDSYM(gather_atoms_concat);
|
||||
|
||||
@ -163,6 +163,7 @@ struct _liblammpsplugin {
|
||||
int (*set_string_variable)(void *, const char *, const char *);
|
||||
int (*set_internal_variable)(void *, const char *, double);
|
||||
int (*variable_info)(void *, int, char *, int);
|
||||
double (*eval)(void *, const char *);
|
||||
|
||||
void (*gather_atoms)(void *, const char *, int, int, void *);
|
||||
void (*gather_atoms_concat)(void *, const char *, int, int, void *);
|
||||
|
||||
13
examples/PACKAGES/imd/deca-ala-solv_imd_v3.py
Normal file
13
examples/PACKAGES/imd/deca-ala-solv_imd_v3.py
Normal file
@ -0,0 +1,13 @@
|
||||
"""
|
||||
For use with 'in.deca-ala-solv_imd_v3'.
|
||||
|
||||
Tested with imdclient v0.1.4 and MDAnalysis v2.8.0
|
||||
"""
|
||||
from imdclient.IMD import IMDReader
|
||||
import MDAnalysis as mda
|
||||
|
||||
u = mda.Universe('data.deca-ala-solv', "imd://localhost:5678", topology_format='DATA')
|
||||
|
||||
for ts in u.trajectory:
|
||||
print(ts.time)
|
||||
print(ts.velocities)
|
||||
31
examples/PACKAGES/imd/in.deca-ala-solv_imd_v3
Normal file
31
examples/PACKAGES/imd/in.deca-ala-solv_imd_v3
Normal file
@ -0,0 +1,31 @@
|
||||
#
|
||||
units real
|
||||
neighbor 2.5 bin
|
||||
neigh_modify delay 1 every 1
|
||||
|
||||
atom_style full
|
||||
bond_style harmonic
|
||||
angle_style charmm
|
||||
dihedral_style charmm
|
||||
improper_style harmonic
|
||||
|
||||
pair_style lj/charmm/coul/long 8 10
|
||||
pair_modify mix arithmetic
|
||||
special_bonds charmm
|
||||
read_data data.deca-ala-solv
|
||||
|
||||
|
||||
group peptide id <= 103
|
||||
fix rigidh all shake 1e-6 100 1000 t 1 2 3 4 5 a 23
|
||||
|
||||
thermo 100
|
||||
thermo_style multi
|
||||
timestep 2.0
|
||||
kspace_style pppm 1e-5
|
||||
|
||||
fix ensemble all npt temp 300.0 300.0 100.0 iso 1.0 1.0 1000.0 drag 0.2
|
||||
|
||||
# IMD setup. Client code available in 'deca-ala-solv_imd_v3.py'
|
||||
fix comm all imd 5678 unwrap on trate 10 version 3 time on box on coordinates on velocities on forces off
|
||||
|
||||
run 5000000
|
||||
@ -126,6 +126,7 @@ MODULE LIBLAMMPS
|
||||
PROCEDURE :: set_variable => lmp_set_variable
|
||||
PROCEDURE :: set_string_variable => lmp_set_string_variable
|
||||
PROCEDURE :: set_internal_variable => lmp_set_internal_variable
|
||||
PROCEDURE :: eval => lmp_eval
|
||||
PROCEDURE, PRIVATE :: lmp_gather_atoms_int
|
||||
PROCEDURE, PRIVATE :: lmp_gather_atoms_double
|
||||
GENERIC :: gather_atoms => lmp_gather_atoms_int, &
|
||||
@ -618,7 +619,14 @@ MODULE LIBLAMMPS
|
||||
INTEGER(c_int) :: lammps_set_internal_variable
|
||||
END FUNCTION lammps_set_internal_variable
|
||||
|
||||
SUBROUTINE lammps_gather_atoms(handle, name, type, count, data) BIND(C)
|
||||
FUNCTION lammps_eval(handle, expr) BIND(C)
|
||||
IMPORT :: c_ptr, c_double
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle, expr
|
||||
REAL(c_double) :: lammps_eval
|
||||
END FUNCTION lammps_eval
|
||||
|
||||
SUBROUTINE lammps_gather_atoms(handle, name, TYPE, count, DATA) BIND(C)
|
||||
IMPORT :: c_int, c_ptr
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle, name, data
|
||||
@ -1812,7 +1820,7 @@ CONTAINS
|
||||
SUBROUTINE lmp_set_internal_variable(self, name, val)
|
||||
CLASS(lammps), INTENT(IN) :: self
|
||||
CHARACTER(LEN=*), INTENT(IN) :: name
|
||||
REAL(KIND=c_double), INTENT(IN) :: val
|
||||
REAL(c_double), INTENT(IN) :: val
|
||||
INTEGER :: err
|
||||
TYPE(c_ptr) :: Cname
|
||||
|
||||
@ -1826,6 +1834,18 @@ CONTAINS
|
||||
END IF
|
||||
END SUBROUTINE lmp_set_internal_variable
|
||||
|
||||
! equivalent function to lammps_eval
|
||||
FUNCTION lmp_eval(self, expr)
|
||||
CLASS(lammps), INTENT(IN) :: self
|
||||
CHARACTER(LEN=*), INTENT(IN) :: expr
|
||||
REAL(c_double) :: lmp_eval
|
||||
TYPE(c_ptr) :: Cexpr
|
||||
|
||||
Cexpr = f2c_string(expr)
|
||||
lmp_eval = lammps_eval(self%handle, Cexpr)
|
||||
CALL lammps_free(Cexpr)
|
||||
END FUNCTION lmp_eval
|
||||
|
||||
! equivalent function to lammps_gather_atoms (for integers)
|
||||
SUBROUTINE lmp_gather_atoms_int(self, name, count, data)
|
||||
CLASS(lammps), INTENT(IN) :: self
|
||||
|
||||
@ -103,7 +103,7 @@ class command_wrapper(object):
|
||||
This method is where the Python 'magic' happens. If a method is not
|
||||
defined by the class command_wrapper, it assumes it is a LAMMPS command. It takes
|
||||
all the arguments, concatinates them to a single string, and executes it using
|
||||
:py:meth:`lammps.command()`.
|
||||
:py:meth:`lammps.command`.
|
||||
|
||||
Starting with Python 3.6 it also supports keyword arguments. key=value is
|
||||
transformed into 'key value'. Note, since these have come last in the
|
||||
@ -426,6 +426,9 @@ class lammps(object):
|
||||
self.lib.lammps_compute_addstep.argtype = [c_void_p, self.c_bigint]
|
||||
self.lib.lammps_compute_addstep_all.argtype = [c_void_p, self.c_bigint]
|
||||
|
||||
self.lib.lammps_eval.argtypes = [c_void_p, c_char_p]
|
||||
self.lib.lammps_eval.restype = c_double
|
||||
|
||||
self.lib.lammps_fix_external_get_force.argtypes = [c_void_p, c_char_p]
|
||||
self.lib.lammps_fix_external_get_force.restype = POINTER(POINTER(c_double))
|
||||
|
||||
@ -1693,6 +1696,30 @@ class lammps(object):
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def eval(self, expr):
|
||||
""" Evaluate a LAMMPS immediate variable expression
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
This function is a wrapper around the function :cpp:func:`lammps_eval`
|
||||
of the C library interface. It evaluates and expression like in
|
||||
immediate variables and returns the value.
|
||||
|
||||
:param expr: immediate variable expression
|
||||
:type name: string
|
||||
:return: the result of the evaluation
|
||||
:rtype: c_double
|
||||
"""
|
||||
|
||||
if expr: newexpr = expr.encode()
|
||||
else: return None
|
||||
|
||||
with ExceptionCheck(self):
|
||||
return self.lib.lammps_eval(self.lmp, newexpr)
|
||||
return None
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# return vector of atom properties gathered across procs
|
||||
# 3 variants to match src/library.cpp
|
||||
# name = atom property recognized by LAMMPS in atom->extract()
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
################################################################################
|
||||
|
||||
class wrapper(object):
|
||||
"""lammps API IPython Wrapper
|
||||
""" lammps API IPython Wrapper
|
||||
|
||||
This is a wrapper class that provides additional methods on top of an
|
||||
existing :py:class:`lammps` instance. It provides additional methods
|
||||
|
||||
@ -63,6 +63,8 @@ void ComputeReaxFFAtomKokkos<DeviceType>::init()
|
||||
template<class DeviceType>
|
||||
void ComputeReaxFFAtomKokkos<DeviceType>::compute_bonds()
|
||||
{
|
||||
invoked_bonds = update->ntimestep;
|
||||
|
||||
if (atom->nmax > nmax) {
|
||||
memory->destroy(array_atom);
|
||||
nmax = atom->nmax;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -56,6 +56,9 @@ FixStyle(imd,FixIMD);
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
/* IMDv3 session information */
|
||||
struct IMDSessionInfo;
|
||||
|
||||
/* prototype for c wrapper that calls the real worker */
|
||||
extern "C" void *fix_imd_ioworker(void *);
|
||||
|
||||
@ -69,8 +72,12 @@ class FixIMD : public Fix {
|
||||
void init() override;
|
||||
void setup(int) override;
|
||||
void post_force(int) override;
|
||||
void end_of_step() override;
|
||||
void post_force_respa(int, int, int) override;
|
||||
double memory_usage() override;
|
||||
// Fix nevery at 1, use trate to skip in 'end_of_step`
|
||||
int nevery = 1;
|
||||
int imd_version; // version of the IMD protocol to be used.
|
||||
|
||||
protected:
|
||||
int imd_port;
|
||||
@ -80,13 +87,15 @@ class FixIMD : public Fix {
|
||||
int num_coords; // total number of atoms controlled by this fix
|
||||
int size_one; // bytes per atom in communication buffer.
|
||||
int maxbuf; // size of atom communication buffer.
|
||||
void *comm_buf; // communication buffer
|
||||
void *coord_data; // communication buffer for coordinates
|
||||
void *vel_data; // communication buffer for velocities
|
||||
void *force_data; // communication buffer for forces
|
||||
void *idmap; // hash for mapping atom indices to consistent order.
|
||||
tagint *rev_idmap; // list of the hash keys for reverse mapping.
|
||||
|
||||
int imd_forces; // number of forces communicated via IMD.
|
||||
void *force_buf; // force data buffer
|
||||
double imd_fscale; // scale factor for forces. in case VMD's units are off.
|
||||
int imd_forces; // number of forces communicated via IMD.
|
||||
void *recv_force_buf; // force data buffer
|
||||
double imd_fscale; // scale factor for forces. in case VMD's units are off.
|
||||
|
||||
int imd_inactive; // true if IMD connection stopped.
|
||||
int imd_terminate; // true if IMD requests termination of run.
|
||||
@ -96,12 +105,22 @@ class FixIMD : public Fix {
|
||||
int nowait_flag; // true if LAMMPS should not wait with the execution for VMD.
|
||||
int connect_msg; // flag to indicate whether a "listen for connection message" is needed.
|
||||
|
||||
/* IMDv3-only */
|
||||
IMDSessionInfo *imdsinfo; // session information for IMDv3
|
||||
|
||||
int me; // my MPI rank in this "world".
|
||||
int nlevels_respa; // flag to determine respa levels.
|
||||
|
||||
int msglen;
|
||||
char *msgdata;
|
||||
|
||||
private:
|
||||
void setup_v2();
|
||||
void setup_v3();
|
||||
void handle_step_v2();
|
||||
void handle_client_input_v3();
|
||||
void handle_output_v3();
|
||||
|
||||
#if defined(LAMMPS_ASYNC_IMD)
|
||||
int buf_has_data; // flag to indicate to the i/o thread what to do.
|
||||
pthread_mutex_t write_mutex; // mutex for sending coordinates to i/o thread
|
||||
|
||||
@ -41,6 +41,9 @@ using namespace LAMMPS_NS;
|
||||
using namespace FixConst;
|
||||
|
||||
static constexpr double QSUMSMALL = 0.00001;
|
||||
static constexpr int MIN_CAP = 50;
|
||||
static constexpr double SAFE_ZONE = 1.2;
|
||||
static constexpr bigint MIN_NBRS = 100;
|
||||
|
||||
namespace {
|
||||
class qeq_parser_error : public std::exception {
|
||||
|
||||
@ -16,12 +16,6 @@
|
||||
|
||||
#include "fix.h"
|
||||
|
||||
#define EV_TO_KCAL_PER_MOL 14.4
|
||||
#define DANGER_ZONE 0.90
|
||||
#define MIN_CAP 50
|
||||
#define SAFE_ZONE 1.2
|
||||
#define MIN_NBRS 100
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class FixQEq : public Fix {
|
||||
@ -36,6 +30,7 @@ class FixQEq : public Fix {
|
||||
void min_pre_force(int) override;
|
||||
|
||||
double compute_scalar() override;
|
||||
static constexpr double DANGER_ZONE = 0.90;
|
||||
|
||||
// derived child classes must provide these functions
|
||||
|
||||
|
||||
@ -33,6 +33,8 @@
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
static constexpr double EV_TO_KCAL_PER_MOL = 14.4;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
FixQEqShielded::FixQEqShielded(LAMMPS *lmp, int narg, char **arg) : FixQEq(lmp, narg, arg)
|
||||
|
||||
@ -121,9 +121,9 @@ void Finish::end(int flag)
|
||||
MPI_Allreduce(&cpu_loop,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
|
||||
cpu_loop = tmp/nprocs;
|
||||
if (time_loop > 0.0) cpu_loop = cpu_loop/time_loop*100.0;
|
||||
output->thermo->footer();
|
||||
|
||||
if (me == 0) {
|
||||
output->thermo->footer();
|
||||
int ntasks = nprocs * nthreads;
|
||||
utils::logmesg(lmp,"Loop time of {:.6g} on {} procs for {} steps with {} atoms\n\n",
|
||||
time_loop,ntasks,update->nsteps,atom->natoms);
|
||||
|
||||
@ -208,14 +208,14 @@ FixDeposit::FixDeposit(LAMMPS *lmp, int narg, char **arg) :
|
||||
FixDeposit::~FixDeposit()
|
||||
{
|
||||
delete random;
|
||||
delete [] molfrac;
|
||||
delete [] idrigid;
|
||||
delete [] idshake;
|
||||
delete [] idregion;
|
||||
delete [] vstr;
|
||||
delete [] xstr;
|
||||
delete [] ystr;
|
||||
delete [] zstr;
|
||||
delete[] molfrac;
|
||||
delete[] idrigid;
|
||||
delete[] idshake;
|
||||
delete[] idregion;
|
||||
delete[] vstr;
|
||||
delete[] xstr;
|
||||
delete[] ystr;
|
||||
delete[] zstr;
|
||||
memory->destroy(coords);
|
||||
memory->destroy(imageflags);
|
||||
}
|
||||
@ -737,7 +737,7 @@ void FixDeposit::options(int narg, char **arg)
|
||||
mode = MOLECULE;
|
||||
onemols = &atom->molecules[imol];
|
||||
nmol = onemols[0]->nset;
|
||||
delete [] molfrac;
|
||||
delete[] molfrac;
|
||||
molfrac = new double[nmol];
|
||||
molfrac[0] = 1.0/nmol;
|
||||
for (int i = 1; i < nmol-1; i++) molfrac[i] = molfrac[i-1] + 1.0/nmol;
|
||||
@ -755,13 +755,13 @@ void FixDeposit::options(int narg, char **arg)
|
||||
iarg += nmol+1;
|
||||
} else if (strcmp(arg[iarg],"rigid") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix deposit command");
|
||||
delete [] idrigid;
|
||||
delete[] idrigid;
|
||||
idrigid = utils::strdup(arg[iarg+1]);
|
||||
rigidflag = 1;
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"shake") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix deposit command");
|
||||
delete [] idshake;
|
||||
delete[] idshake;
|
||||
idshake = utils::strdup(arg[iarg+1]);
|
||||
shakeflag = 1;
|
||||
iarg += 2;
|
||||
|
||||
@ -516,6 +516,9 @@ treated as part of the command and will **not** start a second command.
|
||||
The function returns the expanded string in a new string buffer that
|
||||
must be freed with :cpp:func:`lammps_free` after use to avoid a memory leak.
|
||||
|
||||
*See also*
|
||||
:cpp:func:`lammps_eval`
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance
|
||||
@ -850,7 +853,11 @@ This differs from :cpp:func:`lammps_get_thermo` in that it does **not**
|
||||
trigger an evaluation. Instead it provides direct access to a read-only
|
||||
location of the last thermo output data and the corresponding keyword
|
||||
strings. How to handle the return value depends on the value of the *what*
|
||||
argument string.
|
||||
argument string. When accessing the data from a concurrent thread while
|
||||
LAMMPS is running, the cache needs to be locked first and then unlocked
|
||||
after the data is obtained, so that the data is not corrupted while
|
||||
reading in case LAMMPS wants to update it at the same time. Outside
|
||||
of a run, the lock/unlock calls have no effect.
|
||||
|
||||
.. note::
|
||||
|
||||
@ -899,6 +906,14 @@ argument string.
|
||||
- actual field data for column
|
||||
- pointer to int, int64_t or double
|
||||
- yes
|
||||
* - lock
|
||||
- acquires lock to thermo data cache
|
||||
- NULL pointer
|
||||
- no
|
||||
* - unlock
|
||||
- releases lock to thermo data cache
|
||||
- NULL pointer
|
||||
- no
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
@ -954,8 +969,14 @@ void *lammps_last_thermo(void *handle, const char *what, int index)
|
||||
} else if (field.type == multitype::LAMMPS_DOUBLE) {
|
||||
val = (void *) &field.data.d;
|
||||
}
|
||||
|
||||
} else if (strcmp(what, "lock") == 0) {
|
||||
th->lock_cache();
|
||||
val = nullptr;
|
||||
} else if (strcmp(what, "unlock") == 0) {
|
||||
th->unlock_cache();
|
||||
val = nullptr;
|
||||
} else val = nullptr;
|
||||
|
||||
}
|
||||
END_CAPTURE
|
||||
return val;
|
||||
@ -2906,6 +2927,41 @@ int lammps_variable_info(void *handle, int idx, char *buffer, int buf_size) {
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Evaluate an immediate variable expression
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
This function takes a string with an expression that can be used
|
||||
for :doc:`equal style variables <variable>`, evaluates it and returns
|
||||
the resulting (scalar) value as a floating point number.
|
||||
|
||||
*See also*
|
||||
:cpp:func:`lammps_expand`
|
||||
|
||||
\endverbatim
|
||||
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
* \param expr string with expression
|
||||
* \return result from expression */
|
||||
|
||||
double lammps_eval(void *handle, const char *expr)
|
||||
{
|
||||
auto lmp = (LAMMPS *) handle;
|
||||
double result = 0.0;
|
||||
|
||||
BEGIN_CAPTURE
|
||||
{
|
||||
result = lmp->input->variable->compute_equal(expr);
|
||||
}
|
||||
END_CAPTURE
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Clear whether a compute has been invoked.
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
@ -189,6 +189,7 @@ int lammps_set_variable(void *handle, const char *name, const char *str);
|
||||
int lammps_set_string_variable(void *handle, const char *name, const char *str);
|
||||
int lammps_set_internal_variable(void *handle, const char *name, double value);
|
||||
int lammps_variable_info(void *handle, int idx, char *buf, int bufsize);
|
||||
double lammps_eval(void *handle, const char *expr);
|
||||
|
||||
void lammps_compute_clearstep(void * handle);
|
||||
#if defined(LAMMPS_SMALLSMALL)
|
||||
|
||||
@ -100,8 +100,8 @@ static char fmtbuf[512];
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
Thermo::Thermo(LAMMPS *_lmp, int narg, char **arg) :
|
||||
Pointers(_lmp), style(nullptr), vtype(nullptr), field2index(nullptr), argindex1(nullptr),
|
||||
argindex2(nullptr), temperature(nullptr), pressure(nullptr), pe(nullptr)
|
||||
Pointers(_lmp), style(nullptr), vtype(nullptr), cache_mutex(nullptr), field2index(nullptr),
|
||||
argindex1(nullptr), argindex2(nullptr), temperature(nullptr), pressure(nullptr), pe(nullptr)
|
||||
{
|
||||
style = utils::strdup(arg[0]);
|
||||
|
||||
@ -208,6 +208,7 @@ void Thermo::init()
|
||||
ValueTokenizer *format_line = nullptr;
|
||||
if (format_line_user.size()) format_line = new ValueTokenizer(format_line_user);
|
||||
|
||||
lock_cache();
|
||||
field_data.clear();
|
||||
field_data.resize(nfield);
|
||||
std::string format_this, format_line_user_def;
|
||||
@ -277,6 +278,7 @@ void Thermo::init()
|
||||
format[i] += fmt::format("{:<8} = {} ", keyword[i], format_this);
|
||||
}
|
||||
}
|
||||
unlock_cache();
|
||||
|
||||
// chop off trailing blank or add closing bracket if needed and then add newline
|
||||
if (lineflag == ONELINE)
|
||||
@ -320,6 +322,9 @@ void Thermo::init()
|
||||
if (index_press_scalar >= 0) pressure = computes[index_press_scalar];
|
||||
if (index_press_vector >= 0) pressure = computes[index_press_vector];
|
||||
if (index_pe >= 0) pe = computes[index_pe];
|
||||
|
||||
// create mutex to protect access to cached thermo data
|
||||
cache_mutex = new std::mutex;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -366,9 +371,17 @@ void Thermo::header()
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
// called at the end of a run from Finish class
|
||||
|
||||
void Thermo::footer()
|
||||
{
|
||||
if (lineflag == YAMLLINE) utils::logmesg(lmp, "...\n");
|
||||
if (comm->me == 0) {
|
||||
if (lineflag == YAMLLINE) utils::logmesg(lmp, "...\n");
|
||||
}
|
||||
|
||||
// no more locking for cached thermo data access needed
|
||||
delete cache_mutex;
|
||||
cache_mutex = nullptr;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -422,6 +435,7 @@ void Thermo::compute(int flag)
|
||||
}
|
||||
|
||||
// add each thermo value to line with its specific format
|
||||
lock_cache();
|
||||
field_data.clear();
|
||||
field_data.resize(nfield);
|
||||
|
||||
@ -441,6 +455,7 @@ void Thermo::compute(int flag)
|
||||
field_data[ifield] = bivalue;
|
||||
}
|
||||
}
|
||||
unlock_cache();
|
||||
|
||||
// print line to screen and logfile
|
||||
|
||||
@ -579,7 +594,8 @@ void Thermo::modify_params(int narg, char **arg)
|
||||
if (iarg + 2 > narg) error->all(FLERR, "Illegal thermo_modify command");
|
||||
triclinic_general = utils::logical(FLERR, arg[iarg + 1], false, lmp);
|
||||
if (triclinic_general && !domain->triclinic_general)
|
||||
error->all(FLERR,"Thermo_modify triclinic/general cannot be used "
|
||||
error->all(FLERR,
|
||||
"Thermo_modify triclinic/general cannot be used "
|
||||
"if simulation box is not general triclinic");
|
||||
iarg += 2;
|
||||
|
||||
@ -1566,6 +1582,26 @@ int Thermo::evaluate_keyword(const std::string &word, double *answer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
// lock cache for current thermo data
|
||||
|
||||
void Thermo::lock_cache()
|
||||
{
|
||||
// no locking outside of a run
|
||||
if (!cache_mutex) return;
|
||||
cache_mutex->lock();
|
||||
}
|
||||
|
||||
// unlock cache for current thermo data
|
||||
|
||||
void Thermo::unlock_cache()
|
||||
{
|
||||
// no locking outside of a run
|
||||
if (!cache_mutex) return;
|
||||
cache_mutex->unlock();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
extraction of Compute, Fix, Variable results
|
||||
compute/fix are normalized by atoms if returning extensive value
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
|
||||
#include "pointers.h"
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
@ -43,6 +44,8 @@ class Thermo : protected Pointers {
|
||||
int evaluate_keyword(const std::string &, double *);
|
||||
|
||||
// for accessing cached thermo and related data
|
||||
void lock_cache();
|
||||
void unlock_cache();
|
||||
const int *get_line() const { return &nline; }
|
||||
const char *get_image_fname() const { return image_fname.c_str(); }
|
||||
|
||||
@ -82,6 +85,9 @@ class Thermo : protected Pointers {
|
||||
int nline;
|
||||
std::string image_fname;
|
||||
|
||||
// mutex for locking the cache
|
||||
std::mutex *cache_mutex;
|
||||
|
||||
// data used by routines that compute single values
|
||||
|
||||
int ivalue; // integer value to print
|
||||
|
||||
@ -457,15 +457,21 @@ void Variable::set(int narg, char **arg)
|
||||
// data = 2 values, 1st is string to eval, 2nd is filled on retrieval
|
||||
|
||||
} else if (strcmp(arg[1],"equal") == 0) {
|
||||
if (narg != 3)
|
||||
error->all(FLERR,"Illegal variable command: expected 3 arguments but found {}{}",
|
||||
narg, utils::errorurl(3));
|
||||
if (narg < 3) utils::missing_cmd_args(FLERR, "variable equal", error);
|
||||
|
||||
// combine excess arguments into single string with a blank as separator
|
||||
std::string combined = arg[2];
|
||||
for (int iarg = 3; iarg < narg; ++iarg) {
|
||||
combined += ' ';
|
||||
combined += arg[iarg];
|
||||
}
|
||||
|
||||
int ivar = find(arg[0]);
|
||||
if (ivar >= 0) {
|
||||
if (style[ivar] != EQUAL)
|
||||
error->all(FLERR,"Cannot redefine variable as a different style");
|
||||
delete[] data[ivar][0];
|
||||
data[ivar][0] = utils::strdup(arg[2]);
|
||||
data[ivar][0] = utils::strdup(combined);
|
||||
replaceflag = 1;
|
||||
} else {
|
||||
if (nvar == maxvar) grow();
|
||||
@ -474,7 +480,7 @@ void Variable::set(int narg, char **arg)
|
||||
which[nvar] = 0;
|
||||
pad[nvar] = 0;
|
||||
data[nvar] = new char*[num[nvar]];
|
||||
data[nvar][0] = utils::strdup(arg[2]);
|
||||
data[nvar][0] = utils::strdup(combined);
|
||||
data[nvar][1] = new char[VALUELENGTH];
|
||||
strcpy(data[nvar][1],"(undefined)");
|
||||
}
|
||||
@ -485,15 +491,21 @@ void Variable::set(int narg, char **arg)
|
||||
// data = 1 value, string to eval
|
||||
|
||||
} else if (strcmp(arg[1],"atom") == 0) {
|
||||
if (narg != 3)
|
||||
error->all(FLERR,"Illegal variable command: expected 3 arguments but found {}{}",
|
||||
narg, utils::errorurl(3));
|
||||
if (narg < 3) utils::missing_cmd_args(FLERR, "variable atom", error);
|
||||
|
||||
// combine excess arguments into single string with a blank as separator
|
||||
std::string combined = arg[2];
|
||||
for (int iarg = 3; iarg < narg; ++iarg) {
|
||||
combined += ' ';
|
||||
combined += arg[iarg];
|
||||
}
|
||||
|
||||
int ivar = find(arg[0]);
|
||||
if (ivar >= 0) {
|
||||
if (style[ivar] != ATOM)
|
||||
error->all(FLERR,"Cannot redefine variable as a different style");
|
||||
delete[] data[ivar][0];
|
||||
data[ivar][0] = utils::strdup(arg[2]);
|
||||
data[ivar][0] = utils::strdup(combined);
|
||||
replaceflag = 1;
|
||||
} else {
|
||||
if (nvar == maxvar) grow();
|
||||
@ -502,7 +514,7 @@ void Variable::set(int narg, char **arg)
|
||||
which[nvar] = 0;
|
||||
pad[nvar] = 0;
|
||||
data[nvar] = new char*[num[nvar]];
|
||||
data[nvar][0] = utils::strdup(arg[2]);
|
||||
data[nvar][0] = utils::strdup(combined);
|
||||
}
|
||||
|
||||
// VECTOR
|
||||
@ -513,16 +525,22 @@ void Variable::set(int narg, char **arg)
|
||||
// immediately store it as N-length vector and set dynamic flag to 0
|
||||
|
||||
} else if (strcmp(arg[1],"vector") == 0) {
|
||||
if (narg != 3)
|
||||
error->all(FLERR,"Illegal variable command: expected 3 arguments but found {}{}",
|
||||
narg, utils::errorurl(3));
|
||||
if (narg < 3) utils::missing_cmd_args(FLERR, "variable atom", error);
|
||||
|
||||
// combine excess arguments into single string with a blank as separator
|
||||
std::string combined = arg[2];
|
||||
for (int iarg = 3; iarg < narg; ++iarg) {
|
||||
combined += ' ';
|
||||
combined += arg[iarg];
|
||||
}
|
||||
|
||||
int ivar = find(arg[0]);
|
||||
if (ivar >= 0) {
|
||||
if (style[ivar] != VECTOR)
|
||||
error->all(FLERR,"Cannot redefine variable as a different style");
|
||||
delete[] data[ivar][0];
|
||||
delete[] data[ivar][1];
|
||||
data[ivar][0] = utils::strdup(arg[2]);
|
||||
data[ivar][0] = utils::strdup(combined);
|
||||
if (data[ivar][0][0] != '[')
|
||||
vecs[ivar].dynamic = 1;
|
||||
else {
|
||||
@ -539,7 +557,7 @@ void Variable::set(int narg, char **arg)
|
||||
which[nvar] = 0;
|
||||
pad[nvar] = 0;
|
||||
data[nvar] = new char*[num[nvar]];
|
||||
data[nvar][0] = utils::strdup(arg[2]);
|
||||
data[nvar][0] = utils::strdup(combined);
|
||||
if (data[nvar][0][0] != '[') {
|
||||
vecs[nvar].dynamic = 1;
|
||||
data[nvar][1] = nullptr;
|
||||
|
||||
@ -61,6 +61,8 @@
|
||||
Highlight warnings and error messages in Output window
|
||||
Make Tutorial wizards more compact
|
||||
Include download and compilation of WHAM software from Alan Grossfield
|
||||
Add dialog to run WHAM directly from LAMMPS-GUI
|
||||
Use mutex to avoid corruption of thermo data
|
||||
</description>
|
||||
</release>
|
||||
<release version="1.6.11" timestamp="1725080055">
|
||||
|
||||
@ -1015,6 +1015,7 @@ void LammpsGui::logupdate()
|
||||
void *ptr = lammps.last_thermo("setup", 0);
|
||||
if (ptr && *(int *)ptr) return;
|
||||
|
||||
lammps.last_thermo("lock", 0);
|
||||
ptr = lammps.last_thermo("num", 0);
|
||||
if (ptr) {
|
||||
int ncols = *(int *)ptr;
|
||||
@ -1066,6 +1067,7 @@ void LammpsGui::logupdate()
|
||||
chartwindow->add_data(step, data, i);
|
||||
}
|
||||
}
|
||||
lammps.last_thermo("unlock", 0);
|
||||
}
|
||||
|
||||
// update list of available image file names
|
||||
|
||||
@ -55,8 +55,79 @@ index 0000000..b4f0fe6
|
||||
+ TYPE DOC
|
||||
+ PERMISSIONS OWNER_READ GROUP_READ WORLD_READ
|
||||
+)
|
||||
diff --git a/nr/locate.c b/nr/locate.c
|
||||
index 9f92dc0..f3bf294 100644
|
||||
--- a/nr/locate.c
|
||||
+++ b/nr/locate.c
|
||||
@@ -11,7 +11,7 @@ void locate(double xx[], int n, double x, int *j)
|
||||
ascnd=(xx[n] > xx[0]); // I think this makes it zero based
|
||||
while (ju-jl > 1) {
|
||||
jm=(ju+jl) >> 1;
|
||||
- if (x > xx[jm] == ascnd)
|
||||
+ if ((x > xx[jm]) == ascnd)
|
||||
jl=jm;
|
||||
else
|
||||
ju=jm;
|
||||
diff --git a/wham-2d/histogram.c b/wham-2d/histogram.c
|
||||
index 1bd1329..b5d1c01 100644
|
||||
--- a/wham-2d/histogram.c
|
||||
+++ b/wham-2d/histogram.c
|
||||
@@ -78,14 +78,14 @@ return hp;
|
||||
}
|
||||
|
||||
/* Get a value from a histogram structure
|
||||
- * Given i and j, the indices into the global histogram, return
|
||||
+ * Given i and j, the indices into the global histogram, return
|
||||
* the correct histogram value. Since we only store range of histogram
|
||||
- * indices containing the nonzero values, we have to check the index value
|
||||
+ * indices containing the nonzero values, we have to check the index value
|
||||
* against the range in the structure.
|
||||
*/
|
||||
double get_histval(struct histogram *hist, int i, int j)
|
||||
{
|
||||
-if ( (i < hist->first_x) || (i > hist->last_x)
|
||||
+if ( (i < hist->first_x) || (i > hist->last_x)
|
||||
||(j < hist->first_y) || (j > hist->last_y))
|
||||
{
|
||||
return 0.0;
|
||||
@@ -239,7 +239,7 @@ return error;
|
||||
|
||||
|
||||
// Calculate the free energy, setting the minimum value to 0
|
||||
-void calc_free(double **free, double **prob, double kT,
|
||||
+void calc_free(double **free, double **prob, double kT,
|
||||
int use_mask, int **mask)
|
||||
{
|
||||
int i,j;
|
||||
@@ -257,7 +257,14 @@ for (i=0; i<NUM_BINSx; i++)
|
||||
}
|
||||
else
|
||||
{
|
||||
- free[i][j] = -kT * log(prob[i][j]);
|
||||
+ if (prob[i][j] > 0.0)
|
||||
+ {
|
||||
+ free[i][j] = -kT * log(prob[i][j]);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ free[i][j] = 0.0;
|
||||
+ }
|
||||
if (free[i][j] < min)
|
||||
{
|
||||
min = free[i][j];
|
||||
@@ -321,8 +328,6 @@ return 0.5*(springx*(dx*dx) + springy*(dy*dy));
|
||||
|
||||
void calc_coor(int i, int j, double *coor)
|
||||
{
|
||||
-coor[0] = HIST_MINx + BIN_WIDTHx*((double)i+0.5);
|
||||
-coor[1] = HIST_MINy + BIN_WIDTHy*((double)j+0.5);
|
||||
+coor[0] = HIST_MINx + BIN_WIDTHx*((double)i+0.5);
|
||||
+coor[1] = HIST_MINy + BIN_WIDTHy*((double)j+0.5);
|
||||
}
|
||||
-
|
||||
-
|
||||
diff --git a/wham-2d/wham-2d.c b/wham-2d/wham-2d.c
|
||||
index fb6e059..2c5594f 100644
|
||||
index fb6e059..a6b8483 100644
|
||||
--- a/wham-2d/wham-2d.c
|
||||
+++ b/wham-2d/wham-2d.c
|
||||
@@ -25,7 +25,7 @@
|
||||
@ -77,6 +148,15 @@ index fb6e059..2c5594f 100644
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -57,7 +57,7 @@ double sum;
|
||||
int iteration;
|
||||
int max_iteration = 100000;
|
||||
int numpad;
|
||||
-int **mask;
|
||||
+int **mask = NULL;
|
||||
int use_mask;
|
||||
|
||||
cpu1 = ((double) clock())/CLOCKS_PER_SEC;
|
||||
@@ -76,6 +76,61 @@ for (i=0; i<argc; i++)
|
||||
}
|
||||
printf("\n");
|
||||
@ -139,6 +219,143 @@ index fb6e059..2c5594f 100644
|
||||
PERIODICx = parse_periodic(argv[1], &PERIODx);
|
||||
if (PERIODICx)
|
||||
{
|
||||
@@ -360,8 +415,8 @@ while ( ! iConverged || first)
|
||||
for (j=0; j< NUM_BINSy; j++)
|
||||
{
|
||||
calc_coor(i,j,coor);
|
||||
- printf("%f\t%f\t%f\t%f\n", coor[0], coor[1], free_ene[i][j],
|
||||
- prob[i][j]);
|
||||
+ if (prob[i][j] != 0.0)
|
||||
+ printf("%f\t%f\t%f\t%f\n", coor[0], coor[1], free_ene[i][j], prob[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,8 +499,9 @@ if (!FREEFILE)
|
||||
for (j=0; j< NUM_BINSy; j++)
|
||||
{
|
||||
calc_coor(i,j,coor);
|
||||
- printf("%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
- free_ene[i][j], final_prob[i][j]);
|
||||
+ if (prob[i][j] != 0.0)
|
||||
+ printf("%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
+ free_ene[i][j], final_prob[i][j]);
|
||||
}
|
||||
}
|
||||
exit(errno);
|
||||
@@ -461,25 +517,28 @@ else
|
||||
for (j=-numpad; j<0; j++)
|
||||
{
|
||||
calc_coor(i,j,coor);
|
||||
- fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
- free_ene[NUM_BINSx+i][NUM_BINSy+j],
|
||||
- final_prob[NUM_BINSx+i][NUM_BINSy+j]);
|
||||
+ if (prob[NUM_BINSx+i][NUM_BINSy+j] != 0.0)
|
||||
+ fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
+ free_ene[NUM_BINSx+i][NUM_BINSy+j],
|
||||
+ final_prob[NUM_BINSx+i][NUM_BINSy+j]);
|
||||
}
|
||||
// center values in y
|
||||
for (j=0; j<NUM_BINSy; j++)
|
||||
{
|
||||
calc_coor(i,j,coor);
|
||||
- fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
- free_ene[NUM_BINSx+i][j],
|
||||
- final_prob[NUM_BINSx+i][j]);
|
||||
+ if (prob[NUM_BINSx+i][j] != 0.0)
|
||||
+ fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
+ free_ene[NUM_BINSx+i][j],
|
||||
+ final_prob[NUM_BINSx+i][j]);
|
||||
}
|
||||
// trailing padding values in y
|
||||
for (j=0; j<numpad; j++)
|
||||
{
|
||||
calc_coor(i,NUM_BINSy+j,coor);
|
||||
- fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
- free_ene[NUM_BINSx+i][j],
|
||||
- final_prob[NUM_BINSx+i][j]);
|
||||
+ if (prob[NUM_BINSx+i][j] != 0.0)
|
||||
+ fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
+ free_ene[NUM_BINSx+i][j],
|
||||
+ final_prob[NUM_BINSx+i][j]);
|
||||
}
|
||||
fprintf(FREEFILE, "\n");
|
||||
}
|
||||
@@ -490,25 +549,28 @@ else
|
||||
for (j=-numpad; j<0; j++)
|
||||
{
|
||||
calc_coor(i,j,coor);
|
||||
- fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
- free_ene[i][NUM_BINSy+j],
|
||||
- final_prob[i][NUM_BINSy+j]);
|
||||
+ if (prob[i][NUM_BINSy+j] != 0.0)
|
||||
+ fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
+ free_ene[i][NUM_BINSy+j],
|
||||
+ final_prob[i][NUM_BINSy+j]);
|
||||
}
|
||||
// center values in y
|
||||
for (j=0; j<NUM_BINSy; j++)
|
||||
{
|
||||
calc_coor(i,j,coor);
|
||||
- fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
- free_ene[i][j],
|
||||
- final_prob[i][j]);
|
||||
+ if (prob[i][j] != 0.0)
|
||||
+ fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
+ free_ene[i][j],
|
||||
+ final_prob[i][j]);
|
||||
}
|
||||
// trailing padding values in y
|
||||
for (j=0; j<numpad; j++)
|
||||
{
|
||||
calc_coor(i,NUM_BINSy+j,coor);
|
||||
- fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
- free_ene[i][j],
|
||||
- final_prob[i][j]);
|
||||
+ if (prob[i][j] != 0.0)
|
||||
+ fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
+ free_ene[i][j],
|
||||
+ final_prob[i][j]);
|
||||
}
|
||||
fprintf(FREEFILE, "\n");
|
||||
}
|
||||
@@ -519,25 +581,28 @@ else
|
||||
for (j=-numpad; j<0; j++)
|
||||
{
|
||||
calc_coor(NUM_BINSx+i,j,coor);
|
||||
- fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
- free_ene[i][NUM_BINSy+j],
|
||||
- final_prob[i][NUM_BINSy+j]);
|
||||
+ if (prob[i][NUM_BINSy+j] != 0.0)
|
||||
+ fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
+ free_ene[i][NUM_BINSy+j],
|
||||
+ final_prob[i][NUM_BINSy+j]);
|
||||
}
|
||||
// center values in y
|
||||
for (j=0; j<NUM_BINSy; j++)
|
||||
{
|
||||
calc_coor(NUM_BINSx+i,j,coor);
|
||||
- fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
- free_ene[i][j],
|
||||
- final_prob[i][j]);
|
||||
+ if (prob[i][j] != 0.0)
|
||||
+ fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
+ free_ene[i][j],
|
||||
+ final_prob[i][j]);
|
||||
}
|
||||
// trailing padding values in y
|
||||
for (j=0; j<numpad; j++)
|
||||
{
|
||||
calc_coor(NUM_BINSx+i,NUM_BINSy+j,coor);
|
||||
- fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
- free_ene[i][j],
|
||||
- final_prob[i][j]);
|
||||
+ if (prob[i][j] != 0.0)
|
||||
+ fprintf(FREEFILE,"%f\t%f\t%f\t%f\n", coor[0], coor[1],
|
||||
+ free_ene[i][j],
|
||||
+ final_prob[i][j]);
|
||||
}
|
||||
fprintf(FREEFILE, "\n");
|
||||
}
|
||||
diff --git a/wham-2d/wham-2d.h b/wham-2d/wham-2d.h
|
||||
index b17e4bd..5fc17ff 100644
|
||||
--- a/wham-2d/wham-2d.h
|
||||
@ -163,10 +380,67 @@ index b17e4bd..5fc17ff 100644
|
||||
|
||||
|
||||
// Value inserted for the free energy of masked values
|
||||
diff --git a/wham/histogram.c b/wham/histogram.c
|
||||
index bc52d74..635b39f 100644
|
||||
--- a/wham/histogram.c
|
||||
+++ b/wham/histogram.c
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
|
||||
// Allocate memory for a histogram
|
||||
-struct histogram *hist_alloc(int first, int last, int num_points,
|
||||
+struct histogram *hist_alloc(int first, int last, int num_points,
|
||||
int num_mc_samples)
|
||||
{
|
||||
struct histogram *hp;
|
||||
@@ -45,9 +45,9 @@ return hp;
|
||||
}
|
||||
|
||||
/* Get a value from a histogram structure
|
||||
- * Given index, the index into the global histogram, return
|
||||
+ * Given index, the index into the global histogram, return
|
||||
* the correct histogram value. Since we only store range of histogram
|
||||
- * indices containing the nonzero values, we have to check the index value
|
||||
+ * indices containing the nonzero values, we have to check the index value
|
||||
* against the range in the structure.
|
||||
*/
|
||||
double get_histval(struct histogram *hist, int index)
|
||||
@@ -213,8 +213,16 @@ double min = 1e50;
|
||||
bin_min = 0;
|
||||
for (i=0; i<NUM_BINS; i++)
|
||||
{
|
||||
- free[i] = -kT * log(prob[i]);
|
||||
- if (free[i] < min)
|
||||
+ if (prob[i] > 0.0)
|
||||
+ {
|
||||
+ free[i] = -kT * log(prob[i]);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ free[i] = 0.0;
|
||||
+ }
|
||||
+
|
||||
+ if (free[i] < min)
|
||||
{
|
||||
min = free[i];
|
||||
bin_min = i;
|
||||
@@ -252,5 +260,5 @@ return 0.5*dx*dx*spring;
|
||||
|
||||
double calc_coor(int i)
|
||||
{
|
||||
-return HIST_MIN + BIN_WIDTH*((double)i+0.5);
|
||||
+return HIST_MIN + BIN_WIDTH*((double)i+0.5);
|
||||
}
|
||||
diff --git a/wham/wham.c b/wham/wham.c
|
||||
index 487871b..1496eed 100644
|
||||
index 487871b..edb8125 100644
|
||||
--- a/wham/wham.c
|
||||
+++ b/wham/wham.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/*
|
||||
+/*
|
||||
* WHAM -- Weighted Histogram Analysis Method
|
||||
*
|
||||
* Reference 1: Computer Physics Communications, 91(1995) 275-282, Benoit Roux
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "wham.h"
|
||||
|
||||
@ -184,6 +458,15 @@ index 487871b..1496eed 100644
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -41,7 +42,7 @@ int first;
|
||||
int bin_min;
|
||||
int have_energy;
|
||||
char *freefile;
|
||||
-FILE *METAFILE, *FREEFILE;
|
||||
+FILE *METAFILE, *FREEFILE;
|
||||
struct hist_group *hist_group;
|
||||
struct histogram *hp;
|
||||
double coor;
|
||||
@@ -82,6 +83,61 @@ for (i=0; i<argc; i++)
|
||||
}
|
||||
printf("\n");
|
||||
@ -246,6 +529,213 @@ index 487871b..1496eed 100644
|
||||
if (toupper(argv[1][0]) == 'P')
|
||||
{
|
||||
PERIODIC = 1;
|
||||
@@ -123,7 +179,7 @@ if (argc != 9 && argc !=11)
|
||||
printf( COMMAND_LINE );
|
||||
exit(-1);
|
||||
}
|
||||
-
|
||||
+
|
||||
HIST_MIN = atof(argv[1]);
|
||||
HIST_MAX = atof(argv[2]);
|
||||
NUM_BINS = atoi(argv[3]);
|
||||
@@ -213,13 +269,13 @@ if (!ave_pdf2)
|
||||
printf("couldn't allocate space for ave_pdf2: %s\n", strerror(errno));
|
||||
exit(errno);
|
||||
}
|
||||
-
|
||||
+
|
||||
free_ene = (double *) malloc(sizeof(double) * NUM_BINS);
|
||||
if (!free_ene)
|
||||
{
|
||||
printf("couldn't allocate space for free_ene: %s\n", strerror(errno));
|
||||
exit(errno);
|
||||
- }
|
||||
+ }
|
||||
|
||||
i = get_numwindows(METAFILE);
|
||||
printf("#Number of windows = %d\n", i);
|
||||
@@ -248,7 +304,7 @@ assert(i == hist_group->num_windows);
|
||||
// Figure out if we have trajectories at different temperatures.
|
||||
// Missing temperatures are set to -1 in read_metadata, and
|
||||
// since we require that either all trajectories specify a temperature
|
||||
-// or all trajectories are assumed to be at the wham temperature, we only
|
||||
+// or all trajectories are assumed to be at the wham temperature, we only
|
||||
// have to check one of them
|
||||
if (hist_group->kT[0] > 0)
|
||||
{
|
||||
@@ -257,7 +313,7 @@ if (hist_group->kT[0] > 0)
|
||||
else
|
||||
{
|
||||
have_energy = 0;
|
||||
- for (i=0; i< hist_group->num_windows; i++)
|
||||
+ for (i=0; i< hist_group->num_windows; i++)
|
||||
{
|
||||
hist_group->kT[i] = kT;
|
||||
}
|
||||
@@ -269,7 +325,7 @@ if (!final_f)
|
||||
{
|
||||
printf("couldn't allocate space for final_f: %s\n", strerror(errno));
|
||||
exit(errno);
|
||||
- }
|
||||
+ }
|
||||
|
||||
free(HISTOGRAM);
|
||||
|
||||
@@ -305,7 +361,8 @@ while (! is_converged(hist_group) || first )
|
||||
for (i=0; i< NUM_BINS; i++)
|
||||
{
|
||||
coor = calc_coor(i);
|
||||
- printf("%f\t%f\t%f\n", coor, free_ene[i], prob[i]);
|
||||
+ if (prob[i] != 0.0)
|
||||
+ printf("%f\t%f\t%f\n", coor, free_ene[i], prob[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
@@ -319,7 +376,7 @@ while (! is_converged(hist_group) || first )
|
||||
}
|
||||
}
|
||||
// Cheesy bailout if we're going on too long
|
||||
- if (iteration >= max_iteration)
|
||||
+ if (iteration >= max_iteration)
|
||||
{
|
||||
printf("Too many iterations: %d\n", iteration);
|
||||
break;
|
||||
@@ -383,11 +440,11 @@ for (i=0; i< num_mc_runs; i++)
|
||||
//printf("Faking %d: %d %d\n", i,j,hp->num_points);
|
||||
num_used = hp->last - hp->first + 1;
|
||||
mk_new_hist(hp->cum, hp->data, num_used, hp->num_mc_samples, &idum);
|
||||
-
|
||||
+
|
||||
hist_group->F_old[j] = 0.0;
|
||||
hist_group->F[j] = 0.0;
|
||||
}
|
||||
-
|
||||
+
|
||||
// perform WHAM iterations on the fake data sets
|
||||
iteration = 0;
|
||||
first = 1;
|
||||
@@ -403,7 +460,7 @@ for (i=0; i< num_mc_runs; i++)
|
||||
printf("Too many iterations: %d\n", iteration);
|
||||
break;
|
||||
}
|
||||
- }
|
||||
+ }
|
||||
printf("#MC trial %d: %d iterations\n", i, iteration);
|
||||
printf("#PMF values\n");
|
||||
// accumulate the average and stdev of the resulting probabilities
|
||||
@@ -419,18 +476,19 @@ for (i=0; i< num_mc_runs; i++)
|
||||
for (j=0; j < NUM_BINS; j++)
|
||||
{
|
||||
pdf = -kT*log(prob[j]);
|
||||
-
|
||||
+
|
||||
ave_p[j] += prob[j];
|
||||
ave_pdf[j] += pdf;
|
||||
ave_p2[j] += prob[j] * prob[j];
|
||||
ave_pdf2[j] += pdf*pdf;
|
||||
}
|
||||
- for (j=0; j<hist_group->num_windows;j++)
|
||||
+ for (j=0; j<hist_group->num_windows;j++)
|
||||
{
|
||||
ave_F[j] += hist_group->F[j] - hist_group->F[0];
|
||||
- ave_F2[j] += hist_group->F[j]*hist_group->F[j] ;
|
||||
+ ave_F2[j] += hist_group->F[j]*hist_group->F[j] ;
|
||||
}
|
||||
- }
|
||||
+ }
|
||||
+ if (num_mc_runs == 0) num_mc_runs = 1;
|
||||
for (i=0; i < NUM_BINS; i++)
|
||||
{
|
||||
ave_p[i] /= (double)num_mc_runs;
|
||||
@@ -457,12 +515,12 @@ if (!FREEFILE)
|
||||
for (i=0; i< NUM_BINS; i++)
|
||||
{
|
||||
coor = calc_coor(i);
|
||||
- printf("%f\t%f\t%f\t%f\t%f\n", coor, free_ene[i], ave_pdf2[i],
|
||||
- prob[i], ave_p2[i]);
|
||||
+ if (prob[i] != 0.0)
|
||||
+ printf("%f\t%f\t%f\t%f\t%f\n", coor, free_ene[i], ave_pdf2[i], prob[i], ave_p2[i]);
|
||||
}
|
||||
for (i=0; i<hist_group->num_windows; i++)
|
||||
{
|
||||
- fprintf(FREEFILE,"%d\t%f\t%f\n", i, final_f[i],ave_F2[i]);
|
||||
+ printf("%d\t%f\t%f\n", i, final_f[i],ave_F2[i]);
|
||||
}
|
||||
|
||||
exit(errno);
|
||||
@@ -470,38 +528,37 @@ if (!FREEFILE)
|
||||
else
|
||||
{
|
||||
// write out header
|
||||
- fprintf(FREEFILE, "#Coor\t\tFree\t+/-\t\tProb\t\t+/-\n");
|
||||
+ fprintf(FREEFILE, "#Coor\t\tFree\t\t+/-\t\tProb\t\t+/-\n");
|
||||
// write out the leading padded values
|
||||
for (i=-numpad; i<0; i++)
|
||||
{
|
||||
coor = calc_coor(i);
|
||||
- fprintf(FREEFILE,"%f\t%f\t%f\t%f\t%f\n", coor, free_ene[NUM_BINS+i],
|
||||
- ave_pdf2[NUM_BINS+i],
|
||||
- final_prob[NUM_BINS+i],
|
||||
- ave_p2[NUM_BINS+i]);
|
||||
+ if (prob[NUM_BINS+1] != 0.0)
|
||||
+ fprintf(FREEFILE,"%f\t%f\t%f\t%f\t%f\n", coor, free_ene[NUM_BINS+i],
|
||||
+ ave_pdf2[NUM_BINS+i], final_prob[NUM_BINS+i], ave_p2[NUM_BINS+i]);
|
||||
}
|
||||
// write out the center values
|
||||
for (i=0; i<NUM_BINS; i++)
|
||||
{
|
||||
coor = calc_coor(i);
|
||||
- fprintf(FREEFILE,"%f\t%f\t%f\t%f\t%f\n", coor, free_ene[i],
|
||||
- ave_pdf2[i],final_prob[i],
|
||||
- ave_p2[i]);
|
||||
+ if (prob[i] != 0.0)
|
||||
+ fprintf(FREEFILE,"%f\t%f\t%f\t%f\t%f\n", coor, free_ene[i],
|
||||
+ ave_pdf2[i],final_prob[i],ave_p2[i]);
|
||||
}
|
||||
|
||||
// write out the trailing padded values
|
||||
for (i=0; i<numpad; i++)
|
||||
{
|
||||
coor = calc_coor(NUM_BINS+i);
|
||||
- fprintf(FREEFILE,"%f\t%f\t%f\t%f\t%f\n", coor, free_ene[i],
|
||||
- ave_pdf2[i],final_prob[i],
|
||||
- ave_p2[i]);
|
||||
+ if (prob[i] != 0.0)
|
||||
+ fprintf(FREEFILE,"%f\t%f\t%f\t%f\t%f\n", coor, free_ene[i],
|
||||
+ ave_pdf2[i],final_prob[i], ave_p2[i]);
|
||||
}
|
||||
|
||||
- fprintf(FREEFILE, "#Window\t\tFree\t+/-\t\n");
|
||||
+ fprintf(FREEFILE, "#Window\t\tFree\t\t+/-\t\n");
|
||||
for (i=0; i<hist_group->num_windows; i++)
|
||||
{
|
||||
- fprintf(FREEFILE,"#%d\t%f\t%f\n", i, final_f[i],ave_F2[i]);
|
||||
+ fprintf(FREEFILE,"#%d\t\t%f\t%f\n", i, final_f[i],ave_F2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,7 +572,7 @@ exit(0);
|
||||
/*
|
||||
* Perform a single WHAM iteration
|
||||
*/
|
||||
-void wham_iteration(struct hist_group* hist_group, double *prob,
|
||||
+void wham_iteration(struct hist_group* hist_group, double *prob,
|
||||
int have_energy)
|
||||
{
|
||||
int i,j;
|
||||
@@ -535,9 +592,9 @@ for (i=0; i<NUM_BINS; i++)
|
||||
num += (double) get_histval( &(hist_group->hists[j]),i);
|
||||
bias = calc_bias(hist_group,j,coor);
|
||||
bf = exp((hist_group->F_old[j] - bias) / hist_group->kT[j]);
|
||||
- /* If we have energies, then the histograms contain boltzmann
|
||||
- * factors. If not, they contain integer counts. Accordingly,
|
||||
- * we either use a partition function to normalize, or simply the
|
||||
+ /* If we have energies, then the histograms contain boltzmann
|
||||
+ * factors. If not, they contain integer counts. Accordingly,
|
||||
+ * we either use a partition function to normalize, or simply the
|
||||
* number of points.
|
||||
*/
|
||||
if (have_energy)
|
||||
diff --git a/wham/wham.h b/wham/wham.h
|
||||
index aacc1e8..7d509f2 100644
|
||||
--- a/wham/wham.h
|
||||
|
||||
@ -141,6 +141,8 @@ extern int lammps_extract_variable_datatype(void *handle, const char *name);
|
||||
extern int lammps_set_variable(void *, const char *, const char *);
|
||||
extern int lammps_set_string_variable(void *, const char *, const char *);
|
||||
extern int lammps_set_internal_variable(void *, const char *, double);
|
||||
extern int lammps_variable_info(void *handle, int idx, char *buf, int bufsize);
|
||||
extern double lammps_eval(void *handle, const char *expr);
|
||||
|
||||
extern void lammps_gather_atoms(void *, char *, int, int, void *);
|
||||
extern void lammps_gather_atoms_concat(void *, char *, int, int, void *);
|
||||
@ -332,6 +334,8 @@ extern int lammps_extract_variable_datatype(void *handle, const char *name);
|
||||
extern int lammps_set_variable(void *, const char *, const char *);
|
||||
extern int lammps_set_string_variable(void *, const char *, const char *);
|
||||
extern int lammps_set_internal_variable(void *, const char *, double);
|
||||
extern int lammps_variable_info(void *handle, int idx, char *buf, int bufsize);
|
||||
extern double lammps_eval(void *handle, const char *expr);
|
||||
|
||||
extern void lammps_gather_atoms(void *, char *, int, int, void *);
|
||||
extern void lammps_gather_atoms_concat(void *, char *, int, int, void *);
|
||||
|
||||
@ -233,3 +233,34 @@ TEST_F(LibraryObjects, expand)
|
||||
EXPECT_THAT((char *)ptr, StrEq("'xx_$(4+5)_$(PI) ${one}-${two}-${three}'"));
|
||||
lammps_free(ptr);
|
||||
}
|
||||
|
||||
TEST_F(LibraryObjects, eval)
|
||||
{
|
||||
lammps_get_last_error_message(lmp, nullptr, 1);
|
||||
::testing::internal::CaptureStdout();
|
||||
lammps_commands_string(lmp, "region box1 block 0 10 0 5 -0.5 0.5\n"
|
||||
"lattice fcc 0.8\n"
|
||||
"create_box 1 box1\n"
|
||||
"create_atoms 1 box\n"
|
||||
"mass * 1.0\n"
|
||||
"pair_style lj/cut 4.0\n"
|
||||
"pair_coeff * * 1.0 1.0\n"
|
||||
"variable t equal 15.0\n"
|
||||
"velocity all create 1.5 532656\n"
|
||||
"fix 1 all nve\n"
|
||||
"run 0 post no\n");
|
||||
lammps_command(lmp, "variable one index 1 2 3 4");
|
||||
lammps_command(lmp, "variable two equal 2");
|
||||
std::string output = ::testing::internal::GetCapturedStdout();
|
||||
if (verbose) std::cout << output;
|
||||
ASSERT_EQ(lammps_has_error(lmp), 0);
|
||||
|
||||
EXPECT_DOUBLE_EQ(lammps_eval(lmp, "4+5"), 9.0);
|
||||
EXPECT_EQ(lammps_has_error(lmp), 0);
|
||||
EXPECT_DOUBLE_EQ(lammps_eval(lmp, "v_one / 2.0"), 0.5);
|
||||
EXPECT_EQ(lammps_has_error(lmp), 0);
|
||||
EXPECT_DOUBLE_EQ(lammps_eval(lmp, "count(all)"), 36.0);
|
||||
EXPECT_EQ(lammps_has_error(lmp), 0);
|
||||
EXPECT_DOUBLE_EQ(lammps_eval(lmp, "pe"), -3.9848867644689534);
|
||||
EXPECT_EQ(lammps_has_error(lmp), 0);
|
||||
}
|
||||
|
||||
@ -140,8 +140,8 @@ TEST_F(VariableTest, CreateDelete)
|
||||
command("variable ten1 universe 1 2 3 4");
|
||||
command("variable ten2 uloop 4");
|
||||
command("variable ten3 uloop 4 pad");
|
||||
command("variable ten4 vector [0,1,2,3,5,7,11]");
|
||||
command("variable ten5 vector [0.5,1.25]");
|
||||
command("variable ten4 vector [0,1, 2,3, 5,7,11]");
|
||||
command("variable ten5 vector [ 0.5, 1.25 ]");
|
||||
command("variable dummy index 0");
|
||||
command("variable file equal is_file(MYFILE)");
|
||||
command("variable iswin equal is_os(^Windows)");
|
||||
@ -323,13 +323,13 @@ TEST_F(VariableTest, Expressions)
|
||||
BEGIN_HIDE_OUTPUT();
|
||||
command("variable one index 1");
|
||||
command("variable two equal 2");
|
||||
command("variable three equal v_one+v_two");
|
||||
command("variable three equal v_one + v_two");
|
||||
command("variable four equal PI");
|
||||
command("variable five equal version");
|
||||
command("variable six equal XXX");
|
||||
command("variable seven equal -v_one");
|
||||
command("variable eight equal v_three-0.5");
|
||||
command("variable nine equal v_two*(v_one+v_three)");
|
||||
command("variable nine equal v_two * (v_one+v_three)");
|
||||
command("variable ten equal (1.0/v_two)^2");
|
||||
command("variable eleven equal v_three%2");
|
||||
command("variable twelve equal 1==2");
|
||||
@ -341,7 +341,7 @@ TEST_F(VariableTest, Expressions)
|
||||
command("variable ten8 equal 1|^0");
|
||||
command("variable ten9 equal v_one-v_ten9");
|
||||
command("variable ten10 internal 100.0");
|
||||
command("variable ten11 equal (1!=1)+(2<1)+(2<=1)+(1>2)+(1>=2)+(1&&0)+(0||0)+(1|^1)+10^0");
|
||||
command("variable ten11 equal (1 != 1)+(2 < 1)+(2<=1)+(1>2)+(1>=2)+(1&&0)+(0||0)+(1|^1)+10^0");
|
||||
command("variable ten12 equal yes+no+on+off+true+false");
|
||||
command("variable err1 equal v_one/v_ten7");
|
||||
command("variable err2 equal v_one%v_ten7");
|
||||
@ -350,7 +350,7 @@ TEST_F(VariableTest, Expressions)
|
||||
command("variable vec2 vector v_vec1*0.5");
|
||||
command("variable vec3 equal v_vec2[3]");
|
||||
command("variable vec4 vector '[1, 5, 2.5, -10, -5, 20, 120, 4, 3, 3]'");
|
||||
command("variable sort vector sort(v_vec4)");
|
||||
command("variable sort vector sort(v_vec4 )");
|
||||
command("variable rsrt vector rsort(v_vec4)");
|
||||
command("variable max2 equal sort(v_vec4)[2]");
|
||||
command("variable rmax equal rsort(v_vec4)[1]");
|
||||
|
||||
@ -538,6 +538,27 @@ create_atoms 1 single &
|
||||
expanded = self.lmp.expand("'xx_$(4+5)_$(PI) ${one}-${two}-${three}'")
|
||||
self.assertEqual(expanded, "'xx_$(4+5)_$(PI) ${one}-${two}-${three}'")
|
||||
|
||||
def test_eval(self):
|
||||
self.lmp.commands_string(
|
||||
"""region box1 block 0 10 0 5 -0.5 0.5
|
||||
lattice fcc 0.8
|
||||
create_box 1 box1
|
||||
create_atoms 1 box
|
||||
mass * 1.0
|
||||
pair_style lj/cut 4.0
|
||||
pair_coeff * * 1.0 1.0
|
||||
variable t equal 15.0
|
||||
velocity all create 1.5 532656
|
||||
fix 1 all nve
|
||||
run 0 post no""")
|
||||
self.lmp.command("variable one index 1 2 3 4")
|
||||
self.lmp.command("variable two equal 2")
|
||||
|
||||
self.assertEqual(self.lmp.eval("4+5"), 9.0)
|
||||
self.assertEqual(self.lmp.eval("v_one / 2.0"), 0.5)
|
||||
self.assertEqual(self.lmp.eval("count(all)"), 36.0)
|
||||
self.assertEqual(self.lmp.eval("pe"), -3.9848867644689534)
|
||||
|
||||
def test_get_thermo(self):
|
||||
self.lmp.command("units lj")
|
||||
self.lmp.command("atom_style atomic")
|
||||
|
||||
Reference in New Issue
Block a user