Merge branch 'develop' into bye-bye-python-zwei

This commit is contained in:
Axel Kohlmeyer
2025-02-13 17:01:39 -05:00
35 changed files with 1281 additions and 455 deletions

View File

@ -28,14 +28,14 @@ Create a 'next\_release' branch off 'develop' and make the following changes:
..versionadded:: or ..versionchanged:: are missing and need to be
added
Submit this pull request, rebase if needed. This is the last pull
request merged for the release and should not contain any other
changes. (Exceptions: this document, last minute trivial(!) changes).
Submit this pull request. This is the last pull request merged for the
release and should not contain any other changes. (Exceptions: this
document, last minute trivial(!) changes).
This PR shall not be merged before **all** pending tests have completed
and cleared. We currently use a mix of automated tests running on
either Temple's Jenkins cluster or GitHub workflows. Those include time
consuming tests not run on pull requests. If needed, a bugfix pull
consuming tests not run on pull requests. If needed, a bug-fix pull
request should be created and merged to clear all tests.
### Create release on GitHub
@ -56,7 +56,7 @@ git pull
git checkout release
git pull
git merge --ff-only develop
git tag -s -m "LAMMPS feature release 19 November 2024" patch_19Nov2024
git tag -s -m "LAMMPS feature release 4 February 2025" patch_4Feb2025
git push git@github.com:lammps/lammps.git --tags develop release
```
@ -77,7 +77,7 @@ release page with a summary of all the changes included and references
to the pull requests they were merged from or check the existing draft
for any necessary changes from pull requests that were merged but are
not listed. Then select the applied tag for the release in the "Choose
a tag" dropdown list. Go to the bottom of the list and select the "Set
a tag" drop-down list. Go to the bottom of the list and select the "Set
as pre-release" checkbox. The "Set as the latest release" button is
reserved for stable releases and updates to them.
@ -87,12 +87,18 @@ you can return to edit the release page and publish it.
### Prepare pre-compiled packages, update packages to GitHub
Build a fully static LAMMPS installation using a musl-libc
cross-compiler, install into a lammps-static folder, and create a
tarball called lammps-linux-x86_64-19Nov2024.tar.gz (or using a
corresponding date with a future release) from the lammps-static folder.
A suitable build environment is provided with the
https://download.lammps.org/static/fedora37_musl.sif container image.
https://download.lammps.org/static/fedora41_musl_mingw.sif container
image. The corresponding container build definition file is maintained
in the tools/singularity folder of the LAMMPS source distribution.
#### Fully portable static Linux x86_64 non-MPI binaries
The following commands use the Fedora container to build a fully static
LAMMPS installation using a musl-libc cross-compiler, install it into a
`lammps-static` folder, and create a tarball called
`lammps-linux-x86_64-4Feb2025.tar.gz` (or using a corresponding date
with a future release) from the `lammps-static` folder.
``` sh
rm -rf release-packages
@ -105,49 +111,173 @@ cmake -S lammps-release/cmake -B build-release -G Ninja -D CMAKE_INSTALL_PREFIX=
cmake --build build-release --target all
cmake --build build-release --target install
/usr/musl/bin/x86_64-linux-musl-strip lammps-static/bin/*
tar -czvvf lammps-linux-x86_64-19Nov2024.tar.gz lammps-static
tar -czvvf ../lammps-linux-x86_64-4Feb2025.tar.gz lammps-static
exit # fedora 41 container
cd ..
```
The resulting tar archive can be uploaded to the GitHub release page with:
```
gh release upload patch_19Nov2024 lammps-linux-x86_64-19Nov2024.tar.gz
``` sh
gh release upload patch_4Feb2025 lammps-linux-x86_64-4Feb2025.tar.gz
```
#### Linux x86_64 Flatpak bundle with GUI included
Make sure you have the `flatpak` and `flatpak-builder` packages
installed locally (they cannot be used from the container) and build a
installed locally (they require binaries that run with elevated
privileges and thus cannot be used from the container) and build a
LAMMPS and LAMMPS-GUI flatpak bundle in the `release-packages` folder
with:
``` sh
cd release-packages
flatpak --user remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak-builder --force-clean --verbose --repo=$PWD/flatpak-repo --install-deps-from=flathub --state-dir=$PWD --user --ccache --default-branch=release flatpak-build lammps-release/tools/lammps-gui/org.lammps.lammps-gui.yml
flatpak build-bundle --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo --verbose $PWD/flatpak-repo LAMMPS-Linux-x86_64-GUI-19Nov2024.flatpak org.lammps.lammps-gui release
flatpak build-bundle --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo --verbose $PWD/flatpak-repo ../LAMMPS-Linux-x86_64-GUI-4Feb2025.flatpak org.lammps.lammps-gui release
cd ..
```
The resulting flatpak bundle file can be uploaded to the GitHub release page with:
```
gh release upload patch_19Nov2024 LAMMPS-Linux-x86_64-GUI-19Nov2024.flatpak
``` sh
gh release upload patch_4Feb2025 LAMMPS-Linux-x86_64-GUI-4Feb2025.flatpak
```
Also build serial executable packages that also include LAMMPS-GUI for
Linux, macOS, and Windows, and upload them to the GitHub release.
#### LAMMPS Source tarball
Clean up:
The container for the static binary can also be used to prepare the source
tarball including the HTML and PDF manual (this is currently done automatically
when the releases is created and the tarball uploaded to https://download.lammps.org/tars/).
The steps are as follows:
``` sh
cd release-packages
apptainer shell fedora41_musl_mingw.sif
cd lammps-release
rm -f ../release.tar*
git archive --output=../release.tar --prefix=lammps-4Feb2025/ HEAD
cd doc
make clean-all
make html pdf
tar -rf ../../release.tar --transform 's,^,lammps-4Feb2025/doc/,' html Manual.pdf
gzip -9v ../../release.tar
mv ../../release.tar.gz ../../lammps-src-4Feb2025.tar.gz
exit # fedora41 container
cd ..
```
The resulting source tarball can be uploaded to the GitHub release page with:
``` sh
gh release upload patch_4Feb2025 lammps-src-4Feb2025.tar.gz
```
#### Build Windows Installer Packages with MinGW Linux-to-Windows Cross-compiler
The various Windows installer packages can also be built with
apptainer container image.
``` sh
cd release-packages
apptainer shell fedora41_musl_mingw.sif
git clone --depth 10 https://github.com/lammps/lammps-packages.git lammps-packages
cd lammps-packages/mingw-cross
ln -sf ../../lammps-release lammps
./buildall.sh release >& mk.log & less +F mk.log
```
The installer with the GUI included can be uploaded to the GitHub release page with:
``` sh
ln -sf LAMMPS-64bit-GUI-4Feb2025.exe LAMMPS-Win10-64bit-GUI-4Feb2025.exe
gh release upload patch_4Feb2025 LAMMPS-Win10-64bit-GUI-4Feb2025.exe
```
The symbolic link is used to have a consistent naming scheme for the packages
attached to the GitHub release page.
#### Clean up:
``` sh
cd ..
rm -r release-packages
```
TODO:
- add detailed commands for building GUI packages on Ubuntu 20.04LTS (move to 22.04LTS?),
macOS, and Windows cross-compiler and upload to GitHub
- build all Windows cross-compiled installer packages using lammps-packages repo
#### Build Multi-arch App-bundle for macOS
### Update download website
Building app-bundles for macOS is not as easily automated and portable
as some of the other steps. It requires a machine actually running
macOS. In that machine the Xcode compiler package needs to be
installed. This also includes tools for building and manipulating disk
images. This compiler supports building executables for both, the
x86_64 and the arm64 architectures. This requires building with CMake
and using the CMake settings:
``` sh
-D CMAKE_OSX_ARCHITECTURES=arm64;x86_64
-D CMAKE_OSX_DEPLOYMENT_TARGER=11.0
```
This will add the compiler flags `-arch arm64 -arch x86_64
-mmacosx-version-min=11.0` and thus produce object for both
architectures and support for macOS versions back to version 11 (aka Big
Sur). With these settings the following libraries should be compiled
and installed (e.g. to `$HOME/.local`) as static libraries only:
- libomp taken from the LLVM/Clang source distribution (to support OpenMP)
- jpeg
- zlib
- png
- Qt (for LAMMPS-GUI)
When configuring LAMMPS the `cmake/presets/clang.cmake` should be used
and as many packages as possible enabled. For LAMMPS-GUI, MPI should be
disabled with `-D BUILD_MPI=OFF` and LAMMPS-GUI enabled with
`-D BUILD_LAMMPS_GUI=ON`. If the CMake configuration is successful,
settings for building a macOS app-bundle are enabled and with `cmake
--build build --target dmg` extra steps will be executed that will build
a macOS application installer image under the name
`LAMMPS_GUI-macOS-multiarch-4Feb2025.dmg`
The application image can be uploaded to the GitHub release page with:
``` sh
ln -sf LAMMPS_GUI-macOS-multiarch-4Feb2025.dmg LAMMPS-macOS-multiarch-GUI-4Feb2025.dmg
gh release upload patch_4Feb2025 LAMMPS-macOS-multiarch-GUI-4Feb2025.dmg
```
The symbolic link is used to have a consistent naming scheme for the packages
attached to the GitHub release page.
We are currently building the application images on macOS 12 (aka Monterey).
#### Build Linux x86_64 binary tarball on Ubuntu 20.04LTS
While the flatpak Linux version uses portable runtime libraries provided
by the flatpak environment, we also build regular Linux executables that
use a wrapper script and matching shared libraries in a tarball. To be
compatible with many Linux distributions, one has to build this on a
very old Linux distribution, since most Linux system libraries are
usually backward compatible but not forward compatible. This is
currently done on an Ubuntu 20.04LTS system. Once LAMMPS moves to
require CMake 3.20 and C++17, we will have to move to Ubuntu 22.04LTS.
This installation (either on a real or a virtual machine) should have
the packages installed that are indicated in
`tools/singularity/ubuntu20.04.def` plus Qt version 5.x with development
headers, so that LAMMPS-GUI can be compiled.
Also the building of the binary tarball and setup of the bundled
libraries and wrapper scripts is automated and can executed with `cmake
--build build --target tgz`. This should produce a file
`LAMMPS_GUI-Linux-amd64-4Feb2025.tar.gz` which can be uploaded to the
GitHub release page with:
``` sh
ln -sf LAMMPS_GUI-Linux-amd64-4Feb2025.tar.gz LAMMPS-Linux-x86_64-GUI-4Feb2025.tar.gz
gh release upload patch_4Feb2025 LAMMPS-Linux-x86_64-GUI-4Feb2025.tar.gz
```
### Update download page on LAMMPS website
Check out the LAMMPS website repo
https://github.com/lammps/lammps-website.git and edit the file
@ -156,7 +286,7 @@ html` and review `html/download.html` Then add and commit to git and
push the changes to GitHub. The Temple Jenkis cluster will
automatically update https://www.lammps.org/download.html accordingly.
Notify Steve of the release so he can update `src/bug.txt` on the
Also notify Steve of the release so he can update `src/bug.txt` on the
website from the available release notes.
## LAMMPS Stable Release

View File

@ -77,7 +77,7 @@ jobs:
-D PKG_MDI=on \
-D PKG_MANIFOLD=on \
-D PKG_ML-PACE=on \
-D PKG_ML-RANN=off \
-D PKG_ML-RANN=on \
-D PKG_MOLFILE=on \
-D PKG_RHEO=on \
-D PKG_PTM=on \

15
README
View File

@ -23,17 +23,20 @@ more information about the code and its uses.
The LAMMPS distribution includes the following files and directories:
README this file
LICENSE the GNU General Public License (GPL)
bench benchmark problems
LICENSE the GNU General Public License (GPLv2)
CITATION.cff Citation information for LAMMPS in CFF format
bench benchmark inputs
cmake CMake build files
doc documentation
examples simple test problems
fortran Fortran wrapper for LAMMPS
examples example inputs for many LAMMPS commands
fortran Fortran 2003 module for LAMMPS
lib additional provided or external libraries
potentials interatomic potential files
python Python wrappers for LAMMPS
python Python module for LAMMPS
src source files
tools pre- and post-processing tools
unittest test programs for use with CTest
.github Git and GitHub related files and tools
Point your browser at any of these files to get started:
@ -42,6 +45,8 @@ https://docs.lammps.org/Intro.html hi-level introduction
https://docs.lammps.org/Build.html how to build LAMMPS
https://docs.lammps.org/Run_head.html how to run LAMMPS
https://docs.lammps.org/Commands_all.html Table of available commands
https://docs.lammps.org/Howto.html Short tutorials and HowTo discussions
https://docs.lammps.org/Errors.html How to interpret and debug errors
https://docs.lammps.org/Library.html LAMMPS library interfaces
https://docs.lammps.org/Modify.html how to modify and extend LAMMPS
https://docs.lammps.org/Developer.html LAMMPS developer info

View File

@ -209,7 +209,7 @@ endif()
########################################################################
# User input options #
########################################################################
# backward compatibility with CMake before 3.12 and older LAMMPS documentation
# backward compatibility with older LAMMPS documentation
if (PYTHON_EXECUTABLE)
set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
endif()
@ -936,7 +936,7 @@ endif()
include(Testing)
include(CodeCoverage)
include(CodingStandard)
find_package(ClangFormat 11.0)
find_package(ClangFormat 11.0 QUIET)
if(ClangFormat_FOUND)
add_custom_target(format-src

View File

@ -7,76 +7,76 @@
# For Python coverage the coverage package needs to be installed
###############################################################################
if(ENABLE_COVERAGE)
find_program(GCOVR_BINARY gcovr)
find_package_handle_standard_args(GCOVR DEFAULT_MSG GCOVR_BINARY)
find_program(GCOVR_BINARY gcovr)
find_package_handle_standard_args(GCOVR DEFAULT_MSG GCOVR_BINARY)
find_program(COVERAGE_BINARY coverage)
find_package_handle_standard_args(COVERAGE DEFAULT_MSG COVERAGE_BINARY)
find_program(COVERAGE_BINARY coverage)
find_package_handle_standard_args(COVERAGE DEFAULT_MSG COVERAGE_BINARY)
if(GCOVR_FOUND)
get_filename_component(ABSOLUTE_LAMMPS_SOURCE_DIR ${LAMMPS_SOURCE_DIR} ABSOLUTE)
if(GCOVR_FOUND)
get_filename_component(ABSOLUTE_LAMMPS_SOURCE_DIR ${LAMMPS_SOURCE_DIR} ABSOLUTE)
add_custom_target(
gen_coverage_xml
COMMAND ${GCOVR_BINARY} -s -x -r ${ABSOLUTE_LAMMPS_SOURCE_DIR} --object-directory=${CMAKE_BINARY_DIR} -o coverage.xml
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating XML coverage report..."
)
add_custom_target(
gen_coverage_xml
COMMAND ${GCOVR_BINARY} -s -x -r ${ABSOLUTE_LAMMPS_SOURCE_DIR} --object-directory=${CMAKE_BINARY_DIR} -o coverage.xml
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating XML coverage report..."
)
set(COVERAGE_HTML_DIR ${CMAKE_BINARY_DIR}/coverage_html)
set(COVERAGE_HTML_DIR ${CMAKE_BINARY_DIR}/coverage_html)
add_custom_target(coverage_html_folder
COMMAND ${CMAKE_COMMAND} -E make_directory ${COVERAGE_HTML_DIR})
add_custom_target(coverage_html_folder
COMMAND ${CMAKE_COMMAND} -E make_directory ${COVERAGE_HTML_DIR})
add_custom_target(
gen_coverage_html
COMMAND ${GCOVR_BINARY} -s --html --html-details -r ${ABSOLUTE_LAMMPS_SOURCE_DIR} --object-directory=${CMAKE_BINARY_DIR} -o ${COVERAGE_HTML_DIR}/index.html
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating HTML coverage report..."
)
add_dependencies(gen_coverage_html coverage_html_folder)
add_custom_target(
gen_coverage_html
COMMAND ${GCOVR_BINARY} -s --html --html-details -r ${ABSOLUTE_LAMMPS_SOURCE_DIR} --object-directory=${CMAKE_BINARY_DIR} -o ${COVERAGE_HTML_DIR}/index.html
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating HTML coverage report..."
)
add_dependencies(gen_coverage_html coverage_html_folder)
add_custom_target(clean_coverage_html
${CMAKE_COMMAND} -E remove_directory ${COVERAGE_HTML_DIR}
COMMENT "Deleting HTML coverage report..."
)
add_custom_target(clean_coverage_html
${CMAKE_COMMAND} -E remove_directory ${COVERAGE_HTML_DIR}
COMMENT "Deleting HTML coverage report..."
)
add_custom_target(reset_coverage
${CMAKE_COMMAND} -E remove -f */*.gcda */*/*.gcda */*/*/*.gcda
*/*/*/*/*.gcda */*/*/*/*/*.gcda */*/*/*/*/*/*.gcda
*/*/*/*/*/*/*/*.gcda */*/*/*/*/*/*/*/*.gcda
*/*/*/*/*/*/*/*/*/*.gcda */*/*/*/*/*/*/*/*/*/*.gcda
WORKIND_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Deleting coverage data files..."
)
add_dependencies(reset_coverage clean_coverage_html)
endif()
add_custom_target(reset_coverage
${CMAKE_COMMAND} -E remove -f */*.gcda */*/*.gcda */*/*/*.gcda
*/*/*/*/*.gcda */*/*/*/*/*.gcda */*/*/*/*/*/*.gcda
*/*/*/*/*/*/*/*.gcda */*/*/*/*/*/*/*/*.gcda
*/*/*/*/*/*/*/*/*/*.gcda */*/*/*/*/*/*/*/*/*/*.gcda
WORKIND_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Deleting coverage data files..."
)
add_dependencies(reset_coverage clean_coverage_html)
endif()
if(COVERAGE_FOUND)
set(PYTHON_COVERAGE_HTML_DIR ${CMAKE_BINARY_DIR}/python_coverage_html)
configure_file(.coveragerc.in ${CMAKE_BINARY_DIR}/.coveragerc @ONLY)
if(COVERAGE_FOUND)
set(PYTHON_COVERAGE_HTML_DIR ${CMAKE_BINARY_DIR}/python_coverage_html)
configure_file(.coveragerc.in ${CMAKE_BINARY_DIR}/.coveragerc @ONLY)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/unittest/python/.coverage
COMMAND ${COVERAGE_BINARY} combine
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/unittest/python
COMMENT "Combine Python coverage files..."
)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/unittest/python/.coverage
COMMAND ${COVERAGE_BINARY} combine
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/unittest/python
COMMENT "Combine Python coverage files..."
)
add_custom_target(
gen_python_coverage_html
COMMAND ${COVERAGE_BINARY} html --rcfile=${CMAKE_BINARY_DIR}/.coveragerc -d ${PYTHON_COVERAGE_HTML_DIR}
DEPENDS ${CMAKE_BINARY_DIR}/unittest/python/.coverage ${CMAKE_BINARY_DIR}/.coveragerc
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/unittest/python
COMMENT "Generating HTML Python coverage report..."
)
add_custom_target(
gen_python_coverage_html
COMMAND ${COVERAGE_BINARY} html --rcfile=${CMAKE_BINARY_DIR}/.coveragerc -d ${PYTHON_COVERAGE_HTML_DIR}
DEPENDS ${CMAKE_BINARY_DIR}/unittest/python/.coverage ${CMAKE_BINARY_DIR}/.coveragerc
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/unittest/python
COMMENT "Generating HTML Python coverage report..."
)
add_custom_target(
gen_python_coverage_xml
COMMAND ${COVERAGE_BINARY} xml --rcfile=${CMAKE_BINARY_DIR}/.coveragerc -o ${CMAKE_BINARY_DIR}/python_coverage.xml
DEPENDS ${CMAKE_BINARY_DIR}/unittest/python/.coverage ${CMAKE_BINARY_DIR}/.coveragerc
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/unittest/python
COMMENT "Generating XML Python coverage report..."
)
endif()
add_custom_target(
gen_python_coverage_xml
COMMAND ${COVERAGE_BINARY} xml --rcfile=${CMAKE_BINARY_DIR}/.coveragerc -o ${CMAKE_BINARY_DIR}/python_coverage.xml
DEPENDS ${CMAKE_BINARY_DIR}/unittest/python/.coverage ${CMAKE_BINARY_DIR}/.coveragerc
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/unittest/python
COMMENT "Generating XML Python coverage report..."
)
endif()
endif()

View File

@ -13,7 +13,7 @@ if(BUILD_DOC)
endif()
find_package(Python3 REQUIRED COMPONENTS Interpreter)
if(Python3_VERSION VERSION_LESS 3.8)
message(FATAL_ERROR "Python 3.8 and up is required to build the HTML documentation")
message(FATAL_ERROR "Python 3.8 and up is required to build the LAMMPS HTML documentation")
endif()
set(VIRTUALENV ${Python3_EXECUTABLE} -m venv)
@ -65,8 +65,8 @@ if(BUILD_DOC)
find_package(Sphinx)
endif()
set(MATHJAX_URL "https://github.com/mathjax/MathJax/archive/3.1.3.tar.gz" CACHE STRING "URL for MathJax tarball")
set(MATHJAX_MD5 "b81661c6e6ba06278e6ae37b30b0c492" CACHE STRING "MD5 checksum of MathJax tarball")
set(MATHJAX_URL "https://github.com/mathjax/MathJax/archive/3.2.2.tar.gz" CACHE STRING "URL for MathJax tarball")
set(MATHJAX_MD5 "08dd6ef33ca08870220d9aade2a62845" CACHE STRING "MD5 checksum of MathJax tarball")
mark_as_advanced(MATHJAX_URL)
GetFallbackURL(MATHJAX_URL MATHJAX_FALLBACK)

View File

@ -34,8 +34,26 @@ if(MSVC)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif()
# C++11 is required
set(CMAKE_CXX_STANDARD 11)
if(NOT CMAKE_CXX_STANDARD)
if(cxx_std_17 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
set(CMAKE_CXX_STANDARD 17)
else()
set(CMAKE_CXX_STANDARD 11)
endif()
endif()
if(CMAKE_CXX_STANDARD LESS 11)
message(FATAL_ERROR "C++ standard must be set to at least 11")
endif()
if(CMAKE_CXX_STANDARD LESS 17)
message(WARNING "Selecting C++17 standard is preferred over C++${CMAKE_CXX_STANDARD}")
endif()
if(PKG_KOKKOS AND (CMAKE_CXX_STANDARD LESS 17))
set(CMAKE_CXX_STANDARD 17)
endif()
# turn off C++17 check in lmptype.h
if(LAMMPS_CXX11)
add_compile_definitions(LAMMPS_CXX11)
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Need -restrict with Intel compilers

View File

@ -37,7 +37,7 @@ if(DOWNLOAD_QUIP)
endforeach()
# Fix cmake crashing when MATH_LINKOPTS not set, required for e.g. recent Cray Programming Environment
set(temp "${temp} -L/_DUMMY_PATH_\n")
set(temp "${temp}PYTHON=python\nPIP=pip\nEXTRA_LINKOPTS=\n")
set(temp "${temp}PYTHON=${Python_EXECUTABLE}\nPIP=pip\nEXTRA_LINKOPTS=\n")
set(temp "${temp}HAVE_CP2K=0\nHAVE_VASP=0\nHAVE_TB=0\nHAVE_PRECON=1\nHAVE_LOTF=0\nHAVE_ONIOM=0\n")
set(temp "${temp}HAVE_LOCAL_E_MIX=0\nHAVE_QC=0\nHAVE_GAP=1\nHAVE_DESCRIPTORS_NONCOMMERCIAL=1\n")
set(temp "${temp}HAVE_TURBOGAP=0\nHAVE_QR=1\nHAVE_THIRDPARTY=0\nHAVE_FX=0\nHAVE_SCME=0\nHAVE_MTP=0\n")

View File

@ -40,6 +40,13 @@ mark_as_advanced(PLUMED_URL)
mark_as_advanced(PLUMED_MD5)
GetFallbackURL(PLUMED_URL PLUMED_FALLBACK)
# adjust C++ standard support for self-compiled Plumed2
if(CMAKE_CXX_STANDARD GREATER 11)
set(PLUMED_CXX_STANDARD 14)
else()
set(PLUMED_CXX_STANDARD 11)
endif()
if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND (CMAKE_CROSSCOMPILING))
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(CROSS_CONFIGURE mingw64-configure)
@ -55,7 +62,7 @@ if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND (CMAKE_CROSSCOMPILING))
URL_MD5 ${PLUMED_MD5}
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ${CROSS_CONFIGURE} --disable-shared --disable-bsymbolic
--disable-python --enable-cxx=11
--disable-python --enable-cxx=${PLUMED_CXX_STANDARD}
--enable-modules=-adjmat:+crystallization:-dimred:+drr:+eds:-fisst:+funnel:+logmfd:+manyrestraints:+maze:+opes:+multicolvar:-pamm:-piv:+s2cm:-sasa:-ves
${PLUMED_CONFIG_OMP}
${PLUMED_CONFIG_MPI}
@ -142,7 +149,7 @@ else()
CONFIGURE_COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR>
${CONFIGURE_REQUEST_PIC}
--enable-modules=all
--enable-cxx=11
--enable-cxx=${PLUMED_CXX_STANDARD}
--disable-python
${PLUMED_CONFIG_MPI}
${PLUMED_CONFIG_OMP}

View File

@ -1,6 +1,6 @@
if(NOT Python_INTERPRETER)
# backward compatibility with CMake before 3.12 and older LAMMPS documentation
# backward compatibility with older LAMMPS documentation
if(PYTHON_EXECUTABLE)
set(Python_EXECUTABLE ${PYTHON_EXECUTABLE})
endif()

View File

@ -22,12 +22,12 @@ doxygen-warn.log logfile with warnings from running doxygen
and:
github-development-workflow.md notes on the LAMMPS development workflow
include-file-conventions.md notes on LAMMPS' include file conventions
documentation_conventions.md notes on writing documentation for LAMMPS
If you downloaded a LAMMPS tarball from www.lammps.org, then the html
folder and the PDF manual should be included. If you downloaded LAMMPS
from GitHub then you either need to build them.
using GitHub then you either need to build them yourself or read the
online version at https://docs.lammps.org/
You can build the HTML and PDF files yourself, by typing "make html"
or by "make pdf", respectively. This requires various tools and files.
@ -39,10 +39,10 @@ environment and local folders.
Installing prerequisites for the documentation build
To run the HTML documention build toolchain, python 3.x, doxygen, git,
and the venv python module have to be installed if not already available.
Also internet access is initially required to download external files
and tools.
To run the HTML documention build toolchain, python 3.8 or later,
doxygen 1.8.10 or later, git, and the venv python module have to be
installed if not already available. Also internet access is initially
required to download external files and tools.
Building the PDF format manual requires in addition a compatible LaTeX
installation with support for PDFLaTeX and several add-on LaTeX packages
@ -52,16 +52,24 @@ installed. This includes:
- babel
- capt-of
- cmap
- dvipng
- ellipse
- fncychap
- fontawesom
- framed
- geometry
- gyre
- hyperref
- hypcap
- needspace
- pict2e
- times
- tabulary
- titlesec
- upquote
- wrapfig
- xindy
Also the latexmk script is required to run PDFLaTeX and related tools.
the required number of times to have self-consistent output and include
updated bibliography and indices.

View File

@ -14,6 +14,29 @@ As an alternative, you can download a package with pre-built executables
or automated build trees, as described in the :doc:`Install <Install>`
section of the manual.
Prerequisites
-------------
Which software you need to compile and use LAMMPS strongly depends on
which :doc:`features and settings <Build_settings>` and which
:doc:`optional packages <Packages_list>` you are trying to include.
Common to all is that you need a C++ and C compiler, where the C++
compiler has to support at least the C++11 standard (note that some
compilers require command-line flag to activate C++11 support).
Furthermore, if you are building with CMake, you need at least CMake
version 3.20 and a compatible build tool (make or ninja-build); if you
are building the the legacy GNU make based build system you need GNU
make (other make variants are not going to work since the build system
uses features unique to GNU make) and a Unix-like build environment with
a Bourne shell, and shell tools like "sed", "grep", "touch", "test",
"tr", "cp", "mv", "rm", "ln", "diff" and so on. Parts of LAMMPS
interface with or use Python version 3.6 or later.
The LAMMPS developers aim to keep LAMMPS very portable and usable -
at least in parts - on most operating systems commonly used for
running MD simulations. Please see the :doc:`section on portablility
<Intro_portability>` for more details.
.. toctree::
:maxdepth: 1

View File

@ -52,9 +52,9 @@ software or for people that want to modify or extend LAMMPS.
compilers can be configured and built concurrently from the same
source tree.
- Simplified packaging of LAMMPS for Linux distributions, environment
modules, or automated build tools like `Homebrew <https://brew.sh/>`_.
- Integration of automated unit and regression testing (the LAMMPS side
of this is still under active development).
modules, or automated build tools like `Spack <https://spack.io>`_
or `Homebrew <https://brew.sh/>`_.
- Integration of automated unit and regression testing.
.. _cmake_build:

View File

@ -116,9 +116,9 @@ environment variable.
Prerequisites for HTML
----------------------
To run the HTML documentation build toolchain, python 3, git, doxygen,
and virtualenv have to be installed locally. Here are instructions for
common setups:
To run the HTML documentation build toolchain, Python 3.8 or later, git,
doxygen, and virtualenv have to be installed locally. Here are
instructions for common setups:
.. tabs::
@ -128,13 +128,7 @@ common setups:
sudo apt-get install git doxygen
.. tab:: RHEL or CentOS (Version 7.x)
.. code-block:: bash
sudo yum install git doxygen
.. tab:: Fedora or RHEL/CentOS (8.x or later)
.. tab:: Fedora or RHEL/AlmaLinux/RockyLinux (8.x or later)
.. code-block:: bash
@ -154,7 +148,36 @@ Prerequisites for PDF
In addition to the tools needed for building the HTML format manual,
a working LaTeX installation with support for PDFLaTeX and a selection
of LaTeX styles/packages are required. To run the PDFLaTeX translation
of LaTeX styles/packages are required. Apart from LaTeX packages that
are usually installed by default, the following packages are required:
.. table_from_list::
:columns: 11
- amsmath
- anysize
- babel
- capt-of
- cmap
- dvipng
- ellipse
- fncychap
- fontawesom
- framed
- geometry
- gyre
- hyperref
- hypcap
- needspace
- pict2e
- times
- tabulary
- titlesec
- upquote
- wrapfig
- xindy
To run the PDFLaTeX translation
the ``latexmk`` script needs to be installed as well.
Prerequisites for ePUB and MOBI

View File

@ -8,7 +8,7 @@ Optional build settings
LAMMPS can be built with several optional settings. Each subsection
explains how to do this for building both with CMake and make.
* `C++11 standard compliance`_ when building all of LAMMPS
* `C++11 and C++17 standard compliance`_ when building all of LAMMPS
* `FFT library`_ for use with the :doc:`kspace_style pppm <kspace_style>` command
* `Size of LAMMPS integer types and size limits`_
* `Read or write compressed files`_
@ -23,14 +23,15 @@ explains how to do this for building both with CMake and make.
.. _cxx11:
C++11 standard compliance
-------------------------
C++11 and C++17 standard compliance
-----------------------------------
A C++11 standard compatible compiler is a requirement for compiling LAMMPS.
LAMMPS version 3 March 2020 is the last version compatible with the previous
C++98 standard for the core code and most packages. Most currently used
C++ compilers are compatible with C++11, but some older ones may need extra
flags to enable C++11 compliance. Example for GNU c++ 4.8.x:
A C++11 standard compatible compiler is currently the minimum
requirement for compiling LAMMPS. LAMMPS version 3 March 2020 is the
last version compatible with the previous C++98 standard for the core
code and most packages. Most currently used C++ compilers are compatible
with C++11, but some older ones may need extra flags to enable C++11
compliance. Example for GNU c++ 4.8.x:
.. code-block:: make
@ -40,6 +41,17 @@ Individual packages may require compliance with a later C++ standard
like C++14 or C++17. These requirements will be documented with the
:doc:`individual packages <Packages_details>`.
.. versionchanged:: 4Feb2025
Starting with LAMMPS version 4 February 2025 we are starting a
transition to require the C++17 standard. Most current compilers are
compatible and if the C++17 standard is available by default, LAMMPS
will enable C++17 and will compile normally. If the chosen compiler is
not compatible with C++17, but only supports C++11, then the define
-DLAMMPS_CXX11 is required to fall back to compiling with a C++11
compiler. After the next stable release of LAMMPS in summer 2025, the
LAMMPS development branch and future releases will require C++17.
----------
.. _fft:

View File

@ -20,22 +20,30 @@
#include "comm.h"
#include "domain.h"
#include "error.h"
#include "math_const.h"
#include "math_extra.h"
#include "region.h"
#include "safe_pointers.h"
#include "region_block.h"
#include "region_cone.h"
#include "region_cylinder.h"
#include "region_ellipsoid.h"
#include "region_plane.h"
#include "region_prism.h"
#include "region_sphere.h"
#include <cmath>
#include <cstring>
#include <unordered_set>
using namespace LAMMPS_NS;
using MathConst::MY_2PI;
static constexpr double SMALL = 1.0e-10;
static constexpr double DELTA = 1.0e-5;
static constexpr int RESOLUTION = 20;
static constexpr double RADINC = MY_2PI / RESOLUTION;
static const std::unordered_set<std::string> vmdcolors{
"blue", "red", "gray", "orange", "yellow", "tan", "silver", "green", "white",
@ -158,30 +166,14 @@ static constexpr char draw_ellipsoid_function[] =
" return $gid\n"
"}\n\n";
// class that "owns" the file pointer and closes it when going out of scope.
// this avoids a lot of redundant checks and calls.
class AutoClose {
public:
AutoClose() = delete;
AutoClose(const AutoClose &) = delete;
AutoClose(const AutoClose &&) = delete;
explicit AutoClose(FILE *_fp) : fp(_fp) {};
~AutoClose()
{
if (fp) fclose(fp);
}
private:
FILE *fp;
};
/* ---------------------------------------------------------------------- */
void Region2VMD::command(int narg, char **arg)
{
if (narg < 3) utils::missing_cmd_args(FLERR, "region2vmd", error);
FILE *fp = nullptr;
// automatically close file when it goes out of scope
SafeFilePtr fp;
if (comm->me == 0) {
fp = fopen(arg[0], "w");
if (fp == nullptr) {
@ -193,9 +185,6 @@ void Region2VMD::command(int narg, char **arg)
}
}
// automatically close fp when fpowner goes out of scope
AutoClose fpowner(fp);
// defaults
std::string color = "silver";
std::string material = "Transparent";
@ -277,6 +266,9 @@ void Region2VMD::write_region(FILE *fp, Region *region)
return;
}
// update internal variables
region->prematch();
// compute position offset for moving regions
double dx = 0.0;
@ -323,136 +315,441 @@ void Region2VMD::write_region(FILE *fp, Region *region)
if (!cone) {
error->one(FLERR, Error::NOLASTLINE, "Region {} is not of style 'cone'", region->id);
} else {
if (cone->open_faces[0] || cone->open_faces[1])
error->warning(FLERR, "Drawing open-faced cones is not supported");
// The VMD cone primitive requires one radius set to zero
if (cone->radiuslo < SMALL) {
// a VMD cone uses a single cone primitive
if (cone->axis == 'x') {
utils::print(fp, "draw cone {{{1} {2} {3}}} {{{0} {2} {3}}} radius {4} resolution 20\n",
cone->lo + dx, cone->hi + dx, cone->c1 + dy, cone->c2 + dz, cone->radiushi);
} else if (cone->axis == 'y') {
utils::print(fp, "draw cone {{{2} {1} {3}}} {{{2} {0} {3}}} radius {4} resolution 20\n",
cone->lo + dy, cone->hi + dy, cone->c1 + dx, cone->c2 + dz, cone->radiushi);
} else if (cone->axis == 'z') {
utils::print(fp, "draw cone {{{2} {3} {1}}} {{{2} {3} {0}}} radius {4} resolution 20\n",
cone->lo + dz, cone->hi + dz, cone->c1 + dx, cone->c2 + dy, cone->radiushi);
// draw cone
if (!cone->open_faces[2]) {
// both radii too small
if ((cone->radiuslo < SMALL) && (cone->radiushi < SMALL)) {
; // nothing to draw
// lo end has a tip
} else if (cone->radiuslo < SMALL) {
double v1[3], v2[3], v3[3], v4[3], v5[3];
if (cone->axis == 'x') {
// set tip coordinate
v1[0] = cone->lo + dx;
v1[1] = cone->c1 + dy;
v1[2] = cone->c2 + dz;
// loop around radius
for (int i = 0; i < RESOLUTION; ++i) {
v2[0] = cone->hi + dx;
v2[1] = cone->c1 + cone->radiushi * sin(RADINC * i) + dy;
v2[2] = cone->c2 + cone->radiushi * cos(RADINC * i) + dz;
v3[0] = cone->hi + dx;
v3[1] = cone->c1 + cone->radiushi * sin(RADINC * (i + 1.0)) + dy;
v3[2] = cone->c2 + cone->radiushi * cos(RADINC * (i + 1.0)) + dz;
v4[0] = 0.0;
v4[1] = sin(RADINC * i);
v4[2] = cos(RADINC * i);
v5[0] = 0.0;
v5[1] = sin(RADINC * (i + 1.0));
v5[2] = cos(RADINC * (i + 1.0));
utils::print(fp,
"draw trinorm {{{} {} {}}} {{{} {} {}}} {{{} {} {}}} "
"{{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n",
v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2], 1.0, 0.0,
0.0, v4[0], v4[1], v4[2], v5[0], v5[1], v5[2]);
}
} else if (cone->axis == 'y') {
// set tip coordinate
v1[0] = cone->c1 + dx;
v1[1] = cone->lo + dy;
v1[2] = cone->c2 + dz;
// loop around radius
for (int i = 0; i < RESOLUTION; ++i) {
v2[0] = cone->c1 + cone->radiushi * sin(RADINC * i) + dx;
v2[1] = cone->hi + dy;
v2[2] = cone->c2 + cone->radiushi * cos(RADINC * i) + dz;
v3[0] = cone->c1 + cone->radiushi * sin(RADINC * (i + 1.0)) + dx;
v3[1] = cone->hi + dy;
v3[2] = cone->c2 + cone->radiushi * cos(RADINC * (i + 1.0)) + dz;
v4[0] = sin(RADINC * i);
v4[1] = 0.0;
v4[2] = cos(RADINC * i);
v5[0] = sin(RADINC * (i + 1.0));
v5[1] = 0.0;
v5[2] = cos(RADINC * (i + 1.0));
utils::print(fp,
"draw trinorm {{{} {} {}}} {{{} {} {}}} {{{} {} {}}} "
"{{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n",
v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2], 0.0, 1.0,
0.0, v4[0], v4[1], v4[2], v5[0], v5[1], v5[2]);
}
} else if (cone->axis == 'z') {
// set tip coordinate
v1[0] = cone->c1 + dx;
v1[1] = cone->c2 + dy;
v1[2] = cone->lo + dz;
// loop around radius
for (int i = 0; i < RESOLUTION; ++i) {
v2[0] = cone->c1 + cone->radiushi * sin(RADINC * i) + dx;
v2[1] = cone->c2 + cone->radiushi * cos(RADINC * i) + dy;
v2[2] = cone->hi + dz;
v3[0] = cone->c1 + cone->radiushi * sin(RADINC * (i + 1.0)) + dx;
v3[1] = cone->c2 + cone->radiushi * cos(RADINC * (i + 1.0)) + dy;
v3[2] = cone->hi + dz;
v4[0] = sin(RADINC * i);
v4[1] = cos(RADINC * i);
v4[2] = 0.0;
v5[0] = sin(RADINC * (i + 1.0));
v5[1] = cos(RADINC * (i + 1.0));
v5[2] = 0.0;
utils::print(fp,
"draw trinorm {{{} {} {}}} {{{} {} {}}} {{{} {} {}}} "
"{{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n",
v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2], 0.0, 0.0,
1.0, v4[0], v4[1], v4[2], v5[0], v5[1], v5[2]);
}
}
// hi end has a tip
} else if (cone->radiushi < SMALL) {
double v1[3], v2[3], v3[3], v4[3], v5[3];
if (cone->axis == 'x') {
// set tip coordinate
v1[0] = cone->hi + dx;
v1[1] = cone->c1 + dy;
v1[2] = cone->c2 + dz;
// loop around radius
for (int i = 0; i < RESOLUTION; ++i) {
v2[0] = cone->lo + dx;
v2[1] = cone->c1 + cone->radiuslo * sin(RADINC * i) + dy;
v2[2] = cone->c2 + cone->radiuslo * cos(RADINC * i) + dz;
v3[0] = cone->lo + dx;
v3[1] = cone->c1 + cone->radiuslo * sin(RADINC * (i + 1.0)) + dy;
v3[2] = cone->c2 + cone->radiuslo * cos(RADINC * (i + 1.0)) + dz;
v4[0] = 0.0;
v4[1] = sin(RADINC * i);
v4[2] = cos(RADINC * i);
v5[0] = 0.0;
v5[1] = sin(RADINC * (i + 1.0));
v5[2] = cos(RADINC * (i + 1.0));
utils::print(fp,
"draw trinorm {{{} {} {}}} {{{} {} {}}} {{{} {} {}}} "
"{{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n",
v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2], 1.0, 0.0,
0.0, v4[0], v4[1], v4[2], v5[0], v5[1], v5[2]);
}
} else if (cone->axis == 'y') {
// set tip coordinate
v1[0] = cone->c1 + dx;
v1[1] = cone->hi + dy;
v1[2] = cone->c2 + dz;
// loop around radius
for (int i = 0; i < RESOLUTION; ++i) {
v2[0] = cone->c1 + cone->radiuslo * sin(RADINC * i) + dx;
v2[1] = cone->lo + dy;
v2[2] = cone->c2 + cone->radiuslo * cos(RADINC * i) + dz;
v3[0] = cone->c1 + cone->radiuslo * sin(RADINC * (i + 1.0)) + dx;
v3[1] = cone->lo + dy;
v3[2] = cone->c2 + cone->radiuslo * cos(RADINC * (i + 1.0)) + dz;
v4[0] = sin(RADINC * i);
v4[1] = 0.0;
v4[2] = cos(RADINC * i);
v5[0] = sin(RADINC * (i + 1.0));
v5[1] = 0.0;
v5[2] = cos(RADINC * (i + 1.0));
utils::print(fp,
"draw trinorm {{{} {} {}}} {{{} {} {}}} {{{} {} {}}} "
"{{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n",
v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2], 0.0, 1.0,
0.0, v4[0], v4[1], v4[2], v5[0], v5[1], v5[2]);
}
} else if (cone->axis == 'z') {
// set tip coordinate
v1[0] = cone->c1 + dx;
v1[1] = cone->c2 + dy;
v1[2] = cone->hi + dz;
// loop around radius
for (int i = 0; i < RESOLUTION; ++i) {
v2[0] = cone->c1 + cone->radiuslo * sin(RADINC * i) + dx;
v2[1] = cone->c2 + cone->radiuslo * cos(RADINC * i) + dy;
v2[2] = cone->lo + dz;
v3[0] = cone->c1 + cone->radiuslo * sin(RADINC * (i + 1.0)) + dx;
v3[1] = cone->c2 + cone->radiuslo * cos(RADINC * (i + 1.0)) + dy;
v3[2] = cone->lo + dz;
v4[0] = sin(RADINC * i);
v4[1] = cos(RADINC * i);
v4[2] = 0.0;
v5[0] = sin(RADINC * (i + 1.0));
v5[1] = cos(RADINC * (i + 1.0));
v5[2] = 0.0;
utils::print(fp,
"draw trinorm {{{} {} {}}} {{{} {} {}}} {{{} {} {}}} "
"{{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n",
v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2], 0.0, 0.0,
1.0, v4[0], v4[1], v4[2], v5[0], v5[1], v5[2]);
}
}
// truncated cone
} else if (!cone->open_faces[2]) {
double v1[3], v2[3], v3[3], v4[3], v5[3], v6[3], v7[3], v8[3];
if (cone->axis == 'x') {
// loop around radii
for (int i = 0; i < RESOLUTION; ++i) {
v1[0] = cone->hi + dx;
v1[1] = cone->c1 + cone->radiushi * sin(RADINC * (i - 0.5)) + dy;
v1[2] = cone->c2 + cone->radiushi * cos(RADINC * (i - 0.5)) + dz;
v2[0] = cone->lo + dx;
v2[1] = cone->c1 + cone->radiuslo * sin(RADINC * i) + dy;
v2[2] = cone->c2 + cone->radiuslo * cos(RADINC * i) + dz;
v3[0] = cone->hi + dx;
v3[1] = cone->c1 + cone->radiushi * sin(RADINC * (i + 0.5)) + dy;
v3[2] = cone->c2 + cone->radiushi * cos(RADINC * (i + 0.5)) + dz;
v4[0] = cone->lo + dx;
v4[1] = cone->c1 + cone->radiuslo * sin(RADINC * (i + 1.0)) + dy;
v4[2] = cone->c2 + cone->radiuslo * cos(RADINC * (i + 1.0)) + dz;
v5[0] = 0.0;
v5[1] = sin(RADINC * (i - 0.5));
v5[2] = cos(RADINC * (i - 0.5));
v6[0] = 0.0;
v6[1] = sin(RADINC * i);
v6[2] = cos(RADINC * i);
v7[0] = 0.0;
v7[1] = sin(RADINC * (i + 0.5));
v7[2] = cos(RADINC * (i + 0.5));
v8[0] = 0.0;
v8[1] = sin(RADINC * (i + 1.0));
v8[2] = cos(RADINC * (i + 1.0));
utils::print(fp,
"draw trinorm {{{} {} {}}} {{{} {} {}}} {{{} {} {}}} "
"{{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n",
v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2], v5[0],
v5[1], v5[2], v6[0], v6[1], v6[2], v7[0], v7[1], v7[2]);
utils::print(fp,
"draw trinorm {{{} {} {}}} {{{} {} {}}} {{{} {} {}}} "
"{{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n",
v2[0], v2[1], v2[2], v4[0], v4[1], v4[2], v3[0], v3[1], v3[2], v6[0],
v6[1], v6[2], v8[0], v8[1], v8[2], v7[0], v7[1], v7[2]);
}
} else if (cone->axis == 'y') {
// loop around radii
for (int i = 0; i < RESOLUTION; ++i) {
v1[0] = cone->c1 + cone->radiushi * sin(RADINC * (i - 0.5)) + dx;
v1[1] = cone->hi + dy;
v1[2] = cone->c2 + cone->radiushi * cos(RADINC * (i - 0.5)) + dz;
v2[0] = cone->c1 + cone->radiuslo * sin(RADINC * i) + dx;
v2[1] = cone->lo + dy;
v2[2] = cone->c2 + cone->radiuslo * cos(RADINC * i) + dz;
v3[0] = cone->c1 + cone->radiushi * sin(RADINC * (i + 0.5)) + dx;
v3[1] = cone->hi + dy;
v3[2] = cone->c2 + cone->radiushi * cos(RADINC * (i + 0.5)) + dz;
v4[0] = cone->c1 + cone->radiuslo * sin(RADINC * (i + 1.0)) + dx;
v4[1] = cone->lo + dy;
v4[2] = cone->c2 + cone->radiuslo * cos(RADINC * (i + 1.0)) + dz;
v5[0] = sin(RADINC * (i - 0.5));
v5[1] = 0.0;
v5[2] = cos(RADINC * (i - 0.5));
v6[0] = sin(RADINC * i);
v6[1] = 0.0;
v6[2] = cos(RADINC * i);
v7[0] = sin(RADINC * (i + 0.5));
v7[1] = 0.0;
v7[2] = cos(RADINC * (i + 0.5));
v8[0] = sin(RADINC * (i + 1.0));
v8[1] = 0.0;
v8[2] = cos(RADINC * (i + 1.0));
utils::print(fp,
"draw trinorm {{{} {} {}}} {{{} {} {}}} {{{} {} {}}} "
"{{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n",
v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2], v5[0],
v5[1], v5[2], v6[0], v6[1], v6[2], v7[0], v7[1], v7[2]);
utils::print(fp,
"draw trinorm {{{} {} {}}} {{{} {} {}}} {{{} {} {}}} "
"{{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n",
v2[0], v2[1], v2[2], v4[0], v4[1], v4[2], v3[0], v3[1], v3[2], v6[0],
v6[1], v6[2], v8[0], v8[1], v8[2], v7[0], v7[1], v7[2]);
}
} else if (cone->axis == 'z') {
// loop around radii
for (int i = 0; i < RESOLUTION; ++i) {
v1[0] = cone->c1 + cone->radiushi * sin(RADINC * (i - 0.5)) + dx;
v1[1] = cone->c2 + cone->radiushi * cos(RADINC * (i - 0.5)) + dy;
v1[2] = cone->hi + dz;
v2[0] = cone->c1 + cone->radiuslo * sin(RADINC * i) + dx;
v2[1] = cone->c2 + cone->radiuslo * cos(RADINC * i) + dy;
v2[2] = cone->lo + dz;
v3[0] = cone->c1 + cone->radiushi * sin(RADINC * (i + 0.5)) + dx;
v3[1] = cone->c2 + cone->radiushi * cos(RADINC * (i + 0.5)) + dy;
v3[2] = cone->hi + dz;
v4[0] = cone->c1 + cone->radiuslo * sin(RADINC * (i + 1.0)) + dx;
v4[1] = cone->c2 + cone->radiuslo * cos(RADINC * (i + 1.0)) + dy;
v4[2] = cone->lo + dz;
v5[0] = sin(RADINC * (i - 0.5));
v5[1] = cos(RADINC * (i - 0.5));
v5[2] = 0.0;
v6[0] = sin(RADINC * i);
v6[1] = cos(RADINC * i);
v6[2] = 0.0;
v7[0] = sin(RADINC * (i + 0.5));
v7[1] = cos(RADINC * (i + 0.5));
v7[2] = 0.0;
v8[0] = sin(RADINC * (i + 1.0));
v8[1] = cos(RADINC * (i + 1.0));
v8[2] = 0.0;
utils::print(fp,
"draw trinorm {{{} {} {}}} {{{} {} {}}} {{{} {} {}}} "
"{{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n",
v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2], v5[0],
v5[1], v5[2], v6[0], v6[1], v6[2], v7[0], v7[1], v7[2]);
utils::print(fp,
"draw trinorm {{{} {} {}}} {{{} {} {}}} {{{} {} {}}} "
"{{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n",
v2[0], v2[1], v2[2], v4[0], v4[1], v4[2], v3[0], v3[1], v3[2], v6[0],
v6[1], v6[2], v8[0], v8[1], v8[2], v7[0], v7[1], v7[2]);
}
}
}
} else if (cone->radiushi < SMALL) {
// a VMD cone uses a single cone primitive
}
// draw lids
if ((cone->radiuslo > SMALL) && !cone->open_faces[0]) {
double lid = cone->lo;
if (cone->axis == 'x') {
utils::print(fp, "draw cone {{{0} {2} {3}}} {{{1} {2} {3}}} radius {4} resolution 20\n",
cone->lo + dx, cone->hi + dx, cone->c1 + dy, cone->c2 + dz, cone->radiuslo);
lid += dx;
utils::print(fp,
"draw cylinder {{{0} {2} {3}}} {{{1:.15} {2} {3}}} radius {4} "
"resolution {5} filled yes\n",
lid, lid + DELTA, cone->c1 + dy, cone->c2 + dz, cone->radiuslo, RESOLUTION);
} else if (cone->axis == 'y') {
utils::print(fp, "draw cone {{{2} {0} {3}}} {{{2} {1} {3}}} radius {4} resolution 20\n",
cone->lo + dy, cone->hi + dy, cone->c1 + dx, cone->c2 + dz, cone->radiuslo);
lid += dy;
utils::print(fp,
"draw cylinder {{{2} {0} {3}}} {{{2} {1:.15} {3}}} radius {4} "
"resolution {5} filled yes\n",
lid, lid + DELTA, cone->c1 + dx, cone->c2 + dz, cone->radiuslo, RESOLUTION);
} else if (cone->axis == 'z') {
utils::print(fp, "draw cone {{{2} {3} {0}}} {{{2} {3} {1}}} radius {4} resolution 20\n",
cone->lo + dz, cone->hi + dz, cone->c1 + dx, cone->c2 + dy, cone->radiuslo);
lid += dz;
utils::print(fp,
"draw cylinder {{{2} {3} {0}}} {{{2} {3} {1:.15}}} radius {4} "
"resolution {5} filled yes\n",
lid, lid + DELTA, cone->c1 + dx, cone->c2 + dy, cone->radiuslo, RESOLUTION);
}
}
if ((cone->radiushi > SMALL) && !cone->open_faces[1]) {
double lid = cone->hi;
if (cone->axis == 'x') {
lid += dx;
utils::print(fp,
"draw cylinder {{{0} {2} {3}}} {{{1:.15} {2} {3}}} radius {4} "
"resolution {5} filled yes\n",
lid, lid + DELTA, cone->c1 + dy, cone->c2 + dz, cone->radiushi, RESOLUTION);
} else if (cone->axis == 'y') {
lid += dy;
utils::print(fp,
"draw cylinder {{{2} {0} {3}}} {{{2} {1:.15} {3}}} radius {4} "
"resolution {5} filled yes\n",
lid, lid + DELTA, cone->c1 + dx, cone->c2 + dz, cone->radiushi, RESOLUTION);
} else if (cone->axis == 'z') {
lid += dz;
utils::print(fp,
"draw cylinder {{{2} {3} {0}}} {{{2} {3} {1:.15}}} radius {4} "
"resolution {5} filled yes\n",
lid, lid + DELTA, cone->c1 + dx, cone->c2 + dy, cone->radiushi, RESOLUTION);
}
} else {
utils::logmesg(lmp,
"Cannot (yet) translate a truncated cone to VMD graphics. Skipping...\n");
}
}
} else if (regstyle == "cylinder") {
const auto cylinder = dynamic_cast<RegCylinder *>(region);
if (!cylinder) {
const auto cyl = dynamic_cast<RegCylinder *>(region);
if (!cyl) {
error->one(FLERR, Error::NOLASTLINE, "Region {} is not of style 'cylinder'", region->id);
} else {
std::string filled = "yes";
if (cylinder->open_faces[0] && cylinder->open_faces[1]) {
filled = "no";
} else if (cylinder->open_faces[0] != cylinder->open_faces[1]) {
filled = "no";
// we put a single "lid" on an open cylinder by adding a filled cylinder of zero height
double lid = cylinder->lo;
if (cylinder->open_faces[0]) lid = cylinder->hi;
if (cylinder->axis == 'x') {
utils::print(fp,
"draw cylinder {{{0} {2} {3}}} {{{1:.15} {2} {3}}} radius {4} resolution 20 "
"filled yes\n",
lid + dx, lid + dx + DELTA, cylinder->c1 + dy, cylinder->c2 + dz,
cylinder->radius);
} else if (cylinder->axis == 'y') {
utils::print(fp,
"draw cylinder {{{2} {0} {3}}} {{{2} {1:.15} {3}}} radius {4} resolution 20 "
"filled yes\n",
lid + dy, lid + dy + DELTA, cylinder->c1 + dx, cylinder->c2 + dz,
cylinder->radius);
} else if (cylinder->axis == 'z') {
utils::print(fp,
"draw cylinder {{{2} {3} {0}}} {{{2} {3} {1:.15}}} radius {4} resolution 20 "
"filled yes\n",
lid + dz, lid + dz + DELTA, cylinder->c1 + dx, cylinder->c2 + dy,
cylinder->radius);
// first draw the cylinder. filled only when *all* faces are closed.
// with any open face we draw each part separately
std::string filled = "filled no";
if (!cyl->open_faces[0] && !cyl->open_faces[1] && !cyl->open_faces[2]) {
filled = "filled yes";
}
// the cylinder uses a single cylinder primitive
if (!cyl->open_faces[2]) {
if (cyl->axis == 'x') {
utils::print(
fp, "draw cylinder {{{0} {2} {3}}} {{{1} {2} {3}}} radius {4} resolution {5} {6}\n",
cyl->lo + dx, cyl->hi + dx, cyl->c1 + dy, cyl->c2 + dz, cyl->radius, RESOLUTION,
filled);
} else if (cyl->axis == 'y') {
utils::print(
fp, "draw cylinder {{{2} {0} {3}}} {{{2} {1} {3}}} radius {4} resolution {5} {6}\n",
cyl->lo + dy, cyl->hi + dy, cyl->c1 + dx, cyl->c2 + dz, cyl->radius, RESOLUTION,
filled);
} else if (cyl->axis == 'z') {
utils::print(
fp, "draw cylinder {{{2} {3} {0}}} {{{2} {3} {1}}} radius {4} resolution {5} {6}\n",
cyl->lo + dz, cyl->hi + dz, cyl->c1 + dx, cyl->c2 + dy, cyl->radius, RESOLUTION,
filled);
}
}
if (cylinder->open_faces[2]) {
// need to handle two lids case only. Single lid is already done
if (!cylinder->open_faces[0] && !cylinder->open_faces[1]) {
if (cylinder->axis == 'x') {
utils::print(
fp,
"draw cylinder {{{0} {2} {3}}} {{{1:.15} {2} {3}}} radius {4} resolution 20 "
"filled yes\n",
cylinder->lo + dx, cylinder->lo + dx + DELTA, cylinder->c1 + dy, cylinder->c2 + dz,
cylinder->radius);
utils::print(
fp,
"draw cylinder {{{0} {2} {3}}} {{{1:.15} {2} {3}}} radius {4} resolution 20 "
"filled yes\n",
cylinder->hi + dx, cylinder->hi + dx + DELTA, cylinder->c1 + dy, cylinder->c2 + dz,
cylinder->radius);
} else if (cylinder->axis == 'y') {
utils::print(
fp,
"draw cylinder {{{2} {0} {3}}} {{{2} {1:.15} {3}}} radius {4} resolution 20 "
"filled yes\n",
cylinder->lo + dy, cylinder->lo + dy + DELTA, cylinder->c1 + dx, cylinder->c2 + dz,
cylinder->radius);
utils::print(
fp,
"draw cylinder {{{2} {0} {3}}} {{{2} {1:.15} {3}}} radius {4} resolution 20 "
"filled yes\n",
cylinder->hi + dy, cylinder->hi + dy + DELTA, cylinder->c1 + dx, cylinder->c2 + dz,
cylinder->radius);
} else if (cylinder->axis == 'z') {
utils::print(
fp,
"draw cylinder {{{2} {3} {0}}} {{{2} {3} {1:.15}}} radius {4} resolution 20 "
"filled yes\n",
cylinder->lo + dz, cylinder->lo + dz + DELTA, cylinder->c1 + dx, cylinder->c2 + dy,
cylinder->radius);
utils::print(
fp,
"draw cylinder {{{2} {3} {0}}} {{{2} {3} {1:.15}}} radius {4} resolution 20 "
"filled yes\n",
cylinder->hi + dz, cylinder->hi + dz + DELTA, cylinder->c1 + dx, cylinder->c2 + dy,
cylinder->radius);
}
// draw lids
if ((filled == "filled no") && !cyl->open_faces[0]) {
double lid = cyl->lo;
if (cyl->axis == 'x') {
lid += dx;
utils::print(fp,
"draw cylinder {{{0} {2} {3}}} {{{1:.15} {2} {3}}} radius {4} "
"resolution {5} filled yes\n",
lid, lid + DELTA, cyl->c1 + dy, cyl->c2 + dz, cyl->radius, RESOLUTION);
} else if (cyl->axis == 'y') {
lid += dy;
utils::print(fp,
"draw cylinder {{{2} {0} {3}}} {{{2} {1:.15} {3}}} radius {4} "
"resolution {5} filled yes\n",
lid, lid + DELTA, cyl->c1 + dx, cyl->c2 + dz, cyl->radius, RESOLUTION);
} else if (cyl->axis == 'z') {
lid += dz;
utils::print(fp,
"draw cylinder {{{2} {3} {0}}} {{{2} {3} {1:.15}}} radius {4} "
"resolution {5} filled yes\n",
lid, lid + DELTA, cyl->c1 + dx, cyl->c2 + dy, cyl->radius, RESOLUTION);
}
} else {
// a cylinder uses a single cylinder primitive and possibly a single "lid"
if (cylinder->axis == 'x') {
utils::print(
fp,
"draw cylinder {{{0} {2} {3}}} {{{1} {2} {3}}} radius {4} resolution 20 filled {5}\n",
cylinder->lo + dx, cylinder->hi + dx, cylinder->c1 + dy, cylinder->c2 + dz,
cylinder->radius, filled);
} else if (cylinder->axis == 'y') {
utils::print(
fp,
"draw cylinder {{{2} {0} {3}}} {{{2} {1} {3}}} radius {4} resolution 20 filled {5}\n",
cylinder->lo + dy, cylinder->hi + dy, cylinder->c1 + dx, cylinder->c2 + dz,
cylinder->radius, filled);
} else if (cylinder->axis == 'z') {
utils::print(
fp,
"draw cylinder {{{2} {3} {0}}} {{{2} {3} {1}}} radius {4} resolution 20 filled {5}\n",
cylinder->lo + dz, cylinder->hi + dz, cylinder->c1 + dx, cylinder->c2 + dy,
cylinder->radius, filled);
}
if ((filled == "filled no") && !cyl->open_faces[1]) {
double lid = cyl->hi;
if (cyl->axis == 'x') {
lid += dx;
utils::print(fp,
"draw cylinder {{{0} {2} {3}}} {{{1:.15} {2} {3}}} radius {4} "
"resolution {5} filled yes\n",
lid, lid + DELTA, cyl->c1 + dy, cyl->c2 + dz, cyl->radius, RESOLUTION);
} else if (cyl->axis == 'y') {
lid += dy;
utils::print(fp,
"draw cylinder {{{2} {0} {3}}} {{{2} {1:.15} {3}}} radius {4} "
"resolution {5} filled yes\n",
lid, lid + DELTA, cyl->c1 + dx, cyl->c2 + dz, cyl->radius, RESOLUTION);
} else if (cyl->axis == 'z') {
lid += dz;
utils::print(fp,
"draw cylinder {{{2} {3} {0}}} {{{2} {3} {1:.15}}} radius {4} "
"resolution {5} filled yes\n",
lid, lid + DELTA, cyl->c1 + dx, cyl->c2 + dy, cyl->radius, RESOLUTION);
}
}
}
@ -468,6 +765,85 @@ void Region2VMD::write_region(FILE *fp, Region *region)
ellipsoid->c);
}
} else if (regstyle == "plane") {
const auto plane = dynamic_cast<RegPlane *>(region);
if (!plane) {
error->one(FLERR, Error::NOLASTLINE, "Region {} is not of style 'plane'", region->id);
} else {
double v1[3], v2[3], v3[3], v4[3], v5[3], v6[3];
MathExtra::copy3(plane->normal, v1);
MathExtra::norm3(v1);
v2[0] = plane->xp + dx;
v2[1] = plane->yp + dy;
v2[2] = plane->zp + dz;
// determine the largest component of the plane normal and use that to determine the triangle edges
int dim1, dim2, dim3;
if (fabs(v1[0]) > fabs(v1[1])) { // x > y
if (fabs(v1[0]) > fabs(v1[2])) { // x > z => x is largest
dim3 = 0;
dim1 = 1;
dim2 = 2;
} else { // z is largest
dim3 = 2;
dim1 = 0;
dim2 = 1;
}
} else { // x < y
if (fabs(v1[1]) > fabs(v1[2])) { // y > z => y is largest
dim3 = 1;
dim1 = 0;
dim2 = 2;
} else { // z is largest
dim3 = 2;
dim1 = 0;
dim2 = 1;
}
}
MathExtra::scale3(2.0, domain->boxlo, v3);
v3[dim3] = 0.0;
MathExtra::cross3(v1, v3, v4);
MathExtra::add3(v4, v2, v5);
v3[dim1] = domain->boxhi[dim1];
v3[dim2] = domain->boxlo[dim2];
v3[dim3] = 0.0;
MathExtra::scale3(2.0, v3);
MathExtra::cross3(v1, v3, v4);
MathExtra::add3(v4, v2, v6);
utils::print(fp, "draw triangle {{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n", v2[dim1], v2[dim2],
v2[dim3], v5[dim1], v5[dim2], v5[dim3], v6[dim1], v6[dim2], v6[dim3]);
v3[dim1] = domain->boxlo[dim1];
v3[dim2] = domain->boxhi[dim2];
v3[dim3] = 0.0;
MathExtra::scale3(2.0, v3);
MathExtra::cross3(v1, v3, v4);
MathExtra::add3(v4, v2, v6);
utils::print(fp, "draw triangle {{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n", v2[dim1], v2[dim2],
v2[dim3], v5[dim1], v5[dim2], v5[dim3], v6[dim1], v6[dim2], v6[dim3]);
v3[dim1] = domain->boxhi[dim1];
v3[dim2] = domain->boxhi[dim2];
v3[dim3] = 0.0;
MathExtra::scale3(2.0, v3);
MathExtra::cross3(v1, v3, v4);
MathExtra::add3(v4, v2, v5);
v3[dim1] = domain->boxhi[dim1];
v3[dim2] = domain->boxlo[dim2];
v3[dim3] = 0.0;
MathExtra::scale3(2.0, v3);
MathExtra::cross3(v1, v3, v4);
MathExtra::add3(v4, v2, v6);
utils::print(fp, "draw triangle {{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n", v2[dim1], v2[dim2],
v2[dim3], v5[dim1], v5[dim2], v5[dim3], v6[dim1], v6[dim2], v6[dim3]);
v3[dim1] = domain->boxlo[dim1];
v3[dim2] = domain->boxhi[dim2];
v3[dim3] = 0.0;
MathExtra::scale3(2.0, v3);
MathExtra::cross3(v1, v3, v4);
MathExtra::add3(v4, v2, v6);
utils::print(fp, "draw triangle {{{} {} {}}} {{{} {} {}}} {{{} {} {}}}\n", v2[dim1], v2[dim2],
v2[dim3], v5[dim1], v5[dim2], v5[dim3], v6[dim1], v6[dim2], v6[dim3]);
}
} else if (regstyle == "prism") {
const auto prism = dynamic_cast<RegPrism *>(region);
if (!prism) {
@ -504,8 +880,8 @@ void Region2VMD::write_region(FILE *fp, Region *region)
error->one(FLERR, Error::NOLASTLINE, "Region {} is not of style 'sphere'", region->id);
} else {
// a sphere uses a single sphere primitive
utils::print(fp, "draw sphere {{{} {} {}}} radius {} resolution 20\n", sphere->xc, sphere->yc,
sphere->zc, sphere->radius);
utils::print(fp, "draw sphere {{{} {} {}}} radius {} resolution {}\n", sphere->xc, sphere->yc,
sphere->zc, sphere->radius, RESOLUTION);
}
} else {

View File

@ -793,7 +793,10 @@ void CommKokkos::exchange()
}
atomKK->sync(Host,ALL_MASK);
int prev_auto_sync = lmp->kokkos->auto_sync;
lmp->kokkos->auto_sync = 1;
CommBrick::exchange();
lmp->kokkos->auto_sync = prev_auto_sync;
atomKK->modified(Host,ALL_MASK);
}

View File

@ -36,6 +36,8 @@ DISTRIBUTION A. Approved for public release; distribution unlimited. OPSEC#4918
using namespace LAMMPS_NS::RANN;
static constexpr double SMALL = 1.0e-12;
Fingerprint_bond::Fingerprint_bond(PairRANN *_pair) : Fingerprint(_pair)
{
n_body_type = 3;
@ -317,7 +319,8 @@ void Fingerprint_bond::do3bodyfeatureset_singleneighborloop(double * features,do
i = ilist[ii];
itype = pair->map[type[i]];
int f = pair->net[itype].dimensions[0];
double expr[jnum][kmax+12];
std::vector<double> row(kmax+12, 0.0);
std::vector<std::vector<double>> expr(jnum, row);
int p = kmax;
int countmb=((mlength)*(mlength+1))>>1;
// calculate interpolation expr, rinvs and dfc, for each neighbor
@ -354,13 +357,13 @@ void Fingerprint_bond::do3bodyfeatureset_singleneighborloop(double * features,do
expr[jj][p+1]=dely*rinvs;
expr[jj][p+2]=delz*rinvs;
//Hack to avoid nan when x y or z component of radial vector is exactly 0. Shouldn't affect accuracy.
if (expr[jj][p]*expr[jj][p]<0.000000000001) {
if (expr[jj][p]*expr[jj][p] < SMALL) {
expr[jj][p] = 0.000001;
}
if (expr[jj][p+1]*expr[jj][p+1]<0.000000000001) {
if (expr[jj][p+1]*expr[jj][p+1] < SMALL) {
expr[jj][p+1] = 0.000001;
}
if (expr[jj][p+2]*expr[jj][p+2]<0.000000000001) {
if (expr[jj][p+2]*expr[jj][p+2] < SMALL) {
expr[jj][p+2] = 0.000001;
}
expr[jj][p+3] = -dfc*expr[jj][p];
@ -377,7 +380,7 @@ void Fingerprint_bond::do3bodyfeatureset_singleneighborloop(double * features,do
int kb = kmax;
int mb = mlength;
count = startingneuron;
double Bb[mb];
std::vector<double> Bb(mb, 0.0);
double dBbx;
double dBby;
double dBbz;
@ -397,7 +400,7 @@ void Fingerprint_bond::do3bodyfeatureset_singleneighborloop(double * features,do
}
for (n=0;n<kb;n++) {
for (a1=0;a1<mb;a1++) {
Bb[a1]=0;
Bb[a1]=0.0;
}
ai = n;
double y1 = alpha_k[ai]/re;
@ -409,7 +412,7 @@ void Fingerprint_bond::do3bodyfeatureset_singleneighborloop(double * features,do
continue;
}
double yprod = expr[jj][ai];
double *y4 = &expr[jj][p];
double *y4 = expr[jj].data() + p;
for (a2=0;a2<a;a2++) {
yprod *= y4[M[a2+1]];
}
@ -419,10 +422,7 @@ void Fingerprint_bond::do3bodyfeatureset_singleneighborloop(double * features,do
}
}
if (atomtypes[1]!=atomtypes[2]) {//Bb!=Bg
double Bg[mb];
for (a1=0;a1<mb;a1++) {
Bg[a1]=0;
}
std::vector<double> Bg(mb, 0.0);
ai = n;
double y1 = alpha_k[ai]/re;
//loop over ktype to get Bg
@ -433,7 +433,7 @@ void Fingerprint_bond::do3bodyfeatureset_singleneighborloop(double * features,do
continue;
}
double yprod = expr[jj][ai];
double *y4 = &expr[jj][p];
double *y4 = expr[jj].data() + p;
for (a2=0;a2<a;a2++) {
yprod *= y4[M[a2+1]];
}
@ -450,8 +450,8 @@ void Fingerprint_bond::do3bodyfeatureset_singleneighborloop(double * features,do
if (atomtypes[2] != nelements && atomtypes[2] != jtype) {
continue;
}
double *y3 = &expr[jj][p+3];
double *y4 = &expr[jj][p];
double *y3 = expr[jj].data() + p + 3;
double *y4 = expr[jj].data() + p;
ai = n;
yprod = expr[jj][ai];
for (a2=0;a2<a;a2++) {
@ -477,8 +477,8 @@ void Fingerprint_bond::do3bodyfeatureset_singleneighborloop(double * features,do
if (atomtypes[1] != nelements && atomtypes[1] != jtype) {
continue;
}
double *y3 = &expr[jj][p+3];
double *y4 = &expr[jj][p];
double *y3 = expr[jj].data() + p + 3;
double *y4 = expr[jj].data() + p;
ai = n;
yprod = expr[jj][ai];
for (a2=0;a2<a;a2++) {
@ -512,8 +512,8 @@ void Fingerprint_bond::do3bodyfeatureset_singleneighborloop(double * features,do
if (atomtypes[1] != nelements && atomtypes[1] != jtype) {
continue;
}
double *y3 = &expr[jj][p+3];
double *y4 = &expr[jj][p];
double *y3 = expr[jj].data() + p + 3;
double *y4 = expr[jj].data() + p;
ai = n;
yprod = expr[jj][ai];
for (a2=0;a2<a;a2++) {
@ -572,16 +572,18 @@ void Fingerprint_bond::do3bodyfeatureset_doubleneighborloop(double * features,do
i = ilist[ii];
itype = pair->map[type[i]];
int f = pair->net[itype].dimensions[0];
double expr[jnum][kmax];
double y[jnum][3];
double ri[jnum];
double dfc[jnum];
std::vector<double> row(kmax, 0.0);
std::vector<std::vector<double>> expr(jnum, row);
std::vector<double> yrow(3, 0.0);
std::vector<std::vector<double>> y(jnum, yrow);
std::vector<double> ri(jnum, 0.0);
std::vector<double> dfc(jnum, 0.0);
int kb = kmax;
int mb = mlength;
double c41[kmax];
double c51[kmax];
double c61[kmax];
double ct[kmax];
std::vector<double> c41(kmax, 0.0);
std::vector<double> c51(kmax, 0.0);
std::vector<double> c61(kmax, 0.0);
std::vector<double> ct(kmax, 0.0);
for (jj = 0; jj < jnum; jj++) {
jtype = tn[jj];
if (jtypes != nelements && jtypes != jtype && ktypes != nelements && ktypes != jtype) {

View File

@ -36,6 +36,8 @@ DISTRIBUTION A. Approved for public release; distribution unlimited. OPSEC#4918
using namespace LAMMPS_NS::RANN;
static constexpr double SMALL = 1.0e-12;
Fingerprint_bondscreened::Fingerprint_bondscreened(PairRANN *_pair) : Fingerprint(_pair)
{
n_body_type = 3;
@ -319,7 +321,8 @@ void Fingerprint_bondscreened::do3bodyfeatureset_singleneighborloop(double * fea
i = ilist[ii];
itype = pair->map[type[i]];
int f = pair->net[itype].dimensions[0];
double expr[jnum][kmax+12];
std::vector<double> row(kmax+12, 0.0);
std::vector<std::vector<double>> expr(jnum, row);
int p = kmax;
int countmb=((mlength)*(mlength+1))>>1;
// calculate interpolation expr, rinvs and dfc, for each neighbor
@ -358,13 +361,13 @@ void Fingerprint_bondscreened::do3bodyfeatureset_singleneighborloop(double * fea
expr[jj][p+1]=dely*rinvs;
expr[jj][p+2]=delz*rinvs;
//Hack to avoid nan when x y or z component of radial vector is exactly 0. Shouldn't affect accuracy.
if (expr[jj][p]*expr[jj][p]<0.000000000001) {
if (expr[jj][p]*expr[jj][p] < SMALL) {
expr[jj][p] = 0.000001;
}
if (expr[jj][p+1]*expr[jj][p+1]<0.000000000001) {
if (expr[jj][p+1]*expr[jj][p+1] < SMALL) {
expr[jj][p+1] = 0.000001;
}
if (expr[jj][p+2]*expr[jj][p+2]<0.000000000001) {
if (expr[jj][p+2]*expr[jj][p+2] < SMALL) {
expr[jj][p+2] = 0.000001;
}
expr[jj][p+3] = -dfc*expr[jj][p]-dSikx[jj];
@ -381,20 +384,20 @@ void Fingerprint_bondscreened::do3bodyfeatureset_singleneighborloop(double * fea
int kb = kmax;
int mb = mlength;
count = startingneuron;
double Bb[mb];
std::vector<double> Bb(mb, 0.0);
double dBbx;
double dBby;
double dBbz;
double dBbx1[mb];
double dBby1[mb];
double dBbz1[mb];
std::vector<double> dBbx1(mb, 0.0);
std::vector<double> dBby1(mb, 0.0);
std::vector<double> dBbz1(mb, 0.0);
double yprod;
for (mcount=0;mcount<countmb;mcount++) {
int *M = Mf[mcount];
int *_coeffx = coeffx[mcount];
int *_coeffy = coeffy[mcount];
int *_coeffz = coeffz[mcount];
int *_coeff = coeff[mcount];
int *_coeffy = coeffy[mcount];
int *_coeffz = coeffz[mcount];
int *_coeff = coeff[mcount];
a = mb+1;
for (a1=0;a1<mb;a1++) {
if (Mf[mcount][a1+1]==0) {
@ -420,7 +423,7 @@ void Fingerprint_bondscreened::do3bodyfeatureset_singleneighborloop(double * fea
continue;
}
double yprod = expr[jj][ai];
double *y4 = &expr[jj][p];
double *y4 = expr[jj].data() + p;
for (a2=0;a2<a;a2++) {
yprod *= y4[M[a2+1]];
}
@ -430,10 +433,7 @@ void Fingerprint_bondscreened::do3bodyfeatureset_singleneighborloop(double * fea
}
}
if (atomtypes[1]!=atomtypes[2]) {//Bb!=Bg
double Bg[mb];
for (a1=0;a1<mb;a1++) {
Bg[a1]=0;
}
std::vector<double> Bg(mb, 0.0);
ai = n;
double y1 = alpha_k[ai]/re;
//loop over ktype to get Bg
@ -445,7 +445,7 @@ void Fingerprint_bondscreened::do3bodyfeatureset_singleneighborloop(double * fea
continue;
}
double yprod = expr[jj][ai];
double *y4 = &expr[jj][p];
double *y4 = expr[jj].data() + p;
for (a2=0;a2<a;a2++) {
yprod *= y4[M[a2+1]];
}
@ -463,8 +463,8 @@ void Fingerprint_bondscreened::do3bodyfeatureset_singleneighborloop(double * fea
if (atomtypes[2] != nelements && atomtypes[2] != jtype) {
continue;
}
double *y3 = &expr[jj][p+3];
double *y4 = &expr[jj][p];
double *y3 = expr[jj].data() + p + 3;
double *y4 = expr[jj].data() + p;
ai = n;
yprod = expr[jj][ai];
for (a2=0;a2<a;a2++) {
@ -500,8 +500,8 @@ void Fingerprint_bondscreened::do3bodyfeatureset_singleneighborloop(double * fea
if (atomtypes[1] != nelements && atomtypes[1] != jtype) {
continue;
}
double *y3 = &expr[jj][p+3];
double *y4 = &expr[jj][p];
double *y3 = expr[jj].data() + p + 3;
double *y4 = expr[jj].data() + p;
ai = n;
yprod = expr[jj][ai];
for (a2=0;a2<a;a2++) {
@ -545,8 +545,8 @@ void Fingerprint_bondscreened::do3bodyfeatureset_singleneighborloop(double * fea
if (atomtypes[1] != nelements && atomtypes[1] != jtype) {
continue;
}
double *y3 = &expr[jj][p+3];
double *y4 = &expr[jj][p];
double *y3 = expr[jj].data() + p + 3;
double *y4 = expr[jj].data() + p;
ai = n;
yprod = expr[jj][ai];
for (a2=0;a2<a;a2++) {
@ -615,17 +615,20 @@ void Fingerprint_bondscreened::do3bodyfeatureset_doubleneighborloop(double * fea
i = ilist[ii];
itype = pair->map[type[i]];
int f = pair->net[itype].dimensions[0];
double expr[jnum][kmax];
double y[jnum][3];
double ri[jnum];
double dfc[jnum];
std::vector<double> row(kmax, 0.0);
std::vector<std::vector<double>> expr(jnum, row);
std::vector<double> yrow(3, 0.0);
std::vector<std::vector<double>> y(jnum, yrow);
std::vector<double> ri(jnum, 0.0);
std::vector<double> dfc(jnum, 0.0);
int kb = kmax;
int mb = mlength;
double Bijk[kb][mb];
double c41[kmax];
double c51[kmax];
double c61[kmax];
double ct[kmax];
std::vector<double> brow(mb, 0.0);
std::vector<std::vector<double>> Bijk(kb, brow);
std::vector<double> c41(kmax, 0.0);
std::vector<double> c51(kmax, 0.0);
std::vector<double> c61(kmax, 0.0);
std::vector<double> ct(kmax, 0.0);
for (jj = 0; jj < jnum; jj++) {
if (Bij[jj]==false) {continue;}
jtype = tn[jj];

View File

@ -35,6 +35,8 @@ DISTRIBUTION A. Approved for public release; distribution unlimited. OPSEC#4918
using namespace LAMMPS_NS::RANN;
static constexpr double SMALL = 1.0e-12;
Fingerprint_bondscreenedspin::Fingerprint_bondscreenedspin(PairRANN *_pair) : Fingerprint(_pair)
{
n_body_type = 3;
@ -320,7 +322,8 @@ void Fingerprint_bondscreenedspin::do3bodyfeatureset_singleneighborloop(double *
i = ilist[ii];
itype = pair->map[type[i]];
int f = pair->net[itype].dimensions[0];
double expr[jnum][kmax+12];
std::vector<double> row(kmax+12, 0.0);
std::vector<std::vector<double>> expr(jnum, row);
int p = kmax;
int countmb=((mlength)*(mlength+1))>>1;
double *si = sim->s[i];
@ -360,13 +363,13 @@ void Fingerprint_bondscreenedspin::do3bodyfeatureset_singleneighborloop(double *
expr[jj][p+1]=dely*rinvs;
expr[jj][p+2]=delz*rinvs;
//Hack to avoid nan when x y or z component of radial vector is exactly 0. Shouldn't affect accuracy.
if (expr[jj][p]*expr[jj][p]<0.000000000001) {
if (expr[jj][p]*expr[jj][p] < SMALL) {
expr[jj][p] = 0.000001;
}
if (expr[jj][p+1]*expr[jj][p+1]<0.000000000001) {
if (expr[jj][p+1]*expr[jj][p+1] < SMALL) {
expr[jj][p+1] = 0.000001;
}
if (expr[jj][p+2]*expr[jj][p+2]<0.000000000001) {
if (expr[jj][p+2]*expr[jj][p+2] < SMALL) {
expr[jj][p+2] = 0.000001;
}
expr[jj][p+3] = -dfc*expr[jj][p]-dSikx[jj];
@ -383,8 +386,8 @@ void Fingerprint_bondscreenedspin::do3bodyfeatureset_singleneighborloop(double *
int kb = kmax;
int mb = mlength;
count = startingneuron;
double Bb[mb];
double Bbs[mb];
std::vector<double> Bb(mb, 0.0);
std::vector<double> Bbs(mb, 0.0);
double dBbx;
double dBby;
double dBbz;
@ -421,7 +424,7 @@ void Fingerprint_bondscreenedspin::do3bodyfeatureset_singleneighborloop(double *
double *sj = sim->s[j];
double sp = si[0]*sj[0]+si[1]*sj[1]+si[2]*sj[2];
double yprod = expr[jj][ai];
double *y4 = &expr[jj][p];
double *y4 = expr[jj].data() + p;
for (a2=0;a2<a;a2++) {
yprod *= y4[M[a2+1]];
}
@ -432,12 +435,8 @@ void Fingerprint_bondscreenedspin::do3bodyfeatureset_singleneighborloop(double *
}
}
if (atomtypes[1]!=atomtypes[2]) {//Bb!=Bg
double Bg[mb];
double Bgs[mb];
for (a1=0;a1<mb;a1++) {
Bg[a1]=0;
Bgs[a1]=0;
}
std::vector<double> Bg(mb, 0.0);
std::vector<double> Bgs(mb, 0.0);
ai = n;
double y1 = alpha_k[ai]/re;
//loop over ktype to get Bg
@ -452,7 +451,7 @@ void Fingerprint_bondscreenedspin::do3bodyfeatureset_singleneighborloop(double *
double *sj = sim->s[j];
double sp = si[0]*sj[0]+si[1]*sj[1]+si[2]*sj[2];
double yprod = expr[jj][ai];
double *y4 = &expr[jj][p];
double *y4 = expr[jj].data() + p;
for (a2=0;a2<a;a2++) {
yprod *= y4[M[a2+1]];
}
@ -474,8 +473,8 @@ void Fingerprint_bondscreenedspin::do3bodyfeatureset_singleneighborloop(double *
j = jl[jj];
double *sj = sim->s[j];
double sp = si[0]*sj[0]+si[1]*sj[1]+si[2]*sj[2];
double *y3 = &expr[jj][p+3];
double *y4 = &expr[jj][p];
double *y3 = expr[jj].data() + p + 3;
double *y4 = expr[jj].data() + p;
ai = n;
yprod = expr[jj][ai];
for (a2=0;a2<a;a2++) {
@ -517,8 +516,8 @@ void Fingerprint_bondscreenedspin::do3bodyfeatureset_singleneighborloop(double *
j = jl[jj];
double *sj = sim->s[j];
double sp = si[0]*sj[0]+si[1]*sj[1]+si[2]*sj[2];
double *y3 = &expr[jj][p+3];
double *y4 = &expr[jj][p];
double *y3 = expr[jj].data() + p + 3;
double *y4 = expr[jj].data() + p;
ai = n;
yprod = expr[jj][ai];
for (a2=0;a2<a;a2++) {
@ -568,8 +567,8 @@ void Fingerprint_bondscreenedspin::do3bodyfeatureset_singleneighborloop(double *
j = jl[jj];
double *sj = sim->s[j];
double sp = si[0]*sj[0]+si[1]*sj[1]+si[2]*sj[2];
double *y3 = &expr[jj][p+3];
double *y4 = &expr[jj][p];
double *y3 = expr[jj].data() + p + 3;
double *y4 = expr[jj].data() + p;
ai = n;
yprod = expr[jj][ai];
for (a2=0;a2<a;a2++) {
@ -641,18 +640,21 @@ void Fingerprint_bondscreenedspin::do3bodyfeatureset_doubleneighborloop(double *
i = ilist[ii];
itype = pair->map[type[i]];
int f = pair->net[itype].dimensions[0];
double expr[jnum][kmax];
double y[jnum][3];
double ri[jnum];
double dfc[jnum];
std::vector<double> row(kmax, 0.0);
std::vector<std::vector<double>> expr(jnum, row);
std::vector<double> yrow(3, 0.0);
std::vector<std::vector<double>> y(jnum, yrow);
std::vector<double> ri(jnum, 0.0);
std::vector<double> dfc(jnum, 0.0);
int kb = kmax;
int mb = mlength;
double Bijk[kb][mb];
double c41[kmax];
double c51[kmax];
double c61[kmax];
double ct[kmax];
double *si = sim->s[i];
std::vector<double> brow(mb, 0.0);
std::vector<std::vector<double>> Bijk(kb, brow);
std::vector<double> c41(kmax, 0.0);
std::vector<double> c51(kmax, 0.0);
std::vector<double> c61(kmax, 0.0);
std::vector<double> ct(kmax, 0.0);
for (jj = 0; jj < jnum; jj++) {
if (Bij[jj]==false) {continue;}
jtype = tn[jj];

View File

@ -35,6 +35,8 @@ DISTRIBUTION A. Approved for public release; distribution unlimited. OPSEC#4918
using namespace LAMMPS_NS::RANN;
static constexpr double SMALL = 1.0e-12;
Fingerprint_bondspin::Fingerprint_bondspin(PairRANN *_pair) : Fingerprint(_pair)
{
n_body_type = 3;
@ -317,7 +319,8 @@ void Fingerprint_bondspin::do3bodyfeatureset_singleneighborloop(double * feature
i = ilist[ii];
itype = pair->map[type[i]];
int f = pair->net[itype].dimensions[0];
double expr[jnum][kmax+12];
std::vector<double> row(kmax+12, 0.0);
std::vector<std::vector<double>> expr(jnum, row);
int p = kmax;
int countmb=((mlength)*(mlength+1))>>1;
double *si = sim->s[i];
@ -355,13 +358,13 @@ void Fingerprint_bondspin::do3bodyfeatureset_singleneighborloop(double * feature
expr[jj][p+1]=dely*rinvs;
expr[jj][p+2]=delz*rinvs;
//Hack to avoid nan when x y or z component of radial vector is exactly 0. Shouldn't affect accuracy.
if (expr[jj][p]*expr[jj][p]<0.000000000001) {
if (expr[jj][p]*expr[jj][p] < SMALL) {
expr[jj][p] = 0.000001;
}
if (expr[jj][p+1]*expr[jj][p+1]<0.000000000001) {
if (expr[jj][p+1]*expr[jj][p+1] < SMALL) {
expr[jj][p+1] = 0.000001;
}
if (expr[jj][p+2]*expr[jj][p+2]<0.000000000001) {
if (expr[jj][p+2]*expr[jj][p+2] < SMALL) {
expr[jj][p+2] = 0.000001;
}
expr[jj][p+3] = -dfc*expr[jj][p];
@ -378,8 +381,8 @@ void Fingerprint_bondspin::do3bodyfeatureset_singleneighborloop(double * feature
int kb = kmax;
int mb = mlength;
count = startingneuron;
double Bb[mb];
double Bbs[mb];
std::vector<double> Bb(mb, 0.0);
std::vector<double> Bbs(mb, 0.0);
double dBbx;
double dBby;
double dBbz;
@ -415,7 +418,7 @@ void Fingerprint_bondspin::do3bodyfeatureset_singleneighborloop(double * feature
double *sj = sim->s[j];
double sp = si[0]*sj[0]+si[1]*sj[1]+si[2]*sj[2];
double yprod = expr[jj][ai];
double *y4 = &expr[jj][p];
double *y4 = expr[jj].data() + p;
for (a2=0;a2<a;a2++) {
yprod *= y4[M[a2+1]];
}
@ -426,12 +429,8 @@ void Fingerprint_bondspin::do3bodyfeatureset_singleneighborloop(double * feature
}
}
if (atomtypes[1]!=atomtypes[2]) {//Bb!=Bg
double Bg[mb];
double Bgs[mb];
for (a1=0;a1<mb;a1++) {
Bg[a1]=0;
Bgs[a1]=0;
}
std::vector<double> Bg(mb, 0.0);
std::vector<double> Bgs(mb, 0.0);
ai = n;
double y1 = alpha_k[ai]/re;
//loop over ktype to get Bg
@ -445,7 +444,7 @@ void Fingerprint_bondspin::do3bodyfeatureset_singleneighborloop(double * feature
double *sj = sim->s[j];
double sp = si[0]*sj[0]+si[1]*sj[1]+si[2]*sj[2];
double yprod = expr[jj][ai];
double *y4 = &expr[jj][p];
double *y4 = expr[jj].data() + p;
for (a2=0;a2<a;a2++) {
yprod *= y4[M[a2+1]];
}
@ -466,8 +465,8 @@ void Fingerprint_bondspin::do3bodyfeatureset_singleneighborloop(double * feature
j = jl[jj];
double *sj = sim->s[j];
double sp = si[0]*sj[0]+si[1]*sj[1]+si[2]*sj[2];
double *y3 = &expr[jj][p+3];
double *y4 = &expr[jj][p];
double *y3 = expr[jj].data() + p + 3;
double *y4 = expr[jj].data() + p;
ai = n;
yprod = expr[jj][ai];
for (a2=0;a2<a;a2++) {
@ -502,8 +501,8 @@ void Fingerprint_bondspin::do3bodyfeatureset_singleneighborloop(double * feature
j = jl[jj];
double *sj = sim->s[j];
double sp = si[0]*sj[0]+si[1]*sj[1]+si[2]*sj[2];
double *y3 = &expr[jj][p+3];
double *y4 = &expr[jj][p];
double *y3 = expr[jj].data() + p + 3;
double *y4 = expr[jj].data() + p;
ai = n;
yprod = expr[jj][ai];
for (a2=0;a2<a;a2++) {
@ -546,8 +545,8 @@ void Fingerprint_bondspin::do3bodyfeatureset_singleneighborloop(double * feature
j = jl[jj];
double *sj = sim->s[j];
double sp = si[0]*sj[0]+si[1]*sj[1]+si[2]*sj[2];
double *y3 = &expr[jj][p+3];
double *y4 = &expr[jj][p];
double *y3 = expr[jj].data() + p + 3;
double *y4 = expr[jj].data() + p;
ai = n;
yprod = expr[jj][ai];
for (a2=0;a2<a;a2++) {
@ -612,16 +611,18 @@ void Fingerprint_bondspin::do3bodyfeatureset_doubleneighborloop(double * feature
i = ilist[ii];
itype = pair->map[type[i]];
int f = pair->net[itype].dimensions[0];
double expr[jnum][kmax];
double y[jnum][3];
double ri[jnum];
double dfc[jnum];
std::vector<double> row(kmax, 0.0);
std::vector<std::vector<double>> expr(jnum, row);
std::vector<double> yrow(3, 0.0);
std::vector<std::vector<double>> y(jnum, yrow);
std::vector<double> ri(jnum, 0.0);
std::vector<double> dfc(jnum, 0.0);
int kb = kmax;
int mb = mlength;
double c41[kmax];
double c51[kmax];
double c61[kmax];
double ct[kmax];
std::vector<double> c41(kmax, 0.0);
std::vector<double> c51(kmax, 0.0);
std::vector<double> c61(kmax, 0.0);
std::vector<double> ct(kmax, 0.0);
double *si = sim->s[i];
for (jj = 0; jj < jnum; jj++) {
jtype = tn[jj];

View File

@ -965,6 +965,7 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec)
int *mask = atom->mask;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *type = atom->type;
double localmass, totalmass;
std::string species_str;
@ -1013,12 +1014,12 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec)
if (!(mask[i] & groupbit)) continue;
cid = nint(clusterID[i]);
if (cid == m) {
itype = ele2uele[atom->type[i] - 1];
itype = ele2uele[type[i] - 1];
Name[itype]++;
count++;
marklist[nmarklist++] = i;
if (rmass) localmass += rmass[i];
else localmass += atom->mass[atom->type[i]];
else localmass += mass[type[i]];
}
}

View File

@ -26,6 +26,7 @@
#include "force.h"
#include "input.h"
#include "math_const.h"
#include "safe_pointers.h"
#include "update.h"
#include <cmath>
@ -79,13 +80,12 @@ void AngleWrite::command(int narg, char **arg)
// otherwise make certain that units are consistent
// print header in format used by angle_style table
FILE *fp = nullptr;
SafeFilePtr fp;
std::string coeffs_file = table_file + ".tmp.coeffs";
if (comm->me == 0) {
fp = fopen(coeffs_file.c_str(), "w");
force->angle->write_data(fp);
fclose(fp);
SafeFilePtr coeffs = fopen(coeffs_file.c_str(), "w");
force->angle->write_data(coeffs);
// units sanity check:
// - if this is the first time we write to this potential file,
@ -145,16 +145,14 @@ void AngleWrite::command(int narg, char **arg)
writer->input->one("pair_coeff * *");
writer->input->one("mass * 1.0");
writer->input->one(fmt::format("angle_style {}", force->angle_style));
FILE *coeffs;
char line[MAXLINE] = {'\0'};
coeffs = fopen(coeffs_file.c_str(), "r");
SafeFilePtr coeffs = fopen(coeffs_file.c_str(), "r");
if (!coeffs)
error->one(FLERR, "Unable to open temporary file {}: {}", coeffs_file, utils::getsyserror());
for (int i = 0; i < atom->nangletypes; ++i) {
utils::sfgets(FLERR, line, MAXLINE, coeffs, coeffs_file.c_str(), error);
writer->input->one(fmt::format("angle_coeff {}", line));
}
fclose(coeffs);
platform::unlink(coeffs_file);
// initialize system
@ -221,7 +219,6 @@ void AngleWrite::command(int narg, char **arg)
// clean up
delete writer;
fclose(fp);
}
MPI_Comm_free(&singlecomm);
}

View File

@ -20,6 +20,7 @@
#include "force.h"
#include "memory.h"
#include "neighbor.h"
#include "safe_pointers.h"
#include "suffix.h"
#include "update.h"
@ -365,7 +366,7 @@ void Bond::write_file(int narg, char **arg)
// add line with DATE: and UNITS: tag when creating new file
// print header in format used by bond_style table
FILE *fp = nullptr;
SafeFilePtr fp;
if (comm->me == 0) {
std::string table_file = arg[4];
@ -419,7 +420,6 @@ void Bond::write_file(int narg, char **arg)
e = single(btype, r * r, itype, jtype, f);
fprintf(fp, "%8d %- 22.15g %- 22.15g %- 22.15g\n", i + 1, r, e, f * r);
}
fclose(fp);
}
}

View File

@ -34,6 +34,7 @@
#include "random_mars.h"
#include "random_park.h"
#include "region.h"
#include "safe_pointers.h"
#include "special.h"
#include "text_file_reader.h"
#include "variable.h"
@ -1082,8 +1083,9 @@ void CreateAtoms::add_mesh(const char *filename)
molid = maxmol + 1;
}
FILE *fp = fopen(filename, "rb");
if (fp == nullptr) error->one(FLERR, "Cannot open file {}: {}", filename, utils::getsyserror());
SafeFilePtr fp = fopen(filename, "rb");
if (fp == nullptr)
error->one(FLERR, "Cannot open STL mesh file {}: {}", filename, utils::getsyserror());
// first try reading the file in ASCII format
@ -1184,7 +1186,7 @@ void CreateAtoms::add_mesh(const char *filename)
}
}
} else {
error->all(FLERR, "Error reading triangles from file {}: {}", filename, e.what());
error->all(FLERR, "Error reading triangles from STL mesh file {}: {}", filename, e.what());
}
}
@ -1195,7 +1197,6 @@ void CreateAtoms::add_mesh(const char *filename)
utils::logmesg(lmp, " read {} triangles with {:.2f} atoms per triangle added in {} mode\n",
ntriangle, ratio, mesh_name[mesh_style]);
}
if (fp) fclose(fp);
}
/* ----------------------------------------------------------------------

View File

@ -52,7 +52,7 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
{
if (narg < 5) utils::missing_cmd_args(FLERR,"fix adapt", error);
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
if (nevery < 0) error->all(FLERR,"Illegal fix adapt every value {}", nevery);
if (nevery < 0) error->all(FLERR, 3, "Illegal fix adapt every value {}", nevery);
dynamic_group_allow = 1;
create_attribute = 1;
@ -86,7 +86,7 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
} else break;
}
if (nadapt == 0) error->all(FLERR,"Nothing to adapt in fix adapt command");
if (nadapt == 0) error->all(FLERR, 3, "Nothing to adapt in fix adapt command");
adapt = new Adapt[nadapt];
// parse keywords
@ -119,7 +119,7 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
if (utils::strmatch(arg[iarg+5],"^v_")) {
adapt[nadapt].var = utils::strdup(arg[iarg+5]+2);
} else error->all(FLERR,"Argument #{} must be variable not {}", iarg+6, arg[iarg+5]);
} else error->all(FLERR, iarg+5, "Argument must be variable not {}", arg[iarg+5]);
nadapt++;
iarg += 6;
@ -132,7 +132,7 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
adapt[nadapt].ilo, adapt[nadapt].ihi, lmp, Atom::BOND);
if (utils::strmatch(arg[iarg+4],"^v_")) {
adapt[nadapt].var = utils::strdup(arg[iarg+4]+2);
} else error->all(FLERR,"Argument #{} must be variable not {}", iarg+5, arg[iarg+4]);
} else error->all(FLERR, iarg+4, "Argument must be variable not {}", arg[iarg+4]);
nadapt++;
iarg += 5;
@ -145,7 +145,7 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
adapt[nadapt].ilo, adapt[nadapt].ihi, lmp, Atom::ANGLE);
if (utils::strmatch(arg[iarg+4],"^v_")) {
adapt[nadapt].var = utils::strdup(arg[iarg+4]+2);
} else error->all(FLERR,"Argument #{} must be variable not {}", iarg+5, arg[iarg+4]);
} else error->all(FLERR,iarg+4, "Argument must be variable not {}", arg[iarg+4]);
nadapt++;
iarg += 5;
@ -153,7 +153,7 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
adapt[nadapt].which = KSPACE;
if (utils::strmatch(arg[iarg+1],"^v_")) {
adapt[nadapt].var = utils::strdup(arg[iarg+1]+2);
} else error->all(FLERR,"Argument #{} must be variable not {}", iarg+2, arg[iarg+1]);
} else error->all(FLERR, iarg+1, "Argument must be variable not {}", arg[iarg+1]);
nadapt++;
iarg += 2;
@ -168,10 +168,11 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
} else if (strcmp(arg[iarg+1],"charge") == 0) {
adapt[nadapt].atomparam = CHARGE;
chgflag = 1;
} else error->all(FLERR,"Unsupported per-atom property {} for fix adapt", arg[iarg+1]);
} else error->all(FLERR, iarg+1, "Unsupported per-atom property {} for fix adapt",
arg[iarg+1]);
if (utils::strmatch(arg[iarg+2],"^v_")) {
adapt[nadapt].var = utils::strdup(arg[iarg+2]+2);
} else error->all(FLERR,"Argument #{} must be variable not {}", iarg+3, arg[iarg+2]);
} else error->all(FLERR, iarg+2, "Argument must be variable not {}", arg[iarg+2]);
nadapt++;
iarg += 3;
} else break;
@ -329,7 +330,8 @@ void FixAdapt::init()
if (group->dynamic[igroup])
for (i = 0; i < nadapt; i++)
if (adapt[i].which == ATOM)
error->all(FLERR,"Cannot use dynamic group {} with fix adapt atom", group->names[igroup]);
error->all(FLERR, Error::NOLASTLINE,
"Cannot use dynamic group {} with fix adapt atom", group->names[igroup]);
// setup and error checks
@ -342,9 +344,11 @@ void FixAdapt::init()
ad->ivar = input->variable->find(ad->var);
if (ad->ivar < 0)
error->all(FLERR,"Variable name {} for fix adapt does not exist", ad->var);
error->all(FLERR, Error::NOLASTLINE,
"Variable name {} for fix adapt does not exist", ad->var);
if (!input->variable->equalstyle(ad->ivar))
error->all(FLERR,"Variable {} for fix adapt is invalid style", ad->var);
error->all(FLERR, Error::NOLASTLINE,
"Variable {} for fix adapt is invalid style", ad->var);
if (ad->which == PAIR) {
anypair = 1;
@ -369,17 +373,20 @@ void FixAdapt::init()
ad->pair = force->pair_match(fmt::format("{}/{}",pstyle,lmp->suffix2),1,nsub);
}
if (ad->pair == nullptr) ad->pair = force->pair_match(pstyle,1,nsub);
if (ad->pair == nullptr) error->all(FLERR,"Fix adapt pair style {} not found", pstyle);
if (ad->pair == nullptr)
error->all(FLERR, Error::NOLASTLINE, "Fix adapt pair style {} not found", pstyle);
void *ptr = ad->pair->extract(ad->pparam,ad->pdim);
if (ptr == nullptr)
error->all(FLERR,"Fix adapt pair style {} param {} not supported", ad->pstyle, ad->pparam);
error->all(FLERR, Error::NOLASTLINE,
"Fix adapt pair style {} param {} not supported", ad->pstyle, ad->pparam);
// for pair styles only parameters that are 2-d arrays in atom types or
// scalars are supported
if (ad->pdim != 2 && ad->pdim != 0)
error->all(FLERR,"Pair style parameter {} is not compatible with fix adapt", ad->pparam);
error->all(FLERR, Error::NOLASTLINE,
"Pair style parameter {} is not compatible with fix adapt", ad->pparam);
if (ad->pdim == 2) ad->array = (double **) ptr;
if (ad->pdim == 0) ad->scalar = (double *) ptr;
@ -392,7 +399,7 @@ void FixAdapt::init()
for (i = ad->ilo; i <= ad->ihi; i++) {
for (j = MAX(ad->jlo,i); j <= ad->jhi; j++) {
if (!pair->check_ijtype(i,j,pstyle))
error->all(FLERR,"Fix adapt type pair range is not valid "
error->all(FLERR, Error::NOLASTLINE, "Fix adapt type pair range is not valid "
"for pair hybrid sub-style {}", pstyle);
}
}
@ -411,12 +418,13 @@ void FixAdapt::init()
if (ad->bond == nullptr) ad->bond = force->bond_match(bstyle);
if (ad->bond == nullptr )
error->all(FLERR,"Fix adapt bond style {} does not exist", bstyle);
error->all(FLERR, Error::NOLASTLINE,"Fix adapt bond style {} does not exist", bstyle);
void *ptr = ad->bond->extract(ad->bparam,ad->bdim);
if (ptr == nullptr)
error->all(FLERR,"Fix adapt bond style parameter {} not supported", ad->bparam);
error->all(FLERR, Error::NOLASTLINE,
"Fix adapt bond style parameter {} not supported", ad->bparam);
// for bond styles, use a vector
@ -427,8 +435,8 @@ void FixAdapt::init()
if (bond) {
for (i = ad->ilo; i <= ad->ihi; i++) {
if (!bond->check_itype(i,bstyle))
error->all(FLERR,"Fix adapt type bond range is not valid "
"for pair hybrid sub-style {}", bstyle);
error->all(FLERR, Error::NOLASTLINE, "Fix adapt type bond range is not valid "
"for bond hybrid sub-style {}", bstyle);
}
}
}
@ -445,12 +453,13 @@ void FixAdapt::init()
if (ad->angle == nullptr) ad->angle = force->angle_match(astyle);
if (ad->angle == nullptr )
error->all(FLERR,"Fix adapt angle style {} does not exist", astyle);
error->all(FLERR, Error::NOLASTLINE, "Fix adapt angle style {} does not exist", astyle);
void *ptr = ad->angle->extract(ad->aparam,ad->adim);
if (ptr == nullptr)
error->all(FLERR,"Fix adapt angle style parameter {} not supported", ad->aparam);
error->all(FLERR, Error::NOLASTLINE,
"Fix adapt angle style parameter {} not supported", ad->aparam);
// for angle styles, use a vector
@ -461,8 +470,8 @@ void FixAdapt::init()
if (angle) {
for (i = ad->ilo; i <= ad->ihi; i++) {
if (!angle->check_itype(i,astyle))
error->all(FLERR,"Fix adapt type angle range is not valid "
"for pair hybrid sub-style {}", astyle);
error->all(FLERR, Error::NOLASTLINE, "Fix adapt type angle range is not valid "
"for angle hybrid sub-style {}", astyle);
}
}
}
@ -471,22 +480,23 @@ void FixAdapt::init()
} else if (ad->which == KSPACE) {
if (force->kspace == nullptr)
error->all(FLERR,"Fix adapt expected a kspace style but none was defined");
error->all(FLERR, Error::NOLASTLINE,
"Fix adapt expected a kspace style but none was defined");
kspace_scale = (double *) force->kspace->extract("scale");
} else if (ad->which == ATOM) {
if (ad->atomparam == DIAMETER) {
if (!atom->radius_flag)
error->all(FLERR,"Fix adapt requires atom attribute diameter");
error->all(FLERR, Error::NOLASTLINE, "Fix adapt requires atom attribute diameter");
if (!atom->rmass_flag)
error->all(FLERR,"Fix adapt requires atom attribute mass");
error->all(FLERR, Error::NOLASTLINE, "Fix adapt requires atom attribute mass");
if (discflag && domain->dimension != 2)
error->all(FLERR,"Fix adapt requires 2d simulation");
error->all(FLERR, Error::NOLASTLINE, "Fix adapt requires 2d simulation");
if (!restart_reset) previous_diam_scale = 1.0;
}
if (ad->atomparam == CHARGE) {
if (!atom->q_flag)
error->all(FLERR,"Fix adapt requires atom attribute charge");
error->all(FLERR, Error::NOLASTLINE, "Fix adapt requires atom attribute charge");
if (!restart_reset) previous_chg_scale = 1.0;
}
}
@ -520,11 +530,15 @@ void FixAdapt::init()
if (id_fix_diam) {
fix_diam = dynamic_cast<FixStoreAtom *>(modify->get_fix_by_id(id_fix_diam));
if (!fix_diam) error->all(FLERR,"Could not find fix adapt storage fix ID {}", id_fix_diam);
if (!fix_diam)
error->all(FLERR, Error::NOLASTLINE,
"Could not find fix adapt storage fix ID {}", id_fix_diam);
}
if (id_fix_chg) {
fix_chg = dynamic_cast<FixStoreAtom *>(modify->get_fix_by_id(id_fix_chg));
if (!fix_chg) error->all(FLERR,"Could not find fix adapt storage fix ID {}", id_fix_chg);
if (!fix_chg)
error->all(FLERR, Error::NOLASTLINE,
"Could not find fix adapt storage fix ID {}", id_fix_chg);
}
if (utils::strmatch(update->integrate_style,"^respa"))

View File

@ -65,27 +65,39 @@ void Region::init()
{
if (xstr) {
xvar = input->variable->find(xstr);
if (xvar < 0) error->all(FLERR, "Variable {} for region does not exist", xstr);
if (xvar < 0)
error->all(FLERR, Error::NOLASTLINE, "Variable {} for region {} {} does not exist", xstr,
style, id);
if (!input->variable->equalstyle(xvar))
error->all(FLERR, "Variable {} for region is invalid style", xstr);
error->all(FLERR, Error::NOLASTLINE, "Variable {} for region {} {} is invalid style", xstr,
style, id);
}
if (ystr) {
yvar = input->variable->find(ystr);
if (yvar < 0) error->all(FLERR, "Variable {} for region does not exist", ystr);
if (yvar < 0)
error->all(FLERR, Error::NOLASTLINE, "Variable {} for region {} {} does not exist", ystr,
style, id);
if (!input->variable->equalstyle(yvar))
error->all(FLERR, "Variable {} for region is not equal style", ystr);
error->all(FLERR, Error::NOLASTLINE, "Variable {} for region {} {} is not equal style", ystr,
style, id);
}
if (zstr) {
zvar = input->variable->find(zstr);
if (zvar < 0) error->all(FLERR, "Variable {} for region does not exist", zstr);
if (zvar < 0)
error->all(FLERR, Error::NOLASTLINE, "Variable {} for region {} {} does not exist", zstr,
style, id);
if (!input->variable->equalstyle(zvar))
error->all(FLERR, "Variable {} for region is not equal style", zstr);
error->all(FLERR, Error::NOLASTLINE, "Variable {} for region {} {} is not equal style", zstr,
style, id);
}
if (tstr) {
tvar = input->variable->find(tstr);
if (tvar < 0) error->all(FLERR, "Variable {} for region does not exist", tstr);
if (tvar < 0)
error->all(FLERR, Error::NOLASTLINE, "Variable {} for region {} {} does not exist", tstr,
style, id);
if (!input->variable->equalstyle(tvar))
error->all(FLERR, "Variable {} for region is not equal style", tstr);
error->all(FLERR, Error::NOLASTLINE, "Variable {} for region {} {} is not equal style", tstr,
style, id);
}
vel_timestep = -1;
}
@ -303,6 +315,16 @@ void Region::options(int narg, char **arg)
{
if (narg < 0) utils::missing_cmd_args(FLERR, "region", error);
int offset = -20;
if (input && input->arg && arg) {
for (int i = 0; i < input->narg; ++i) {
if (arg[0] == input->arg[i]) {
offset = i;
break;
}
}
}
// option defaults
interior = 1;
@ -321,7 +343,7 @@ void Region::options(int narg, char **arg)
else if (strcmp(arg[iarg + 1], "lattice") == 0)
scaleflag = 1;
else
error->all(FLERR, "Illegal region units: {}", arg[iarg + 1]);
error->all(FLERR, iarg + 1 + offset, "Unknown region units: {}", arg[iarg + 1]);
iarg += 2;
} else if (strcmp(arg[iarg], "side") == 0) {
if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "region side", error);
@ -330,24 +352,27 @@ void Region::options(int narg, char **arg)
else if (strcmp(arg[iarg + 1], "out") == 0)
interior = 0;
else
error->all(FLERR, "Illegal region side: {}", arg[iarg + 1]);
error->all(FLERR, iarg + 1 + offset, "Unknown region side setting: {}", arg[iarg + 1]);
iarg += 2;
} else if (strcmp(arg[iarg], "move") == 0) {
if (iarg + 4 > narg) utils::missing_cmd_args(FLERR, "region move", error);
if (strcmp(arg[iarg + 1], "NULL") != 0) {
if (strstr(arg[iarg + 1], "v_") != arg[iarg + 1])
error->all(FLERR, "Illegal region move x displacement variable: {}", arg[iarg + 1]);
error->all(FLERR, iarg + 1 + offset, "Illegal region move x displacement variable: {}",
arg[iarg + 1]);
xstr = utils::strdup(&arg[iarg + 1][2]);
}
if (strcmp(arg[iarg + 2], "NULL") != 0) {
if (strstr(arg[iarg + 2], "v_") != arg[iarg + 2])
error->all(FLERR, "Illegal region move y displacement variable: {}", arg[iarg + 2]);
error->all(FLERR, iarg + 2 + offset, "Illegal region move y displacement variable: {}",
arg[iarg + 2]);
ystr = utils::strdup(&arg[iarg + 2][2]);
}
if (strcmp(arg[iarg + 3], "NULL") != 0) {
if (strstr(arg[iarg + 3], "v_") != arg[iarg + 3])
error->all(FLERR, "Illegal region move z displacement variable: {}", arg[iarg + 3]);
error->all(FLERR, iarg + 3 + offset, "Illegal region move z displacement variable: {}",
arg[iarg + 3]);
zstr = utils::strdup(&arg[iarg + 3][2]);
}
moveflag = 1;
@ -369,19 +394,20 @@ void Region::options(int narg, char **arg)
} else if (strcmp(arg[iarg], "open") == 0) {
if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "region open", error);
int iface = utils::inumeric(FLERR, arg[iarg + 1], false, lmp);
if (iface < 1 || iface > 6) error->all(FLERR, "Illegal region open face index: {}", iface);
if (iface < 1 || iface > 6)
error->all(FLERR, iarg + 1 + offset, "Illegal region open face index: {}", iface);
// additional checks on valid face index are done by region classes
open_faces[iface - 1] = 1;
openflag = 1;
iarg += 2;
} else
error->all(FLERR, iarg, "Unknown region command argument: {}", arg[iarg]);
error->all(FLERR, iarg + offset, "Unknown region command argument: {}", arg[iarg]);
}
// error check
if ((moveflag || rotateflag) && (strcmp(style, "union") == 0 || strcmp(style, "intersect") == 0))
error->all(FLERR, "Region union or intersect cannot be dynamic");
error->all(FLERR, 1, "Region union or intersect cannot be dynamic");
// setup scaling
@ -402,7 +428,7 @@ void Region::options(int narg, char **arg)
if (rotateflag) {
double len = sqrt(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]);
if (len == 0.0) error->all(FLERR, "Region cannot have 0 length rotation vector");
if (len == 0.0) error->all(FLERR, Error::NOPOINTER, "Region cannot have 0 length rotation vector");
runit[0] = axis[0] / len;
runit[1] = axis[1] / len;
runit[2] = axis[2] / len;

View File

@ -41,10 +41,11 @@ RegCone::RegCone(LAMMPS *lmp, int narg, char **arg) :
if (openflag)
for (int i = 3; i < 6; i++)
if (open_faces[i]) error->all(FLERR, "Illegal region cone open face: {}", i + 1);
if (open_faces[i])
error->all(FLERR, Error::NOPOINTER, "Illegal region cone open face: {}", i + 1);
if (strcmp(arg[2], "x") != 0 && strcmp(arg[2], "y") != 0 && strcmp(arg[2], "z") != 0)
error->all(FLERR, "Illegal region cone axis: {}", arg[2]);
error->all(FLERR, 2, "Illegal region cone axis: {}", arg[2]);
axis = arg[2][0];
if (axis == 'x') {
@ -256,8 +257,8 @@ RegCone::RegCone(LAMMPS *lmp, int narg, char **arg) :
// error check
if (radiuslo < 0.0) error->all(FLERR, "Illegal radius in region cone command");
if (radiushi < 0.0) error->all(FLERR, "Illegal radius in region cone command");
if (radiuslo < 0.0) error->all(FLERR, 5, "Illegal lower radius in region cone command");
if (radiushi < 0.0) error->all(FLERR, 6, "Illegal upper radius in region cone command");
if (radiuslo == 0.0 && radiushi == 0.0)
error->all(FLERR, "Illegal radius in region cone command");
if (hi <= lo) error->all(FLERR, "Illegal cone length in region cone command");

View File

@ -25,6 +25,8 @@ RegionStyle(plane,RegPlane);
namespace LAMMPS_NS {
class RegPlane : public Region {
friend class Region2VMD;
public:
RegPlane(class LAMMPS *, int, char **);
~RegPlane() override;

60
src/safe_pointers.h Normal file
View File

@ -0,0 +1,60 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
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.
------------------------------------------------------------------------- */
#ifndef LMP_SAFE_POINTERS_H
#define LMP_SAFE_POINTERS_H
// collection of smart pointers for specific purposes
#include <cstdio>
namespace LAMMPS_NS {
/** Class to automatically close a FILE pointer when a class instance goes out of scope.
\verbatim embed:rst
Drop in replacement for ``FILE *``. Use as ``SafeFilePtr fp;`` instead of
``FILE *fp = nullptr;`` and there is no more need to explicitly call
``fclose(fp)``.
\endverbatim
*/
class SafeFilePtr {
public:
SafeFilePtr() : fp(nullptr) {};
SafeFilePtr(FILE *_fp) : fp(_fp) {};
SafeFilePtr(const SafeFilePtr &) = delete;
SafeFilePtr(const SafeFilePtr &&) = delete;
SafeFilePtr &operator=(const SafeFilePtr &) = delete;
~SafeFilePtr()
{
if (fp) fclose(fp);
}
SafeFilePtr &operator=(FILE *_fp)
{
if (fp && (fp != _fp)) fclose(fp);
fp = _fp;
return *this;
}
operator FILE *() const { return fp; }
private:
FILE *fp;
};
} // namespace LAMMPS_NS
#endif

View File

@ -26,6 +26,7 @@
namespace LAMMPS_NS {
class TextFileReader {
private:
std::string filetype;
bool closefp;
int bufsize;

View File

@ -1 +1,2 @@
#define LAMMPS_VERSION "4 Feb 2025"
#define LAMMPS_UPDATE "Development"

View File

@ -279,7 +279,7 @@ if(APPLE)
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE_ICON_FILE lammps.icns
MACOSX_BUNDLE_COPYRIGHT "(c) 2003 - 2024, The LAMMPS Developers"
MACOSX_BUNDLE_COPYRIGHT "(c) 2003 - 2025, The LAMMPS Developers"
MACOSX_BUNDLE TRUE
)
# additional targets to populate the bundle tree and create the .dmg image file

View File

@ -1,6 +1,6 @@
# Apptainer (aka Singularity) container definitions for compiling/testing LAMMPS
The *.def files in this folder can be used to build container images
The \*.def files in this folder can be used to build container images
for [Apptainer](https://apptainer.org) (previously called
[Singularity](https://sylabs.io)), suitable for compiling and testing
LAMMPS on a variety of OS variants with support for most standard

View File

@ -0,0 +1,109 @@
BootStrap: docker
From: fedora:41
%setup
curl -L -o musl-gcc-f37.tar.gz https://download.lammps.org/static/musl-gcc-f37.tar.gz
cp musl-gcc-f37.tar.gz ${APPTAINER_ROOTFS}
%post
dnf -y update
dnf -y install vim-enhanced git file make cmake patch which file \
ninja-build libomp-devel diffutils dos2unix findutils rsync \
ccache gcc-c++ gcc-gfortran gdb valgrind python3-pyyaml \
enchant enchant2 python3-enchant python3-virtualenv doxygen latexmk \
texlive-latex-fonts texlive-pslatex texlive-collection-latexrecommended \
texlive-latex texlive-latexconfig doxygen-latex texlive-collection-latex \
texlive-latex-bin texlive-lualatex-math texlive-fncychap texlive-tabulary \
texlive-framed texlive-wrapfig texlive-upquote texlive-capt-of texlive-pict2e \
texlive-needspace texlive-titlesec texlive-anysize texlive-dvipng texlive-xindy \
texlive-fontawesome texlive-ellipse texlive-tex-gyre \
mingw-filesystem-base mingw32-nsis mingw-binutils-generic \
mingw64-filesystem mingw64-pkg-config \
mingw64-crt mingw64-headers mingw64-binutils \
mingw64-cpp mingw64-gcc mingw64-gcc-gfortran mingw64-gcc-c++ \
mingw64-curl \
mingw64-libgomp \
mingw64-winpthreads \
mingw64-eigen3 \
mingw64-fftw \
mingw64-libjpeg-turbo \
mingw64-libpng \
mingw64-python3 \
mingw64-python3-numpy \
mingw64-python3-pyyaml \
mingw64-python3-setuptools \
mingw64-readline \
mingw64-termcap \
mingw64-tcl \
mingw64-tk \
mingw64-zlib \
mingw64-zstd \
mingw64-qt5-qtdeclarative \
mingw64-qt5-qmldevtools \
mingw64-qt5-qmldevtools-devel \
mingw64-qt5-qttools-tools \
mingw64-qt5-qtcharts \
mingw64-qt5-qttools \
mingw64-qt5-qmake \
mingw64-qt5-qtbase \
mingw64-qt5-qtbase-devel \
mingw64-qt5-qtbase-static \
dnf clean all
# install musl-libc Linux-2-Linux cross-compiler
tar -C /usr/ -xvf /musl-gcc-f37.tar.gz
rm -f /musl-gcc-f37.tar.gz
# install NSIS EnVar plugin
curl -L -o EnVar_plugin.zip https://nsis.sourceforge.io/mediawiki/images/7/7f/EnVar_plugin.zip
unzip -d /usr/share/nsis EnVar_plugin.zip
rm EnVar_plugin.zip
# create missing termcap pkgconfig file
cat > /usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig/termcap.pc <<EOF
prefix=/usr/x86_64-w64-mingw32/sys-root/mingw
exec_prefix=/usr/x86_64-w64-mingw32/sys-root/mingw
libdir=/usr/x86_64-w64-mingw32/sys-root/mingw/lib
includedir=/usr/x86_64-w64-mingw32/sys-root/mingw/include
Name: Termcap
Description: GNU/MinGW terminal feature database
URL: ftp://ftp.gnu.org/gnu/termcap/
Version: 1.3
Libs: -L\${libdir} -ltermcap
Cflags:
EOF
# set custom prompt indicating the container name
CUSTOM_PROMPT_ENV=/.singularity.d/env/99-zz_custom_prompt.sh
cat >$CUSTOM_PROMPT_ENV <<EOF
#!/bin/bash
PS1="[fedora41/musl-mingw:\u@\h] \W> "
EOF
chmod 755 $CUSTOM_PROMPT_ENV
%environment
# we need to reset any module variables
# inherited from the host.
unset __LMOD_REF_COUNT__LMFILES_
unset __LMOD_REF_COUNT_PATH
unset __LMOD_REF_COUNT_LD_LIBRARY_PATH
unset __LMOD_REF_COUNT_MANPATH
unset __LMOD_REF_COUNT_MODULEPATH
unset __LMOD_REF_COUNT_LOADEDMODULES
unset _LMFILES_
unset MODULEPATH
unset MODULESHOME
unset MODULEPATH_ROOT
unset LOADEDMODULES
unset LMOD_SYSTEM_DEFAULT_MODULES
. /etc/profile
# tell OpenMPI to not try using Infiniband
OMPI_MCA_btl="^openib"
# do not warn about unused components as this messes up testing
OMPI_MCA_btl_base_warn_component_unused="0"
export OMPI_MCA_btl OMPI_MCA_btl_base_warn_component_unused
%labels
Author akohlmey