Merge remote-tracking branch 'github/master' into coul_tt

This commit is contained in:
Axel Kohlmeyer
2020-09-28 13:56:00 -04:00
307 changed files with 9323 additions and 5453 deletions

View File

@ -2,7 +2,7 @@
<!--Briefly describe the new feature(s), enhancement(s), or bugfix(es) included in this pull request.--> <!--Briefly describe the new feature(s), enhancement(s), or bugfix(es) included in this pull request.-->
**Related Issues** **Related Issue(s)**
<!--If this addresses an open GitHub issue for this project, please mention the issue number here, and describe the relation. Use the phrases `fixes #221` or `closes #135`, when you want an issue to be automatically closed when the pull request is merged--> <!--If this addresses an open GitHub issue for this project, please mention the issue number here, and describe the relation. Use the phrases `fixes #221` or `closes #135`, when you want an issue to be automatically closed when the pull request is merged-->

View File

@ -9,34 +9,37 @@ assignees: ''
**Summary** **Summary**
<!--Briefly describe the bug or bugs, that are eliminated by this pull request.--> <!--Briefly describe the bug(s) that are eliminated by this pull request.-->
**Related Issue(s)** **Related Issue(s)**
<!--If this request addresses or is related to an existing (open) GitHub issue, e.g. a bug report, mention the issue number number here following a pound sign (aka hashmark), e.g.`#222`.--> <!--If this addresses an open GitHub issue for this project, please mention the issue number here, and describe the relation. Use the phrases `fixes #221` or `closes #135`, when you want an issue to be automatically closed when the pull request is merged-->
**Author(s)** **Author(s)**
<!--Please state name and affiliation of the author or authors that should be credited with the changes in this pull request--> <!--Please state name and affiliation of the author or authors that should be credited with the changes in this pull request. If this pull request adds new files to the distribution, please also provide a suitable "long-lived" e-mail address (ideally something that can outlive your institution's e-mail, in case you change jobs) for the *corresponding* author, i.e. the person the LAMMPS developers can contact directly with questions and requests related to maintenance and support of this contributed code.-->
**Licensing** **Licensing**
By submitting this pull request I implicitly accept, that my submission is subject to the same licensing terms as the files that are modified. By submitting this pull request, I agree, that my contribution will be included in LAMMPS and redistributed under either the GNU General Public License version 2 (GPL v2) or the GNU Lesser General Public License version 2.1 (LGPL v2.1).
**Backward Compatibility** **Backward Compatibility**
<!--Please state whether any changes in the pull request break backward compatibility for inputs, and - if yes - explain what has been changed and why--> <!--Please state whether any changes in the pull request will break backward compatibility for inputs, and - if yes - explain what has been changed and why-->
**Detailed Description** **Detailed Description**
<!--Provide any relevant details about how the fixed bug can be reproduced, how the changes are implemented, how correctness was verified, how other features - if any - in LAMMPS are affected--> <!--Provide any relevant details about how the fixed bug can be reproduced, how the changes are implemented, how correctness was verified, how other features - if any - in LAMMPS are affected-->
## Post Submission Checklist **Post Submission Checklist**
<!--Please check the fields below as they are completed *after* the pull request is submitted--> <!--Please check the fields below as they are completed **after** the pull request has been submitted. Delete lines that don't apply-->
- [ ] The code in this pull request is complete
- [ ] The feature or features in this pull request is complete
- [ ] Licensing information is complete
- [ ] Corresponding author information is complete
- [ ] The source code follows the LAMMPS formatting guidelines - [ ] The source code follows the LAMMPS formatting guidelines
- [ ] The feature has been verified to work with the conventional build system
- [ ] The feature has been verified to work with the CMake based build system
- [ ] Suitable tests have been added to the unittest tree.
## Further Information, Files, and Links
<!--Put any additional information here, attach relevant text or image files, and URLs to external sites (e.g. to download input decks for testing)-->

View File

@ -13,23 +13,31 @@ assignees: ''
**Related Issue(s)** **Related Issue(s)**
<!--If this request addresses or is related to an existing (open) GitHub issue, e.g. a bug report, mention the issue number number here following a pound sign (aka hashmark), e.g.`#222`. <!--If this addresses an open GitHub issue for this project, please mention the issue number here, and describe the relation. Use the phrases `fixes #221` or `closes #135`, when you want an issue to be automatically closed when the pull request is merged-->
**Author(s)** **Author(s)**
<!--Please state name and affiliation of the author or authors that should be credited with the changes in this pull request--> <!--Please state name and affiliation of the author or authors that should be credited with the changes in this pull request. If this pull request adds new files to the distribution, please also provide a suitable "long-lived" e-mail address (ideally something that can outlive your institution's e-mail, in case you change jobs) for the *corresponding* author, i.e. the person the LAMMPS developers can contact directly with questions and requests related to maintenance and support of this contributed code.-->
**Licensing** **Licensing**
By submitting this pull request I implicitly accept, that my submission is subject to the same licensing terms as the files that are modified. By submitting this pull request, I agree, that my contribution will be included in LAMMPS and redistributed under either the GNU General Public License version 2 (GPL v2) or the GNU Lesser General Public License version 2.1 (LGPL v2.1).
**Backward Compatibility**
<!--Please state whether any changes in the pull request will break backward compatibility for inputs, and - if yes - explain what has been changed and why-->
**Detailed Description** **Detailed Description**
<!--Provide any relevant details about the included changes.--> <!--Provide any relevant details about how the changes are implemented, how correctness was verified, how other features - if any - in LAMMPS are affected-->
## Post Submission Checklist **Post Submission Checklist**
<!--Please check the fields below as they are completed *after* the pull request is submitted--> <!--Please check the fields below as they are completed *after* the pull request is submitted-->
- [ ] The pull request is complete - [ ] The pull request is complete
- [ ] The source code follows the LAMMPS formatting guidelines - [ ] The source code follows the LAMMPS formatting guidelines
- [ ] The feature has been verified to work with the conventional build system
- [ ] The feature has been verified to work with the CMake based build system
- [ ] Suitable tests have been added to the unittest tree.

View File

@ -11,32 +11,29 @@ assignees: ''
<!--Briefly describe the new feature(s) included in this pull request.--> <!--Briefly describe the new feature(s) included in this pull request.-->
**Related Issues** **Related Issue(s)**
<!--If this addresses an existing (open) GitHub issue, e.g. a feature request, mention the issue number here following a pound sign (aka hashmark), e.g. `#331`.--> <!--If this addresses an open GitHub issue for this project, please mention the issue number here, and describe the relation. Use the phrases `fixes #221` or `closes #135`, when you want an issue to be automatically closed when the pull request is merged-->
**Author(s)** **Author(s)**
<!--Please state name and affiliation of the author or authors that should be credited with the features added in this pull request. Please provide a suitable "long-lived" e-mail address (e.g. from gmail, yahoo, outlook, etc.) for the *corresponding* author, i.e. the person the LAMMPS developers can contact directly with questions and requests related to maintenance and support of this code. now and in the future--> <!--Please state name and affiliation of the author or authors that should be credited with the changes in this pull request. If this pull request adds new files to the distribution, please also provide a suitable "long-lived" e-mail address (ideally something that can outlive your institution's e-mail, in case you change jobs) for the *corresponding* author, i.e. the person the LAMMPS developers can contact directly with questions and requests related to maintenance and support of this contributed code.-->
**Licensing** **Licensing**
<!--Please add *yes* or *no* to the following two statements (please contact @lammps/core if you have questions about this)--> By submitting this pull request, I agree, that my contribution will be included in LAMMPS and redistributed under either the GNU General Public License version 2 (GPL v2) or the GNU Lesser General Public License version 2.1 (LGPL v2.1).
My contribution may be licensed as GPL v2 (default LAMMPS license):
My contribution may be licensed as LGPL (for use as a library with proprietary software):
**Backward Compatibility** **Backward Compatibility**
<!--Please state if any of the changes in this pull request will affect backward compatibility for inputs, and - if yes - explain what has been changed and why--> <!--Please state whether any changes in the pull request will break backward compatibility for inputs, and - if yes - explain what has been changed and why-->
**Implementation Notes** **Implementation Notes**
<!--Provide any relevant details about how the new features are implemented, how correctness was verified, what platforms (OS, compiler, MPI, hardware, number of processors, accelerator(s)) it was tested on--> <!--Provide any relevant details about how the new feature(s) are implemented, how correctness was verified, how other features - if any - in LAMMPS are affected-->
## Post Submission Checklist **Post Submission Checklist**
<!--Please check the fields below as they are completed *after* the pull request has been submitted--> <!--Please check the fields below as they are completed **after** the pull request has been submitted. Delete lines that don't apply-->
- [ ] The feature or features in this pull request is complete - [ ] The feature or features in this pull request is complete
- [ ] Licensing information is complete - [ ] Licensing information is complete
@ -46,10 +43,11 @@ My contribution may be licensed as LGPL (for use as a library with proprietary s
- [ ] The added/updated documentation is integrated and tested with the documentation build system - [ ] The added/updated documentation is integrated and tested with the documentation build system
- [ ] The feature has been verified to work with the conventional build system - [ ] The feature has been verified to work with the conventional build system
- [ ] The feature has been verified to work with the CMake based build system - [ ] The feature has been verified to work with the CMake based build system
- [ ] Suitable tests have been added to the unittest tree.
- [ ] A package specific README file has been included or updated - [ ] A package specific README file has been included or updated
- [ ] One or more example input decks are included - [ ] One or more example input decks are included
## Further Information, Files, and Links **Further Information, Files, and Links**
<!--Put any additional information here, attach relevant text or image files, and URLs to external sites (e.g. DOIs or webpages)--> <!--Put any additional information here, attach relevant text or image files, and URLs to external sites (e.g. DOIs or webpages)-->

View File

@ -11,17 +11,21 @@ assignees: ''
<!--Briefly describe what kind of updates or enhancements for a package or feature are included. If you are not the original author of the package or feature, please mention, whether your contribution was created independently or in collaboration/cooperation with the original author.--> <!--Briefly describe what kind of updates or enhancements for a package or feature are included. If you are not the original author of the package or feature, please mention, whether your contribution was created independently or in collaboration/cooperation with the original author.-->
**Related Issue(s)**
<!--If this addresses an open GitHub issue for this project, please mention the issue number here, and describe the relation. Use the phrases `fixes #221` or `closes #135`, when you want an issue to be automatically closed when the pull request is merged-->
**Author(s)** **Author(s)**
<!--Please state name and affiliation of the author or authors that should be credited with the changes in this pull request--> <!--Please state name and affiliation of the author or authors that should be credited with the changes in this pull request-->
**Licensing** **Licensing**
By submitting this pull request I implicitly accept, that my submission is subject to the same licensing terms as the original package or feature(s) that are updated or amended by this pull request. By submitting this pull request, I agree, that my contribution will be included in LAMMPS and redistributed under either the GNU General Public License version 2 (GPL v2) or the GNU Lesser General Public License version 2.1 (LGPL v2.1).
**Backward Compatibility** **Backward Compatibility**
<!--Please state whether any changes in the pull request break backward compatibility for inputs, and - if yes - explain what has been changed and why--> <!--Please state whether any changes in the pull request will break backward compatibility for inputs, and - if yes - explain what has been changed and why-->
**Implementation Notes** **Implementation Notes**
@ -29,11 +33,19 @@ By submitting this pull request I implicitly accept, that my submission is subje
**Post Submission Checklist** **Post Submission Checklist**
<!--Please check the fields below as they are completed--> <!--Please check the fields below as they are completed **after** the pull request has been submitted. Delete lines that don't apply-->
- [ ] The feature or features in this pull request is complete - [ ] The feature or features in this pull request is complete
- [ ] Suitable updates to the existing docs are included - [ ] Licensing information is complete
- [ ] One or more example input decks are included - [ ] Corresponding author information is complete
- [ ] The source code follows the LAMMPS formatting guidelines - [ ] The source code follows the LAMMPS formatting guidelines
- [ ] Suitable updates to the existing docs are included
- [ ] The updated documentation is integrated and tested with the documentation build system
- [ ] The feature has been verified to work with the conventional build system
- [ ] The feature has been verified to work with the CMake based build system
- [ ] Suitable tests have been updated or added to the unittest tree.
- [ ] A package specific README file has been updated
- [ ] One or more example input decks are included
**Further Information, Files, and Links** **Further Information, Files, and Links**

22
README
View File

@ -25,25 +25,29 @@ The LAMMPS distribution includes the following files and directories:
README this file README this file
LICENSE the GNU General Public License (GPL) LICENSE the GNU General Public License (GPL)
bench benchmark problems bench benchmark problems
cmake CMake build system cmake CMake build files
doc documentation doc documentation
examples simple test problems examples simple test problems
lib libraries LAMMPS can be linked with fortran Fortran wrapper for LAMMPS
lib additional provided or external libraries
potentials interatomic potential files potentials interatomic potential files
python Python wrapper on LAMMPS as a library python Python wrappers for LAMMPS
src source files src source files
tools pre- and post-processing tools tools pre- and post-processing tools
Point your browser at any of these files to get started: Point your browser at any of these files to get started:
http://lammps.sandia.gov/doc/Manual.html the LAMMPS manual https://lammps.sandia.gov/doc/Manual.html LAMMPS user manual
http://lammps.sandia.gov/doc/Intro.html hi-level introduction https://lammps.sandia.gov/doc/Intro.html hi-level introduction
http://lammps.sandia.gov/doc/Build.html how to build LAMMPS https://lammps.sandia.gov/doc/Build.html how to build LAMMPS
http://lammps.sandia.gov/doc/Run_head.html how to run LAMMPS https://lammps.sandia.gov/doc/Run_head.html how to run LAMMPS
http://lammps.sandia.gov/doc/Developer.pdf LAMMPS developer guide https://lammps.sandia.gov/doc/Commands_all.html Table of available commands
https://lammps.sandia.gov/doc/pg_library.html LAMMPS programmer guide
https://lammps.sandia.gov/doc/Modify.html how to modify and extend LAMMPS
https://lammps.sandia.gov/doc/pg_developer.html LAMMPS developer guide
You can also create these doc pages locally: You can also create these doc pages locally:
% cd doc % cd doc
% make html # creates HTML pages in doc/html % make html # creates HTML pages in doc/html
% make pdf # creates Manual.pdf and Developer.pdf % make pdf # creates Manual.pdf

View File

@ -157,11 +157,11 @@ else()
file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.c) file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.c)
add_library(mpi_stubs STATIC ${MPI_SOURCES}) add_library(mpi_stubs STATIC ${MPI_SOURCES})
set_target_properties(mpi_stubs PROPERTIES OUTPUT_NAME lammps_mpi_stubs${LAMMPS_MACHINE}) set_target_properties(mpi_stubs PROPERTIES OUTPUT_NAME lammps_mpi_stubs${LAMMPS_MACHINE})
target_include_directories(mpi_stubs PUBLIC $<BUILD_INTERFACE:${LAMMPS_SOURCE_DIR}/STUBS> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/lammps/mpi>) target_include_directories(mpi_stubs PUBLIC $<BUILD_INTERFACE:${LAMMPS_SOURCE_DIR}/STUBS>)
install(FILES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/lammps/mpi)
if(BUILD_SHARED_LIBS) if(BUILD_SHARED_LIBS)
target_link_libraries(lammps PRIVATE mpi_stubs) target_link_libraries(lammps PRIVATE mpi_stubs)
target_include_directories(lammps INTERFACE $<BUILD_INTERFACE:${LAMMPS_SOURCE_DIR}/STUBS> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/lammps/mpi>) target_include_directories(lammps INTERFACE $<BUILD_INTERFACE:${LAMMPS_SOURCE_DIR}/STUBS>)
target_compile_definitions(lammps INTERFACE $<INSTALL_INTERFACE:LAMMPS_LIB_NO_MPI>)
else() else()
target_link_libraries(lammps PUBLIC mpi_stubs) target_link_libraries(lammps PUBLIC mpi_stubs)
endif() endif()
@ -574,7 +574,7 @@ if (${_index} GREATER -1)
endif() endif()
set(LAMMPS_CXX_HEADERS angle.h atom.h bond.h citeme.h comm.h compute.h dihedral.h domain.h error.h fix.h force.h group.h improper.h set(LAMMPS_CXX_HEADERS angle.h atom.h bond.h citeme.h comm.h compute.h dihedral.h domain.h error.h fix.h force.h group.h improper.h
input.h info.h kspace.h lammps.h lattice.h library.h lmppython.h lmptype.h memory.h modify.h neighbor.h neigh_list.h output.h input.h info.h kspace.h lammps.h lattice.h library.h lmppython.h lmptype.h memory.h modify.h neighbor.h neigh_list.h output.h
pair.h pointers.h region.h timer.h universe.h update.h variable.h) pair.h pointers.h region.h timer.h universe.h update.h utils.h variable.h)
if(LAMMPS_EXCEPTIONS) if(LAMMPS_EXCEPTIONS)
list(APPEND LAMMPS_CXX_HEADERS exceptions.h) list(APPEND LAMMPS_CXX_HEADERS exceptions.h)
endif() endif()

View File

@ -3,11 +3,16 @@
# #
# Requires latest gcovr (for GCC 8.1 support):# # Requires latest gcovr (for GCC 8.1 support):#
# pip install git+https://github.com/gcovr/gcovr.git # pip install git+https://github.com/gcovr/gcovr.git
#
# For Python coverage the coverage package needs to be installed
############################################################################### ###############################################################################
if(ENABLE_COVERAGE) if(ENABLE_COVERAGE)
find_program(GCOVR_BINARY gcovr) find_program(GCOVR_BINARY gcovr)
find_package_handle_standard_args(GCOVR DEFAULT_MSG GCOVR_BINARY) 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)
if(GCOVR_FOUND) if(GCOVR_FOUND)
get_filename_component(ABSOLUTE_LAMMPS_SOURCE_DIR ${LAMMPS_SOURCE_DIR} ABSOLUTE) get_filename_component(ABSOLUTE_LAMMPS_SOURCE_DIR ${LAMMPS_SOURCE_DIR} ABSOLUTE)
@ -46,4 +51,30 @@ if(ENABLE_COVERAGE)
) )
add_dependencies(reset_coverage clean_coverage_html) add_dependencies(reset_coverage clean_coverage_html)
endif() endif()
if(COVERAGE_FOUND)
set(PYTHON_COVERAGE_HTML_DIR ${CMAKE_BINARY_DIR}/python_coverage_html)
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 -d ${PYTHON_COVERAGE_HTML_DIR}
DEPENDS ${CMAKE_BINARY_DIR}/unittest/python/.coverage
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/unittest/python
COMMENT "Generating HTML Python coverage report..."
)
add_custom_target(
gen_python_coverage_xml
COMMAND ${COVERAGE_BINARY} xml -o ${CMAKE_BINARY_DIR}/python_coverage.xml
DEPENDS ${CMAKE_BINARY_DIR}/unittest/python/.coverage
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/unittest/python
COMMENT "Generating XML Python coverage report..."
)
endif()
endif() endif()

View File

@ -1,3 +1,3 @@
# utility script to call GenerateBinaryHeader function # utility script to call GenerateBinaryHeader function
include(${SOURCE_DIR}/Modules/LAMMPSUtils.cmake) include(${SOURCE_DIR}/Modules/LAMMPSUtils.cmake)
GenerateBinaryHeader(${VARNAME} ${HEADER_FILE} ${SOURCE_FILES}) GenerateBinaryHeader(${VARNAME} ${HEADER_FILE} ${SOURCE_FILE})

View File

@ -71,19 +71,15 @@ macro(pkg_depends PKG1 PKG2)
endmacro() endmacro()
# CMake-only replacement for bin2c and xxd # CMake-only replacement for bin2c and xxd
function(GenerateBinaryHeader varname outfile files) function(GenerateBinaryHeader varname outfile infile)
message("Creating ${outfile}...") message("Creating ${outfile}...")
file(WRITE ${outfile} "// CMake generated file\n") file(WRITE ${outfile} "// CMake generated file\n")
math(EXPR ARG_END "${ARGC}-1")
foreach(IDX RANGE 2 ${ARG_END}) file(READ ${infile} content HEX)
list(GET ARGV ${IDX} filename)
file(READ ${filename} content HEX)
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," content "${content}") string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," content "${content}")
string(REGEX REPLACE ",$" "" content "${content}") string(REGEX REPLACE ",$" "" content "${content}")
file(APPEND ${outfile} "const unsigned char ${varname}[] = { ${content} };\n") file(APPEND ${outfile} "const unsigned char ${varname}[] = { ${content} };\n")
file(APPEND ${outfile} "const unsigned int ${varname}_size = sizeof(${varname});\n") file(APPEND ${outfile} "const unsigned int ${varname}_size = sizeof(${varname});\n")
endforeach()
endfunction(GenerateBinaryHeader) endfunction(GenerateBinaryHeader)
# fetch missing potential files # fetch missing potential files

View File

@ -309,7 +309,7 @@ elseif(GPU_API STREQUAL "HIP")
endif() endif()
add_custom_command(OUTPUT ${CUBIN_H_FILE} add_custom_command(OUTPUT ${CUBIN_H_FILE}
COMMAND ${CMAKE_COMMAND} -D SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -D VARNAME=${CU_NAME} -D HEADER_FILE=${CUBIN_H_FILE} -D SOURCE_FILES=${CUBIN_FILE} -P ${CMAKE_CURRENT_SOURCE_DIR}/Modules/GenerateBinaryHeader.cmake COMMAND ${CMAKE_COMMAND} -D SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -D VARNAME=${CU_NAME} -D HEADER_FILE=${CUBIN_H_FILE} -D SOURCE_FILE=${CUBIN_FILE} -P ${CMAKE_CURRENT_SOURCE_DIR}/Modules/GenerateBinaryHeader.cmake
DEPENDS ${CUBIN_FILE} DEPENDS ${CUBIN_FILE}
COMMENT "Generating ${CU_NAME}_cubin.h") COMMENT "Generating ${CU_NAME}_cubin.h")

View File

@ -2,6 +2,8 @@ set(COLVARS_SOURCE_DIR ${LAMMPS_LIB_SOURCE_DIR}/colvars)
file(GLOB COLVARS_SOURCES ${COLVARS_SOURCE_DIR}/[^.]*.cpp) file(GLOB COLVARS_SOURCES ${COLVARS_SOURCE_DIR}/[^.]*.cpp)
option(COLVARS_DEBUG "Debugging messages for Colvars (quite verbose)" OFF)
# Build Lepton by default # Build Lepton by default
option(COLVARS_LEPTON "Build and link the Lepton library" ON) option(COLVARS_LEPTON "Build and link the Lepton library" ON)
@ -16,11 +18,18 @@ if(COLVARS_LEPTON)
endif() endif()
add_library(colvars STATIC ${COLVARS_SOURCES}) add_library(colvars STATIC ${COLVARS_SOURCES})
target_compile_definitions(colvars PRIVATE -DLAMMPS_${LAMMPS_SIZES}) target_compile_definitions(colvars PRIVATE -DCOLVARS_LAMMPS)
set_target_properties(colvars PROPERTIES OUTPUT_NAME lammps_colvars${LAMMPS_MACHINE}) set_target_properties(colvars PROPERTIES OUTPUT_NAME lammps_colvars${LAMMPS_MACHINE})
target_include_directories(colvars PUBLIC ${LAMMPS_LIB_SOURCE_DIR}/colvars) target_include_directories(colvars PUBLIC ${LAMMPS_LIB_SOURCE_DIR}/colvars)
# The line below is needed to locate math_eigen_impl.h
target_include_directories(colvars PRIVATE ${LAMMPS_SOURCE_DIR})
target_link_libraries(lammps PRIVATE colvars) target_link_libraries(lammps PRIVATE colvars)
if(COLVARS_DEBUG)
# Need to export the macro publicly to also affect the proxy
target_compile_definitions(colvars PUBLIC -DCOLVARS_DEBUG)
endif()
if(COLVARS_LEPTON) if(COLVARS_LEPTON)
target_link_libraries(lammps PRIVATE lepton) target_link_libraries(lammps PRIVATE lepton)
target_compile_definitions(colvars PRIVATE -DLEPTON) target_compile_definitions(colvars PRIVATE -DLEPTON)

View File

@ -1,6 +1,12 @@
# Makefile for LAMMPS documentation # Makefile for LAMMPS documentation
SHELL = /bin/bash SHELL = /bin/bash
HAS_BASH = YES
ifeq (,$(wildcard $(SHELL)))
OSHELL := $(SHELL)
override SHELL = /bin/sh
HAS_BASH = NO
endif
BUILDDIR = ${CURDIR} BUILDDIR = ${CURDIR}
RSTDIR = $(BUILDDIR)/src RSTDIR = $(BUILDDIR)/src
VENV = $(BUILDDIR)/docenv VENV = $(BUILDDIR)/docenv
@ -37,8 +43,10 @@ HAS_VIRTUALENV = YES
endif endif
ifeq ($(shell which pdflatex >/dev/null 2>&1; echo $$?), 0) ifeq ($(shell which pdflatex >/dev/null 2>&1; echo $$?), 0)
ifeq ($(shell which latexmk >/dev/null 2>&1; echo $$?), 0)
HAS_PDFLATEX = YES HAS_PDFLATEX = YES
endif endif
endif
#SPHINXEXTRA = -j $(shell $(PYTHON) -c 'import multiprocessing;print(multiprocessing.cpu_count())') $(shell test -f $(BUILDDIR)/doxygen/xml/run.stamp && printf -- "-E") #SPHINXEXTRA = -j $(shell $(PYTHON) -c 'import multiprocessing;print(multiprocessing.cpu_count())') $(shell test -f $(BUILDDIR)/doxygen/xml/run.stamp && printf -- "-E")
@ -55,6 +63,7 @@ DOXYFILES = $(shell sed -n -e 's/\#.*$$//' -e '/^ *INPUT \+=/,/^[A-Z_]\+ \+
# ------------------------------------------ # ------------------------------------------
help: help:
@if [ "$(HAS_BASH)" == "NO" ] ; then echo "bash was not found at $(OSHELL)! Please use: $(MAKE) SHELL=/path/to/bash" 1>&2; exit 1; fi
@echo "Please use \`make <target>' where <target> is one of" @echo "Please use \`make <target>' where <target> is one of"
@echo " html create HTML doc pages in html dir" @echo " html create HTML doc pages in html dir"
@echo " pdf create Manual.pdf in this dir" @echo " pdf create Manual.pdf in this dir"
@ -72,7 +81,7 @@ help:
# ------------------------------------------ # ------------------------------------------
clean-all: clean clean-all: clean
rm -rf $(BUILDDIR)/docenv $(MATHJAX) $(BUILDDIR)/LAMMPS.mobi $(BUILDDIR)/LAMMPS.epub $(BUILDDIR)/Manual.pdf rm -rf $(BUILDDIR)/docenv $(MATHJAX) $(POLYFILL) $(BUILDDIR)/LAMMPS.mobi $(BUILDDIR)/LAMMPS.epub $(BUILDDIR)/Manual.pdf
clean: clean-spelling clean: clean-spelling
rm -rf $(BUILDDIR)/html $(BUILDDIR)/epub $(BUILDDIR)/latex $(BUILDDIR)/doctrees $(BUILDDIR)/doxygen/xml $(BUILDDIR)/doxygen-warn.log $(BUILDDIR)/doxygen/Doxyfile $(SPHINXCONFIG)/conf.py rm -rf $(BUILDDIR)/html $(BUILDDIR)/epub $(BUILDDIR)/latex $(BUILDDIR)/doctrees $(BUILDDIR)/doxygen/xml $(BUILDDIR)/doxygen-warn.log $(BUILDDIR)/doxygen/Doxyfile $(SPHINXCONFIG)/conf.py
@ -87,6 +96,7 @@ $(SPHINXCONFIG)/conf.py: $(SPHINXCONFIG)/conf.py.in
-e 's,@LAMMPS_DOC_DIR@,$(BUILDDIR),g' $< > $@ -e 's,@LAMMPS_DOC_DIR@,$(BUILDDIR),g' $< > $@
html: xmlgen $(SPHINXCONFIG)/conf.py $(ANCHORCHECK) $(MATHJAX) $(POLYFILL) html: xmlgen $(SPHINXCONFIG)/conf.py $(ANCHORCHECK) $(MATHJAX) $(POLYFILL)
@if [ "$(HAS_BASH)" == "NO" ] ; then echo "bash was not found at $(OSHELL)! Please use: $(MAKE) SHELL=/path/to/bash" 1>&2; exit 1; fi
@$(MAKE) $(MFLAGS) -C graphviz all @$(MAKE) $(MFLAGS) -C graphviz all
@(\ @(\
. $(VENV)/bin/activate ; env PYTHONWARNINGS= \ . $(VENV)/bin/activate ; env PYTHONWARNINGS= \
@ -110,6 +120,7 @@ html: xmlgen $(SPHINXCONFIG)/conf.py $(ANCHORCHECK) $(MATHJAX) $(POLYFILL)
@echo "Build finished. The HTML pages are in doc/html." @echo "Build finished. The HTML pages are in doc/html."
spelling: xmlgen $(VENV) $(SPHINXCONFIG)/false_positives.txt spelling: xmlgen $(VENV) $(SPHINXCONFIG)/false_positives.txt
@if [ "$(HAS_BASH)" == "NO" ] ; then echo "bash was not found at $(OSHELL)! Please use: $(MAKE) SHELL=/path/to/bash" 1>&2; exit 1; fi
@(\ @(\
. $(VENV)/bin/activate ; env PYTHONWARNINGS= \ . $(VENV)/bin/activate ; env PYTHONWARNINGS= \
cp $(SPHINXCONFIG)/false_positives.txt $(RSTDIR)/ ; env PYTHONWARNINGS= \ cp $(SPHINXCONFIG)/false_positives.txt $(RSTDIR)/ ; env PYTHONWARNINGS= \
@ -120,6 +131,7 @@ spelling: xmlgen $(VENV) $(SPHINXCONFIG)/false_positives.txt
@echo "Spell check finished." @echo "Spell check finished."
epub: xmlgen $(VENV) $(SPHINXCONFIG)/conf.py $(ANCHORCHECK) epub: xmlgen $(VENV) $(SPHINXCONFIG)/conf.py $(ANCHORCHECK)
@if [ "$(HAS_BASH)" == "NO" ] ; then echo "bash was not found at $(OSHELL)! Please use: $(MAKE) SHELL=/path/to/bash" 1>&2; exit 1; fi
@$(MAKE) $(MFLAGS) -C graphviz all @$(MAKE) $(MFLAGS) -C graphviz all
@mkdir -p epub/JPG @mkdir -p epub/JPG
@rm -f LAMMPS.epub @rm -f LAMMPS.epub
@ -140,8 +152,9 @@ mobi: epub
@echo "Conversion finished. The MOBI manual file is created." @echo "Conversion finished. The MOBI manual file is created."
pdf: xmlgen $(VENV) $(SPHINXCONFIG)/conf.py $(ANCHORCHECK) pdf: xmlgen $(VENV) $(SPHINXCONFIG)/conf.py $(ANCHORCHECK)
@if [ "$(HAS_BASH)" == "NO" ] ; then echo "bash was not found at $(OSHELL)! Please use: $(MAKE) SHELL=/path/to/bash" 1>&2; exit 1; fi
@$(MAKE) $(MFLAGS) -C graphviz all @$(MAKE) $(MFLAGS) -C graphviz all
@if [ "$(HAS_PDFLATEX)" == "NO" ] ; then echo "PDFLaTeX was not found! Please check README.md for further instructions" 1>&2; exit 1; fi @if [ "$(HAS_PDFLATEX)" == "NO" ] ; then echo "PDFLaTeX or latexmk were not found! Please check README for further instructions" 1>&2; exit 1; fi
@(\ @(\
. $(VENV)/bin/activate ; env PYTHONWARNINGS= \ . $(VENV)/bin/activate ; env PYTHONWARNINGS= \
sphinx-build $(SPHINXEXTRA) -b latex -c $(SPHINXCONFIG) -d $(BUILDDIR)/doctrees $(RSTDIR) latex ;\ sphinx-build $(SPHINXEXTRA) -b latex -c $(SPHINXCONFIG) -d $(BUILDDIR)/doctrees $(RSTDIR) latex ;\
@ -155,15 +168,13 @@ pdf: xmlgen $(VENV) $(SPHINXCONFIG)/conf.py $(ANCHORCHECK)
deactivate ;\ deactivate ;\
) )
@cd latex && \ @cd latex && \
sed 's/latexmk -pdf -dvi- -ps-/pdflatex/g' Makefile > temp && \
mv temp Makefile && \
sed 's/\\begin{equation}//g' LAMMPS.tex > tmp.tex && \ sed 's/\\begin{equation}//g' LAMMPS.tex > tmp.tex && \
mv tmp.tex LAMMPS.tex && \ mv tmp.tex LAMMPS.tex && \
sed 's/\\end{equation}//g' LAMMPS.tex > tmp.tex && \ sed 's/\\end{equation}//g' LAMMPS.tex > tmp.tex && \
mv tmp.tex LAMMPS.tex && \ mv tmp.tex LAMMPS.tex && \
make && \ sed 's/\\contentsname}{.*}}/\\contentsname}{LAMMPS Documentation}}/g' LAMMPS.tex > tmp.tex && \
make && \ mv tmp.tex LAMMPS.tex && \
make && \ $(MAKE) $(MFLAGS) && \
mv LAMMPS.pdf ../Manual.pdf && \ mv LAMMPS.pdf ../Manual.pdf && \
cd ../; cd ../;
@rm -rf latex/_sources @rm -rf latex/_sources
@ -211,6 +222,7 @@ doxygen/xml/index.xml : $(VENV) doxygen/Doxyfile $(DOXYFILES)
# ------------------------------------------ # ------------------------------------------
$(VENV): $(VENV):
@if [ "$(HAS_BASH)" == "NO" ] ; then echo "bash was not found at $(OSHELL)! Please use: $(MAKE) SHELL=/path/to/bash" 1>&2; exit 1; fi
@if [ "$(HAS_PYTHON3)" == "NO" ] ; then echo "python3 was not found! Please see README for further instructions" 1>&2; exit 1; fi @if [ "$(HAS_PYTHON3)" == "NO" ] ; then echo "python3 was not found! Please see README for further instructions" 1>&2; exit 1; fi
@if [ "$(HAS_DOXYGEN)" == "NO" ] ; then echo "doxygen was not found! Please see README for further instructions" 1>&2; exit 1; fi @if [ "$(HAS_DOXYGEN)" == "NO" ] ; then echo "doxygen was not found! Please see README for further instructions" 1>&2; exit 1; fi
@if [ "$(HAS_VIRTUALENV)" == "NO" ] ; then echo "virtualenv was not found! Please see README for further instructions" 1>&2; exit 1; fi @if [ "$(HAS_VIRTUALENV)" == "NO" ] ; then echo "virtualenv was not found! Please see README for further instructions" 1>&2; exit 1; fi
@ -225,8 +237,12 @@ $(VENV):
$(MATHJAX): $(MATHJAX):
@git clone --depth 1 https://github.com/mathjax/MathJax.git $@ @git clone --depth 1 https://github.com/mathjax/MathJax.git $@
# fall back to using wget and/or unencrypted download, if curl fails
$(POLYFILL): $(MATHJAX) $(POLYFILL): $(MATHJAX)
@curl -s -o $@ "https://polyfill.io/v3/polyfill.min.js?features=es6" @curl -s -o $@ "https://polyfill.io/v3/polyfill.min.js?features=es6" > /dev/null 2>&1 || \
curl -s -o $@ "http://polyfill.io/v3/polyfill.min.js?features=es6" > /dev/null 2>&1 || \
wget -O $@ "https://polyfill.io/v3/polyfill.min.js?features=es6" > /dev/null 2>&1 || \
wget -O $@ "http://polyfill.io/v3/polyfill.min.js?features=es6" > /dev/null 2>&1
$(TXT2RST) $(ANCHORCHECK): $(VENV) $(TXT2RST) $(ANCHORCHECK): $(VENV)
@( \ @( \

View File

@ -9,12 +9,10 @@ src content files for LAMMPS documentation
html HTML version of the LAMMPS manual (see html/Manual.html) html HTML version of the LAMMPS manual (see html/Manual.html)
utils utilities and settings for building the documentation utils utilities and settings for building the documentation
Manual.pdf PDF version of entire manual Manual.pdf PDF version of entire manual
Developer.pdf PDF with info about how LAMMPS is structured
LAMMPS.epub Manual in ePUB format LAMMPS.epub Manual in ePUB format
LAMMPS.mobi Manual in MOBI (Kindle) format LAMMPS.mobi Manual in MOBI (Kindle) format
lammps.1 man page for the lammps command lammps.1 man page for the lammps command
msi2lmp.1 man page for the msi2lmp command msi2lmp.1 man page for the msi2lmp command
mathjax code and fonts for rendering math in html
doctree temporary data doctree temporary data
docenv python virtual environment for generating the manual docenv python virtual environment for generating the manual
doxygen Doxygen configuration and output doxygen Doxygen configuration and output
@ -32,9 +30,9 @@ folder and the PDF manual should be included. If you downloaded LAMMPS
from GitHub then you either need to download them or build them. from GitHub then you either need to download them or build them.
(a) You can "fetch" the current HTML and PDF files from the LAMMPS web (a) You can "fetch" the current HTML and PDF files from the LAMMPS web
site. Just type "make fetch". This should create a html_www dir and site. Just type "make fetch". This should create a html_www directory
Manual_www.pdf/Developer_www.pdf files. These files will always and Manual_www.pdf file. These will always represent the latest published
represent the latest published patch/development version of LAMMPS. patch/development version of LAMMPS.
(b) You can build the HTML and PDF files yourself, by typing "make html" (b) You can build the HTML and PDF files yourself, by typing "make html"
or by "make pdf", respectively. This requires various tools and files. or by "make pdf", respectively. This requires various tools and files.
@ -68,6 +66,9 @@ installed. This includes:
- tabulary - tabulary
- upquote - upquote
- wrapfig - wrapfig
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.
Building the EPUB format requires LaTeX installation with the same packages Building the EPUB format requires LaTeX installation with the same packages
as for the PDF format plus the 'dvipng' command to convert the embedded math as for the PDF format plus the 'dvipng' command to convert the embedded math

View File

@ -416,6 +416,7 @@ INPUT = @LAMMPS_SOURCE_DIR@/utils.cpp \
@LAMMPS_SOURCE_DIR@/library.h \ @LAMMPS_SOURCE_DIR@/library.h \
@LAMMPS_SOURCE_DIR@/lammps.cpp \ @LAMMPS_SOURCE_DIR@/lammps.cpp \
@LAMMPS_SOURCE_DIR@/lammps.h \ @LAMMPS_SOURCE_DIR@/lammps.h \
@LAMMPS_SOURCE_DIR@/pointers.h \
@LAMMPS_SOURCE_DIR@/lmptype.h \ @LAMMPS_SOURCE_DIR@/lmptype.h \
@LAMMPS_SOURCE_DIR@/atom.cpp \ @LAMMPS_SOURCE_DIR@/atom.cpp \
@LAMMPS_SOURCE_DIR@/atom.h \ @LAMMPS_SOURCE_DIR@/atom.h \
@ -431,6 +432,7 @@ INPUT = @LAMMPS_SOURCE_DIR@/utils.cpp \
@LAMMPS_SOURCE_DIR@/my_page.h \ @LAMMPS_SOURCE_DIR@/my_page.h \
@LAMMPS_SOURCE_DIR@/my_pool_chunk.cpp \ @LAMMPS_SOURCE_DIR@/my_pool_chunk.cpp \
@LAMMPS_SOURCE_DIR@/my_pool_chunk.h \ @LAMMPS_SOURCE_DIR@/my_pool_chunk.h \
@LAMMPS_SOURCE_DIR@/math_eigen.h \
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded # directories that are symbolic links (a Unix file system feature) are excluded

View File

@ -1,6 +1,5 @@
# Makefile for generating images with graphviz # Makefile for generating images with graphviz
# #
SHELL = /bin/bash
BUILDDIR = ${CURDIR}/.. BUILDDIR = ${CURDIR}/..
IMGDIR = $(BUILDDIR)/src/JPG IMGDIR = $(BUILDDIR)/src/JPG
IMGSRC = $(wildcard *.dot) IMGSRC = $(wildcard *.dot)

View File

@ -1,4 +1,4 @@
.TH LAMMPS "24 August 2020" "2020-08-24" .TH LAMMPS "18 September 2020" "2020-09-18"
.SH NAME .SH NAME
.B LAMMPS .B LAMMPS
\- Molecular Dynamics Simulator. \- Molecular Dynamics Simulator.

View File

@ -159,11 +159,11 @@ others (e.g. GCC version 9 and beyond, Clang version 10 and later) may
implement strict OpenMP 4.0 and later semantics, which are incompatible implement strict OpenMP 4.0 and later semantics, which are incompatible
with the OpenMP 3.1 semantics used in LAMMPS for maximal compatibility with the OpenMP 3.1 semantics used in LAMMPS for maximal compatibility
with compiler versions in use. If compilation with OpenMP enabled fails with compiler versions in use. If compilation with OpenMP enabled fails
because of your compiler requiring strict OpenMP 4.0 semantic, you can because of your compiler requiring strict OpenMP 4.0 semantics, you can
change the behavior by adding ``-D LAMMPS_OMP_COMPAT=4`` to the change the behavior by adding ``-D LAMMPS_OMP_COMPAT=4`` to the
``LMP_INC`` variable in your makefile, or add it to the command line ``LMP_INC`` variable in your makefile, or add it to the command line
while configuring with CMake. CMake will detect the suitable setting for while configuring with CMake. LAMMPS will autodetect a suitable setting
the GNU, Clang, and Intel compilers. for most GNU, Clang, and Intel compilers.
---------- ----------

View File

@ -487,3 +487,41 @@ e.g. to Python. Of course, the calling code has to be set up to
cleanly recover from an exception since not all parallel ranks may cleanly recover from an exception since not all parallel ranks may
throw an exception and thus other MPI ranks may get stuck waiting for throw an exception and thus other MPI ranks may get stuck waiting for
messages from the ones with errors. messages from the ones with errors.
----------
.. _trap_fpe:
Trigger selected floating-point exceptions
------------------------------------------
Many kinds of CPUs have the capability to detect when a calculation
results in an invalid math operation like a division by zero or calling
the square root with a negative argument. The default behavior on
most operating systems is to continue and have values for ``NaN`` (= not
a number) or ``Inf`` (= infinity). This allows software to detect and
recover from such conditions. This behavior can be changed, however,
often through use of compiler flags. On Linux systems (or more general
on systems using the GNU C library), these so-called floating-point traps
can also be selectively enabled through library calls. LAMMPS supports
that by setting the ``-DLAMMPS_TRAP_FPE`` pre-processor define. As it is
done in the ``main()`` function, this applies only to the standalone
executable, not the library.
.. tabs::
.. tab:: CMake build
.. code-block:: bash
-D CMAKE_TUNE_FLAGS=-DLAMMPS_TRAP_FPE
.. tab:: Traditional make
.. code-block:: make
LMP_INC = -DLAMMPS_TRAP_FPE
After compilation with this flag set, the LAMMPS executable will stop
and produce a core dump when a division by zero, overflow, illegal math
function argument or other invalid floating point operation is encountered.

View File

@ -5708,6 +5708,9 @@ Doc page with :doc:`WARNING messages <Errors_warnings>`
*Molecule file has dihedrals but no ndihedrals setting* *Molecule file has dihedrals but no ndihedrals setting*
Self-explanatory. Self-explanatory.
*Molecule file has fragments but no nfragments setting*
Self-explanatory.
*Molecule file has impropers but no nimpropers setting* *Molecule file has impropers but no nimpropers setting*
Self-explanatory. Self-explanatory.
@ -5717,6 +5720,9 @@ Doc page with :doc:`WARNING messages <Errors_warnings>`
*Molecule file has no Body Integers section* *Molecule file has no Body Integers section*
Self-explanatory. Self-explanatory.
*Molecule file has no Fragments section*
Self-explanatory.
*Molecule file has special flags but no bonds* *Molecule file has special flags but no bonds*
Self-explanatory. Self-explanatory.

View File

@ -23,7 +23,7 @@ need the source code.
These are the files and sub-directories in the LAMMPS distribution: These are the files and sub-directories in the LAMMPS distribution:
+------------+-------------------------------------------+ +------------+-------------------------------------------+
| README | text file | | README | Short description of the LAMMPS package |
+------------+-------------------------------------------+ +------------+-------------------------------------------+
| LICENSE | GNU General Public License (GPL) | | LICENSE | GNU General Public License (GPL) |
+------------+-------------------------------------------+ +------------+-------------------------------------------+
@ -35,16 +35,20 @@ These are the files and sub-directories in the LAMMPS distribution:
+------------+-------------------------------------------+ +------------+-------------------------------------------+
| examples | simple test problems | | examples | simple test problems |
+------------+-------------------------------------------+ +------------+-------------------------------------------+
| fortran | Fortran wrapper for LAMMPS |
+------------+-------------------------------------------+
| lib | additional provided or external libraries | | lib | additional provided or external libraries |
+------------+-------------------------------------------+ +------------+-------------------------------------------+
| potentials | interatomic potential files | | potentials | interatomic potential files |
+------------+-------------------------------------------+ +------------+-------------------------------------------+
| python | Python wrapper on LAMMPS | | python | Python wrappers for LAMMPS |
+------------+-------------------------------------------+ +------------+-------------------------------------------+
| src | source files | | src | source files |
+------------+-------------------------------------------+ +------------+-------------------------------------------+
| tools | pre- and post-processing tools | | tools | pre- and post-processing tools |
+------------+-------------------------------------------+ +------------+-------------------------------------------+
| unittest | sources and inputs for testing LAMMPS |
+------------+-------------------------------------------+
You will have all of these if you download source. You will only have You will have all of these if you download source. You will only have
some of them if you download executables, as explained on the pages some of them if you download executables, as explained on the pages

View File

@ -12,4 +12,5 @@ These pages provide a brief introduction to LAMMPS.
Intro_nonfeatures Intro_nonfeatures
Intro_opensource Intro_opensource
Intro_authors Intro_authors
Intro_citing
Intro_website Intro_website

52
doc/src/Intro_citing.rst Normal file
View File

@ -0,0 +1,52 @@
Citing LAMMPS
=============
Core Algorithms
^^^^^^^^^^^^^^^
Since LAMMPS is a community project, there is not a single one
publication or reference that describes **all** of LAMMPS.
The canonical publication that describes the foundation, that is
the basic spatial decomposition approach, the neighbor finding,
and basic communications algorithms used in LAMMPS is:
`S. Plimpton, Fast Parallel Algorithms for Short-Range Molecular Dynamics, J Comp Phys, 117, 1-19 (1995). <http://www.sandia.gov/~sjplimp/papers/jcompphys95.pdf>`_
So any project using LAMMPS (or a derivative application using LAMMPS as
a simulation engine) should cite this paper. A new publication
describing the developments and improvements of LAMMPS in the 25 years
since then is currently in preparation.
DOI for the LAMMPS code
^^^^^^^^^^^^^^^^^^^^^^^
LAMMPS developers use the `Zenodo service at CERN
<https://zenodo.org/>`_ to create digital object identifies (DOI) for
stable releases of the LAMMPS code. There are two types of DOIs for the
LAMMPS source code: 1) the canonical DOI for **all** versions of LAMMPS,
which will always point to the latest stable release version is:
`DOI: 10.5281/zenodo.3726416 <https://dx.doi/org/10.5281/zenodo.3726416>`_
In addition there are DOIs for individual stable releases starting with
the `3 March 2020 version, DOI:10.5281/zenodo.3726417 <https://dx.doi/org/10.5281/zenodo.3726416>`_
Home page
^^^^^^^^^
The LAMMPS website at `https://lammps.sandia.gov/ <https://lammps.sandia.gov>`_ is the canonical
location for information about LAMMPS and more detailed lists of publications
using LAMMPS and contributing features.
Citing contributions
^^^^^^^^^^^^^^^^^^^^
LAMMPS has many features and uses previously published methods and
algorithms or novel features. It also includes potential parameter
filed for specific models. You can look up relevant publications either
in the LAMMPS output to the screen, the ``log.cite`` file (which is
populated with references to relevant papers through embedding them into
the source code) and in the documentation of the :doc:`corresponding commands
<Commands_all>` or in the :doc:`Howto tutorials <Howto>`.

View File

@ -1,13 +1,8 @@
LAMMPS Documentation LAMMPS version |version| Documentation
#################### ######################################
|version| version LAMMPS stands for **L**\ arge-scale **A**\ tomic/**M**\ olecular
***************** **M**\ assively **P**\ arallel **S**\ imulator.
:doc:`What is a LAMMPS version? <Manual_version>`
LAMMPS stands for Large-scale Atomic/Molecular Massively Parallel
Simulator.
LAMMPS is a classical molecular dynamics simulation code with a focus LAMMPS is a classical molecular dynamics simulation code with a focus
on materials modeling. It was designed to run efficiently on parallel on materials modeling. It was designed to run efficiently on parallel
@ -28,17 +23,23 @@ The content for this manual is part of the LAMMPS distribution. You
can build a local copy of the Manual as HTML pages or a PDF file, by can build a local copy of the Manual as HTML pages or a PDF file, by
following the steps on the :doc:`Manual build <Manual_build>` doc page. following the steps on the :doc:`Manual build <Manual_build>` doc page.
The manual is organized in two parts: The manual is organized in two parts:
1) A :ref:`User documentation <user_documentation>` for how to install 1) the :ref:`User documentation <user_documentation>` for how to install
and use LAMMPS and 2) a :ref:`Programmer documentation <programmer_documentation>` and use LAMMPS and 2) the :ref:`Programmer documentation <programmer_documentation>`
for how to write programs using the LAMMPS library or how to modify LAMMPS. for how to write programs using the LAMMPS library from different
programming languages and how to modify and extend LAMMPS.
---------- .. only:: html
Once you are familiar with LAMMPS, you may want to bookmark :doc:`this page <Commands_all>` since it gives quick access to a doc page for Once you are familiar with LAMMPS, you may want to bookmark :doc:`this page <Commands_all>` since it gives quick access to a doc page for
every LAMMPS command. every LAMMPS command.
.. _lws: https://lammps.sandia.gov .. _lws: https://lammps.sandia.gov
----------
User Documentation
******************
.. _user_documentation: .. _user_documentation:
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
@ -61,6 +62,9 @@ every LAMMPS command.
Errors Errors
Manual_build Manual_build
Programmer Documentation
************************
.. _programmer_documentation: .. _programmer_documentation:
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
@ -89,7 +93,9 @@ every LAMMPS command.
fix_modify_atc_commands fix_modify_atc_commands
Indices and tables Indices and tables
================== ******************
.. only:: html
* :ref:`genindex` * :ref:`genindex`
* :ref:`search` * :ref:`search`

View File

@ -18,7 +18,6 @@ files. Here is a list with descriptions:
LAMMPS.mobi # Manual in MOBI e-book format LAMMPS.mobi # Manual in MOBI e-book format
docenv # virtualenv folder for processing the manual sources docenv # virtualenv folder for processing the manual sources
doctrees # temporary data from processing the manual doctrees # temporary data from processing the manual
mathjax # code and fonts for rendering math in html
doxygen # doxygen configuration and output doxygen # doxygen configuration and output
.gitignore # list of files and folders to be ignored by git .gitignore # list of files and folders to be ignored by git
doxygen-warn.log # logfile with warnings from running doxygen doxygen-warn.log # logfile with warnings from running doxygen
@ -34,11 +33,10 @@ of two ways:
a. You can "fetch" the current HTML and PDF files from the LAMMPS web a. You can "fetch" the current HTML and PDF files from the LAMMPS web
site. Just type ``make fetch``. This should download a html_www site. Just type ``make fetch``. This should download a html_www
directory and a Manual_www.pdf file. Note that if directory and a Manual_www.pdf file. Note that if new LAMMPS features
new LAMMPS features have been added more recently than the date of have been added more recently than the date of your LAMMPS version, the
your LAMMPS version, the fetched documentation will include those fetched documentation will include those changes (but your source code
changes (but your source code will not, unless you update your local will not, unless you update your local repository).
repository).
b. You can build the HTML or PDF files yourself, by typing ``make html`` b. You can build the HTML or PDF files yourself, by typing ``make html``
or ``make pdf``. This requires various tools and files. Some of them or ``make pdf``. This requires various tools and files. Some of them
@ -133,7 +131,8 @@ Installing prerequisites for PDF build
In addition to the tools needed for building the HTML format manual, In addition to the tools needed for building the HTML format manual,
a working LaTeX installation with support for PDFLaTeX and a selection a working LaTeX installation with support for PDFLaTeX and a selection
of LaTeX styles/packages are required. of LaTeX styles/packages are required. To run the PDFLaTeX translation
the ``latexmk`` script needs to be installed as well.
Installing prerequisites for e-book reader builds Installing prerequisites for e-book reader builds
================================================= =================================================

View File

@ -41,7 +41,7 @@ Syntax
* template-ID(post-reacted) = ID of a molecule template containing post-reaction topology * template-ID(post-reacted) = ID of a molecule template containing post-reaction topology
* map_file = name of file specifying corresponding atom-IDs in the pre- and post-reacted templates * map_file = name of file specifying corresponding atom-IDs in the pre- and post-reacted templates
* zero or more individual keyword/value pairs may be appended to each react argument * zero or more individual keyword/value pairs may be appended to each react argument
* individual_keyword = *prob* or *max_rxn* or *stabilize_steps* or *update_edges* * individual_keyword = *prob* or *max_rxn* or *stabilize_steps* or *custom_charges*
.. parsed-literal:: .. parsed-literal::
@ -52,10 +52,9 @@ Syntax
N = maximum number of reactions allowed to occur N = maximum number of reactions allowed to occur
*stabilize_steps* value = timesteps *stabilize_steps* value = timesteps
timesteps = number of timesteps to apply the internally-created :doc:`nve/limit <fix_nve_limit>` fix to reacting atoms timesteps = number of timesteps to apply the internally-created :doc:`nve/limit <fix_nve_limit>` fix to reacting atoms
*update_edges* value = *none* or *charges* or *custom* *custom_charges* value = *no* or *fragmentID*
*none* = do not update topology near the edges of reaction templates no = update all atomic charges (default)
*charges* = update atomic charges of all atoms in reaction templates fragmentID = ID of molecule fragment whose charges are updated
*custom* = force the update of user-specified atomic charges
Examples Examples
"""""""" """"""""
@ -271,14 +270,14 @@ A discussion of correctly handling this is also provided on the
The map file is a text document with the following format: The map file is a text document with the following format:
A map file has a header and a body. The header of map file the A map file has a header and a body. The header of map file the
contains one mandatory keyword and five optional keywords. The contains one mandatory keyword and four optional keywords. The
mandatory keyword is 'equivalences': mandatory keyword is 'equivalences':
.. parsed-literal:: .. parsed-literal::
N *equivalences* = # of atoms N in the reaction molecule templates N *equivalences* = # of atoms N in the reaction molecule templates
The optional keywords are 'edgeIDs', 'deleteIDs', 'customIDs' and The optional keywords are 'edgeIDs', 'deleteIDs', 'chiralIDs' and
'constraints': 'constraints':
.. parsed-literal:: .. parsed-literal::
@ -286,10 +285,9 @@ The optional keywords are 'edgeIDs', 'deleteIDs', 'customIDs' and
N *edgeIDs* = # of edge atoms N in the pre-reacted molecule template N *edgeIDs* = # of edge atoms N in the pre-reacted molecule template
N *deleteIDs* = # of atoms N that are specified for deletion N *deleteIDs* = # of atoms N that are specified for deletion
N *chiralIDs* = # of specified chiral centers N N *chiralIDs* = # of specified chiral centers N
N *customIDs* = # of atoms N that are specified for a custom update
N *constraints* = # of specified reaction constraints N N *constraints* = # of specified reaction constraints N
The body of the map file contains two mandatory sections and five The body of the map file contains two mandatory sections and four
optional sections. The first mandatory section begins with the keyword optional sections. The first mandatory section begins with the keyword
'BondingIDs' and lists the atom IDs of the bonding atom pair in the 'BondingIDs' and lists the atom IDs of the bonding atom pair in the
pre-reacted molecule template. The second mandatory section begins pre-reacted molecule template. The second mandatory section begins
@ -303,16 +301,11 @@ molecule template. The second optional section begins with the keyword
'DeleteIDs' and lists the atom IDs of pre-reaction template atoms to 'DeleteIDs' and lists the atom IDs of pre-reaction template atoms to
delete. The third optional section begins with the keyword 'ChiralIDs' delete. The third optional section begins with the keyword 'ChiralIDs'
lists the atom IDs of chiral atoms whose handedness should be lists the atom IDs of chiral atoms whose handedness should be
enforced. The fourth optional section begins with the keyword 'Custom enforced. The fourth optional section begins with the keyword
Edges' and allows for forcing the update of a specific atom's atomic 'Constraints' and lists additional criteria that must be satisfied in
charge. The first column is the ID of an atom near the edge of the order for the reaction to occur. Currently, there are five types of
pre-reacted molecule template, and the value of the second column is constraints available, as discussed below: 'distance', 'angle',
either 'none' or 'charges.' Further details are provided in the 'dihedral', 'arrhenius', and 'rmsd'.
discussion of the 'update_edges' keyword. The fifth optional section
begins with the keyword 'Constraints' and lists additional criteria
that must be satisfied in order for the reaction to occur. Currently,
there are five types of constraints available, as discussed below:
'distance', 'angle', 'dihedral', 'arrhenius', and 'rmsd'.
A sample map file is given below: A sample map file is given below:
@ -488,17 +481,12 @@ individually tuned for each fix reaction step. Note that in some
situations, decreasing rather than increasing this parameter will situations, decreasing rather than increasing this parameter will
result in an increase in stability. result in an increase in stability.
The *update_edges* keyword can increase the number of atoms whose The *custom_charges* keyword can be used to specify which atoms'
atomic charges are updated, when the pre-reaction template contains atomic charges are updated. When the value is set to 'no,' all atomic
edge atoms. When the value is set to 'charges,' all atoms' atomic charges are updated to those specified by the post-reaction template
charges are updated to those specified by the post-reaction template, (default). Otherwise, the value should be the name of a molecule
including atoms near the edge of reaction templates. When the value is fragment defined in the pre-reaction molecule template. In this case,
set to 'custom,' an additional section must be included in the map only the atomic charges of atoms in the molecule fragment are updated.
file that specifies whether or not to update charges, on a per-atom
basis. The format of this section is detailed above. Listing a
pre-reaction atom ID with a value of 'charges' will force the update
of the atom's charge, even if it is near a template edge. Atoms not
near a template edge are unaffected by this setting.
A few other considerations: A few other considerations:
@ -584,7 +572,7 @@ Default
""""""" """""""
The option defaults are stabilization = no, prob = 1.0, stabilize_steps = 60, The option defaults are stabilization = no, prob = 1.0, stabilize_steps = 60,
reset_mol_ids = yes, update_edges = none reset_mol_ids = yes, custom_charges = no
---------- ----------

View File

@ -26,7 +26,6 @@ the ``delete`` operator. Here is a simple example:
.. code-block:: c++ .. code-block:: c++
#include "lammps.h" #include "lammps.h"
#include "universe.h"
#include <mpi.h> #include <mpi.h>
#include <iostream> #include <iostream>
@ -44,7 +43,7 @@ the ``delete`` operator. Here is a simple example:
// create LAMMPS instance // create LAMMPS instance
lmp = new LAMMPS_NS::LAMMPS(lmpargc, (char **)lmpargv, MPI_COMM_WORLD); lmp = new LAMMPS_NS::LAMMPS(lmpargc, (char **)lmpargv, MPI_COMM_WORLD);
// output numerical version string // output numerical version string
std::cout << "LAMMPS version: " << lmp->universe->num_ver << std::endl; std::cout << "LAMMPS version ID: " << lmp->num_ver << std::endl;
// delete LAMMPS instance // delete LAMMPS instance
delete lmp; delete lmp;
@ -53,8 +52,8 @@ the ``delete`` operator. Here is a simple example:
return 0; return 0;
} }
Please note that this requires to include the ``lammps.h`` header for accessing This minimal example only requires to include the ``lammps.h`` header
the members of the LAMMPS class and then the ``universe.h`` header for accessing the ``num_ver`` member of the :cpp:class:`Universe` class. file since it only accesses a non-pointer member of the LAMMPS class.
Executing LAMMPS commands Executing LAMMPS commands

View File

@ -10,7 +10,7 @@ strings into specific types of numbers with checking for validity. This
reduces redundant implementations and encourages consistent behavior. reduces redundant implementations and encourages consistent behavior.
I/O with status check I/O with status check
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
These are wrappers around the corresponding C library calls like These are wrappers around the corresponding C library calls like
``fgets()`` or ``fread()``. They will check if there were errors ``fgets()`` or ``fread()``. They will check if there were errors
@ -26,6 +26,8 @@ indicating the name of the problematic file, if possible.
.. doxygenfunction:: sfread .. doxygenfunction:: sfread
:project: progguide :project: progguide
----------
String to number conversions with validity check String to number conversions with validity check
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -42,8 +44,9 @@ is called only on a single MPI rank, as that will then trigger the
a call to ``Error::one()`` for errors instead of ``Error::all()`` a call to ``Error::one()`` for errors instead of ``Error::all()``
and avoids a "hanging" calculation when run in parallel. and avoids a "hanging" calculation when run in parallel.
Please also see :cpp:func:`is_integer` and :cpp:func:`is_double` for Please also see :cpp:func:`is_integer() <LAMMPS_NS::utils::is_integer>`
testing strings for compliance without conversion. and :cpp:func:`is_double() <LAMMPS_NS::utils::is_double>` for testing
strings for compliance without conversion.
---------- ----------
@ -169,6 +172,27 @@ Customized standard functions
--------------------------- ---------------------------
Communication buffer coding with *ubuf*
=========================================
LAMMPS uses communication buffers where it collects data from various
class instances and then exchanges the data with neighboring sub-domains.
For simplicity those buffers are defined as ``double`` buffers and
used for doubles and integer numbers. This presents a unique problem
when 64-bit integers are used. While the storage needed for a ``double``
is also 64-bit, it cannot be used by a simple assignment. To get around
that limitation, LAMMPS uses the :cpp:union:`ubuf <LAMMPS_NS::ubuf>`
union. It is used in the various "pack" and "unpack" functions in the
LAMMPS classes to store and retrieve integers that may be 64-bit from
the communication buffers.
---------------------------
.. doxygenunion:: LAMMPS_NS::ubuf
:project: progguide
---------------------------
Tokenizer classes Tokenizer classes
================= =================
@ -281,6 +305,8 @@ This code example should produce the following output:
:project: progguide :project: progguide
:members: what :members: what
----------
File reader classes File reader classes
==================== ====================
@ -333,6 +359,8 @@ convert numbers, so that LAMMPS will be aborted.
A file that would be parsed by the reader code fragment looks like this: A file that would be parsed by the reader code fragment looks like this:
.. parsed-literal::
# DATE: 2015-02-19 UNITS: metal CONTRIBUTOR: Ray Shan CITATION: Streitz and Mintmire, Phys Rev B, 50, 11996-12003 (1994) # DATE: 2015-02-19 UNITS: metal CONTRIBUTOR: Ray Shan CITATION: Streitz and Mintmire, Phys Rev B, 50, 11996-12003 (1994)
# #
# X (eV) J (eV) gamma (1/\AA) zeta (1/\AA) Z (e) # X (eV) J (eV) gamma (1/\AA) zeta (1/\AA) Z (e)
@ -351,7 +379,6 @@ A file that would be parsed by the reader code fragment looks like this:
:project: progguide :project: progguide
:members: :members:
---------- ----------
Memory pool classes Memory pool classes
@ -415,3 +442,43 @@ its size is registered later with :cpp:func:`vgot()
.. doxygenclass:: LAMMPS_NS::MyPoolChunk .. doxygenclass:: LAMMPS_NS::MyPoolChunk
:project: progguide :project: progguide
:members: :members:
----------
Eigensolver functions
=====================
The ``MathEigen`` sub-namespace of the ``LAMMPS_NS`` namespace contains
functions and classes for eigensolvers. Currently only the
:cpp:func:`jacobi3 function <MathEigen::jacobi3>` is used in various
places in LAMMPS. That function is built on top of a group of more
generic eigensolvers that are maintained in the ``math_eigen_impl.h``
header file. This header contains the implementation of three template
classes:
#. "Jacobi" calculates all of the eigenvalues and eigenvectors
of a dense, symmetric, real matrix.
#. The "PEigenDense" class only calculates the principal eigenvalue
(ie. the largest or smallest eigenvalue), and its corresponding
eigenvector. However it is much more efficient than "Jacobi" when
applied to large matrices (larger than 13x13). PEigenDense also can
understand complex-valued Hermitian matrices.
#. The "LambdaLanczos" class is a generalization of "PEigenDense" which can be
applied to arbitrary sparse matrices.
The "math_eigen_impl.h" code is an amalgamation of `jacobi_pd
<https://github.com/jewettaij/jacobi_pd>`_ by Andrew Jewett at Scripps
Research (under CC0-1.0 license) and `Lambda Lanczos
<https://github.com/mrcdr/lambda-lanczos>`_ by Yuya Kurebayashi at
Tohoku University (under MIT license)
----------
.. doxygenfunction:: MathEigen::jacobi3(double const *const *mat, double *eval, double **evec)
:project: progguide
.. doxygenfunction:: MathEigen::jacobi3(double const mat[3][3], double *eval, double evec[3][3])
:project: progguide

View File

@ -14,9 +14,20 @@ C-library interface, or the :py:class:`lammps.lammps` class constructor
of the Python module, or the :f:func:`lammps` constructor of the Fortran of the Python module, or the :f:func:`lammps` constructor of the Fortran
module. module.
In order to avoid clashes of function names, all of the core code in
LAMMPS is placed into the ``LAMMPS_NS`` namespace. Functions or variables
outside of that namespace must be "static", i.e. visible only to the
scope of the file/object they are defined in. Code in packages or the
libraries in the ``lib`` folder may not adhere to this as some of them
are adapted from legacy code or consist of external libraries with their
own requirements and policies.
-------------------- --------------------
.. doxygenclass:: LAMMPS_NS::LAMMPS .. doxygenclass:: LAMMPS_NS::LAMMPS
:project: progguide :project: progguide
:members: :members:
.. doxygenclass:: LAMMPS_NS::Pointers
:project: progguide

View File

@ -26,6 +26,8 @@ computes, fixes, or variables in LAMMPS.
----------------------- -----------------------
.. doxygenenum:: _LMP_DATATYPE_CONST
.. doxygenenum:: _LMP_STYLE_CONST .. doxygenenum:: _LMP_STYLE_CONST
.. doxygenenum:: _LMP_TYPE_CONST .. doxygenenum:: _LMP_TYPE_CONST

View File

@ -84,11 +84,22 @@ event as atoms are migrating between sub-domains.
----------------------- -----------------------
.. doxygenfunction:: lammps_extract_global_datatype
:project: progguide
-----------------------
.. doxygenfunction:: lammps_extract_global .. doxygenfunction:: lammps_extract_global
:project: progguide :project: progguide
----------------------- -----------------------
.. doxygenfunction:: lammps_extract_atom_datatype
:project: progguide
-----------------------
.. doxygenfunction:: lammps_extract_atom .. doxygenfunction:: lammps_extract_atom
:project: progguide :project: progguide

View File

@ -28,16 +28,58 @@ There are multiple Python interface classes in the :py:mod:`lammps` module:
---------- ----------
Setting up a Python virtual environment
***************************************
LAMMPS and its Python module can be installed together into a Python virtual
environment. This lets you isolate your customized Python environment from
your user or system installation. The following is a minimal working example:
.. code-block:: bash
# create and change into build directory
mkdir build
cd build
# create virtual environment
virtualenv myenv
# Add venv lib folder to LD_LIBRARY_PATH when activating it
echo 'export LD_LIBRARY_PATH=$VIRTUAL_ENV/lib:$LD_LIBRARY_PATH' >> myenv/bin/activate
# Add LAMMPS_POTENTIALS path when activating venv
echo 'export LAMMPS_POTENTIALS=$VIRTUAL_ENV/share/lammps/potentials' >> myenv/bin/activate
# activate environment
source myenv/bin/activate
# configure LAMMPS compilation
# compiles as shared library with PYTHON package and C++ exceptions
# and installs into myvenv
(myenv)$ cmake -C ../cmake/presets/minimal.cmake \
-D BUILD_SHARED_LIBS=on \
-D PKG_PYTHON=on \
-D LAMMPS_EXCEPTIONS=on \
-D CMAKE_INSTALL_PREFIX=$VIRTUAL_ENV \
../cmake
# compile LAMMPS
(myenv)$ cmake --build . --parallel
# install LAMMPS into myvenv
(myenv)$ cmake --install .
Creating or deleting a LAMMPS object Creating or deleting a LAMMPS object
************************************ ************************************
With the Python interface the creation of a :cpp:class:`LAMMPS With the Python interface the creation of a :cpp:class:`LAMMPS
<LAMMPS_NS::LAMMPS>` instance is included in the constructor for the <LAMMPS_NS::LAMMPS>` instance is included in the constructors for the
:py:func:`lammps <lammps.lammps>` class. Internally it will call either :py:meth:`lammps <lammps.lammps.__init__()>`, :py:meth:`PyLammps <lammps.PyLammps.__init__()>`,
:cpp:func:`lammps_open` or :cpp:func:`lammps_open_no_mpi` from the C and :py:meth:`PyLammps <lammps.IPyLammps.__init__()>` classes.
Internally it will call either :cpp:func:`lammps_open` or :cpp:func:`lammps_open_no_mpi` from the C
library API to create the class instance. library API to create the class instance.
All arguments are optional. The *name* argument is to allow loading a All arguments are optional. The *name* argument allows loading a
LAMMPS shared library that is named ``liblammps_machine.so`` instead of LAMMPS shared library that is named ``liblammps_machine.so`` instead of
the default name of ``liblammps.so``. In most cases the latter will be the default name of ``liblammps.so``. In most cases the latter will be
installed or used. The *ptr* argument is for use of the installed or used. The *ptr* argument is for use of the
@ -48,13 +90,20 @@ to the Python class and used instead of creating a new instance. The
*comm* argument may be used in combination with the `mpi4py <mpi4py_url_>`_ *comm* argument may be used in combination with the `mpi4py <mpi4py_url_>`_
module to pass an MPI communicator to LAMMPS and thus it is possible module to pass an MPI communicator to LAMMPS and thus it is possible
to run the Python module like the library interface on a subset of the to run the Python module like the library interface on a subset of the
MPI ranks after splitting the communicator. Here is a simple example: MPI ranks after splitting the communicator.
Here are simple examples using all three Python interfaces:
.. tabs::
.. tab:: lammps API
.. code-block:: python .. code-block:: python
from lammps import lammps from lammps import lammps
# NOTE: argv[0] is set by the Python module # NOTE: argv[0] is set by the lammps class constructor
args = ["-log", "none"] args = ["-log", "none"]
# create LAMMPS instance # create LAMMPS instance
lmp = lammps(cmdargs=args) lmp = lammps(cmdargs=args)
@ -63,7 +112,77 @@ MPI ranks after splitting the communicator. Here is a simple example:
# explicitly close and delete LAMMPS instance (optional) # explicitly close and delete LAMMPS instance (optional)
lmp.close() lmp.close()
Same as with the :ref:`C library API <lammps_c_api>` this will use the .. tab:: PyLammps API
The :py:class:`PyLammps` class is a wrapper around the
:py:class:`lammps` class and all of its lower level functions.
By default, it will create a new instance of :py:class:`lammps` passing
along all arguments to the constructor of :py:class:`lammps`.
.. code-block:: python
from lammps import PyLammps
# NOTE: argv[0] is set by the lammps class constructor
args = ["-log", "none"]
# create LAMMPS instance
L = PyLammps(cmdargs=args)
# get and print numerical version code
print("LAMMPS Version: ", L.version())
# explicitly close and delete LAMMPS instance (optional)
L.close()
:py:class:`PyLammps` objects can also be created on top of an existing :py:class:`lammps` object:
.. code-block:: Python
from lammps import lammps, PyLammps
...
# create LAMMPS instance
lmp = lammps(cmdargs=args)
# create PyLammps instance using previously created LAMMPS instance
L = PyLammps(ptr=lmp)
This is useful if you have to create the :py:class:`lammps <lammps.lammps>`
instance is a specific way, but want to take advantage of the
:py:class:`PyLammps <lammps.PyLammps>` interface.
.. tab:: IPyLammps API
The :py:class:`IPyLammps` class is an extension of the
:py:class:`PyLammps` class. It has the same construction behavior. By
default, it will create a new instance of :py:class:`lammps` passing
along all arguments to the constructor of :py:class:`lammps`.
.. code-block:: python
from lammps import IPyLammps
# NOTE: argv[0] is set by the lammps class constructor
args = ["-log", "none"]
# create LAMMPS instance
L = IPyLammps(cmdargs=args)
# get and print numerical version code
print("LAMMPS Version: ", L.version())
# explicitly close and delete LAMMPS instance (optional)
L.close()
You can also initialize IPyLammps on top of an existing :py:class:`lammps` or :py:class:`PyLammps` object:
.. code-block:: Python
from lammps import lammps, IPyLammps
...
# create LAMMPS instance
lmp = lammps(cmdargs=args)
# create PyLammps instance using previously created LAMMPS instance
L = PyLammps(ptr=lmp)
This is useful if you have to create the :py:class:`lammps <lammps.lammps>`
instance is a specific way, but want to take advantage of the
:py:class:`IPyLammps <lammps.IPyLammps>` interface.
In all of the above cases, same as with the :ref:`C library API <lammps_c_api>`, this will use the
``MPI_COMM_WORLD`` communicator for the MPI library that LAMMPS was ``MPI_COMM_WORLD`` communicator for the MPI library that LAMMPS was
compiled with. The :py:func:`lmp.close() <lammps.lammps.close>` call is compiled with. The :py:func:`lmp.close() <lammps.lammps.close>` call is
optional since the LAMMPS class instance will also be deleted optional since the LAMMPS class instance will also be deleted
@ -73,13 +192,19 @@ destructor.
Executing LAMMPS commands Executing LAMMPS commands
************************* *************************
Once an instance of the :py:class:`lammps <lammps.lammps>` class is Once an instance of the :py:class:`lammps`, :py:class:`PyLammps`, or
created, there are multiple ways to "feed" it commands. In a way that is :py:class:`IPyLammps` class is created, there are multiple ways to "feed" it
not very different from running a LAMMPS input script, except that commands. In a way that is not very different from running a LAMMPS input
Python has many more facilities for structured programming than the script, except that Python has many more facilities for structured
LAMMPS input script syntax. Furthermore it is possible to "compute" programming than the LAMMPS input script syntax. Furthermore it is possible
what the next LAMMPS command should be. Same as in the equivalent `C to "compute" what the next LAMMPS command should be.
library functions <pg_lib_execute>`, commands can be read from a file, a
.. tabs::
.. tab:: lammps API
Same as in the equivalent
:doc:`C library functions <pg_lib_execute>`, commands can be read from a file, a
single string, a list of strings and a block of commands in a single single string, a list of strings and a block of commands in a single
multi-line string. They are processed under the same boundary conditions multi-line string. They are processed under the same boundary conditions
as the C library counterparts. The example below demonstrates the use as the C library counterparts. The example below demonstrates the use
@ -89,7 +214,6 @@ of :py:func:`lammps.file`, :py:func:`lammps.command`,
.. code-block:: python .. code-block:: python
from lammps import lammps from lammps import lammps
lmp = lammps() lmp = lammps()
# read commands from file 'in.melt' # read commands from file 'in.melt'
lmp.file('in.melt') lmp.file('in.melt')
@ -107,6 +231,71 @@ of :py:func:`lammps.file`, :py:func:`lammps.command`,
""" """
lmp.commands_string(block) lmp.commands_string(block)
.. tab:: PyLammps/IPyLammps API
Unlike the lammps API, the PyLammps/IPyLammps APIs allow running LAMMPS
commands by calling equivalent member functions.
For instance, the following LAMMPS command
.. code-block:: LAMMPS
region box block 0 10 0 5 -0.5 0.5
can be executed using the following Python code if *L* is a :py:class:`lammps` instance:
.. code-block:: Python
L.command("region box block 0 10 0 5 -0.5 0.5")
With the PyLammps interface, any LAMMPS command can be split up into arbitrary parts.
These parts are then passed to a member function with the name of the command.
For the ``region`` command that means the :code:`region` method can be called.
The arguments of the command can be passed as one string, or
individually.
.. code-block:: Python
L.region("box block", 0, 10, 0, 5, -0.5, 0.5)
In this example all parameters except the first are Python floating-point literals. The
PyLammps interface takes the entire parameter list and transparently
merges it to a single command string.
The benefit of this approach is avoiding redundant command calls and easier
parameterization. In the original interface parameterization this needed to be done
manually by creating formatted strings.
.. code-block:: Python
L.command("region box block %f %f %f %f %f %f" % (xlo, xhi, ylo, yhi, zlo, zhi))
In contrast, methods of PyLammps accept parameters directly and will convert
them automatically to a final command string.
.. code-block:: Python
L.region("box block", xlo, xhi, ylo, yhi, zlo, zhi)
Using these facilities, the example shown for the lammps API can be rewritten as follows:
.. code-block:: python
from lammps import PyLammps
L = PyLammps()
# read commands from file 'in.melt'
L.file('in.melt')
# issue a single command
L.variable('zpos', 'index', 1.0)
# create 10 groups with 10 atoms each
for i in range(10):
L.group(f"g{i}", "id", f"{10*i+1}:{10*(i+1)}")
L.clear()
L.region("box block", 0, 2, 0, 2, 0, 2)
L.create_box(1, "box")
L.create_atoms(1, "single", 1.0, 1.0, "${zpos}")
---------- ----------
The ``lammps`` class API The ``lammps`` class API
@ -130,14 +319,34 @@ functions. Below is a detailed documentation of the API.
The ``PyLammps`` class API The ``PyLammps`` class API
************************** **************************
The :py:class:`PyLammps <lammps.PyLammps>` class is a wrapper that creates a
simpler, more "Pythonic" interface to common LAMMPS functionality. LAMMPS
data structures are exposed through objects and properties. This makes Python
scripts shorter and more concise. See the :doc:`PyLammps Tutorial
<Howto_pylammps>` for an introduction on how to use this interface.
.. autoclass:: lammps.PyLammps .. autoclass:: lammps.PyLammps
:members: :members:
.. autoclass:: lammps.AtomList
:members:
.. autoclass:: lammps.Atom
:members:
.. autoclass:: lammps.Atom2D
:members:
---------- ----------
The ``IPyLammps`` class API The ``IPyLammps`` class API
*************************** ***************************
The :py:class:`IPyLammps <lammps.PyLammps>` class is an extension of
:py:class:`PyLammps <lammps.PyLammps>`, adding additional functions to
quickly display visualizations such as images and videos inside of IPython.
See the :doc:`PyLammps Tutorial <Howto_pylammps>` for examples.
.. autoclass:: lammps.IPyLammps .. autoclass:: lammps.IPyLammps
:members: :members:
@ -150,14 +359,24 @@ The :py:mod:`lammps` module additionally contains several constants
and the :py:class:`NeighList <lammps.NeighList>` class: and the :py:class:`NeighList <lammps.NeighList>` class:
.. _py_data_constants: .. _py_data_constants:
.. py:data:: LAMMPS_INT, LAMMPS_DOUBLE, LAMMPS_BIGINT, LAMMPS_TAGINT, LAMMPS_STRING
Data Types
----------
.. py:data:: LAMMPS_INT, LAMMPS_INT_2D, LAMMPS_DOUBLE, LAMMPS_DOUBLE_2D, LAMMPS_INT64, LAMMPS_INT64_2D, LAMMPS_STRING
:type: int :type: int
Constants in the :py:mod:`lammps` module to indicate how to Constants in the :py:mod:`lammps` module to indicate how to
cast data when the C library function returns a void pointer. cast data when the C library function returns a void pointer.
Used in :py:func:`lammps.extract_global`. Used in :py:func:`lammps.extract_global` and :py:func:`lammps.extract_atom`.
See :cpp:enum:`_LMP_DATATYPE_CONST` for the equivalent constants in the
C library interface.
.. _py_style_constants: .. _py_style_constants:
Style Constants
---------------
.. py:data:: LMP_STYLE_GLOBAL, LMP_STYLE_ATOM, LMP_STYLE_LOCAL .. py:data:: LMP_STYLE_GLOBAL, LMP_STYLE_ATOM, LMP_STYLE_LOCAL
:type: int :type: int
@ -167,6 +386,10 @@ and the :py:class:`NeighList <lammps.NeighList>` class:
:py:func:`lammps.extract_compute` and :py:func:`lammps.extract_fix`. :py:func:`lammps.extract_compute` and :py:func:`lammps.extract_fix`.
.. _py_type_constants: .. _py_type_constants:
Type Constants
--------------
.. py:data:: LMP_TYPE_SCALAR, LMP_TYLE_VECTOR, LMP_TYPE_ARRAY, LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS .. py:data:: LMP_TYPE_SCALAR, LMP_TYLE_VECTOR, LMP_TYPE_ARRAY, LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS
:type: int :type: int
@ -176,13 +399,36 @@ and the :py:class:`NeighList <lammps.NeighList>` class:
:py:func:`lammps.extract_compute` and :py:func:`lammps.extract_fix`. :py:func:`lammps.extract_compute` and :py:func:`lammps.extract_fix`.
.. _py_var_constants: .. _py_var_constants:
Variable Style Constants
------------------------
.. py:data:: LMP_VAR_EQUAL, LMP_VAR_ATOM .. py:data:: LMP_VAR_EQUAL, LMP_VAR_ATOM
:type: int :type: int
Constants in the :py:mod:`lammps` module to select what style of Constants in the :py:mod:`lammps` module to select what style of
variable to query when calling :py:func:`lammps.extract_variable`. variable to query when calling :py:func:`lammps.extract_variable`.
Classes representing internal objects
-------------------------------------
.. autoclass:: lammps.NeighList .. autoclass:: lammps.NeighList
:members: :members:
:no-undoc-members: :no-undoc-members:
LAMMPS error handling in Python
*******************************
Compiling the shared library with :ref:`C++ exception support <exceptions>` provides a better error
handling experience. Without exceptions the LAMMPS code will terminate the
current Python process with an error message. C++ exceptions allow capturing
them on the C++ side and rethrowing them on the Python side. This way
LAMMPS errors can be handled through the Python exception handling mechanism.
.. warning::
Capturing a LAMMPS exception in Python can still mean that the
current LAMMPS process is in an illegal state and must be terminated. It is
advised to save your data and terminate the Python instance as quickly as
possible.

View File

@ -18,3 +18,41 @@
.versionmodified { .versionmodified {
font-weight: bold; font-weight: bold;
} }
hr {
margin: 12px 0;
}
.rst-content {
margin-bottom: 12px !important;
}
#user-documentation.section h2 {
display: none;
}
#programmer-documentation.section h2 {
display: none;
}
.ui.tabular.menu .item {
padding-right: 1em;
padding-left: 1em;
padding-top: 0.1em;
padding-bottom: 0.1em;
border-radius: 6px;
}
.btn {
padding: 4px;
font-size: 80%;
border-radius: 4px;
}
.rst-breadcrumbs-buttons {
margin: 0;
}
p {
margin-bottom: 12px;
}

View File

@ -1,9 +0,0 @@
.lammps_version {
text-align: center;
display: block;
margin-bottom: 0.809em;
}
.versionmodified {
font-weight: bold;
}

View File

@ -13,6 +13,6 @@ includehidden = True
titles_only = titles_only =
logo_only = logo_only =
display_version = True display_version = True
prev_next_buttons_location = bottom prev_next_buttons_location = both
style_external_links = False style_external_links = True
style_nav_header_background = style_nav_header_background =

View File

@ -110,7 +110,9 @@ api
Apoorva Apoorva
Appl Appl
Apu Apu
arallel
arccos arccos
arge
Archlinux Archlinux
arcsin arcsin
arg arg
@ -128,6 +130,7 @@ aspherical
asphericity asphericity
Asq Asq
assignee assignee
assively
Asta Asta
Astart Astart
Astop Astop
@ -325,6 +328,7 @@ Buyl
Bybee Bybee
bz bz
cadetblue cadetblue
calc
calibre calibre
caltech caltech
Caltech Caltech
@ -397,6 +401,7 @@ ChiralIDs
chiralIDs chiralIDs
chirality chirality
Cho Cho
ChooseOffset
chris chris
Christoph Christoph
Chu Chu
@ -469,6 +474,7 @@ config
configfile configfile
configurational configurational
conformational conformational
ConstMatrix
Contrib Contrib
cooperativity cooperativity
coord coord
@ -639,7 +645,10 @@ dhex
dia dia
diag diag
diagonalization diagonalization
diagonalize
diagonalized diagonalized
diagonalizers
diagonalizing
Diallo Diallo
diel diel
differentiable differentiable
@ -778,8 +787,15 @@ Eggebrecht
ehex ehex
eHEX eHEX
Ei Ei
Eigen eigen
Eigensolve eigensolve
eigensolver
eigensolvers
eigendecomposition
eigenvalue
eigenvalues
eigenvector
eigenvectors
eij eij
Eij Eij
Eijnden Eijnden
@ -893,6 +909,11 @@ eV
evalue evalue
Evanseck Evanseck
evdwl evdwl
evector
evec
evecs
eval
evals
Everaers Everaers
Evgeny Evgeny
evirials evirials
@ -1069,6 +1090,7 @@ Germann
Germano Germano
gerolf gerolf
Gerolf Gerolf
Gershgorin
gettimeofday gettimeofday
gewald gewald
Gezelter Gezelter
@ -1184,6 +1206,7 @@ Henkelman
Henkes Henkes
henrich henrich
Henrich Henrich
Hermitian
Herrmann Herrmann
Hertizian Hertizian
hertzian hertzian
@ -1257,6 +1280,7 @@ icosahedral
idealgas idealgas
IDR IDR
idx idx
ie
ielement ielement
ieni ieni
ifdefs ifdefs
@ -1279,8 +1303,10 @@ Imageint
Imagemagick Imagemagick
imd imd
Impey Impey
impl
impropers impropers
Impropers Impropers
imulator
includelink includelink
incompressible incompressible
incrementing incrementing
@ -1348,6 +1374,8 @@ isothermal
isotropically isotropically
isovolume isovolume
Isralewitz Isralewitz
iter
iters
iteratively iteratively
Ith Ith
Itsets Itsets
@ -1525,6 +1553,7 @@ Kub
Kubo Kubo
Kumagai Kumagai
Kumar Kumar
Kurebayashi
Kuronen Kuronen
Kusters Kusters
Kutta Kutta
@ -1535,12 +1564,14 @@ Ladd
lagrangian lagrangian
lambdai lambdai
lamda lamda
LambdaLanczos
lammps lammps
Lammps Lammps
LAMMPS LAMMPS
lammpsplot lammpsplot
Lampis Lampis
Lamoureux Lamoureux
Lanczos
Lande Lande
Landron Landron
langevin langevin
@ -1848,6 +1879,7 @@ Microscale
midnightblue midnightblue
mie mie
Mie Mie
Mij
Mikami Mikami
Militzer Militzer
Minary Minary
@ -1946,6 +1978,7 @@ Muccioli
mui mui
Mukherjee Mukherjee
Mulders Mulders
mult
multi multi
multibody multibody
Multibody Multibody
@ -1990,6 +2023,7 @@ Nakano
nall nall
namespace namespace
namespaces namespaces
namedtuple
nan nan
NaN NaN
Nandor Nandor
@ -2226,6 +2260,7 @@ Okamoto
O'Keefe O'Keefe
OKeefe OKeefe
oldlace oldlace
olecular
Oleinik Oleinik
Olfason Olfason
olivedrab olivedrab
@ -2332,6 +2367,7 @@ peachpuff
Pearlman Pearlman
Pedersen Pedersen
peID peID
PEigenDense
Peng Peng
peptide peptide
peratom peratom
@ -2560,6 +2596,8 @@ rdf
RDideal RDideal
rdx rdx
reacter reacter
realTypeMap
real_t
README README
realtime realtime
reamin reamin
@ -2744,6 +2782,7 @@ Schuring
Schwen Schwen
screenshot screenshot
screenshots screenshots
Scripps
Scripta Scripta
sdk sdk
sdpd sdpd
@ -3072,10 +3111,12 @@ Tmin
tmp tmp
tN tN
Tobias Tobias
Tohoku
tokenizer tokenizer
tokyo tokyo
tol tol
Toennies Toennies
tomic
toolchain toolchain
topologies topologies
Toporov Toporov
@ -3136,6 +3177,8 @@ tu
Tuckerman Tuckerman
tue tue
tunable tunable
tuple
tuples
Turkand Turkand
Tutein Tutein
tweakable tweakable
@ -3430,6 +3473,7 @@ Yuh
yukawa yukawa
Yukawa Yukawa
Yusof Yusof
Yuya
yx yx
yy yy
yz yz

View File

@ -2,3 +2,7 @@
*.d *.d
*.a *.a
*~ *~
liblammps.mod
simpleC
simpleCC
simpleF

View File

@ -8,14 +8,12 @@ code to perform a coupled calculation.
simple.cpp is the C++ driver simple.cpp is the C++ driver
simple.c is the C driver simple.c is the C driver
simple.f90 is the Fortran driver simple.f90 is the Fortran driver
libfwrapper.c is the Fortran-to-C wrapper
The 3 codes do the same thing, so you can compare them to see how to The 3 codes do the same thing, so you can compare them to see how to
drive LAMMPS from each language. See lammps/python/example/simple.py drive LAMMPS from each language. See python/example/simple.py
to do something similar from Python. The Fortran driver requires an to do something similar from Python. The Fortran driver requires a
additional wrapper library that interfaces the C interface of the Fortran module that uses the Fortran 03 ISO_C_BINDING module to
LAMMPS library to Fortran and also translates the MPI communicator interface the LAMMPS C library functions to Fortran.
from Fortran to C.
First build LAMMPS as a library (see examples/COUPLE/README), e.g. First build LAMMPS as a library (see examples/COUPLE/README), e.g.
@ -26,27 +24,23 @@ these, which include paths to the LAMMPS library interface, and
linking with FFTW (only needed if you built LAMMPS as a library with linking with FFTW (only needed if you built LAMMPS as a library with
its PPPM solver). its PPPM solver).
This builds the C++ driver with the LAMMPS library using the mpiCC This builds the C++ driver with the LAMMPS library using the mpicxx
(C++) compiler: (C++) compiler:
mpiCC -I/home/sjplimp/lammps/src -c simple.cpp mpicxx -I/home/sjplimp/lammps/src -c simple.cpp
mpiCC -L/home/sjplimp/lammps/src simple.o -llammps -lfftw -o simpleCC mpicxx -L/home/sjplimp/lammps/src simple.o -llammps -o simpleCC
This builds the C driver with the LAMMPS library using the mpicc (C) This builds the C driver with the LAMMPS library using the mpicc (C)
compiler: compiler:
mpicc -I/home/sjplimp/lammps/src -c simple.c mpicc -I/home/sjplimp/lammps/src -c simple.c
mpicc -L/home/sjplimp/lammps/src simple.o -llammps -lfftw -o simpleC mpicc -L/home/sjplimp/lammps/src simple.o -llammps -o simpleC
This builds the Fortran wrapper and driver with the LAMMPS library This builds the Fortran module and driver with the LAMMPS library
using the mpicc (C) and mpifort (Fortran) compilers, using the wrapper using the mpifort (Fortran) compilers, using the Fortran module from
in the fortran directory: the fortran directory:
cp ../fortran/libfwrapper.c . mpifort -L/home/sjplimp/lammps/src ../../../fortran/lammps.f90 simple.f90 -llammps -o simpleF
mpicc -I/home/sjplimp/lammps/src -c libfwrapper.c
mpifort -c simple.f90
mpifort -L/home/sjplimp/lammps/src simple.o libfwrapper.o \
-llammps -lfftw -o simpleF
You then run simpleCC, simpleC, or simpleF on a parallel machine You then run simpleCC, simpleC, or simpleF on a parallel machine
on some number of processors Q with 2 arguments: on some number of processors Q with 2 arguments:
@ -69,10 +63,9 @@ The C driver is calling C-style routines in the src/library.cpp file
of LAMMPS. You could add any functions you wish to this file to of LAMMPS. You could add any functions you wish to this file to
manipulate LAMMPS data however you wish. manipulate LAMMPS data however you wish.
The Fortran driver is using the same C-style routines, but requires an The Fortran driver is using the Fortran 03 module which uses a derived
additional wrapper to make them Fortran callable. Only a subset of the type with type bound subroutines. Only a small subset of the C library
library functions are currently wrapped, but it should be clear how to functions are currently accessible through the Fortran module.
extend the wrapper if desired.
The C++ driver does the same thing, except that it instantiates LAMMPS The C++ driver does the same thing, except that it instantiates LAMMPS
as an object first. Some of the functions in src/library.cpp can be as an object first. Some of the functions in src/library.cpp can be

View File

@ -19,11 +19,11 @@
in.lammps = LAMMPS input script in.lammps = LAMMPS input script
See README for compilation instructions */ See README for compilation instructions */
#include "stdio.h" #include <stdio.h>
#include "stdlib.h" #include <stdlib.h>
#include "string.h" #include <string.h>
#include "mpi.h" #include <mpi.h>
#include "lammps/library.h" /* this is a LAMMPS include file */ #include "library.h" /* this is a LAMMPS include file */
int main(int narg, char **arg) int main(int narg, char **arg)
{ {
@ -72,7 +72,7 @@ int main(int narg, char **arg)
all LAMMPS procs call lammps_command() on the line */ all LAMMPS procs call lammps_command() on the line */
void *lmp = NULL; void *lmp = NULL;
if (lammps == 1) lammps_open(0,NULL,comm_lammps,&lmp); if (lammps == 1) lmp = lammps_open(0,NULL,comm_lammps,NULL);
int n; int n;
char line[1024]; char line[1024];
@ -124,10 +124,10 @@ int main(int narg, char **arg)
/* use commands_string() and commands_list() to invoke more commands */ /* use commands_string() and commands_list() to invoke more commands */
char *strtwo = "run 10\nrun 20"; const char *strtwo = "run 10\nrun 20";
if (lammps == 1) lammps_commands_string(lmp,strtwo); if (lammps == 1) lammps_commands_string(lmp,strtwo);
char *cmds[2]; const char *cmds[2];
cmds[0] = "run 10"; cmds[0] = "run 10";
cmds[1] = "run 20"; cmds[1] = "run 20";
if (lammps == 1) lammps_commands_list(lmp,2,cmds); if (lammps == 1) lammps_commands_list(lmp,2,cmds);

View File

@ -25,10 +25,10 @@
#include <mpi.h> #include <mpi.h>
// these are LAMMPS include files // these are LAMMPS include files
#include <lammps/lammps.h> #include "lammps.h"
#include <lammps/input.h> #include "input.h"
#include <lammps/atom.h> #include "atom.h"
#include <lammps/library.h> #include "library.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -135,10 +135,10 @@ int main(int narg, char **arg)
// use commands_string() and commands_list() to invoke more commands // use commands_string() and commands_list() to invoke more commands
char *strtwo = (char *) "run 10\nrun 20"; const char *strtwo = (char *) "run 10\nrun 20";
if (lammps == 1) lammps_commands_string(lmp,strtwo); if (lammps == 1) lammps_commands_string(lmp,strtwo);
char *cmds[2]; const char *cmds[2];
cmds[0] = (char *) "run 10"; cmds[0] = (char *) "run 10";
cmds[1] = (char *) "run 20"; cmds[1] = (char *) "run 20";
if (lammps == 1) lammps_commands_list(lmp,2,cmds); if (lammps == 1) lammps_commands_list(lmp,2,cmds);

View File

@ -18,13 +18,14 @@
! See README for compilation instructions ! See README for compilation instructions
PROGRAM f_driver PROGRAM f_driver
USE mpi
USE liblammps
IMPLICIT NONE IMPLICIT NONE
INCLUDE 'mpif.h'
INTEGER, PARAMETER :: fp=20 INTEGER, PARAMETER :: fp=20
INTEGER :: n, narg, ierr, me, nprocs, natoms INTEGER :: n, narg, ierr, me, nprocs, natoms
INTEGER :: lammps, nprocs_lammps, comm_lammps INTEGER :: color, nprocs_lammps, comm_lammps
INTEGER (kind=8) :: ptr TYPE(LAMMPS) :: lmp
REAL (kind=8), ALLOCATABLE :: x(:) REAL (kind=8), ALLOCATABLE :: x(:)
REAL (kind=8), PARAMETER :: epsilon=0.1 REAL (kind=8), PARAMETER :: epsilon=0.1
@ -58,14 +59,14 @@ PROGRAM f_driver
END IF END IF
END IF END IF
lammps = 0 color = 0
IF (me < nprocs_lammps) THEN IF (me < nprocs_lammps) THEN
lammps = 1 color = 1
ELSE ELSE
lammps = MPI_UNDEFINED color = MPI_UNDEFINED
END IF END IF
CALL mpi_comm_split(MPI_COMM_WORLD,lammps,0,comm_lammps,ierr) CALL mpi_comm_split(MPI_COMM_WORLD,color,0,comm_lammps,ierr)
! open LAMMPS input script on rank zero ! open LAMMPS input script on rank zero
@ -81,7 +82,7 @@ PROGRAM f_driver
! (could just send it to proc 0 of comm_lammps and let it Bcast) ! (could just send it to proc 0 of comm_lammps and let it Bcast)
! all LAMMPS procs call lammps_command() on the line */ ! all LAMMPS procs call lammps_command() on the line */
IF (lammps == 1) CALL lammps_open(comm_lammps,ptr) IF (color == 1) lmp=lammps(comm=comm_lammps)
n = 0 n = 0
DO DO
@ -99,7 +100,7 @@ PROGRAM f_driver
CALL mpi_bcast(n,1,MPI_INTEGER,0,MPI_COMM_WORLD,ierr) CALL mpi_bcast(n,1,MPI_INTEGER,0,MPI_COMM_WORLD,ierr)
IF (n == 0) EXIT IF (n == 0) EXIT
CALL mpi_bcast(line,n,MPI_CHARACTER,0,MPI_COMM_WORLD,ierr) CALL mpi_bcast(line,n,MPI_CHARACTER,0,MPI_COMM_WORLD,ierr)
IF (lammps == 1) CALL lammps_command(ptr,line,n) IF (color == 1) CALL lmp%command(line(1:n))
END DO END DO
CLOSE(UNIT=fp) CLOSE(UNIT=fp)
@ -109,27 +110,27 @@ PROGRAM f_driver
! put coords back into LAMMPS ! put coords back into LAMMPS
! run a single step with changed coords */ ! run a single step with changed coords */
IF (lammps == 1) THEN IF (color == 1) THEN
CALL lammps_command(ptr,'run 10',6) CALL lmp%command('run 10')
CALL lammps_get_natoms(ptr,natoms) natoms = NINT(lmp%get_natoms())
ALLOCATE(x(3*natoms)) ALLOCATE(x(3*natoms))
! these calls are commented out, b/c libfwrapper.c ! these calls are commented out, b/c libfwrapper.c
! needs to be updated to use gather_atoms and scatter_atoms ! needs to be updated to use gather_atoms and scatter_atoms
!CALL lammps_gather_atoms(ptr,'x',1,3,x); !CALL lammps_gather_atoms(ptr,'x',1,3,x)
!x(1) = x(1) + epsilon !x(1) = x(1) + epsilon
!CALL lammps_scatter_atoms(ptr,'x',1,3,x); !CALL lammps_scatter_atoms(ptr,'x',1,3,x)
DEALLOCATE(x) DEALLOCATE(x)
CALL lammps_command(ptr,'run 1',5); CALL lmp%command('run 1')
END IF END IF
! free LAMMPS object ! free LAMMPS object
IF (lammps == 1) CALL lammps_close(ptr); IF (color == 1) CALL lmp%close()
! close down MPI ! close down MPI

View File

@ -1,7 +1,7 @@
configuration { configuration {
step 200 step 200
dt 2.000000e+00 dt 2.000000e+00
version 2018-11-16 version 2020-07-07
} }
colvar { colvar {

View File

@ -1,7 +1,7 @@
configuration { configuration {
step 100 step 100
dt 2.000000e+00 dt 2.000000e+00
version 2018-11-16 version 2020-07-07
} }
colvar { colvar {

View File

@ -1,7 +1,7 @@
configuration { configuration {
step 300 step 300
dt 2.000000e+00 dt 2.000000e+00
version 2018-11-16 version 2020-07-07
} }
colvar { colvar {

View File

@ -1,7 +1,7 @@
configuration { configuration {
step 100 step 100
dt 2.000000e+00 dt 2.000000e+00
version 2018-11-16 version 2020-07-07
} }
colvar { colvar {

View File

@ -23,12 +23,12 @@ from lammps import lammps
def end_of_step_callback(lmp): def end_of_step_callback(lmp):
L = lammps(ptr=lmp) L = lammps(ptr=lmp)
t = L.extract_global("ntimestep", 0) t = L.extract_global("ntimestep")
print("### END OF STEP ###", t) print("### END OF STEP ###", t)
def post_force_callback(lmp, v): def post_force_callback(lmp, v):
L = lammps(ptr=lmp) L = lammps(ptr=lmp)
t = L.extract_global("ntimestep", 0) t = L.extract_global("ntimestep")
print("### POST_FORCE ###", t) print("### POST_FORCE ###", t)
""" """

View File

@ -35,14 +35,13 @@ def post_force_callback(lmp, v):
#mylist = L.get_neighlist(0) #mylist = L.get_neighlist(0)
mylist = L.find_pair_neighlist("lj/cut", request=0) mylist = L.find_pair_neighlist("lj/cut", request=0)
print(pid_prefix, mylist) print(pid_prefix, mylist)
nlocal = L.extract_global("nlocal", 0) nlocal = L.extract_global("nlocal")
nghost = L.extract_global("nghost", 0) nghost = L.extract_global("nghost")
ntypes = L.extract_global("ntypes", 0) mass = L.numpy.extract_atom("mass")
mass = L.numpy.extract_atom_darray("mass", ntypes+1) atype = L.numpy.extract_atom("type", nelem=nlocal+nghost)
atype = L.numpy.extract_atom_iarray("type", nlocal+nghost) x = L.numpy.extract_atom("x", nelem=nlocal+nghost, dim=3)
x = L.numpy.extract_atom_darray("x", nlocal+nghost, dim=3) v = L.numpy.extract_atom("v", nelem=nlocal+nghost, dim=3)
v = L.numpy.extract_atom_darray("v", nlocal+nghost, dim=3) f = L.numpy.extract_atom("f", nelem=nlocal+nghost, dim=3)
f = L.numpy.extract_atom_darray("f", nlocal+nghost, dim=3)
for iatom, numneigh, neighs in mylist: for iatom, numneigh, neighs in mylist:
print(pid_prefix, "- {}".format(iatom), x[iatom], v[iatom], f[iatom], " : ", numneigh, "Neighbors") print(pid_prefix, "- {}".format(iatom), x[iatom], v[iatom], f[iatom], " : ", numneigh, "Neighbors")

View File

@ -1,12 +1,12 @@
from __future__ import print_function from __future__ import print_function
import lammps from lammps import lammps, LAMMPS_INT, LAMMPS_DOUBLE
import ctypes import ctypes
import traceback import traceback
import numpy as np import numpy as np
class LAMMPSFix(object): class LAMMPSFix(object):
def __init__(self, ptr, group_name="all"): def __init__(self, ptr, group_name="all"):
self.lmp = lammps.lammps(ptr=ptr) self.lmp = lammps(ptr=ptr)
self.group_name = group_name self.group_name = group_name
class LAMMPSFixMove(LAMMPSFix): class LAMMPSFixMove(LAMMPSFix):
@ -39,19 +39,18 @@ class NVE(LAMMPSFixMove):
assert(self.group_name == "all") assert(self.group_name == "all")
def init(self): def init(self):
dt = self.lmp.extract_global("dt", 1) dt = self.lmp.extract_global("dt")
ftm2v = self.lmp.extract_global("ftm2v", 1) ftm2v = self.lmp.extract_global("ftm2v")
self.ntypes = self.lmp.extract_global("ntypes", 0) self.ntypes = self.lmp.extract_global("ntypes")
self.dtv = dt self.dtv = dt
self.dtf = 0.5 * dt * ftm2v self.dtf = 0.5 * dt * ftm2v
def initial_integrate(self, vflag): def initial_integrate(self, vflag):
nlocal = self.lmp.extract_global("nlocal", 0) mass = self.lmp.numpy.extract_atom("mass")
mass = self.lmp.numpy.extract_atom_darray("mass", self.ntypes+1) atype = self.lmp.numpy.extract_atom("type")
atype = self.lmp.numpy.extract_atom_iarray("type", nlocal) x = self.lmp.numpy.extract_atom("x")
x = self.lmp.numpy.extract_atom_darray("x", nlocal, dim=3) v = self.lmp.numpy.extract_atom("v")
v = self.lmp.numpy.extract_atom_darray("v", nlocal, dim=3) f = self.lmp.numpy.extract_atom("f")
f = self.lmp.numpy.extract_atom_darray("f", nlocal, dim=3)
for i in range(x.shape[0]): for i in range(x.shape[0]):
dtfm = self.dtf / mass[int(atype[i])] dtfm = self.dtf / mass[int(atype[i])]
@ -59,11 +58,10 @@ class NVE(LAMMPSFixMove):
x[i,:] += self.dtv * v[i,:] x[i,:] += self.dtv * v[i,:]
def final_integrate(self): def final_integrate(self):
nlocal = self.lmp.extract_global("nlocal", 0) mass = self.lmp.numpy.extract_atom("mass")
mass = self.lmp.numpy.extract_atom_darray("mass", self.ntypes+1) atype = self.lmp.numpy.extract_atom("type")
atype = self.lmp.numpy.extract_atom_iarray("type", nlocal) v = self.lmp.numpy.extract_atom("v")
v = self.lmp.numpy.extract_atom_darray("v", nlocal, dim=3) f = self.lmp.numpy.extract_atom("f")
f = self.lmp.numpy.extract_atom_darray("f", nlocal, dim=3)
for i in range(v.shape[0]): for i in range(v.shape[0]):
dtfm = self.dtf / mass[int(atype[i])] dtfm = self.dtf / mass[int(atype[i])]
@ -77,19 +75,19 @@ class NVE_Opt(LAMMPSFixMove):
assert(self.group_name == "all") assert(self.group_name == "all")
def init(self): def init(self):
dt = self.lmp.extract_global("dt", 1) dt = self.lmp.extract_global("dt")
ftm2v = self.lmp.extract_global("ftm2v", 1) ftm2v = self.lmp.extract_global("ftm2v")
self.ntypes = self.lmp.extract_global("ntypes", 0) self.ntypes = self.lmp.extract_global("ntypes")
self.dtv = dt self.dtv = dt
self.dtf = 0.5 * dt * ftm2v self.dtf = 0.5 * dt * ftm2v
self.mass = self.lmp.numpy.extract_atom_darray("mass", self.ntypes+1) self.mass = self.lmp.numpy.extract_atom("mass")
def initial_integrate(self, vflag): def initial_integrate(self, vflag):
nlocal = self.lmp.extract_global("nlocal", 0) nlocal = self.lmp.extract_global("nlocal")
atype = self.lmp.numpy.extract_atom_iarray("type", nlocal) atype = self.lmp.numpy.extract_atom("type")
x = self.lmp.numpy.extract_atom_darray("x", nlocal, dim=3) x = self.lmp.numpy.extract_atom("x")
v = self.lmp.numpy.extract_atom_darray("v", nlocal, dim=3) v = self.lmp.numpy.extract_atom("v")
f = self.lmp.numpy.extract_atom_darray("f", nlocal, dim=3) f = self.lmp.numpy.extract_atom("f")
dtf = self.dtf dtf = self.dtf
dtv = self.dtv dtv = self.dtv
mass = self.mass mass = self.mass
@ -102,13 +100,12 @@ class NVE_Opt(LAMMPSFixMove):
x[:,d] += dtv * v[:,d] x[:,d] += dtv * v[:,d]
def final_integrate(self): def final_integrate(self):
nlocal = self.lmp.extract_global("nlocal", 0) nlocal = self.lmp.extract_global("nlocal")
mass = self.lmp.numpy.extract_atom_darray("mass", self.ntypes+1) mass = self.lmp.numpy.extract_atom("mass")
atype = self.lmp.numpy.extract_atom_iarray("type", nlocal) atype = self.lmp.numpy.extract_atom("type")
v = self.lmp.numpy.extract_atom_darray("v", nlocal, dim=3) v = self.lmp.numpy.extract_atom("v")
f = self.lmp.numpy.extract_atom_darray("f", nlocal, dim=3) f = self.lmp.numpy.extract_atom("f")
dtf = self.dtf dtf = self.dtf
dtv = self.dtv
mass = self.mass mass = self.mass
dtfm = dtf / np.take(mass, atype) dtfm = dtf / np.take(mass, atype)

View File

@ -15,7 +15,7 @@ else
COLVARS_DEBUG_INCFLAGS = -DCOLVARS_DEBUG COLVARS_DEBUG_INCFLAGS = -DCOLVARS_DEBUG
endif endif
COLVARS_INCFLAGS = $(COLVARS_DEBUG_INCFLAGS) $(COLVARS_PYTHON_INCFLAGS) COLVARS_INCFLAGS = -DCOLVARS_LAMMPS $(COLVARS_DEBUG_INCFLAGS) $(COLVARS_PYTHON_INCFLAGS) -I../../src
.SUFFIXES: .SUFFIXES:
@ -38,6 +38,7 @@ COLVARS_SRCS = \
colvarcomp_gpath.cpp \ colvarcomp_gpath.cpp \
colvarcomp_protein.cpp \ colvarcomp_protein.cpp \
colvarcomp_rotations.cpp \ colvarcomp_rotations.cpp \
colvarcomp_volmaps.cpp \
colvar.cpp \ colvar.cpp \
colvardeps.cpp \ colvardeps.cpp \
colvargrid.cpp \ colvargrid.cpp \
@ -46,7 +47,12 @@ COLVARS_SRCS = \
colvarparse.cpp \ colvarparse.cpp \
colvarproxy.cpp \ colvarproxy.cpp \
colvarproxy_replicas.cpp \ colvarproxy_replicas.cpp \
colvarproxy_tcl.cpp \
colvarproxy_volmaps.cpp \
colvarscript.cpp \ colvarscript.cpp \
colvarscript_commands.cpp \
colvarscript_commands_bias.cpp \
colvarscript_commands_colvar.cpp \
colvartypes.cpp \ colvartypes.cpp \
colvarvalue.cpp colvarvalue.cpp
@ -61,7 +67,7 @@ ifeq ($(COLVARS_LEPTON),no)
LEPTON_INCFLAGS = LEPTON_INCFLAGS =
COLVARS_OBJS = $(COLVARS_SRCS:.cpp=.o) COLVARS_OBJS = $(COLVARS_SRCS:.cpp=.o)
else else
LEPTON_INCFLAGS = -Ilepton/include -DLEPTON -DLEPTON_USE_STATIC_LIBRARIES LEPTON_INCFLAGS = -Ilepton/include -DLEPTON
COLVARS_OBJS = $(COLVARS_SRCS:.cpp=.o) $(LEPTON_SRCS:.cpp=.o) COLVARS_OBJS = $(COLVARS_SRCS:.cpp=.o) $(LEPTON_SRCS:.cpp=.o)
endif endif
@ -77,25 +83,9 @@ Makefile.deps: $(COLVARS_SRCS)
@echo > $@ @echo > $@
@for src in $^ ; do \ @for src in $^ ; do \
obj=`basename $$src .cpp`.o ; \ obj=`basename $$src .cpp`.o ; \
$(CXX) -MM $(COLVARS_INCFLAGS) $(LEPTON_INCFLAGS) \ $(CXX) $(CXXFLAGS) -MM $(COLVARS_INCFLAGS) $(LEPTON_INCFLAGS) \
-MT '$$(COLVARS_OBJ_DIR)'$$obj $$src >> $@ ; \ -MT '$$(COLVARS_OBJ_DIR)'$$obj $$src >> $@ ; \
done done
include Makefile.deps include Makefile.deps
# Exceptions to pattern rule above for Lepton objects
lepton/src/CompiledExpression.o: lepton/src/CompiledExpression.cpp
$(CXX) $(CXXFLAGS) -Ilepton/include -DLEPTON_BUILDING_STATIC_LIBRARY -c -o $@ $<
lepton/src/ExpressionProgram.o: lepton/src/ExpressionProgram.cpp
$(CXX) $(CXXFLAGS) -Ilepton/include -DLEPTON_BUILDING_STATIC_LIBRARY -c -o $@ $<
lepton/src/ExpressionTreeNode.o: lepton/src/ExpressionTreeNode.cpp
$(CXX) $(CXXFLAGS) -Ilepton/include -DLEPTON_BUILDING_STATIC_LIBRARY -c -o $@ $<
lepton/src/Operation.o: lepton/src/Operation.cpp
$(CXX) $(CXXFLAGS) -Ilepton/include -DLEPTON_BUILDING_STATIC_LIBRARY -c -o $@ $<
lepton/src/ParsedExpression.o: lepton/src/ParsedExpression.cpp
$(CXX) $(CXXFLAGS) -Ilepton/include -DLEPTON_BUILDING_STATIC_LIBRARY -c -o $@ $<
lepton/src/Parser.o: lepton/src/Parser.cpp
$(CXX) $(CXXFLAGS) -Ilepton/include -DLEPTON_BUILDING_STATIC_LIBRARY -c -o $@ $<
include Makefile.lepton.deps # Hand-generated include Makefile.lepton.deps # Hand-generated

View File

@ -1,83 +1,270 @@
$(COLVARS_OBJ_DIR)colvaratoms.o: colvaratoms.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvaratoms.o: colvaratoms.cpp colvarmodule.h \
colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \ colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \
colvarparse.h colvarparams.h colvaratoms.h colvardeps.h colvarproxy_tcl.h colvarproxy_volmaps.h colvarparse.h colvarparams.h \
colvaratoms.h colvardeps.h
$(COLVARS_OBJ_DIR)colvarbias_abf.o: colvarbias_abf.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvarbias_abf.o: colvarbias_abf.cpp colvarmodule.h \
colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h colvar.h \ colvars_version.h colvar.h colvarvalue.h colvartypes.h colvarparse.h \
colvarparse.h colvarparams.h colvardeps.h colvarbias_abf.h colvarbias.h \ colvarparams.h colvardeps.h lepton/include/Lepton.h \
colvargrid.h colvar_UIestimator.h lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarbias_abf.h colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \
colvarbias.h colvargrid.h colvar_UIestimator.h
$(COLVARS_OBJ_DIR)colvarbias_alb.o: colvarbias_alb.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvarbias_alb.o: colvarbias_alb.cpp colvarmodule.h \
colvars_version.h colvarbias.h colvar.h colvarvalue.h colvartypes.h \ colvars_version.h colvarbias.h colvar.h colvarvalue.h colvartypes.h \
colvarparse.h colvarparams.h colvardeps.h colvarbias_alb.h colvarparse.h colvarparams.h colvardeps.h lepton/include/Lepton.h \
lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarbias_alb.h
$(COLVARS_OBJ_DIR)colvarbias.o: colvarbias.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvarbias.o: colvarbias.cpp colvarmodule.h \
colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h colvarbias.h \ colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \
colvar.h colvarparse.h colvarparams.h colvardeps.h colvargrid.h colvarproxy_tcl.h colvarproxy_volmaps.h colvarbias.h colvar.h \
colvarparse.h colvarparams.h colvardeps.h lepton/include/Lepton.h \
lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvargrid.h
$(COLVARS_OBJ_DIR)colvarbias_histogram.o: colvarbias_histogram.cpp \ $(COLVARS_OBJ_DIR)colvarbias_histogram.o: colvarbias_histogram.cpp \
colvarmodule.h colvars_version.h colvarproxy.h colvartypes.h \ colvarmodule.h colvars_version.h colvarproxy.h colvartypes.h \
colvarvalue.h colvar.h colvarparse.h colvarparams.h colvardeps.h \ colvarvalue.h colvarproxy_tcl.h colvarproxy_volmaps.h colvar.h \
colvarparse.h colvarparams.h colvardeps.h lepton/include/Lepton.h \
lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarbias_histogram.h colvarbias.h colvargrid.h colvarbias_histogram.h colvarbias.h colvargrid.h
$(COLVARS_OBJ_DIR)colvarbias_meta.o: colvarbias_meta.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvarbias_meta.o: colvarbias_meta.cpp colvarmodule.h \
colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h colvar.h \ colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \
colvarparse.h colvarparams.h colvardeps.h colvarbias_meta.h colvarbias.h \ colvarproxy_tcl.h colvarproxy_volmaps.h colvar.h colvarparse.h \
colvargrid.h colvarparams.h colvardeps.h lepton/include/Lepton.h \
lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarbias_meta.h colvarbias.h colvargrid.h
$(COLVARS_OBJ_DIR)colvarbias_restraint.o: colvarbias_restraint.cpp \ $(COLVARS_OBJ_DIR)colvarbias_restraint.o: colvarbias_restraint.cpp \
colvarmodule.h colvars_version.h colvarproxy.h colvartypes.h \ colvarmodule.h colvars_version.h colvarproxy.h colvartypes.h \
colvarvalue.h colvarbias_restraint.h colvarbias.h colvar.h colvarparse.h \ colvarvalue.h colvarproxy_tcl.h colvarproxy_volmaps.h \
colvarparams.h colvardeps.h colvarbias_restraint.h colvarbias.h colvar.h colvarparse.h \
colvarparams.h colvardeps.h lepton/include/Lepton.h \
lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h
$(COLVARS_OBJ_DIR)colvarcomp_angles.o: colvarcomp_angles.cpp \ $(COLVARS_OBJ_DIR)colvarcomp_angles.o: colvarcomp_angles.cpp \
colvarmodule.h colvars_version.h colvar.h colvarvalue.h colvartypes.h \ colvarmodule.h colvars_version.h colvar.h colvarvalue.h colvartypes.h \
colvarparse.h colvarparams.h colvardeps.h colvarcomp.h colvaratoms.h \ colvarparse.h colvarparams.h colvardeps.h lepton/include/Lepton.h \
colvarproxy.h colvar_arithmeticpath.h colvar_geometricpath.h lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_tcl.h \
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_apath.o: colvarcomp_apath.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvarcomp_apath.o: colvarcomp_apath.cpp colvarmodule.h \
colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \ colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \
colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \ colvarparams.h colvar.h colvardeps.h lepton/include/Lepton.h \
colvarproxy.h colvar_arithmeticpath.h colvar_geometricpath.h lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_tcl.h \
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_coordnums.o: colvarcomp_coordnums.cpp \ $(COLVARS_OBJ_DIR)colvarcomp_coordnums.o: colvarcomp_coordnums.cpp \
colvarmodule.h colvars_version.h colvarparse.h colvarvalue.h \ colvarmodule.h colvars_version.h colvarparse.h colvarvalue.h \
colvartypes.h colvarparams.h colvaratoms.h colvarproxy.h colvardeps.h \ colvartypes.h colvarparams.h colvaratoms.h colvarproxy.h \
colvar.h colvarcomp.h colvar_arithmeticpath.h colvar_geometricpath.h colvarproxy_tcl.h colvarproxy_volmaps.h colvardeps.h colvar.h \
lepton/include/Lepton.h lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarcomp.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp.o: colvarcomp.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvarcomp.o: colvarcomp.cpp colvarmodule.h \
colvars_version.h colvarvalue.h colvartypes.h colvar.h colvarparse.h \ colvars_version.h colvarvalue.h colvartypes.h colvar.h colvarparse.h \
colvarparams.h colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h \ colvarparams.h colvardeps.h lepton/include/Lepton.h \
colvar_arithmeticpath.h colvar_geometricpath.h lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_tcl.h \
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_distances.o: colvarcomp_distances.cpp \ $(COLVARS_OBJ_DIR)colvarcomp_distances.o: colvarcomp_distances.cpp \
colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \ colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
colvarparse.h colvarparams.h colvar.h colvardeps.h colvarcomp.h \ colvarparse.h colvarparams.h colvar.h colvardeps.h \
colvaratoms.h colvarproxy.h colvar_arithmeticpath.h \ lepton/include/Lepton.h lepton/include/lepton/CompiledExpression.h \
colvar_geometricpath.h lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_tcl.h \
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_gpath.o: colvarcomp_gpath.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvarcomp_gpath.o: colvarcomp_gpath.cpp colvarmodule.h \
colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \ colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \
colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \ colvarparams.h colvar.h colvardeps.h lepton/include/Lepton.h \
colvarproxy.h colvar_arithmeticpath.h colvar_geometricpath.h lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_tcl.h \
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_protein.o: colvarcomp_protein.cpp \ $(COLVARS_OBJ_DIR)colvarcomp_protein.o: colvarcomp_protein.cpp \
colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \ colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
colvarparse.h colvarparams.h colvar.h colvardeps.h colvarcomp.h \ colvarparse.h colvarparams.h colvar.h colvardeps.h \
colvaratoms.h colvarproxy.h colvar_arithmeticpath.h \ lepton/include/Lepton.h lepton/include/lepton/CompiledExpression.h \
colvar_geometricpath.h lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_tcl.h \
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_rotations.o: colvarcomp_rotations.cpp \ $(COLVARS_OBJ_DIR)colvarcomp_rotations.o: colvarcomp_rotations.cpp \
colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \ colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
colvarparse.h colvarparams.h colvar.h colvardeps.h colvarcomp.h \ colvarparse.h colvarparams.h colvar.h colvardeps.h \
colvaratoms.h colvarproxy.h colvar_arithmeticpath.h \ lepton/include/Lepton.h lepton/include/lepton/CompiledExpression.h \
colvar_geometricpath.h lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_tcl.h \
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_volmaps.o: colvarcomp_volmaps.cpp \
colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
colvarparse.h colvarparams.h colvar.h colvardeps.h \
lepton/include/Lepton.h lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_tcl.h \
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvar.o: colvar.cpp colvarmodule.h colvars_version.h \ $(COLVARS_OBJ_DIR)colvar.o: colvar.cpp colvarmodule.h colvars_version.h \
colvarvalue.h colvartypes.h colvarparse.h colvarparams.h colvar.h \ colvarvalue.h colvartypes.h colvarparse.h colvarparams.h colvar.h \
colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h \ colvardeps.h lepton/include/Lepton.h \
colvar_arithmeticpath.h colvar_geometricpath.h colvarscript.h \ lepton/include/lepton/CompiledExpression.h \
colvarbias.h lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_tcl.h \
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h \
colvarscript.h colvarbias.h colvarscript_commands.h \
colvarscript_commands_colvar.h colvarscript_commands_bias.h
$(COLVARS_OBJ_DIR)colvardeps.o: colvardeps.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvardeps.o: colvardeps.cpp colvarmodule.h \
colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h colvardeps.h \ colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \
colvarparse.h colvarparams.h colvarproxy_tcl.h colvarproxy_volmaps.h colvardeps.h colvarparse.h \
colvarparams.h
$(COLVARS_OBJ_DIR)colvargrid.o: colvargrid.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvargrid.o: colvargrid.cpp colvarmodule.h \
colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \ colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \
colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \ colvarparams.h colvar.h colvardeps.h lepton/include/Lepton.h \
colvarproxy.h colvar_arithmeticpath.h colvar_geometricpath.h \ lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_tcl.h \
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h \
colvargrid.h colvargrid.h
$(COLVARS_OBJ_DIR)colvarmodule.o: colvarmodule.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvarmodule.o: colvarmodule.cpp colvarmodule.h \
colvars_version.h colvarparse.h colvarvalue.h colvartypes.h \ colvars_version.h colvarparse.h colvarvalue.h colvartypes.h \
colvarparams.h colvarproxy.h colvar.h colvardeps.h colvarbias.h \ colvarparams.h colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \
colvarbias_abf.h colvargrid.h colvar_UIestimator.h colvarbias_alb.h \ colvar.h colvardeps.h lepton/include/Lepton.h \
colvarbias_histogram.h colvarbias_meta.h colvarbias_restraint.h \ lepton/include/lepton/CompiledExpression.h \
colvarscript.h colvaratoms.h colvarcomp.h colvar_arithmeticpath.h \ lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarbias.h colvarbias_abf.h colvargrid.h colvar_UIestimator.h \
colvarbias_alb.h colvarbias_histogram.h colvarbias_meta.h \
colvarbias_restraint.h colvarscript.h colvarscript_commands.h \
colvarscript_commands_colvar.h colvarscript_commands_bias.h \
colvaratoms.h colvarcomp.h colvar_arithmeticpath.h \
colvar_geometricpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarparams.o: colvarparams.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvarparams.o: colvarparams.cpp colvarmodule.h \
colvars_version.h colvarvalue.h colvartypes.h colvarparams.h colvars_version.h colvarvalue.h colvartypes.h colvarparams.h
@ -86,17 +273,92 @@ $(COLVARS_OBJ_DIR)colvarparse.o: colvarparse.cpp colvarmodule.h \
colvarparams.h colvarparams.h
$(COLVARS_OBJ_DIR)colvarproxy.o: colvarproxy.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvarproxy.o: colvarproxy.cpp colvarmodule.h \
colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \ colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \
colvarscript.h colvarbias.h colvar.h colvarparse.h colvarparams.h \ colvarproxy_tcl.h colvarproxy_volmaps.h colvarscript.h colvarbias.h \
colvardeps.h colvaratoms.h colvar.h colvarparse.h colvarparams.h colvardeps.h \
lepton/include/Lepton.h lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarscript_commands.h colvarscript_commands_colvar.h \
colvarscript_commands_bias.h colvaratoms.h
$(COLVARS_OBJ_DIR)colvarproxy_replicas.o: colvarproxy_replicas.cpp \ $(COLVARS_OBJ_DIR)colvarproxy_replicas.o: colvarproxy_replicas.cpp \
colvarmodule.h colvars_version.h colvarproxy.h colvartypes.h \ colvarmodule.h colvars_version.h colvarproxy.h colvartypes.h \
colvarvalue.h colvarvalue.h colvarproxy_tcl.h colvarproxy_volmaps.h
$(COLVARS_OBJ_DIR)colvarscript.o: colvarscript.cpp colvarscript.h \ $(COLVARS_OBJ_DIR)colvarproxy_tcl.o: colvarproxy_tcl.cpp colvarmodule.h \
colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \ colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \
colvarbias.h colvar.h colvarparse.h colvarparams.h colvardeps.h \ colvarproxy_tcl.h colvarproxy_volmaps.h colvaratoms.h colvarparse.h \
colvarproxy.h colvarparams.h colvardeps.h
$(COLVARS_OBJ_DIR)colvarproxy_volmaps.o: colvarproxy_volmaps.cpp \
colvarmodule.h colvars_version.h colvarproxy_volmaps.h
$(COLVARS_OBJ_DIR)colvarscript.o: colvarscript.cpp colvarproxy.h \
colvarmodule.h colvars_version.h colvartypes.h colvarvalue.h \
colvarproxy_tcl.h colvarproxy_volmaps.h colvardeps.h colvarparse.h \
colvarparams.h colvarscript.h colvarbias.h colvar.h \
lepton/include/Lepton.h lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarscript_commands.h colvarscript_commands_colvar.h \
colvarscript_commands_bias.h
$(COLVARS_OBJ_DIR)colvarscript_commands.o: colvarscript_commands.cpp \
colvarproxy.h colvarmodule.h colvars_version.h colvartypes.h \
colvarvalue.h colvarproxy_tcl.h colvarproxy_volmaps.h colvardeps.h \
colvarparse.h colvarparams.h colvarscript.h colvarbias.h colvar.h \
lepton/include/Lepton.h lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarscript_commands.h colvarscript_commands_colvar.h \
colvarscript_commands_bias.h
$(COLVARS_OBJ_DIR)colvarscript_commands_bias.o: \
colvarscript_commands_bias.cpp colvarproxy.h colvarmodule.h \
colvars_version.h colvartypes.h colvarvalue.h colvarproxy_tcl.h \
colvarproxy_volmaps.h colvardeps.h colvarparse.h colvarparams.h \
colvarscript.h colvarbias.h colvar.h lepton/include/Lepton.h \
lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarscript_commands.h colvarscript_commands_colvar.h \
colvarscript_commands_bias.h
$(COLVARS_OBJ_DIR)colvarscript_commands_colvar.o: \
colvarscript_commands_colvar.cpp colvarproxy.h colvarmodule.h \
colvars_version.h colvartypes.h colvarvalue.h colvarproxy_tcl.h \
colvarproxy_volmaps.h colvardeps.h colvarparse.h colvarparams.h \
colvarscript.h colvarbias.h colvar.h lepton/include/Lepton.h \
lepton/include/lepton/CompiledExpression.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/windowsIncludes.h \
lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/ExpressionProgram.h \
lepton/include/lepton/ExpressionTreeNode.h \
lepton/include/lepton/Operation.h lepton/include/lepton/CustomFunction.h \
lepton/include/lepton/Exception.h \
lepton/include/lepton/ParsedExpression.h lepton/include/lepton/Parser.h \
colvarscript_commands.h colvarscript_commands_colvar.h \
colvarscript_commands_bias.h
$(COLVARS_OBJ_DIR)colvartypes.o: colvartypes.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvartypes.o: colvartypes.cpp colvarmodule.h \
colvars_version.h colvartypes.h colvarparse.h colvarvalue.h \ colvars_version.h colvartypes.h colvarparse.h colvarvalue.h \
colvarparams.h colvarparams.h ../../src/math_eigen.h
$(COLVARS_OBJ_DIR)colvarvalue.o: colvarvalue.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvarvalue.o: colvarvalue.cpp colvarmodule.h \
colvars_version.h colvarvalue.h colvartypes.h colvars_version.h colvarvalue.h colvartypes.h

View File

@ -18,7 +18,9 @@
#include "colvarcomp.h" #include "colvarcomp.h"
#include "colvarscript.h" #include "colvarscript.h"
#if (__cplusplus >= 201103L)
std::map<std::string, std::function<colvar::cvc* (const std::string& subcv_conf)>> colvar::global_cvc_map = std::map<std::string, std::function<colvar::cvc* (const std::string& subcv_conf)>>();
#endif
colvar::colvar() colvar::colvar()
{ {
@ -541,7 +543,7 @@ int colvar::init_grid_parameters(std::string const &conf)
cvm::log("Reading legacy options lowerWall and lowerWallConstant: " cvm::log("Reading legacy options lowerWall and lowerWallConstant: "
"consider using a harmonicWalls restraint (caution: force constant would then be scaled by width^2).\n"); "consider using a harmonicWalls restraint (caution: force constant would then be scaled by width^2).\n");
if (!get_keyval(conf, "lowerWall", lower_wall)) { if (!get_keyval(conf, "lowerWall", lower_wall)) {
error_code != cvm::error("Error: the value of lowerWall must be set " error_code |= cvm::error("Error: the value of lowerWall must be set "
"explicitly.\n", INPUT_ERROR); "explicitly.\n", INPUT_ERROR);
} }
lw_conf = std::string("\n\ lw_conf = std::string("\n\
@ -554,7 +556,7 @@ int colvar::init_grid_parameters(std::string const &conf)
cvm::log("Reading legacy options upperWall and upperWallConstant: " cvm::log("Reading legacy options upperWall and upperWallConstant: "
"consider using a harmonicWalls restraint (caution: force constant would then be scaled by width^2).\n"); "consider using a harmonicWalls restraint (caution: force constant would then be scaled by width^2).\n");
if (!get_keyval(conf, "upperWall", upper_wall)) { if (!get_keyval(conf, "upperWall", upper_wall)) {
error_code != cvm::error("Error: the value of upperWall must be set " error_code |= cvm::error("Error: the value of upperWall must be set "
"explicitly.\n", INPUT_ERROR); "explicitly.\n", INPUT_ERROR);
} }
uw_conf = std::string("\n\ uw_conf = std::string("\n\
@ -616,7 +618,7 @@ harmonicWalls {\n\
"are enabled).\n", INPUT_ERROR); "are enabled).\n", INPUT_ERROR);
} }
return COLVARS_OK; return error_code;
} }
@ -681,6 +683,9 @@ int colvar::init_extended_Lagrangian(std::string const &conf)
// Adjust Langevin sigma for slow time step if time_step_factor != 1 // Adjust Langevin sigma for slow time step if time_step_factor != 1
ext_sigma = cvm::sqrt(2.0 * cvm::boltzmann() * temp * ext_gamma * ext_mass / (cvm::dt() * cvm::real(time_step_factor))); ext_sigma = cvm::sqrt(2.0 * cvm::boltzmann() * temp * ext_gamma * ext_mass / (cvm::dt() * cvm::real(time_step_factor)));
} }
get_keyval_feature(this, conf, "reflectingLowerBoundary", f_cv_reflecting_lower_boundary, false);
get_keyval_feature(this, conf, "reflectingUpperBoundary", f_cv_reflecting_upper_boundary, false);
} }
return COLVARS_OK; return COLVARS_OK;
@ -721,15 +726,15 @@ int colvar::init_output_flags(std::string const &conf)
return COLVARS_OK; return COLVARS_OK;
} }
// read the configuration and set up corresponding instances, for // read the configuration and set up corresponding instances, for
// each type of component implemented // each type of component implemented
template<typename def_class_name> int colvar::init_components_type(std::string const &conf, template<typename def_class_name> int colvar::init_components_type(std::string const &conf,
char const * /* def_desc */, char const * /* def_desc */,
char const *def_config_key) char const *def_config_key)
{ {
#if (__cplusplus >= 201103L)
global_cvc_map[def_config_key] = [](const std::string& cvc_conf){return new def_class_name(cvc_conf);};
#endif
size_t def_count = 0; size_t def_count = 0;
std::string def_conf = ""; std::string def_conf = "";
size_t pos = 0; size_t pos = 0;
@ -863,6 +868,8 @@ int colvar::init_components(std::string const &conf)
error_code |= init_components_type<aspathCV>(conf, "arithmetic path collective variables (s) for other CVs", "aspathCV"); error_code |= init_components_type<aspathCV>(conf, "arithmetic path collective variables (s) for other CVs", "aspathCV");
error_code |= init_components_type<azpathCV>(conf, "arithmetic path collective variables (s) for other CVs", "azpathCV"); error_code |= init_components_type<azpathCV>(conf, "arithmetic path collective variables (s) for other CVs", "azpathCV");
error_code |= init_components_type<map_total>(conf, "total value of atomic map", "mapTotal");
if (!cvcs.size() || (error_code != COLVARS_OK)) { if (!cvcs.size() || (error_code != COLVARS_OK)) {
cvm::error("Error: no valid components were provided " cvm::error("Error: no valid components were provided "
"for this collective variable.\n", "for this collective variable.\n",
@ -1040,85 +1047,93 @@ int colvar::init_dependencies() {
init_feature(f_cv_gradient, "gradient", f_type_dynamic); init_feature(f_cv_gradient, "gradient", f_type_dynamic);
require_feature_children(f_cv_gradient, f_cvc_gradient); require_feature_children(f_cv_gradient, f_cvc_gradient);
init_feature(f_cv_collect_gradient, "collect gradient", f_type_dynamic); init_feature(f_cv_collect_gradient, "collect_gradient", f_type_dynamic);
require_feature_self(f_cv_collect_gradient, f_cv_gradient); require_feature_self(f_cv_collect_gradient, f_cv_gradient);
require_feature_self(f_cv_collect_gradient, f_cv_scalar); require_feature_self(f_cv_collect_gradient, f_cv_scalar);
// The following exlusion could be lifted by implementing the feature // The following exlusion could be lifted by implementing the feature
exclude_feature_self(f_cv_collect_gradient, f_cv_scripted); exclude_feature_self(f_cv_collect_gradient, f_cv_scripted);
require_feature_children(f_cv_collect_gradient, f_cvc_explicit_gradient); require_feature_children(f_cv_collect_gradient, f_cvc_explicit_gradient);
init_feature(f_cv_fdiff_velocity, "velocity from finite differences", f_type_dynamic); init_feature(f_cv_fdiff_velocity, "velocity_from_finite_differences", f_type_dynamic);
// System force: either trivial (spring force); through extended Lagrangian, or calculated explicitly // System force: either trivial (spring force); through extended Lagrangian, or calculated explicitly
init_feature(f_cv_total_force, "total force", f_type_dynamic); init_feature(f_cv_total_force, "total_force", f_type_dynamic);
require_feature_alt(f_cv_total_force, f_cv_extended_Lagrangian, f_cv_total_force_calc); require_feature_alt(f_cv_total_force, f_cv_extended_Lagrangian, f_cv_total_force_calc);
// Deps for explicit total force calculation // Deps for explicit total force calculation
init_feature(f_cv_total_force_calc, "total force calculation", f_type_dynamic); init_feature(f_cv_total_force_calc, "total_force_calculation", f_type_dynamic);
require_feature_self(f_cv_total_force_calc, f_cv_scalar); require_feature_self(f_cv_total_force_calc, f_cv_scalar);
require_feature_self(f_cv_total_force_calc, f_cv_linear); require_feature_self(f_cv_total_force_calc, f_cv_linear);
require_feature_children(f_cv_total_force_calc, f_cvc_inv_gradient); require_feature_children(f_cv_total_force_calc, f_cvc_inv_gradient);
require_feature_self(f_cv_total_force_calc, f_cv_Jacobian); require_feature_self(f_cv_total_force_calc, f_cv_Jacobian);
init_feature(f_cv_Jacobian, "Jacobian derivative", f_type_dynamic); init_feature(f_cv_Jacobian, "Jacobian_derivative", f_type_dynamic);
require_feature_self(f_cv_Jacobian, f_cv_scalar); require_feature_self(f_cv_Jacobian, f_cv_scalar);
require_feature_self(f_cv_Jacobian, f_cv_linear); require_feature_self(f_cv_Jacobian, f_cv_linear);
require_feature_children(f_cv_Jacobian, f_cvc_Jacobian); require_feature_children(f_cv_Jacobian, f_cvc_Jacobian);
init_feature(f_cv_hide_Jacobian, "hide Jacobian force", f_type_user); init_feature(f_cv_hide_Jacobian, "hide_Jacobian_force", f_type_user);
require_feature_self(f_cv_hide_Jacobian, f_cv_Jacobian); // can only hide if calculated require_feature_self(f_cv_hide_Jacobian, f_cv_Jacobian); // can only hide if calculated
init_feature(f_cv_extended_Lagrangian, "extended Lagrangian", f_type_user); init_feature(f_cv_extended_Lagrangian, "extended_Lagrangian", f_type_user);
require_feature_self(f_cv_extended_Lagrangian, f_cv_scalar); require_feature_self(f_cv_extended_Lagrangian, f_cv_scalar);
require_feature_self(f_cv_extended_Lagrangian, f_cv_gradient); require_feature_self(f_cv_extended_Lagrangian, f_cv_gradient);
init_feature(f_cv_Langevin, "Langevin dynamics", f_type_user); init_feature(f_cv_Langevin, "Langevin_dynamics", f_type_user);
require_feature_self(f_cv_Langevin, f_cv_extended_Lagrangian); require_feature_self(f_cv_Langevin, f_cv_extended_Lagrangian);
init_feature(f_cv_single_cvc, "single component", f_type_static); init_feature(f_cv_single_cvc, "single_component", f_type_static);
init_feature(f_cv_linear, "linear", f_type_static); init_feature(f_cv_linear, "linear", f_type_static);
init_feature(f_cv_scalar, "scalar", f_type_static); init_feature(f_cv_scalar, "scalar", f_type_static);
init_feature(f_cv_output_energy, "output energy", f_type_user); init_feature(f_cv_output_energy, "output_energy", f_type_user);
init_feature(f_cv_output_value, "output value", f_type_user); init_feature(f_cv_output_value, "output_value", f_type_user);
init_feature(f_cv_output_velocity, "output velocity", f_type_user); init_feature(f_cv_output_velocity, "output_velocity", f_type_user);
require_feature_self(f_cv_output_velocity, f_cv_fdiff_velocity); require_feature_self(f_cv_output_velocity, f_cv_fdiff_velocity);
init_feature(f_cv_output_applied_force, "output applied force", f_type_user); init_feature(f_cv_output_applied_force, "output_applied_force", f_type_user);
init_feature(f_cv_output_total_force, "output total force", f_type_user); init_feature(f_cv_output_total_force, "output_total_force", f_type_user);
require_feature_self(f_cv_output_total_force, f_cv_total_force); require_feature_self(f_cv_output_total_force, f_cv_total_force);
init_feature(f_cv_subtract_applied_force, "subtract applied force from total force", f_type_user); init_feature(f_cv_subtract_applied_force, "subtract_applied_force_from_total_force", f_type_user);
require_feature_self(f_cv_subtract_applied_force, f_cv_total_force); require_feature_self(f_cv_subtract_applied_force, f_cv_total_force);
init_feature(f_cv_lower_boundary, "lower boundary", f_type_user); init_feature(f_cv_lower_boundary, "lower_boundary", f_type_user);
require_feature_self(f_cv_lower_boundary, f_cv_scalar); require_feature_self(f_cv_lower_boundary, f_cv_scalar);
init_feature(f_cv_upper_boundary, "upper boundary", f_type_user); init_feature(f_cv_upper_boundary, "upper_boundary", f_type_user);
require_feature_self(f_cv_upper_boundary, f_cv_scalar); require_feature_self(f_cv_upper_boundary, f_cv_scalar);
init_feature(f_cv_hard_lower_boundary, "hard lower boundary", f_type_user); init_feature(f_cv_hard_lower_boundary, "hard_lower_boundary", f_type_user);
require_feature_self(f_cv_hard_lower_boundary, f_cv_lower_boundary); require_feature_self(f_cv_hard_lower_boundary, f_cv_lower_boundary);
init_feature(f_cv_hard_upper_boundary, "hard upper boundary", f_type_user); init_feature(f_cv_hard_upper_boundary, "hard_upper_boundary", f_type_user);
require_feature_self(f_cv_hard_upper_boundary, f_cv_upper_boundary); require_feature_self(f_cv_hard_upper_boundary, f_cv_upper_boundary);
init_feature(f_cv_reflecting_lower_boundary, "reflecting_lower_boundary", f_type_user);
require_feature_self(f_cv_reflecting_lower_boundary, f_cv_lower_boundary);
require_feature_self(f_cv_reflecting_lower_boundary, f_cv_extended_Lagrangian);
init_feature(f_cv_reflecting_upper_boundary, "reflecting_upper_boundary", f_type_user);
require_feature_self(f_cv_reflecting_upper_boundary, f_cv_upper_boundary);
require_feature_self(f_cv_reflecting_upper_boundary, f_cv_extended_Lagrangian);
init_feature(f_cv_grid, "grid", f_type_dynamic); init_feature(f_cv_grid, "grid", f_type_dynamic);
require_feature_self(f_cv_grid, f_cv_lower_boundary); require_feature_self(f_cv_grid, f_cv_lower_boundary);
require_feature_self(f_cv_grid, f_cv_upper_boundary); require_feature_self(f_cv_grid, f_cv_upper_boundary);
init_feature(f_cv_runave, "running average", f_type_user); init_feature(f_cv_runave, "running_average", f_type_user);
init_feature(f_cv_corrfunc, "correlation function", f_type_user); init_feature(f_cv_corrfunc, "correlation_function", f_type_user);
init_feature(f_cv_scripted, "scripted", f_type_user); init_feature(f_cv_scripted, "scripted", f_type_user);
init_feature(f_cv_custom_function, "custom function", f_type_user); init_feature(f_cv_custom_function, "custom_function", f_type_user);
exclude_feature_self(f_cv_custom_function, f_cv_scripted); exclude_feature_self(f_cv_custom_function, f_cv_scripted);
init_feature(f_cv_periodic, "periodic", f_type_static); init_feature(f_cv_periodic, "periodic", f_type_static);
@ -1129,7 +1144,7 @@ int colvar::init_dependencies() {
// because total forces are obtained from the previous time step, // because total forces are obtained from the previous time step,
// we cannot (currently) have colvar values and total forces for the same timestep // we cannot (currently) have colvar values and total forces for the same timestep
init_feature(f_cv_multiple_ts, "multiple timestep colvar", f_type_static); init_feature(f_cv_multiple_ts, "multiple_timestep", f_type_static);
exclude_feature_self(f_cv_multiple_ts, f_cv_total_force_calc); exclude_feature_self(f_cv_multiple_ts, f_cv_total_force_calc);
// check that everything is initialized // check that everything is initialized
@ -1199,8 +1214,17 @@ colvar::~colvar()
(*ci)->remove_all_children(); (*ci)->remove_all_children();
delete *ci; delete *ci;
} }
cvcs.clear();
// remove reference to this colvar from the CVM while (biases.size() > 0) {
size_t const i = biases.size()-1;
cvm::log("Warning: before deleting colvar " + name
+ ", deleting related bias " + biases[i]->name);
delete biases[i];
}
biases.clear();
// remove reference to this colvar from the module
colvarmodule *cv = cvm::main(); colvarmodule *cv = cvm::main();
for (std::vector<colvar *>::iterator cvi = cv->variables()->begin(); for (std::vector<colvar *>::iterator cvi = cv->variables()->begin();
cvi != cv->variables()->end(); cvi != cv->variables()->end();
@ -1211,6 +1235,8 @@ colvar::~colvar()
} }
} }
cv->config_changed();
#ifdef LEPTON #ifdef LEPTON
for (std::vector<Lepton::CompiledExpression *>::iterator cei = value_evaluators.begin(); for (std::vector<Lepton::CompiledExpression *>::iterator cei = value_evaluators.begin();
cei != value_evaluators.end(); cei != value_evaluators.end();
@ -1599,6 +1625,15 @@ int colvar::calc_colvar_properties()
// just calculated from the cvcs // just calculated from the cvcs
if ((cvm::step_relative() == 0 && !after_restart) || x_ext.type() == colvarvalue::type_notset) { if ((cvm::step_relative() == 0 && !after_restart) || x_ext.type() == colvarvalue::type_notset) {
x_ext = x; x_ext = x;
if (is_enabled(f_cv_reflecting_lower_boundary) && x_ext < lower_boundary) {
cvm::log("Warning: initializing extended coordinate to reflective lower boundary, as colvar value is below.");
x_ext = lower_boundary;
}
if (is_enabled(f_cv_reflecting_upper_boundary) && x_ext > upper_boundary) {
cvm::log("Warning: initializing extended coordinate to reflective upper boundary, as colvar value is above.");
x_ext = upper_boundary;
}
v_ext.reset(); // (already 0; added for clarity) v_ext.reset(); // (already 0; added for clarity)
} }
@ -1672,10 +1707,10 @@ cvm::real colvar::update_forces_energy()
cvm::log("Updating extended-Lagrangian degree of freedom.\n"); cvm::log("Updating extended-Lagrangian degree of freedom.\n");
} }
if (prev_timestep > -1) { if (prev_timestep > -1L) {
// Keep track of slow timestep to integrate MTS colvars // Keep track of slow timestep to integrate MTS colvars
// the colvar checks the interval after waking up twice // the colvar checks the interval after waking up twice
int n_timesteps = cvm::step_relative() - prev_timestep; cvm::step_number n_timesteps = cvm::step_relative() - prev_timestep;
if (n_timesteps != 0 && n_timesteps != time_step_factor) { if (n_timesteps != 0 && n_timesteps != time_step_factor) {
cvm::error("Error: extended-Lagrangian " + description + " has timeStepFactor " + cvm::error("Error: extended-Lagrangian " + description + " has timeStepFactor " +
cvm::to_str(time_step_factor) + ", but was activated after " + cvm::to_str(n_timesteps) + cvm::to_str(time_step_factor) + ", but was activated after " + cvm::to_str(n_timesteps) +
@ -1737,6 +1772,14 @@ cvm::real colvar::update_forces_energy()
} }
v_ext += (0.5 * dt) * f_ext / ext_mass; v_ext += (0.5 * dt) * f_ext / ext_mass;
x_ext += dt * v_ext; x_ext += dt * v_ext;
cvm::real delta = 0; // Length of overshoot past either reflecting boundary
if ((is_enabled(f_cv_reflecting_lower_boundary) && (delta = x_ext - lower_boundary) < 0) ||
(is_enabled(f_cv_reflecting_upper_boundary) && (delta = x_ext - upper_boundary) > 0)) {
x_ext -= 2.0 * delta;
v_ext *= -1.0;
}
x_ext.apply_constraints(); x_ext.apply_constraints();
this->wrap(x_ext); this->wrap(x_ext);
} else { } else {
@ -2082,7 +2125,7 @@ void colvar::wrap(colvarvalue &x_unwrapped) const
std::istream & colvar::read_state(std::istream &is) std::istream & colvar::read_state(std::istream &is)
{ {
size_t const start_pos = is.tellg(); std::streampos const start_pos = is.tellg();
std::string conf; std::string conf;
if ( !(is >> colvarparse::read_block("colvar", &conf)) ) { if ( !(is >> colvarparse::read_block("colvar", &conf)) ) {
@ -2163,7 +2206,7 @@ std::istream & colvar::read_state(std::istream &is)
std::istream & colvar::read_traj(std::istream &is) std::istream & colvar::read_traj(std::istream &is)
{ {
size_t const start_pos = is.tellg(); std::streampos const start_pos = is.tellg();
if (is_enabled(f_cv_output_value)) { if (is_enabled(f_cv_output_value)) {

View File

@ -12,6 +12,11 @@
#include <iostream> #include <iostream>
#if (__cplusplus >= 201103L)
#include <map>
#include <functional>
#endif
#include "colvarmodule.h" #include "colvarmodule.h"
#include "colvarvalue.h" #include "colvarvalue.h"
#include "colvarparse.h" #include "colvarparse.h"
@ -114,6 +119,7 @@ public:
/// List of biases that depend on this colvar /// List of biases that depend on this colvar
std::vector<colvarbias *> biases; std::vector<colvarbias *> biases;
protected: protected:
@ -602,6 +608,17 @@ public:
class cartesian; class cartesian;
class orientation; class orientation;
// components that do not handle any atoms directly
class map_total;
/// getter of the global cvc map
#if (__cplusplus >= 201103L)
/// A global mapping of cvc names to the cvc constructors
static const std::map<std::string, std::function<colvar::cvc* (const std::string& subcv_conf)>>& get_global_cvc_map() {
return global_cvc_map;
}
#endif
protected: protected:
/// \brief Array of \link colvar::cvc \endlink objects /// \brief Array of \link colvar::cvc \endlink objects
@ -636,6 +653,11 @@ protected:
double dev_null; double dev_null;
#endif #endif
#if (__cplusplus >= 201103L)
/// A global mapping of cvc names to the cvc constructors
static std::map<std::string, std::function<colvar::cvc* (const std::string& subcv_conf)>> global_cvc_map;
#endif
public: public:
/// \brief Sorted array of (zero-based) IDs for all atoms involved /// \brief Sorted array of (zero-based) IDs for all atoms involved

View File

@ -116,7 +116,7 @@ namespace UIestimator {
int i; int i;
for (i = 0; i < dimension; i++) { for (i = 0; i < dimension; i++) {
temp[i] = round((round(y[i] / width[i] + EPSILON) - round(x[i] / width[i] + EPSILON)) + (y_size - 1) / 2 + EPSILON); temp[i] = int(round((round(y[i] / width[i] + EPSILON) - round(x[i] / width[i] + EPSILON)) + (y_size - 1) / 2 + EPSILON));
} }
int index = 0; int index = 0;
@ -305,12 +305,6 @@ namespace UIestimator {
int i; int i;
if (step % output_freq == 0) {
calc_pmf();
write_files();
//write_interal_data();
}
for (i = 0; i < dimension; i++) { for (i = 0; i < dimension; i++) {
// for dihedral RC, it is possible that x = 179 and y = -179, should correct it // for dihedral RC, it is possible that x = 179 and y = -179, should correct it
// may have problem, need to fix // may have problem, need to fix
@ -381,6 +375,7 @@ namespace UIestimator {
bool written; bool written;
bool written_1D; bool written_1D;
public:
// calculate gradients from the internal variables // calculate gradients from the internal variables
void calc_pmf() { void calc_pmf() {
int norm; int norm;

View File

@ -240,19 +240,19 @@ int cvm::atom_group::init_dependencies() {
} }
init_feature(f_ag_active, "active", f_type_dynamic); init_feature(f_ag_active, "active", f_type_dynamic);
init_feature(f_ag_center, "translational fit", f_type_static); init_feature(f_ag_center, "translational_fit", f_type_static);
init_feature(f_ag_rotate, "rotational fit", f_type_static); init_feature(f_ag_rotate, "rotational_fit", f_type_static);
init_feature(f_ag_fitting_group, "fitting group", f_type_static); init_feature(f_ag_fitting_group, "fitting_group", f_type_static);
init_feature(f_ag_explicit_gradient, "explicit atom gradient", f_type_dynamic); init_feature(f_ag_explicit_gradient, "explicit_atom_gradient", f_type_dynamic);
init_feature(f_ag_fit_gradients, "fit gradients", f_type_user); init_feature(f_ag_fit_gradients, "fit_gradients", f_type_user);
require_feature_self(f_ag_fit_gradients, f_ag_explicit_gradient); require_feature_self(f_ag_fit_gradients, f_ag_explicit_gradient);
init_feature(f_ag_atom_forces, "atomic forces", f_type_dynamic); init_feature(f_ag_atom_forces, "atomic_forces", f_type_dynamic);
// parallel calculation implies that we have at least a scalable center of mass, // parallel calculation implies that we have at least a scalable center of mass,
// but f_ag_scalable is kept as a separate feature to deal with future dependencies // but f_ag_scalable is kept as a separate feature to deal with future dependencies
init_feature(f_ag_scalable, "scalable group calculation", f_type_static); init_feature(f_ag_scalable, "scalable_group", f_type_static);
init_feature(f_ag_scalable_com, "scalable group center of mass calculation", f_type_static); init_feature(f_ag_scalable_com, "scalable_group_center_of_mass", f_type_static);
require_feature_self(f_ag_scalable, f_ag_scalable_com); require_feature_self(f_ag_scalable, f_ag_scalable_com);
// check that everything is initialized // check that everything is initialized

View File

@ -7,6 +7,9 @@
// If you wish to distribute your changes, please submit them to the // If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub. // Colvars repository at GitHub.
#include <fstream>
#include <cstring>
#include "colvarmodule.h" #include "colvarmodule.h"
#include "colvarproxy.h" #include "colvarproxy.h"
#include "colvarvalue.h" #include "colvarvalue.h"
@ -23,8 +26,12 @@ colvarbias::colvarbias(char const *key)
init_dependencies(); init_dependencies();
rank = 1; rank = 1;
time_step_factor = 1;
has_data = false; has_data = false;
b_output_energy = false; b_output_energy = false;
output_freq = cvm::restart_out_freq;
reset(); reset();
state_file_step = 0L; state_file_step = 0L;
matching_state = false; matching_state = false;
@ -93,12 +100,18 @@ int colvarbias::init(std::string const &conf)
output_prefix = cvm::output_prefix(); output_prefix = cvm::output_prefix();
get_keyval_feature(this, conf, "stepZeroData", f_cvb_step_zero_data, is_enabled(f_cvb_step_zero_data));
// Write energy to traj file?
get_keyval(conf, "outputEnergy", b_output_energy, b_output_energy); get_keyval(conf, "outputEnergy", b_output_energy, b_output_energy);
// Disabled by default in base class; default value can be overridden by derived class constructor // How often to write full output files?
get_keyval_feature(this, conf, "bypassExtendedLagrangian", f_cvb_bypass_ext_lagrangian, is_enabled(f_cvb_bypass_ext_lagrangian), parse_silent); get_keyval(conf, "outputFreq", output_freq, output_freq);
get_keyval(conf, "timeStepFactor", time_step_factor, 1); // Disabled by default in base class; default value can be overridden by derived class constructor
get_keyval_feature(this, conf, "bypassExtendedLagrangian", f_cvb_bypass_ext_lagrangian, is_enabled(f_cvb_bypass_ext_lagrangian), parse_echo);
get_keyval(conf, "timeStepFactor", time_step_factor, time_step_factor);
if (time_step_factor < 1) { if (time_step_factor < 1) {
cvm::error("Error: timeStepFactor must be 1 or greater.\n"); cvm::error("Error: timeStepFactor must be 1 or greater.\n");
return COLVARS_ERROR; return COLVARS_ERROR;
@ -125,37 +138,40 @@ int colvarbias::init_dependencies() {
init_feature(f_cvb_awake, "awake", f_type_static); init_feature(f_cvb_awake, "awake", f_type_static);
require_feature_self(f_cvb_awake, f_cvb_active); require_feature_self(f_cvb_awake, f_cvb_active);
init_feature(f_cvb_apply_force, "apply force", f_type_user); init_feature(f_cvb_step_zero_data, "step_zero_data", f_type_user);
init_feature(f_cvb_apply_force, "apply_force", f_type_user);
require_feature_children(f_cvb_apply_force, f_cv_gradient); require_feature_children(f_cvb_apply_force, f_cv_gradient);
init_feature(f_cvb_bypass_ext_lagrangian, "bypass extended-Lagrangian coordinates", f_type_user); init_feature(f_cvb_bypass_ext_lagrangian, "bypass_extended_Lagrangian_coordinates", f_type_user);
// The exclusion below prevents the inconsistency where biasing forces are applied onto // The exclusion below prevents the inconsistency where biasing forces are applied onto
// the actual colvar, while total forces are measured on the extended coordinate // the actual colvar, while total forces are measured on the extended coordinate
exclude_feature_self(f_cvb_bypass_ext_lagrangian, f_cvb_get_total_force); exclude_feature_self(f_cvb_bypass_ext_lagrangian, f_cvb_get_total_force);
init_feature(f_cvb_get_total_force, "obtain total force", f_type_dynamic); init_feature(f_cvb_get_total_force, "obtain_total_force", f_type_dynamic);
require_feature_children(f_cvb_get_total_force, f_cv_total_force); require_feature_children(f_cvb_get_total_force, f_cv_total_force);
init_feature(f_cvb_output_acc_work, "output accumulated work", f_type_user); init_feature(f_cvb_output_acc_work, "output_accumulated_work", f_type_user);
require_feature_self(f_cvb_output_acc_work, f_cvb_apply_force); require_feature_self(f_cvb_output_acc_work, f_cvb_apply_force);
init_feature(f_cvb_history_dependent, "history-dependent", f_type_static); init_feature(f_cvb_history_dependent, "history_dependent", f_type_static);
init_feature(f_cvb_time_dependent, "time-dependent", f_type_static); init_feature(f_cvb_time_dependent, "time_dependent", f_type_static);
init_feature(f_cvb_scalar_variables, "require scalar variables", f_type_static); init_feature(f_cvb_scalar_variables, "require_scalar_variables", f_type_static);
require_feature_children(f_cvb_scalar_variables, f_cv_scalar); require_feature_children(f_cvb_scalar_variables, f_cv_scalar);
init_feature(f_cvb_calc_pmf, "calculate a PMF", f_type_static); init_feature(f_cvb_calc_pmf, "calculate_a_PMF", f_type_static);
init_feature(f_cvb_calc_ti_samples, "calculate TI samples", f_type_dynamic); init_feature(f_cvb_calc_ti_samples, "calculate_TI_samples", f_type_dynamic);
require_feature_self(f_cvb_calc_ti_samples, f_cvb_get_total_force); require_feature_self(f_cvb_calc_ti_samples, f_cvb_get_total_force);
require_feature_children(f_cvb_calc_ti_samples, f_cv_grid); require_feature_children(f_cvb_calc_ti_samples, f_cv_grid);
init_feature(f_cvb_write_ti_samples, "write TI samples ", f_type_user); init_feature(f_cvb_write_ti_samples, "write_TI_samples_", f_type_user);
require_feature_self(f_cvb_write_ti_samples, f_cvb_calc_ti_samples); require_feature_self(f_cvb_write_ti_samples, f_cvb_calc_ti_samples);
init_feature(f_cvb_write_ti_pmf, "write TI PMF", f_type_user); init_feature(f_cvb_write_ti_pmf, "write_TI_PMF", f_type_user);
require_feature_self(f_cvb_write_ti_pmf, f_cvb_calc_ti_samples); require_feature_self(f_cvb_write_ti_pmf, f_cvb_calc_ti_samples);
// check that everything is initialized // check that everything is initialized
@ -237,6 +253,8 @@ int colvarbias::clear()
} }
} }
cv->config_changed();
return COLVARS_OK; return COLVARS_OK;
} }
@ -302,6 +320,17 @@ int colvarbias::update()
} }
bool colvarbias::can_accumulate_data()
{
colvarproxy *proxy = cvm::main()->proxy;
if (((cvm::step_relative() > 0) && !proxy->simulation_continuing()) ||
is_enabled(f_cvb_step_zero_data)) {
return true;
}
return false;
}
int colvarbias::calc_energy(std::vector<colvarvalue> const *) int colvarbias::calc_energy(std::vector<colvarvalue> const *)
{ {
bias_energy = 0.0; bias_energy = 0.0;
@ -451,7 +480,7 @@ std::ostream & colvarbias::write_state(std::ostream &os)
std::istream & colvarbias::read_state(std::istream &is) std::istream & colvarbias::read_state(std::istream &is)
{ {
size_t const start_pos = is.tellg(); std::streampos const start_pos = is.tellg();
std::string key, brace, conf; std::string key, brace, conf;
if ( !(is >> key) || !(key == state_keyword || key == bias_type) || if ( !(is >> key) || !(key == state_keyword || key == bias_type) ||
@ -501,12 +530,80 @@ std::istream & colvarbias::read_state(std::istream &is)
} }
int colvarbias::write_state_prefix(std::string const &prefix)
{
std::string const filename =
cvm::state_file_prefix(prefix.c_str())+".colvars.state";
std::ostream *os = cvm::proxy->output_stream(filename.c_str());
int error_code = COLVARS_OK;
if (os != NULL) {
os->setf(std::ios::scientific, std::ios::floatfield);
error_code = write_state(*os).good() ? COLVARS_OK : FILE_ERROR;
} else {
error_code = FILE_ERROR;
}
cvm::proxy->close_output_stream(filename.c_str());
return error_code;
}
int colvarbias::write_state_string(std::string &output)
{
std::ostringstream os;
if (!write_state(os)) {
return cvm::error("Error: in writing state of bias \""+name+
"\" to buffer.\n", FILE_ERROR);
}
output = os.str();
return COLVARS_OK;
}
int colvarbias::read_state_prefix(std::string const &prefix)
{
std::string filename((prefix+std::string(".colvars.state")).c_str());
std::ifstream is(filename.c_str());
if (!is.good()) {
// try without the suffix
is.clear();
filename = prefix;
is.open(filename.c_str());
}
return read_state(is).good() ? COLVARS_OK :
cvm::error("Error: in reading state for \""+name+"\" from input file \""+
std::string(filename)+"\".\n", FILE_ERROR);
}
int colvarbias::read_state_string(char const *buffer)
{
if (buffer != NULL) {
size_t const buffer_size = strlen(buffer);
if (cvm::debug()) {
cvm::log("colvarbias::read_state_string() with argument:\n");
cvm::log(buffer);
}
if (buffer_size > 0) {
std::istringstream is;
is.rdbuf()->pubsetbuf(const_cast<char *>(buffer), buffer_size);
return read_state(is).good() ? COLVARS_OK :
cvm::error("Error: in reading state for \""+name+"\" from buffer.\n",
FILE_ERROR);
}
return COLVARS_OK;
}
return cvm::error("Error: NULL pointer for colvarbias::read_state_string()",
BUG_ERROR);
}
std::istream & colvarbias::read_state_data_key(std::istream &is, char const *key) std::istream & colvarbias::read_state_data_key(std::istream &is, char const *key)
{ {
size_t const start_pos = is.tellg(); std::streampos const start_pos = is.tellg();
std::string key_in; std::string key_in;
if ( !(is >> key_in) || if ( !(is >> key_in) ||
!(key_in == to_lower_cppstr(std::string(key))) ) { !(to_lower_cppstr(key_in) == to_lower_cppstr(std::string(key))) ) {
cvm::error("Error: in reading restart configuration for "+ cvm::error("Error: in reading restart configuration for "+
bias_type+" bias \""+this->name+"\" at position "+ bias_type+" bias \""+this->name+"\" at position "+
cvm::to_str(static_cast<size_t>(is.tellg()))+ cvm::to_str(static_cast<size_t>(is.tellg()))+
@ -546,7 +643,12 @@ std::ostream & colvarbias::write_traj(std::ostream &os)
colvarbias_ti::colvarbias_ti(char const *key) colvarbias_ti::colvarbias_ti(char const *key)
: colvarbias(key) : colvarbias(key)
{ {
colvarproxy *proxy = cvm::main()->proxy;
provide(f_cvb_calc_ti_samples); provide(f_cvb_calc_ti_samples);
if (!proxy->total_forces_same_step()) {
// Samples at step zero can not be collected
feature_states[f_cvb_step_zero_data].available = false;
}
ti_avg_forces = NULL; ti_avg_forces = NULL;
ti_count = NULL; ti_count = NULL;
} }
@ -683,9 +785,11 @@ int colvarbias_ti::update_system_forces(std::vector<colvarvalue> const
(*subtract_forces)[i] : previous_colvar_forces[i]); (*subtract_forces)[i] : previous_colvar_forces[i]);
} }
} }
if (cvm::step_relative() > 0 || is_enabled(f_cvb_step_zero_data)) {
ti_avg_forces->acc_value(ti_bin, ti_system_forces); ti_avg_forces->acc_value(ti_bin, ti_system_forces);
} }
} }
}
if (!proxy->total_forces_same_step()) { if (!proxy->total_forces_same_step()) {
// Set the index for use in the next iteration, when total forces come in // Set the index for use in the next iteration, when total forces come in

View File

@ -57,6 +57,10 @@ public:
/// Some implementations may use calc_energy() and calc_forces() /// Some implementations may use calc_energy() and calc_forces()
virtual int update(); virtual int update();
/// Returns true if the current step represent a valid increment, whose data
/// can be recorded (as opposed to e.g. a continuation step from a restart)
virtual bool can_accumulate_data();
/// Compute the energy of the bias /// Compute the energy of the bias
/// Uses the vector of colvar values provided if not NULL, and the values /// Uses the vector of colvar values provided if not NULL, and the values
/// currently cached in the bias instance otherwise /// currently cached in the bias instance otherwise
@ -144,14 +148,28 @@ public:
} }
/// Read a keyword from the state data (typically a header) /// Read a keyword from the state data (typically a header)
/// \param Input stream
/// \param Keyword labeling the header block
std::istream & read_state_data_key(std::istream &is, char const *key); std::istream & read_state_data_key(std::istream &is, char const *key);
/// Write the bias configuration to a restart file or other stream /// Write the bias configuration to a state file or other stream
std::ostream & write_state(std::ostream &os); std::ostream & write_state(std::ostream &os);
/// Read the bias configuration from a restart file or other stream /// Read the bias configuration from a restart file or other stream
std::istream & read_state(std::istream &is); std::istream & read_state(std::istream &is);
/// Write the bias state to a file with the given prefix
int write_state_prefix(std::string const &prefix);
/// Write the bias state to a string
int write_state_string(std::string &output);
/// Read the bias state from a file with this name or prefix
int read_state_prefix(std::string const &prefix);
/// Read the bias state from this string buffer
int read_state_string(char const *buffer);
/// Write a label to the trajectory file (comment line) /// Write a label to the trajectory file (comment line)
virtual std::ostream & write_traj_label(std::ostream &os); virtual std::ostream & write_traj_label(std::ostream &os);
@ -164,6 +182,9 @@ public:
return COLVARS_OK; return COLVARS_OK;
} }
/// Frequency for writing output files
size_t output_freq;
/// Write any output files that this bias may have (e.g. PMF files) /// Write any output files that this bias may have (e.g. PMF files)
virtual int write_output_files() virtual int write_output_files()
{ {

View File

@ -8,7 +8,6 @@
// Colvars repository at GitHub. // Colvars repository at GitHub.
#include "colvarmodule.h" #include "colvarmodule.h"
#include "colvarproxy.h"
#include "colvar.h" #include "colvar.h"
#include "colvarbias_abf.h" #include "colvarbias_abf.h"
@ -29,7 +28,13 @@ colvarbias_abf::colvarbias_abf(char const *key)
last_gradients(NULL), last_gradients(NULL),
last_samples(NULL) last_samples(NULL)
{ {
colvarproxy *proxy = cvm::main()->proxy;
if (!proxy->total_forces_same_step()) {
// Samples at step zero can not be collected
feature_states[f_cvb_step_zero_data].available = false;
} }
}
int colvarbias_abf::init(std::string const &conf) int colvarbias_abf::init(std::string const &conf)
{ {
@ -71,8 +76,19 @@ int colvarbias_abf::init(std::string const &conf)
// full_samples - min_samples >= 1 is guaranteed // full_samples - min_samples >= 1 is guaranteed
get_keyval(conf, "inputPrefix", input_prefix, std::vector<std::string>()); get_keyval(conf, "inputPrefix", input_prefix, std::vector<std::string>());
get_keyval(conf, "outputFreq", output_freq, cvm::restart_out_freq);
get_keyval(conf, "historyFreq", history_freq, 0); get_keyval(conf, "historyFreq", history_freq, 0);
if (history_freq != 0) {
if (output_freq == 0) {
cvm::error("Error: historyFreq must be a multiple of outputFreq.\n",
INPUT_ERROR);
} else {
if ((history_freq % output_freq) != 0) {
cvm::error("Error: historyFreq must be a multiple of outputFreq.\n",
INPUT_ERROR);
}
}
}
b_history_files = (history_freq > 0); b_history_files = (history_freq > 0);
// shared ABF // shared ABF
@ -146,6 +162,7 @@ int colvarbias_abf::init(std::string const &conf)
for (i = 0; i < num_variables(); i++) { for (i = 0; i < num_variables(); i++) {
if (max_force[i] < 0.0) { if (max_force[i] < 0.0) {
cvm::error("Error: maxForce should be non-negative."); cvm::error("Error: maxForce should be non-negative.");
return COLVARS_ERROR;
} }
} }
cap_force = true; cap_force = true;
@ -184,25 +201,24 @@ int colvarbias_abf::init(std::string const &conf)
czar_gradients = new colvar_grid_gradient(colvars); czar_gradients = new colvar_grid_gradient(colvars);
} }
get_keyval(conf, "integrate", b_integrate, num_variables() <= 3); // Integrate for output if d<=3
if (b_integrate) {
// For now, we integrate on-the-fly iff the grid is < 3D // For now, we integrate on-the-fly iff the grid is < 3D
if ( num_variables() <= 3 ) { if ( num_variables() > 3 ) {
cvm::error("Error: cannot integrate free energy in dimension > 3.\n");
return COLVARS_ERROR;
}
pmf = new integrate_potential(colvars, gradients); pmf = new integrate_potential(colvars, gradients);
if ( b_CZAR_estimator ) { if ( b_CZAR_estimator ) {
czar_pmf = new integrate_potential(colvars, czar_gradients); czar_pmf = new integrate_potential(colvars, czar_gradients);
} }
get_keyval(conf, "integrate", b_integrate, true); // Integrate for output
if ( num_variables() > 1 ) {
// Projected ABF
get_keyval(conf, "pABFintegrateFreq", pabf_freq, 0);
// Parameters for integrating initial (and final) gradient data // Parameters for integrating initial (and final) gradient data
get_keyval(conf, "integrateInitMaxIterations", integrate_initial_iterations, 1e4); get_keyval(conf, "integrateMaxIterations", integrate_iterations, 1e4, colvarparse::parse_silent);
get_keyval(conf, "integrateInitTol", integrate_initial_tol, 1e-6); get_keyval(conf, "integrateTol", integrate_tol, 1e-6, colvarparse::parse_silent);
// for updating the integrated PMF on the fly // Projected ABF, updating the integrated PMF on the fly
get_keyval(conf, "integrateMaxIterations", integrate_iterations, 100); get_keyval(conf, "pABFintegrateFreq", pabf_freq, 0, colvarparse::parse_silent);
get_keyval(conf, "integrateTol", integrate_tol, 1e-4); get_keyval(conf, "pABFintegrateMaxIterations", pabf_integrate_iterations, 100, colvarparse::parse_silent);
} get_keyval(conf, "pABFintegrateTol", pabf_integrate_tol, 1e-4, colvarparse::parse_silent);
} else {
b_integrate = false;
} }
// For shared ABF, we store a second set of grids. // For shared ABF, we store a second set of grids.
@ -330,7 +346,7 @@ int colvarbias_abf::update()
force_bin = bin; force_bin = bin;
} }
if (cvm::step_relative() > 0 || cvm::proxy->total_forces_same_step()) { if (cvm::step_relative() > 0 || is_enabled(f_cvb_step_zero_data)) {
if (update_bias) { if (update_bias) {
// if (b_adiabatic_reweighting) { // if (b_adiabatic_reweighting) {
@ -370,10 +386,10 @@ int colvarbias_abf::update()
if ( b_integrate ) { if ( b_integrate ) {
if ( pabf_freq && cvm::step_relative() % pabf_freq == 0 ) { if ( pabf_freq && cvm::step_relative() % pabf_freq == 0 ) {
cvm::real err; cvm::real err;
int iter = pmf->integrate(integrate_iterations, integrate_tol, err); int iter = pmf->integrate(pabf_integrate_iterations, pabf_integrate_tol, err);
if ( iter == integrate_iterations ) { if ( iter == pabf_integrate_iterations ) {
cvm::log("Warning: PMF integration did not converge to " + cvm::to_str(integrate_tol) cvm::log("Warning: PMF integration did not converge to " + cvm::to_str(pabf_integrate_tol)
+ " in " + cvm::to_str(integrate_iterations) + " in " + cvm::to_str(pabf_integrate_iterations)
+ " steps. Residual error: " + cvm::to_str(err)); + " steps. Residual error: " + cvm::to_str(err));
} }
pmf->set_zero_minimum(); // TODO: do this only when necessary pmf->set_zero_minimum(); // TODO: do this only when necessary
@ -448,17 +464,6 @@ int colvarbias_abf::update()
output_prefix = cvm::output_prefix() + "." + this->name; output_prefix = cvm::output_prefix() + "." + this->name;
} }
if (output_freq && (cvm::step_absolute() % output_freq) == 0) {
if (cvm::debug()) cvm::log("ABF bias trying to write gradients and samples to disk");
write_gradients_samples(output_prefix);
}
if (b_history_files && (cvm::step_absolute() % history_freq) == 0) {
// file already exists iff cvm::step_relative() > 0
// otherwise, backup and replace
write_gradients_samples(output_prefix + ".hist", (cvm::step_relative() > 0));
}
if (shared_on && shared_last_step >= 0 && cvm::step_absolute() % shared_freq == 0) { if (shared_on && shared_last_step >= 0 && cvm::step_absolute() % shared_freq == 0) {
// Share gradients and samples for shared ABF. // Share gradients and samples for shared ABF.
replica_share(); replica_share();
@ -487,10 +492,10 @@ int colvarbias_abf::update()
eabf_UI.update(cvm::step_absolute(), x, y); eabf_UI.update(cvm::step_absolute(), x, y);
} }
/// Add the bias energy for 1D ABF /// Compute the bias energy
bias_energy = calc_energy(NULL); int error_code = calc_energy(NULL);
return COLVARS_OK; return error_code;
} }
@ -570,83 +575,71 @@ int colvarbias_abf::replica_share() {
last_samples->copy_grid(*samples); last_samples->copy_grid(*samples);
shared_last_step = cvm::step_absolute(); shared_last_step = cvm::step_absolute();
if (b_integrate) {
// Update divergence to account for newly shared gradients
pmf->set_div();
}
return COLVARS_OK; return COLVARS_OK;
} }
template <class T> int colvarbias_abf::write_grid_to_file(T const *grid,
void colvarbias_abf::write_gradients_samples(const std::string &prefix, bool append) std::string const &filename,
{ bool close) {
std::string samples_out_name = prefix + ".count"; std::ostream *os = cvm::proxy->output_stream(filename);
std::string gradients_out_name = prefix + ".grad"; if (!os) {
std::ios::openmode mode = (append ? std::ios::app : std::ios::out); return cvm::error("Error opening file " + filename + " for writing.\n", COLVARS_ERROR | FILE_ERROR);
}
std::ostream *samples_os = grid->write_multicol(*os);
cvm::proxy->output_stream(samples_out_name, mode); if (close) {
if (!samples_os) return; cvm::proxy->close_output_stream(filename);
samples->write_multicol(*samples_os); } else {
cvm::proxy->close_output_stream(samples_out_name); // Insert empty line between frames in history files
*os << std::endl;
// In dimension higher than 2, dx is easier to handle and visualize cvm::proxy->flush_output_stream(os);
if (num_variables() > 2) {
std::string samples_dx_out_name = prefix + ".count.dx";
std::ostream *samples_dx_os = cvm::proxy->output_stream(samples_dx_out_name, mode);
if (!samples_os) return;
samples->write_opendx(*samples_dx_os);
*samples_dx_os << std::endl;
cvm::proxy->close_output_stream(samples_dx_out_name);
} }
std::ostream *gradients_os = // In dimension higher than 2, dx is easier to handle and visualize
cvm::proxy->output_stream(gradients_out_name, mode); // but we cannot write multiple frames in a dx file now
if (!gradients_os) return; // (could be implemented as multiple dx files)
gradients->write_multicol(*gradients_os); if (num_variables() > 2 && close) {
cvm::proxy->close_output_stream(gradients_out_name); std::string dx = filename + ".dx";
std::ostream *dx_os = cvm::proxy->output_stream(dx);
if (!dx_os) {
return cvm::error("Error opening file " + dx + " for writing.\n", COLVARS_ERROR | FILE_ERROR);
}
grid->write_opendx(*dx_os);
// if (close) {
cvm::proxy->close_output_stream(dx);
// }
// else {
// // TODO, decide convention for multiple datasets in dx file
// *dx_os << std::endl;
// dx_os->flush();
// }
}
return COLVARS_OK;
}
void colvarbias_abf::write_gradients_samples(const std::string &prefix, bool close)
{
write_grid_to_file<colvar_grid_count>(samples, prefix + ".count", close);
write_grid_to_file<colvar_grid_gradient>(gradients, prefix + ".grad", close);
if (b_integrate) { if (b_integrate) {
// Do numerical integration (to high precision) and output a PMF // Do numerical integration (to high precision) and output a PMF
cvm::real err; cvm::real err;
pmf->integrate(integrate_initial_iterations, integrate_initial_tol, err); pmf->integrate(integrate_iterations, integrate_tol, err);
pmf->set_zero_minimum(); pmf->set_zero_minimum();
write_grid_to_file<colvar_grid_scalar>(pmf, prefix + ".pmf", close);
std::string pmf_out_name = prefix + ".pmf";
std::ostream *pmf_os = cvm::proxy->output_stream(pmf_out_name, mode);
if (!pmf_os) return;
pmf->write_multicol(*pmf_os);
// In dimension higher than 2, dx is easier to handle and visualize
if (num_variables() > 2) {
std::string pmf_dx_out_name = prefix + ".pmf.dx";
std::ostream *pmf_dx_os = cvm::proxy->output_stream(pmf_dx_out_name, mode);
if (!pmf_dx_os) return;
pmf->write_opendx(*pmf_dx_os);
*pmf_dx_os << std::endl;
cvm::proxy->close_output_stream(pmf_dx_out_name);
}
*pmf_os << std::endl;
cvm::proxy->close_output_stream(pmf_out_name);
} }
if (b_CZAR_estimator) { if (b_CZAR_estimator) {
// Write eABF CZAR-related quantities // Write eABF CZAR-related quantities
write_grid_to_file<colvar_grid_count>(z_samples, prefix + ".zcount", close);
std::string z_samples_out_name = prefix + ".zcount";
std::ostream *z_samples_os =
cvm::proxy->output_stream(z_samples_out_name, mode);
if (!z_samples_os) return;
z_samples->write_multicol(*z_samples_os);
cvm::proxy->close_output_stream(z_samples_out_name);
if (b_czar_window_file) { if (b_czar_window_file) {
std::string z_gradients_out_name = prefix + ".zgrad"; write_grid_to_file<colvar_grid_gradient>(z_gradients, prefix + ".zgrad", close);
std::ostream *z_gradients_os =
cvm::proxy->output_stream(z_gradients_out_name, mode);
if (!z_gradients_os) return;
z_gradients->write_multicol(*z_gradients_os);
cvm::proxy->close_output_stream(z_gradients_out_name);
} }
// Calculate CZAR estimator of gradients // Calculate CZAR estimator of gradients
@ -657,39 +650,15 @@ void colvarbias_abf::write_gradients_samples(const std::string &prefix, bool app
- cvm::temperature() * cvm::boltzmann() * z_samples->log_gradient_finite_diff(ix, n), n); - cvm::temperature() * cvm::boltzmann() * z_samples->log_gradient_finite_diff(ix, n), n);
} }
} }
write_grid_to_file<colvar_grid_gradient>(czar_gradients, prefix + ".czar.grad", close);
std::string czar_gradients_out_name = prefix + ".czar.grad";
std::ostream *czar_gradients_os =
cvm::proxy->output_stream(czar_gradients_out_name, mode);
if (!czar_gradients_os) return;
czar_gradients->write_multicol(*czar_gradients_os);
cvm::proxy->close_output_stream(czar_gradients_out_name);
if (b_integrate) { if (b_integrate) {
// Do numerical integration (to high precision) and output a PMF // Do numerical integration (to high precision) and output a PMF
cvm::real err; cvm::real err;
czar_pmf->set_div(); czar_pmf->set_div();
czar_pmf->integrate(integrate_initial_iterations, integrate_initial_tol, err); czar_pmf->integrate(integrate_iterations, integrate_tol, err);
czar_pmf->set_zero_minimum(); czar_pmf->set_zero_minimum();
write_grid_to_file<colvar_grid_scalar>(czar_pmf, prefix + ".czar.pmf", close);
std::string czar_pmf_out_name = prefix + ".czar.pmf";
std::ostream *czar_pmf_os = cvm::proxy->output_stream(czar_pmf_out_name, mode);
if (!czar_pmf_os) return;
czar_pmf->write_multicol(*czar_pmf_os);
// In dimension higher than 2, dx is easier to handle and visualize
if (num_variables() > 2) {
std::string czar_pmf_dx_out_name = prefix + ".czar.pmf.dx";
std::ostream *czar_pmf_dx_os = cvm::proxy->output_stream(czar_pmf_dx_out_name, mode);
if (!czar_pmf_dx_os) return;
czar_pmf->write_opendx(*czar_pmf_dx_os);
*czar_pmf_dx_os << std::endl;
cvm::proxy->close_output_stream(czar_pmf_dx_out_name);
}
*czar_pmf_os << std::endl;
cvm::proxy->close_output_stream(czar_pmf_out_name);
} }
} }
return; return;
@ -836,25 +805,56 @@ std::istream & colvarbias_abf::read_state_data(std::istream& is)
return is; return is;
} }
int colvarbias_abf::write_output_files() int colvarbias_abf::write_output_files()
{ {
write_gradients_samples(output_prefix); if (cvm::debug()) {
cvm::log("ABF bias trying to write gradients and samples to disk");
}
if (shared_on && cvm::main()->proxy->replica_index() > 0) {
// No need to report the same data as replica 0, let it do the I/O job
return COLVARS_OK; return COLVARS_OK;
} }
int colvarbias_abf::calc_energy(std::vector<colvarvalue> const *values) write_gradients_samples(output_prefix);
{ if (b_history_files) {
if (values) { if ((cvm::step_absolute() % history_freq) == 0) {
return cvm::error("colvarbias_abf::calc_energy() with an argument " write_gradients_samples(output_prefix + ".hist", false);
"is currently not implemented.\n", }
COLVARS_NOT_IMPLEMENTED);
} }
if (num_variables() != 1) return 0.0; if (b_UI_estimator) {
eabf_UI.calc_pmf();
eabf_UI.write_files();
}
return COLVARS_OK;
}
int colvarbias_abf::calc_energy(std::vector<colvarvalue> const *values)
{
bias_energy = 0.0; // default value, overridden if a value can be calculated
if (num_variables() > 1 || values != NULL) {
// Use simple estimate: neglect effect of fullSamples,
// return value at center of bin
if (pmf != NULL) {
std::vector<int> const curr_bin = values ?
pmf->get_colvars_index(*values) :
pmf->get_colvars_index();
if (pmf->index_ok(curr_bin)) {
bias_energy = pmf->value(curr_bin);
}
}
return COLVARS_OK;
}
// Get the home bin. // Get the home bin.
int home0 = gradients->current_bin_scalar(0); int home0 = gradients->current_bin_scalar(0);
if (home0 < 0) return 0.0; if (home0 < 0) return COLVARS_OK;
int gradient_len = (int)(gradients->number_of_points(0)); int gradient_len = (int)(gradients->number_of_points(0));
int home = (home0 < gradient_len) ? home0 : (gradient_len-1); int home = (home0 < gradient_len) ? home0 : (gradient_len-1);
@ -886,5 +886,6 @@ int colvarbias_abf::calc_energy(std::vector<colvarvalue> const *values)
sum += fact*gradients->value(ix)/count*gradients->widths[0]*frac; sum += fact*gradients->value(ix)/count*gradients->widths[0]*frac;
// The applied potential is the negative integral of force samples. // The applied potential is the negative integral of force samples.
return -sum; bias_energy = -sum;
return COLVARS_OK;
} }

View File

@ -15,6 +15,7 @@
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
#include "colvarproxy.h"
#include "colvarbias.h" #include "colvarbias.h"
#include "colvargrid.h" #include "colvargrid.h"
#include "colvar_UIestimator.h" #include "colvar_UIestimator.h"
@ -56,8 +57,6 @@ private:
size_t full_samples; size_t full_samples;
/// Number of samples per bin before applying a scaled-down biasing force /// Number of samples per bin before applying a scaled-down biasing force
size_t min_samples; size_t min_samples;
/// frequency for updating output files
int output_freq;
/// Write combined files with a history of all output data? /// Write combined files with a history of all output data?
bool b_history_files; bool b_history_files;
/// Write CZAR output file for stratified eABF (.zgrad) /// Write CZAR output file for stratified eABF (.zgrad)
@ -74,13 +73,13 @@ private:
/// Frequency for updating pABF PMF (if zero, pABF is not used) /// Frequency for updating pABF PMF (if zero, pABF is not used)
int pabf_freq; int pabf_freq;
/// Max number of CG iterations for integrating PMF at startup and for file output /// Max number of CG iterations for integrating PMF at startup and for file output
int integrate_initial_iterations;
/// Tolerance for integrating PMF at startup and for file output
cvm::real integrate_initial_tol;
/// Max number of CG iterations for integrating PMF at on-the-fly pABF updates
int integrate_iterations; int integrate_iterations;
/// Tolerance for integrating PMF at on-the-fly pABF updates /// Tolerance for integrating PMF at startup and for file output
cvm::real integrate_tol; cvm::real integrate_tol;
/// Max number of CG iterations for integrating PMF at on-the-fly pABF updates
int pabf_integrate_iterations;
/// Tolerance for integrating PMF at on-the-fly pABF updates
cvm::real pabf_integrate_tol;
/// Cap the biasing force to be applied? (option maxForce) /// Cap the biasing force to be applied? (option maxForce)
bool cap_force; bool cap_force;
@ -151,11 +150,16 @@ private:
virtual int bin_count(int bin_index); virtual int bin_count(int bin_index);
/// Write human-readable FE gradients and sample count, and DX file in dim > 2 /// Write human-readable FE gradients and sample count, and DX file in dim > 2
void write_gradients_samples(const std::string &prefix, bool append = false); void write_gradients_samples(const std::string &prefix, bool close = true);
/// Read human-readable FE gradients and sample count (if not using restart) /// Read human-readable FE gradients and sample count (if not using restart)
void read_gradients_samples(); void read_gradients_samples();
/// Template used in write_gradient_samples()
template <class T> int write_grid_to_file(T const *grid,
std::string const &name,
bool close);
virtual std::istream& read_state_data(std::istream&); virtual std::istream& read_state_data(std::istream&);
virtual std::ostream& write_state_data(std::ostream&); virtual std::ostream& write_state_data(std::ostream&);
virtual int write_output_files(); virtual int write_output_files();

View File

@ -30,9 +30,10 @@ int colvarbias_histogram::init(std::string const &conf)
size_t i; size_t i;
get_keyval(conf, "outputFile", out_name, std::string("")); get_keyval(conf, "outputFile", out_name, "");
get_keyval(conf, "outputFileDX", out_name_dx, std::string("")); // Write DX file by default only in dimension >= 3
get_keyval(conf, "outputFreq", output_freq, cvm::restart_out_freq); std::string default_name_dx = this->num_variables() > 2 ? "" : "none";
get_keyval(conf, "outputFileDX", out_name_dx, default_name_dx);
/// with VMD, this may not be an error /// with VMD, this may not be an error
// if ( output_freq == 0 ) { // if ( output_freq == 0 ) {
@ -146,9 +147,11 @@ int colvarbias_histogram::update()
bin[i] = grid->current_bin_scalar(i); bin[i] = grid->current_bin_scalar(i);
} }
if (can_accumulate_data()) {
if (grid->index_ok(bin)) { if (grid->index_ok(bin)) {
grid->acc_value(bin, 1.0); grid->acc_value(bin, 1.0);
} }
}
} else { } else {
// update indices for vector/array values // update indices for vector/array values
size_t iv, i; size_t iv, i;
@ -163,10 +166,6 @@ int colvarbias_histogram::update()
} }
} }
if (output_freq && (cvm::step_absolute() % output_freq) == 0) {
write_output_files();
}
error_code |= cvm::get_error(); error_code |= cvm::get_error();
return error_code; return error_code;
} }
@ -179,7 +178,7 @@ int colvarbias_histogram::write_output_files()
return COLVARS_OK; return COLVARS_OK;
} }
if (out_name.size()) { if (out_name.size() && out_name != "none") {
cvm::log("Writing the histogram file \""+out_name+"\".\n"); cvm::log("Writing the histogram file \""+out_name+"\".\n");
cvm::backup_file(out_name.c_str()); cvm::backup_file(out_name.c_str());
std::ostream *grid_os = cvm::proxy->output_stream(out_name); std::ostream *grid_os = cvm::proxy->output_stream(out_name);
@ -191,7 +190,7 @@ int colvarbias_histogram::write_output_files()
cvm::proxy->close_output_stream(out_name); cvm::proxy->close_output_stream(out_name);
} }
if (out_name_dx.size()) { if (out_name_dx.size() && out_name_dx != "none") {
cvm::log("Writing the histogram file \""+out_name_dx+"\".\n"); cvm::log("Writing the histogram file \""+out_name_dx+"\".\n");
cvm::backup_file(out_name_dx.c_str()); cvm::backup_file(out_name_dx.c_str());
std::ostream *grid_os = cvm::proxy->output_stream(out_name_dx); std::ostream *grid_os = cvm::proxy->output_stream(out_name_dx);

View File

@ -566,8 +566,8 @@ int colvarbias_meta::update_grid_params()
int colvarbias_meta::update_bias() int colvarbias_meta::update_bias()
{ {
// add a new hill if the required time interval has passed // add a new hill if the required time interval has passed
if ((cvm::step_absolute() % new_hill_freq) == 0 && if (((cvm::step_absolute() % new_hill_freq) == 0) &&
is_enabled(f_cvb_history_dependent)) { can_accumulate_data() && is_enabled(f_cvb_history_dependent)) {
if (cvm::debug()) { if (cvm::debug()) {
cvm::log("Metadynamics bias \""+this->name+"\""+ cvm::log("Metadynamics bias \""+this->name+"\""+
@ -883,7 +883,7 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first,
// TODO: improve it by looping over a small subgrid instead of the whole grid // TODO: improve it by looping over a small subgrid instead of the whole grid
std::vector<colvarvalue> colvar_values(num_variables()); std::vector<colvarvalue> new_colvar_values(num_variables());
std::vector<cvm::real> colvar_forces_scalar(num_variables()); std::vector<cvm::real> colvar_forces_scalar(num_variables());
std::vector<int> he_ix = he->new_index(); std::vector<int> he_ix = he->new_index();
@ -902,17 +902,17 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first,
count++) { count++) {
size_t i; size_t i;
for (i = 0; i < num_variables(); i++) { for (i = 0; i < num_variables(); i++) {
colvar_values[i] = hills_energy->bin_to_value_scalar(he_ix[i], i); new_colvar_values[i] = hills_energy->bin_to_value_scalar(he_ix[i], i);
} }
// loop over the hills and increment the energy grid locally // loop over the hills and increment the energy grid locally
hills_energy_here = 0.0; hills_energy_here = 0.0;
calc_hills(h_first, h_last, hills_energy_here, &colvar_values); calc_hills(h_first, h_last, hills_energy_here, &new_colvar_values);
he->acc_value(he_ix, hills_energy_here); he->acc_value(he_ix, hills_energy_here);
for (i = 0; i < num_variables(); i++) { for (i = 0; i < num_variables(); i++) {
hills_forces_here[i].reset(); hills_forces_here[i].reset();
calc_hills_force(i, h_first, h_last, hills_forces_here, &colvar_values); calc_hills_force(i, h_first, h_last, hills_forces_here, &new_colvar_values);
colvar_forces_scalar[i] = hills_forces_here[i].real_value; colvar_forces_scalar[i] = hills_forces_here[i].real_value;
} }
hg->acc_force(hg_ix, &(colvar_forces_scalar.front())); hg->acc_force(hg_ix, &(colvar_forces_scalar.front()));
@ -935,16 +935,18 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first,
} else { } else {
// TODO delete this (never used)
// simpler version, with just the energy // simpler version, with just the energy
for ( ; (he->index_ok(he_ix)); ) { for ( ; (he->index_ok(he_ix)); ) {
for (size_t i = 0; i < num_variables(); i++) { for (size_t i = 0; i < num_variables(); i++) {
colvar_values[i] = hills_energy->bin_to_value_scalar(he_ix[i], i); new_colvar_values[i] = hills_energy->bin_to_value_scalar(he_ix[i], i);
} }
hills_energy_here = 0.0; hills_energy_here = 0.0;
calc_hills(h_first, h_last, hills_energy_here, &colvar_values); calc_hills(h_first, h_last, hills_energy_here, &new_colvar_values);
he->acc_value(he_ix, hills_energy_here); he->acc_value(he_ix, hills_energy_here);
he->incr(he_ix); he->incr(he_ix);
@ -1240,7 +1242,7 @@ void colvarbias_meta::read_replica_files()
// test whether this is the end of the file // test whether this is the end of the file
is.seekg(0, std::ios::end); is.seekg(0, std::ios::end);
if (is.tellg() > (replicas[ir])->replica_hills_file_pos+1) { if (is.tellg() > (replicas[ir])->replica_hills_file_pos + ((std::streampos) 1)) {
(replicas[ir])->update_status++; (replicas[ir])->update_status++;
} else { } else {
(replicas[ir])->update_status = 0; (replicas[ir])->update_status = 0;
@ -1324,7 +1326,7 @@ std::istream & colvarbias_meta::read_state_data(std::istream& is)
hills_energy_gradients = new colvar_grid_gradient(colvars); hills_energy_gradients = new colvar_grid_gradient(colvars);
} }
size_t const hills_energy_pos = is.tellg(); std::streampos const hills_energy_pos = is.tellg();
std::string key; std::string key;
if (!(is >> key)) { if (!(is >> key)) {
if (hills_energy_backup != NULL) { if (hills_energy_backup != NULL) {
@ -1363,7 +1365,7 @@ std::istream & colvarbias_meta::read_state_data(std::istream& is)
} }
} }
size_t const hills_energy_gradients_pos = is.tellg(); std::streampos const hills_energy_gradients_pos = is.tellg();
if (!(is >> key)) { if (!(is >> key)) {
if (hills_energy_backup != NULL) { if (hills_energy_backup != NULL) {
delete hills_energy; delete hills_energy;
@ -1511,7 +1513,7 @@ std::istream & colvarbias_meta::read_hill(std::istream &is)
{ {
if (!is) return is; // do nothing if failbit is set if (!is) return is; // do nothing if failbit is set
size_t const start_pos = is.tellg(); std::streampos const start_pos = is.tellg();
size_t i = 0; size_t i = 0;
std::string data; std::string data;
@ -1958,11 +1960,12 @@ colvarbias_meta::hill::hill(cvm::step_number it_in,
colvarbias_meta::hill::hill(colvarbias_meta::hill const &h) colvarbias_meta::hill::hill(colvarbias_meta::hill const &h)
: sW(1.0), : it(h.it),
hill_value(0.0),
sW(1.0),
W(h.W), W(h.W),
centers(h.centers), centers(h.centers),
sigmas(h.sigmas), sigmas(h.sigmas),
it(h.it),
replica(h.replica) replica(h.replica)
{} {}

View File

@ -257,7 +257,7 @@ protected:
std::string replica_hills_file; std::string replica_hills_file;
/// Position within replica_hills_file (when reading it) /// Position within replica_hills_file (when reading it)
int replica_hills_file_pos; std::streampos replica_hills_file_pos;
}; };

View File

@ -169,7 +169,7 @@ cvm::atom_group *colvar::cvc::parse_group(std::string const &conf,
group->check_keywords(group_conf, group_key); group->check_keywords(group_conf, group_key);
if (cvm::get_error()) { if (cvm::get_error()) {
cvm::error("Error parsing definition for atom group \""+ cvm::error("Error parsing definition for atom group \""+
std::string(group_key)+"\"\n.", INPUT_ERROR); std::string(group_key)+"\".", INPUT_ERROR);
} }
cvm::decrease_depth(); cvm::decrease_depth();
@ -200,40 +200,40 @@ int colvar::cvc::init_dependencies() {
init_feature(f_cvc_periodic, "periodic", f_type_static); init_feature(f_cvc_periodic, "periodic", f_type_static);
init_feature(f_cvc_width, "defined width", f_type_static); init_feature(f_cvc_width, "defined_width", f_type_static);
init_feature(f_cvc_lower_boundary, "defined lower boundary", f_type_static); init_feature(f_cvc_lower_boundary, "defined_lower_boundary", f_type_static);
init_feature(f_cvc_upper_boundary, "defined upper boundary", f_type_static); init_feature(f_cvc_upper_boundary, "defined_upper_boundary", f_type_static);
init_feature(f_cvc_gradient, "gradient", f_type_dynamic); init_feature(f_cvc_gradient, "gradient", f_type_dynamic);
init_feature(f_cvc_explicit_gradient, "explicit gradient", f_type_static); init_feature(f_cvc_explicit_gradient, "explicit_gradient", f_type_static);
require_feature_children(f_cvc_explicit_gradient, f_ag_explicit_gradient); require_feature_children(f_cvc_explicit_gradient, f_ag_explicit_gradient);
init_feature(f_cvc_inv_gradient, "inverse gradient", f_type_dynamic); init_feature(f_cvc_inv_gradient, "inverse_gradient", f_type_dynamic);
require_feature_self(f_cvc_inv_gradient, f_cvc_gradient); require_feature_self(f_cvc_inv_gradient, f_cvc_gradient);
init_feature(f_cvc_debug_gradient, "debug gradient", f_type_user); init_feature(f_cvc_debug_gradient, "debug_gradient", f_type_user);
require_feature_self(f_cvc_debug_gradient, f_cvc_gradient); require_feature_self(f_cvc_debug_gradient, f_cvc_gradient);
require_feature_self(f_cvc_debug_gradient, f_cvc_explicit_gradient); require_feature_self(f_cvc_debug_gradient, f_cvc_explicit_gradient);
init_feature(f_cvc_Jacobian, "Jacobian derivative", f_type_dynamic); init_feature(f_cvc_Jacobian, "Jacobian_derivative", f_type_dynamic);
require_feature_self(f_cvc_Jacobian, f_cvc_inv_gradient); require_feature_self(f_cvc_Jacobian, f_cvc_inv_gradient);
// Compute total force on first site only to avoid unwanted // Compute total force on first site only to avoid unwanted
// coupling to other colvars (see e.g. Ciccotti et al., 2005) // coupling to other colvars (see e.g. Ciccotti et al., 2005)
init_feature(f_cvc_one_site_total_force, "compute total force from one group", f_type_user); init_feature(f_cvc_one_site_total_force, "total_force_from_one_group", f_type_user);
require_feature_self(f_cvc_one_site_total_force, f_cvc_com_based); require_feature_self(f_cvc_one_site_total_force, f_cvc_com_based);
init_feature(f_cvc_com_based, "depends on group centers of mass", f_type_static); init_feature(f_cvc_com_based, "function_of_centers_of_mass", f_type_static);
init_feature(f_cvc_pbc_minimum_image, "use minimum-image distances with PBCs", f_type_user); init_feature(f_cvc_pbc_minimum_image, "use_minimum-image_with_PBCs", f_type_user);
init_feature(f_cvc_scalable, "scalable calculation", f_type_static); init_feature(f_cvc_scalable, "scalable_calculation", f_type_static);
require_feature_self(f_cvc_scalable, f_cvc_scalable_com); require_feature_self(f_cvc_scalable, f_cvc_scalable_com);
init_feature(f_cvc_scalable_com, "scalable calculation of centers of mass", f_type_static); init_feature(f_cvc_scalable_com, "scalable_calculation_of_centers_of_mass", f_type_static);
require_feature_self(f_cvc_scalable_com, f_cvc_com_based); require_feature_self(f_cvc_scalable_com, f_cvc_com_based);
@ -626,6 +626,7 @@ void colvar::cvc::wrap(colvarvalue & /* x_unwrapped */) const
} }
// Static members // Static members
std::vector<colvardeps::feature *> colvar::cvc::cvc_features; std::vector<colvardeps::feature *> colvar::cvc::cvc_features;

View File

@ -1358,8 +1358,14 @@ protected:
cvm::atom_group *atoms; cvm::atom_group *atoms;
/// Reference coordinates (for RMSD calculation only) /// Reference coordinates (for RMSD calculation only)
/// Includes sets with symmetry permutations (n_permutations * n_atoms)
std::vector<cvm::atom_pos> ref_pos; std::vector<cvm::atom_pos> ref_pos;
/// Number of permutations of symmetry-related atoms
size_t n_permutations;
/// Index of the permutation yielding the smallest RMSD (0 for identity)
size_t best_perm_index;
public: public:
/// Constructor /// Constructor
@ -1487,8 +1493,6 @@ class colvar::linearCombination
: public colvar::cvc : public colvar::cvc
{ {
protected: protected:
/// Map from string to the types of colvar components
std::map<std::string, std::function<colvar::cvc* (const std::string& subcv_conf)>> string_cv_map;
/// Sub-colvar components /// Sub-colvar components
std::vector<colvar::cvc*> cv; std::vector<colvar::cvc*> cv;
/// If all sub-cvs use explicit gradients then we also use it /// If all sub-cvs use explicit gradients then we also use it
@ -1508,8 +1512,6 @@ class colvar::CVBasedPath
: public colvar::cvc : public colvar::cvc
{ {
protected: protected:
/// Map from string to the types of colvar components
std::map<std::string, std::function<colvar::cvc* (const std::string& subcv_conf)>> string_cv_map;
/// Sub-colvar components /// Sub-colvar components
std::vector<colvar::cvc*> cv; std::vector<colvar::cvc*> cv;
/// Reference colvar values from path /// Reference colvar values from path
@ -1661,6 +1663,33 @@ public:
#endif // C++11 checking #endif // C++11 checking
// \brief Colvar component: total value of a scalar map
// (usually implemented as a grid by the simulation engine)
class colvar::map_total
: public colvar::cvc
{
public:
map_total();
map_total(std::string const &conf);
virtual ~map_total() {}
virtual int init(std::string const &conf);
virtual void calc_value();
virtual void calc_gradients();
virtual void apply_force(colvarvalue const &force);
protected:
/// Identifier of the map object (as used by the simulation engine)
std::string map_name;
/// Index of the map objet in the proxy arrays
int volmap_index;
};
// metrics functions for cvc implementations // metrics functions for cvc implementations
// simple definitions of the distance functions; these are useful only // simple definitions of the distance functions; these are useful only
@ -1691,6 +1720,6 @@ public:
{ \ { \
return this->dist2_lgrad(x2, x1); \ return this->dist2_lgrad(x2, x1); \
} \ } \
\
#endif #endif

View File

@ -7,6 +7,8 @@
// If you wish to distribute your changes, please submit them to the // If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub. // Colvars repository at GitHub.
#include <algorithm>
#include "colvarmodule.h" #include "colvarmodule.h"
#include "colvarvalue.h" #include "colvarvalue.h"
#include "colvarparse.h" #include "colvarparse.h"
@ -1045,6 +1047,44 @@ colvar::rmsd::rmsd(std::string const &conf)
// this is only required for ABF, but we do both groups here for better caching // this is only required for ABF, but we do both groups here for better caching
atoms->rot.request_group2_gradients(atoms->size()); atoms->rot.request_group2_gradients(atoms->size());
} }
std::string perm_conf;
size_t pos = 0; // current position in config string
n_permutations = 1;
while (key_lookup(conf, "atomPermutation", &perm_conf, &pos)) {
std::vector<size_t> perm;
if (perm_conf.size()) {
std::istringstream is(perm_conf);
size_t index;
while (is >> index) {
std::vector<int> const &ids = atoms->ids();
size_t const ia = std::find(ids.begin(), ids.end(), index-1) - ids.begin();
if (ia == atoms->size()) {
cvm::error("Error: atom id " + cvm::to_str(index) +
" is not a member of group \"atoms\".");
return;
}
if (std::find(perm.begin(), perm.end(), ia) != perm.end()) {
cvm::error("Error: atom id " + cvm::to_str(index) +
" is mentioned more than once in atomPermutation list.");
return;
}
perm.push_back(ia);
}
if (perm.size() != atoms->size()) {
cvm::error("Error: symmetry permutation in input contains " + cvm::to_str(perm.size()) +
" indices, but group \"atoms\" contains " + cvm::to_str(atoms->size()) + " atoms.");
return;
}
cvm::log("atomPermutation = " + cvm::to_str(perm));
n_permutations++;
// Record a copy of reference positions in new order
for (size_t ia = 0; ia < atoms->size(); ia++) {
ref_pos.push_back(ref_pos[perm[ia]]);
}
}
}
} }
@ -1056,6 +1096,20 @@ void colvar::rmsd::calc_value()
for (size_t ia = 0; ia < atoms->size(); ia++) { for (size_t ia = 0; ia < atoms->size(); ia++) {
x.real_value += ((*atoms)[ia].pos - ref_pos[ia]).norm2(); x.real_value += ((*atoms)[ia].pos - ref_pos[ia]).norm2();
} }
best_perm_index = 0;
// Compute sum of squares for each symmetry permutation of atoms, keep the smallest
size_t ref_pos_index = atoms->size();
for (size_t ip = 1; ip < n_permutations; ip++) {
cvm::real value = 0.0;
for (size_t ia = 0; ia < atoms->size(); ia++) {
value += ((*atoms)[ia].pos - ref_pos[ref_pos_index++]).norm2();
}
if (value < x.real_value) {
x.real_value = value;
best_perm_index = ip;
}
}
x.real_value /= cvm::real(atoms->size()); // MSD x.real_value /= cvm::real(atoms->size()); // MSD
x.real_value = cvm::sqrt(x.real_value); x.real_value = cvm::sqrt(x.real_value);
} }
@ -1067,8 +1121,10 @@ void colvar::rmsd::calc_gradients()
0.5 / (x.real_value * cvm::real(atoms->size())) : 0.5 / (x.real_value * cvm::real(atoms->size())) :
0.0; 0.0;
// Use the appropriate symmetry permutation of reference positions to calculate gradients
size_t const start = atoms->size() * best_perm_index;
for (size_t ia = 0; ia < atoms->size(); ia++) { for (size_t ia = 0; ia < atoms->size(); ia++) {
(*atoms)[ia].grad = (drmsddx2 * 2.0 * ((*atoms)[ia].pos - ref_pos[ia])); (*atoms)[ia].grad = (drmsddx2 * 2.0 * ((*atoms)[ia].pos - ref_pos[start + ia]));
} }
} }

View File

@ -19,10 +19,6 @@
#include "colvar.h" #include "colvar.h"
#include "colvarcomp.h" #include "colvarcomp.h"
namespace GeometricPathCV {
void init_string_cv_map(std::map<std::string, std::function<colvar::cvc* (const std::string& conf)>>& string_cv_map);
}
bool compareColvarComponent(colvar::cvc *i, colvar::cvc *j) bool compareColvarComponent(colvar::cvc *i, colvar::cvc *j)
{ {
return i->name < j->name; return i->name < j->name;
@ -406,9 +402,8 @@ void colvar::gzpath::apply_force(colvarvalue const &force) {
} }
colvar::linearCombination::linearCombination(std::string const &conf): cvc(conf) { colvar::linearCombination::linearCombination(std::string const &conf): cvc(conf) {
GeometricPathCV::init_string_cv_map(string_cv_map);
// Lookup all available sub-cvcs // Lookup all available sub-cvcs
for (auto it_cv_map = string_cv_map.begin(); it_cv_map != string_cv_map.end(); ++it_cv_map) { for (auto it_cv_map = colvar::get_global_cvc_map().begin(); it_cv_map != colvar::get_global_cvc_map().end(); ++it_cv_map) {
if (key_lookup(conf, it_cv_map->first.c_str())) { if (key_lookup(conf, it_cv_map->first.c_str())) {
std::vector<std::string> sub_cvc_confs; std::vector<std::string> sub_cvc_confs;
get_key_string_multi_value(conf, it_cv_map->first.c_str(), sub_cvc_confs); get_key_string_multi_value(conf, it_cv_map->first.c_str(), sub_cvc_confs);
@ -506,9 +501,8 @@ void colvar::linearCombination::apply_force(colvarvalue const &force) {
} }
colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) { colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) {
GeometricPathCV::init_string_cv_map(string_cv_map);
// Lookup all available sub-cvcs // Lookup all available sub-cvcs
for (auto it_cv_map = string_cv_map.begin(); it_cv_map != string_cv_map.end(); ++it_cv_map) { for (auto it_cv_map = colvar::get_global_cvc_map().begin(); it_cv_map != colvar::get_global_cvc_map().end(); ++it_cv_map) {
if (key_lookup(conf, it_cv_map->first.c_str())) { if (key_lookup(conf, it_cv_map->first.c_str())) {
std::vector<std::string> sub_cvc_confs; std::vector<std::string> sub_cvc_confs;
get_key_string_multi_value(conf, it_cv_map->first.c_str(), sub_cvc_confs); get_key_string_multi_value(conf, it_cv_map->first.c_str(), sub_cvc_confs);
@ -909,33 +903,4 @@ void colvar::gzpathCV::apply_force(colvarvalue const &force) {
} }
} }
void GeometricPathCV::init_string_cv_map(std::map<std::string, std::function<colvar::cvc* (const std::string& subcv_conf)>>& string_cv_map) {
string_cv_map["distance"] = [](const std::string& conf){return new colvar::distance(conf);};
string_cv_map["dihedral"] = [](const std::string& conf){return new colvar::dihedral(conf);};
string_cv_map["angle"] = [](const std::string& conf){return new colvar::angle(conf);};
string_cv_map["rmsd"] = [](const std::string& conf){return new colvar::rmsd(conf);};
string_cv_map["gyration"] = [](const std::string& conf){return new colvar::gyration(conf);};
string_cv_map["inertia"] = [](const std::string& conf){return new colvar::inertia(conf);};
string_cv_map["inertiaZ"] = [](const std::string& conf){return new colvar::inertia_z(conf);};
string_cv_map["tilt"] = [](const std::string& conf){return new colvar::tilt(conf);};
string_cv_map["distanceZ"] = [](const std::string& conf){return new colvar::distance_z(conf);};
string_cv_map["distanceXY"] = [](const std::string& conf){return new colvar::distance_xy(conf);};
string_cv_map["polarTheta"] = [](const std::string& conf){return new colvar::polar_theta(conf);};
string_cv_map["polarPhi"] = [](const std::string& conf){return new colvar::polar_phi(conf);};
string_cv_map["distanceVec"] = [](const std::string& conf){return new colvar::distance_vec(conf);};
string_cv_map["orientationAngle"] = [](const std::string& conf){return new colvar::orientation_angle(conf);};
string_cv_map["distancePairs"] = [](const std::string& conf){return new colvar::distance_pairs(conf);};
string_cv_map["dipoleMagnitude"] = [](const std::string& conf){return new colvar::dipole_magnitude(conf);};
string_cv_map["coordNum"] = [](const std::string& conf){return new colvar::coordnum(conf);};
string_cv_map["selfCoordNum"] = [](const std::string& conf){return new colvar::selfcoordnum(conf);};
string_cv_map["dipoleAngle"] = [](const std::string& conf){return new colvar::dipole_angle(conf);};
string_cv_map["orientation"] = [](const std::string& conf){return new colvar::orientation(conf);};
string_cv_map["orientationProj"] = [](const std::string& conf){return new colvar::orientation_proj(conf);};
string_cv_map["eigenvector"] = [](const std::string& conf){return new colvar::eigenvector(conf);};
string_cv_map["cartesian"] = [](const std::string& conf){return new colvar::cartesian(conf);};
string_cv_map["alpha"] = [](const std::string& conf){return new colvar::alpha_angles(conf);};
string_cv_map["dihedralPC"] = [](const std::string& conf){return new colvar::dihedPC(conf);};
string_cv_map["linearCombination"] = [](const std::string& conf){return new colvar::linearCombination(conf);};
}
#endif #endif

View File

@ -0,0 +1,60 @@
// -*- c++ -*-
// This file is part of the Collective Variables module (Colvars).
// The original version of Colvars and its updates are located at:
// https://github.com/Colvars/colvars
// Please update all Colvars source files before making any changes.
// If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub.
#include "colvarmodule.h"
#include "colvarvalue.h"
#include "colvarparse.h"
#include "colvar.h"
#include "colvarcomp.h"
colvar::map_total::map_total()
: cvc(), volmap_index(-1)
{
function_type = "map_total";
x.type(colvarvalue::type_scalar);
}
colvar::map_total::map_total(std::string const &conf)
: cvc(), volmap_index(-1)
{
function_type = "map_total";
x.type(colvarvalue::type_scalar);
map_total::init(conf);
}
int colvar::map_total::init(std::string const &conf)
{
int error_code = cvc::init(conf);
get_keyval(conf, "mapName", map_name, map_name);
volmap_index = (cvm::proxy)->init_volmap(map_name);
error_code |= volmap_index > 0 ? COLVARS_OK : INPUT_ERROR;
return error_code;
}
void colvar::map_total::calc_value()
{
x.real_value = (cvm::proxy)->get_volmap_value(volmap_index);
}
void colvar::map_total::calc_gradients()
{
// Atomic coordinates are not available here
}
void colvar::map_total::apply_force(colvarvalue const &force)
{
(cvm::proxy)->apply_volmap_force(volmap_index, force.real_value);
}

View File

@ -115,7 +115,9 @@ bool colvardeps::get_keyval_feature(colvarparse *cvp,
} }
bool value; bool value;
bool const found = cvp->get_keyval(conf, key, value, def_value, parse_mode); bool const found = cvp->get_keyval(conf, key, value, def_value, parse_mode);
if (value) enable(feature_id); // If the default value is on, this function should be able to disable the feature!
set_enabled(feature_id, value);
return found; return found;
} }

View File

@ -227,6 +227,8 @@ public:
f_cvb_active, f_cvb_active,
/// \brief Bias is awake (active on its own accord) this timestep /// \brief Bias is awake (active on its own accord) this timestep
f_cvb_awake, f_cvb_awake,
/// Accumulates data starting from step 0 of a simulation run
f_cvb_step_zero_data,
/// \brief will apply forces /// \brief will apply forces
f_cvb_apply_force, f_cvb_apply_force,
/// \brief force this bias to act on actual value for extended-Lagrangian coordinates /// \brief force this bias to act on actual value for extended-Lagrangian coordinates
@ -302,6 +304,10 @@ public:
f_cv_hard_lower_boundary, f_cv_hard_lower_boundary,
/// \brief The upper boundary is not defined from user's choice /// \brief The upper boundary is not defined from user's choice
f_cv_hard_upper_boundary, f_cv_hard_upper_boundary,
/// \brief Reflecting lower boundary condition
f_cv_reflecting_lower_boundary,
/// \brief Reflecting upper boundary condition
f_cv_reflecting_upper_boundary,
/// \brief Provide a discretization of the values of the colvar to /// \brief Provide a discretization of the values of the colvar to
/// be used by the biases or in analysis (needs lower and upper /// be used by the biases or in analysis (needs lower and upper
/// boundary) /// boundary)

View File

@ -239,19 +239,21 @@ public:
} }
/// \brief Constructor from a vector of colvars /// \brief Constructor from a vector of colvars
/// \param add_extra_bin requests that non-periodic dimensions are extended
/// by 1 bin to accommodate the integral (PMF) of another gridded quantity (gradient)
colvar_grid(std::vector<colvar *> const &colvars, colvar_grid(std::vector<colvar *> const &colvars,
T const &t = T(), T const &t = T(),
size_t mult_i = 1, size_t mult_i = 1,
bool margin = false) bool add_extra_bin = false)
: has_data(false) : has_data(false)
{ {
this->init_from_colvars(colvars, t, mult_i, margin); this->init_from_colvars(colvars, t, mult_i, add_extra_bin);
} }
int init_from_colvars(std::vector<colvar *> const &colvars, int init_from_colvars(std::vector<colvar *> const &colvars,
T const &t = T(), T const &t = T(),
size_t mult_i = 1, size_t mult_i = 1,
bool margin = false) bool add_extra_bin = false)
{ {
if (cvm::debug()) { if (cvm::debug()) {
cvm::log("Reading grid configuration from collective variables.\n"); cvm::log("Reading grid configuration from collective variables.\n");
@ -299,7 +301,7 @@ public:
use_actual_value[i-1] = true; use_actual_value[i-1] = true;
} }
if (margin) { if (add_extra_bin) {
if (periodic[i]) { if (periodic[i]) {
// Shift the grid by half the bin width (values at edges instead of center of bins) // Shift the grid by half the bin width (values at edges instead of center of bins)
lower_boundaries.push_back(cv[i]->lower_boundary.real_value - 0.5 * widths[i]); lower_boundaries.push_back(cv[i]->lower_boundary.real_value - 0.5 * widths[i]);
@ -699,7 +701,7 @@ public:
} }
if (scale_factor != 1.0) if (scale_factor != 1.0)
for (size_t i = 0; i < data.size(); i++) { for (size_t i = 0; i < data.size(); i++) {
data[i] += scale_factor * other_grid.data[i]; data[i] += static_cast<T>(scale_factor * other_grid.data[i]);
} }
else else
// skip multiplication if possible // skip multiplication if possible
@ -712,7 +714,7 @@ public:
/// \brief Return the value suitable for output purposes (so that it /// \brief Return the value suitable for output purposes (so that it
/// may be rescaled or manipulated without changing it permanently) /// may be rescaled or manipulated without changing it permanently)
virtual inline T value_output(std::vector<int> const &ix, virtual inline T value_output(std::vector<int> const &ix,
size_t const &imult = 0) size_t const &imult = 0) const
{ {
return value(ix, imult); return value(ix, imult);
} }
@ -820,6 +822,8 @@ public:
std::vector<int> old_nx = nx; std::vector<int> old_nx = nx;
std::vector<colvarvalue> old_lb = lower_boundaries; std::vector<colvarvalue> old_lb = lower_boundaries;
std::vector<colvarvalue> old_ub = upper_boundaries;
std::vector<cvm::real> old_w = widths;
{ {
size_t nd_in = 0; size_t nd_in = 0;
@ -858,12 +862,15 @@ public:
if (! periodic.size()) periodic.assign(nd, false); if (! periodic.size()) periodic.assign(nd, false);
if (! widths.size()) widths.assign(nd, 1.0); if (! widths.size()) widths.assign(nd, 1.0);
cvm::real eps = 1.e-10;
bool new_params = false; bool new_params = false;
if (old_nx.size()) { if (old_nx.size()) {
for (size_t i = 0; i < nd; i++) { for (size_t i = 0; i < nd; i++) {
if ( (old_nx[i] != nx[i]) || if (old_nx[i] != nx[i] ||
(cvm::sqrt(cv[i]->dist2(old_lb[i], cvm::sqrt(cv[i]->dist2(old_lb[i], lower_boundaries[i])) > eps ||
lower_boundaries[i])) > 1.0E-10) ) { cvm::sqrt(cv[i]->dist2(old_ub[i], upper_boundaries[i])) > eps ||
cvm::fabs(old_w[i] - widths[i]) > eps) {
new_params = true; new_params = true;
} }
} }
@ -928,7 +935,7 @@ public:
/// \brief Read grid entry in restart file /// \brief Read grid entry in restart file
std::istream & read_restart(std::istream &is) std::istream & read_restart(std::istream &is)
{ {
size_t const start_pos = is.tellg(); std::streampos const start_pos = is.tellg();
std::string key, conf; std::string key, conf;
if ((is >> key) && (key == std::string("grid_parameters"))) { if ((is >> key) && (key == std::string("grid_parameters"))) {
is.seekg(start_pos, std::ios::beg); is.seekg(start_pos, std::ios::beg);
@ -955,7 +962,7 @@ public:
/// represented in memory /// represented in memory
/// \param buf_size Number of values per line /// \param buf_size Number of values per line
std::ostream & write_raw(std::ostream &os, std::ostream & write_raw(std::ostream &os,
size_t const buf_size = 3) size_t const buf_size = 3) const
{ {
std::streamsize const w = os.width(); std::streamsize const w = os.width();
std::streamsize const p = os.precision(); std::streamsize const p = os.precision();
@ -981,7 +988,7 @@ public:
/// \brief Read data written by colvar_grid::write_raw() /// \brief Read data written by colvar_grid::write_raw()
std::istream & read_raw(std::istream &is) std::istream & read_raw(std::istream &is)
{ {
size_t const start_pos = is.tellg(); std::streampos const start_pos = is.tellg();
for (std::vector<int> ix = new_index(); index_ok(ix); incr(ix)) { for (std::vector<int> ix = new_index(); index_ok(ix); incr(ix)) {
for (size_t imult = 0; imult < mult; imult++) { for (size_t imult = 0; imult < mult; imult++) {
@ -1004,7 +1011,7 @@ public:
/// \brief Write the grid in a format which is both human readable /// \brief Write the grid in a format which is both human readable
/// and suitable for visualization e.g. with gnuplot /// and suitable for visualization e.g. with gnuplot
void write_multicol(std::ostream &os) void write_multicol(std::ostream &os) const
{ {
std::streamsize const w = os.width(); std::streamsize const w = os.width();
std::streamsize const p = os.precision(); std::streamsize const p = os.precision();
@ -1145,7 +1152,7 @@ public:
/// \brief Write the grid data without labels, as they are /// \brief Write the grid data without labels, as they are
/// represented in memory /// represented in memory
std::ostream & write_opendx(std::ostream &os) std::ostream & write_opendx(std::ostream &os) const
{ {
// write the header // write the header
os << "object 1 class gridpositions counts"; os << "object 1 class gridpositions counts";
@ -1208,7 +1215,7 @@ public:
/// Constructor from a vector of colvars /// Constructor from a vector of colvars
colvar_grid_count(std::vector<colvar *> &colvars, colvar_grid_count(std::vector<colvar *> &colvars,
size_t const &def_count = 0, size_t const &def_count = 0,
bool margin = false); bool add_extra_bin = false);
/// Increment the counter at given position /// Increment the counter at given position
inline void incr_count(std::vector<int> const &ix) inline void incr_count(std::vector<int> const &ix)
@ -1360,7 +1367,7 @@ public:
/// Constructor from a vector of colvars /// Constructor from a vector of colvars
colvar_grid_scalar(std::vector<colvar *> &colvars, colvar_grid_scalar(std::vector<colvar *> &colvars,
bool margin = 0); bool add_extra_bin = false);
/// Accumulate the value /// Accumulate the value
inline void acc_value(std::vector<int> const &ix, inline void acc_value(std::vector<int> const &ix,
@ -1419,9 +1426,9 @@ public:
// 100 101 110 111 000 001 010 011 // 100 101 110 111 000 001 010 011
grad[0] = 0.25 * ((p[4] + p[5] + p[6] + p[7]) - (p[0] + p[1] + p[2] + p[3])) / widths[0]; grad[0] = 0.25 * ((p[4] + p[5] + p[6] + p[7]) - (p[0] + p[1] + p[2] + p[3])) / widths[0];
// 010 011 110 111 000 001 100 101 // 010 011 110 111 000 001 100 101
grad[1] = 0.25 * ((p[2] + p[3] + p[6] + p[7]) - (p[0] + p[1] + p[4] + p[5])) / widths[0]; grad[1] = 0.25 * ((p[2] + p[3] + p[6] + p[7]) - (p[0] + p[1] + p[4] + p[5])) / widths[1];
// 001 011 101 111 000 010 100 110 // 001 011 101 111 000 010 100 110
grad[2] = 0.25 * ((p[1] + p[3] + p[5] + p[7]) - (p[0] + p[2] + p[4] + p[6])) / widths[0]; grad[2] = 0.25 * ((p[1] + p[3] + p[5] + p[7]) - (p[0] + p[2] + p[4] + p[6])) / widths[2];
} else { } else {
cvm::error("Finite differences available in dimension 2 and 3 only."); cvm::error("Finite differences available in dimension 2 and 3 only.");
} }
@ -1430,7 +1437,7 @@ public:
/// \brief Return the value of the function at ix divided by its /// \brief Return the value of the function at ix divided by its
/// number of samples (if the count grid is defined) /// number of samples (if the count grid is defined)
virtual cvm::real value_output(std::vector<int> const &ix, virtual cvm::real value_output(std::vector<int> const &ix,
size_t const &imult = 0) size_t const &imult = 0) const
{ {
if (imult > 0) { if (imult > 0) {
cvm::error("Error: trying to access a component " cvm::error("Error: trying to access a component "
@ -1574,7 +1581,7 @@ public:
/// \brief Return the value of the function at ix divided by its /// \brief Return the value of the function at ix divided by its
/// number of samples (if the count grid is defined) /// number of samples (if the count grid is defined)
virtual inline cvm::real value_output(std::vector<int> const &ix, virtual inline cvm::real value_output(std::vector<int> const &ix,
size_t const &imult = 0) size_t const &imult = 0) const
{ {
if (samples) if (samples)
return (samples->value(ix) > 0) ? return (samples->value(ix) > 0) ?

View File

@ -50,7 +50,7 @@ colvarmodule::colvarmodule(colvarproxy *proxy_in)
cvm::log("Initializing the collective variables module, version "+ cvm::log("Initializing the collective variables module, version "+
cvm::to_str(COLVARS_VERSION)+".\n"); cvm::to_str(COLVARS_VERSION)+".\n");
cvm::log("Please cite Fiorin et al, Mol Phys 2013:\n " cvm::log("Please cite Fiorin et al, Mol Phys 2013:\n "
"https://doi.org/10.1080/00268976.2013.813594\n" "https://dx.doi.org/10.1080/00268976.2013.813594\n"
"in any publication based on this calculation.\n"); "in any publication based on this calculation.\n");
if (proxy->smp_enabled() == COLVARS_OK) { if (proxy->smp_enabled() == COLVARS_OK) {
@ -80,7 +80,7 @@ colvarmodule::colvarmodule(colvarproxy *proxy_in)
colvarmodule::rotation::crossing_threshold = 1.0e-02; colvarmodule::rotation::crossing_threshold = 1.0e-02;
cv_traj_freq = 100; cv_traj_freq = 100;
restart_out_freq = proxy->restart_frequency(); restart_out_freq = proxy->default_restart_frequency();
// by default overwrite the existing trajectory file // by default overwrite the existing trajectory file
cv_traj_append = false; cv_traj_append = false;
@ -91,7 +91,7 @@ colvarmodule::colvarmodule(colvarproxy *proxy_in)
colvarmodule * colvarmodule::main() colvarmodule * colvarmodule::main()
{ {
return proxy->colvars; return proxy ? proxy->colvars : NULL;
} }
@ -245,9 +245,6 @@ int colvarmodule::parse_config(std::string &conf)
// Update any necessary proxy data // Update any necessary proxy data
proxy->setup(); proxy->setup();
// configuration might have changed, better redo the labels
cv_traj_write_labels = true;
return get_error(); return get_error();
} }
@ -265,6 +262,12 @@ int colvarmodule::append_new_config(std::string const &new_conf)
} }
void colvarmodule::config_changed()
{
cv_traj_write_labels = true;
}
int colvarmodule::parse_global_params(std::string const &conf) int colvarmodule::parse_global_params(std::string const &conf)
{ {
// TODO document and then echo this keyword // TODO document and then echo this keyword
@ -332,8 +335,13 @@ int colvarmodule::parse_global_params(std::string const &conf)
scripting_after_biases, scripting_after_biases); scripting_after_biases, scripting_after_biases);
if (use_scripted_forces && !proxy->force_script_defined) { if (use_scripted_forces && !proxy->force_script_defined) {
if (proxy->simulation_running()) {
return cvm::error("User script for scripted colvar forces not found.", return cvm::error("User script for scripted colvar forces not found.",
INPUT_ERROR); INPUT_ERROR);
} else {
// Not necessary if we are not applying biases in a real simulation (eg. VMD)
cvm::log("Warning: User script for scripted colvar forces not found.");
}
} }
return cvm::get_error(); return cvm::get_error();
@ -369,6 +377,11 @@ int colvarmodule::parse_colvars(std::string const &conf)
colvar_conf = ""; colvar_conf = "";
} }
if (pos > 0) {
// One or more new variables were added
config_changed();
}
if (!colvars.size()) { if (!colvars.size()) {
cvm::log("Warning: no collective variables defined.\n"); cvm::log("Warning: no collective variables defined.\n");
} }
@ -419,6 +432,10 @@ int colvarmodule::parse_biases_type(std::string const &conf,
} }
bias_conf = ""; bias_conf = "";
} }
if (conf_saved_pos > 0) {
// One or more new biases were added
config_changed();
}
return COLVARS_OK; return COLVARS_OK;
} }
@ -656,6 +673,7 @@ std::string colvarmodule::read_colvar(std::string const &name)
return ss.str(); return ss.str();
} }
cvm::real colvarmodule::energy_difference(std::string const &bias_name, cvm::real colvarmodule::energy_difference(std::string const &bias_name,
std::string const &conf) std::string const &conf)
{ {
@ -672,75 +690,6 @@ cvm::real colvarmodule::energy_difference(std::string const &bias_name,
return energy_diff; return energy_diff;
} }
int colvarmodule::bias_current_bin(std::string const &bias_name)
{
cvm::increase_depth();
int ret;
colvarbias *b = bias_by_name(bias_name);
if (b != NULL) {
ret = b->current_bin();
} else {
cvm::error("Error: bias not found.\n");
ret = COLVARS_ERROR;
}
cvm::decrease_depth();
return ret;
}
int colvarmodule::bias_bin_num(std::string const &bias_name)
{
cvm::increase_depth();
int ret;
colvarbias *b = bias_by_name(bias_name);
if (b != NULL) {
ret = b->bin_num();
} else {
cvm::error("Error: bias not found.\n");
ret = COLVARS_ERROR;
}
cvm::decrease_depth();
return ret;
}
int colvarmodule::bias_bin_count(std::string const &bias_name, size_t bin_index)
{
cvm::increase_depth();
int ret;
colvarbias *b = bias_by_name(bias_name);
if (b != NULL) {
ret = b->bin_count(bin_index);
} else {
cvm::error("Error: bias not found.\n");
ret = COLVARS_ERROR;
}
cvm::decrease_depth();
return ret;
}
int colvarmodule::bias_share(std::string const &bias_name)
{
cvm::increase_depth();
int ret;
colvarbias *b = bias_by_name(bias_name);
if (b != NULL) {
b->replica_share();
ret = COLVARS_OK;
} else {
cvm::error("Error: bias not found.\n");
ret = COLVARS_ERROR;
}
cvm::decrease_depth();
return ret;
}
int colvarmodule::calc() int colvarmodule::calc()
{ {
@ -753,11 +702,6 @@ int colvarmodule::calc()
} }
error_code |= calc_colvars(); error_code |= calc_colvars();
// set biasing forces to zero before biases are calculated and summed over
for (std::vector<colvar *>::iterator cvi = colvars.begin();
cvi != colvars.end(); cvi++) {
(*cvi)->reset_bias_force();
}
error_code |= calc_biases(); error_code |= calc_biases();
error_code |= update_colvar_forces(); error_code |= update_colvar_forces();
@ -768,17 +712,45 @@ int colvarmodule::calc()
error_code |= write_traj_files(); error_code |= write_traj_files();
} }
// write restart files, if needed // write restart files and similar data
if (restart_out_freq && (cvm::step_relative() > 0) && if (restart_out_freq && (cvm::step_relative() > 0) &&
((cvm::step_absolute() % restart_out_freq) == 0) ) { ((cvm::step_absolute() % restart_out_freq) == 0) ) {
if (restart_out_name.size()) { if (restart_out_name.size()) {
// Write restart file, if different from main output // Write restart file, if different from main output
error_code |= write_restart_file(restart_out_name); error_code |= write_restart_file(restart_out_name);
} else { } else {
error_code |= write_restart_file(output_prefix()+".colvars.state"); error_code |= write_restart_file(output_prefix()+".colvars.state");
} }
write_output_files();
cvm::increase_depth();
for (std::vector<colvar *>::iterator cvi = colvars.begin();
cvi != colvars.end();
cvi++) {
// TODO remove this when corrFunc becomes a bias
error_code |= (*cvi)->write_output_files();
} }
for (std::vector<colvarbias *>::iterator bi = biases.begin();
bi != biases.end();
bi++) {
error_code |= (*bi)->write_state_to_replicas();
}
cvm::decrease_depth();
}
// Write output files for biases, at the specified frequency for each
cvm::increase_depth();
for (std::vector<colvarbias *>::iterator bi = biases.begin();
bi != biases.end();
bi++) {
if ((*bi)->output_freq > 0) {
if ((cvm::step_relative() > 0) &&
((cvm::step_absolute() % (*bi)->output_freq) == 0) ) {
error_code |= (*bi)->write_output_files();
}
}
}
cvm::decrease_depth();
error_code |= end_of_step(); error_code |= end_of_step();
@ -885,6 +857,12 @@ int colvarmodule::calc_biases()
if (cvm::debug() && num_biases()) if (cvm::debug() && num_biases())
cvm::log("Updating collective variable biases.\n"); cvm::log("Updating collective variable biases.\n");
// set biasing forces to zero before biases are calculated and summed over
for (std::vector<colvar *>::iterator cvi = colvars.begin();
cvi != colvars.end(); cvi++) {
(*cvi)->reset_bias_force();
}
std::vector<colvarbias *>::iterator bi; std::vector<colvarbias *>::iterator bi;
int error_code = COLVARS_OK; int error_code = COLVARS_OK;
@ -1031,12 +1009,32 @@ int colvarmodule::write_restart_file(std::string const &out_name)
return cvm::error("Error: in writing restart file.\n", FILE_ERROR); return cvm::error("Error: in writing restart file.\n", FILE_ERROR);
} }
proxy->close_output_stream(out_name); proxy->close_output_stream(out_name);
if (cv_traj_os != NULL) {
// Take the opportunity to flush colvars.traj
proxy->flush_output_stream(cv_traj_os);
}
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
} }
int colvarmodule::write_restart_string(std::string &output)
{
cvm::log("Saving state to output buffer.\n");
std::ostringstream os;
if (!write_restart(os)) {
return cvm::error("Error: in writing restart to buffer.\n", FILE_ERROR);
}
output = os.str();
return COLVARS_OK;
}
int colvarmodule::write_traj_files() int colvarmodule::write_traj_files()
{ {
if (cvm::debug()) {
cvm::log("colvarmodule::write_traj_files()\n");
}
if (cv_traj_os == NULL) { if (cv_traj_os == NULL) {
if (open_traj_file(cv_traj_name) != COLVARS_OK) { if (open_traj_file(cv_traj_name) != COLVARS_OK) {
return cvm::get_error(); return cvm::get_error();
@ -1057,15 +1055,12 @@ int colvarmodule::write_traj_files()
write_traj(*cv_traj_os); write_traj(*cv_traj_os);
} }
if (restart_out_freq && (cv_traj_os != NULL)) { if (restart_out_freq && (cv_traj_os != NULL) &&
// flush the trajectory file if we are at the restart frequency
if ( (cvm::step_relative() > 0) &&
((cvm::step_absolute() % restart_out_freq) == 0)) { ((cvm::step_absolute() % restart_out_freq) == 0)) {
cvm::log("Synchronizing (emptying the buffer of) trajectory file \""+ cvm::log("Synchronizing (emptying the buffer of) trajectory file \""+
cv_traj_name+"\".\n"); cv_traj_name+"\".\n");
proxy->flush_output_stream(cv_traj_os); proxy->flush_output_stream(cv_traj_os);
} }
}
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
} }
@ -1182,53 +1177,64 @@ int colvarmodule::reset()
reset_index_groups(); reset_index_groups();
proxy->flush_output_streams();
proxy->reset(); proxy->reset();
if (cv_traj_os != NULL) {
// Do not close traj file here, as we might not be done with it yet.
proxy->flush_output_stream(cv_traj_os);
}
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
} }
int colvarmodule::setup_input() int colvarmodule::setup_input()
{ {
std::string restart_in_name("");
// read the restart configuration, if available
if (proxy->input_prefix().size()) { if (proxy->input_prefix().size()) {
// read the restart file // Read a state file
restart_in_name = proxy->input_prefix(); std::string restart_in_name(proxy->input_prefix()+
std::string(".colvars.state"));
std::ifstream input_is(restart_in_name.c_str()); std::ifstream input_is(restart_in_name.c_str());
if (!input_is.good()) { if (!input_is.good()) {
// try by adding the suffix // Try without the suffix
input_is.clear(); input_is.clear();
restart_in_name = restart_in_name+std::string(".colvars.state"); restart_in_name = proxy->input_prefix();
input_is.open(restart_in_name.c_str()); input_is.open(restart_in_name.c_str());
} }
// Now that the file has been opened, clear this for the next round
proxy->input_prefix().clear();
if (!input_is.good()) { if (!input_is.good()) {
cvm::error("Error: in opening input file \""+ return cvm::error("Error: in opening input state file \""+
std::string(restart_in_name)+"\".\n", std::string(restart_in_name)+"\".\n",
FILE_ERROR); FILE_ERROR);
return COLVARS_ERROR;
} else { } else {
cvm::log(cvm::line_marker); cvm::log(cvm::line_marker);
cvm::log("Restarting from file \""+restart_in_name+"\".\n"); cvm::log("Loading state from file \""+restart_in_name+"\".\n");
read_restart(input_is); read_restart(input_is);
if (cvm::get_error() != COLVARS_OK) {
return COLVARS_ERROR;
} else {
proxy->input_prefix().clear();
}
cvm::log(cvm::line_marker); cvm::log(cvm::line_marker);
return cvm::get_error();
} }
} }
if (proxy->input_buffer() != NULL) {
// Read a string buffer
char const *buffer = proxy->input_buffer();
size_t const buffer_size = strlen(proxy->input_buffer());
// Clear proxy pointer for the next round
proxy->input_buffer() = NULL;
if (buffer_size > 0) {
std::istringstream input_is;
// Replace the buffer of input_is; work around the lack of const in
// pubsetbuf's prototype (which also needs to support output streams)
input_is.rdbuf()->pubsetbuf(const_cast<char *>(buffer), buffer_size);
cvm::log(cvm::line_marker);
cvm::log("Loading state from input buffer.\n");
read_restart(input_is);
cvm::log(cvm::line_marker);
return cvm::get_error(); return cvm::get_error();
} }
}
return COLVARS_OK;
}
int colvarmodule::setup_output() int colvarmodule::setup_output()
@ -1277,6 +1283,20 @@ int colvarmodule::setup_output()
} }
std::string colvarmodule::state_file_prefix(char const *filename)
{
std::string const filename_str(filename);
std::string const prefix =
filename_str.substr(0, filename_str.find(".colvars.state"));
if (prefix.size() == 0) {
cvm::error("Error: invalid filename/prefix value \""+filename_str+"\".",
INPUT_ERROR);
}
return prefix;
}
std::istream & colvarmodule::read_restart(std::istream &is) std::istream & colvarmodule::read_restart(std::istream &is)
{ {
bool warn_total_forces = false; bool warn_total_forces = false;
@ -1340,7 +1360,7 @@ std::istream & colvarmodule::read_restart(std::istream &is)
std::istream & colvarmodule::read_objects_state(std::istream &is) std::istream & colvarmodule::read_objects_state(std::istream &is)
{ {
size_t pos = 0; std::streampos pos = 0;
std::string word; std::string word;
while (is.good()) { while (is.good()) {
@ -1365,7 +1385,7 @@ std::istream & colvarmodule::read_objects_state(std::istream &is)
"collective variable \""+(*cvi)->name+"\".\n", "collective variable \""+(*cvi)->name+"\".\n",
INPUT_ERROR); INPUT_ERROR);
} }
if (static_cast<size_t>(is.tellg()) > pos) break; // found it if (is.tellg() > pos) break; // found it
} }
cvm::decrease_depth(); cvm::decrease_depth();
@ -1386,13 +1406,13 @@ std::istream & colvarmodule::read_objects_state(std::istream &is)
(*bi)->name+"\".\n", (*bi)->name+"\".\n",
INPUT_ERROR); INPUT_ERROR);
} }
if (static_cast<size_t>(is.tellg()) > pos) break; // found it if (is.tellg() > pos) break; // found it
} }
cvm::decrease_depth(); cvm::decrease_depth();
} }
} }
if (static_cast<size_t>(is.tellg()) == pos) { if (is.tellg() == pos) {
// This block has not been read by any object: discard it and move on // This block has not been read by any object: discard it and move on
// to the next one // to the next one
is >> colvarparse::read_block(word, NULL); is >> colvarparse::read_block(word, NULL);
@ -1438,34 +1458,21 @@ int colvarmodule::backup_file(char const *filename)
int colvarmodule::write_output_files() int colvarmodule::write_output_files()
{ {
int error_code = COLVARS_OK; int error_code = COLVARS_OK;
cvm::increase_depth();
for (std::vector<colvar *>::iterator cvi = colvars.begin();
cvi != colvars.end();
cvi++) {
error_code |= (*cvi)->write_output_files();
}
cvm::decrease_depth();
cvm::increase_depth(); cvm::increase_depth();
for (std::vector<colvarbias *>::iterator bi = biases.begin(); for (std::vector<colvarbias *>::iterator bi = biases.begin();
bi != biases.end(); bi != biases.end();
bi++) { bi++) {
// Only write output files if they have not already been written this time step
if ((*bi)->output_freq == 0 || (cvm::step_absolute() % (*bi)->output_freq) != 0) {
error_code |= (*bi)->write_output_files(); error_code |= (*bi)->write_output_files();
}
error_code |= (*bi)->write_state_to_replicas(); error_code |= (*bi)->write_state_to_replicas();
} }
cvm::decrease_depth(); cvm::decrease_depth();
if (cv_traj_os != NULL) {
// do not close, there may be another run command
proxy->flush_output_stream(cv_traj_os);
}
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
} }
int colvarmodule::read_traj(char const *traj_filename, int colvarmodule::read_traj(char const *traj_filename,
long traj_read_begin, long traj_read_begin,
long traj_read_end) long traj_read_end)
@ -1581,12 +1588,10 @@ int colvarmodule::open_traj_file(std::string const &file_name)
// (re)open trajectory file // (re)open trajectory file
if (cv_traj_append) { if (cv_traj_append) {
cvm::log("Appending to colvar trajectory file \""+file_name+ cvm::log("Appending to trajectory file \""+file_name+"\".\n");
"\".\n");
cv_traj_os = (cvm::proxy)->output_stream(file_name, std::ios::app); cv_traj_os = (cvm::proxy)->output_stream(file_name, std::ios::app);
} else { } else {
cvm::log("Writing to colvar trajectory file \""+file_name+ cvm::log("Opening trajectory file \""+file_name+"\".\n");
"\".\n");
proxy->backup_file(file_name.c_str()); proxy->backup_file(file_name.c_str());
cv_traj_os = (cvm::proxy)->output_stream(file_name); cv_traj_os = (cvm::proxy)->output_stream(file_name);
} }
@ -1603,6 +1608,7 @@ int colvarmodule::open_traj_file(std::string const &file_name)
int colvarmodule::close_traj_file() int colvarmodule::close_traj_file()
{ {
if (cv_traj_os != NULL) { if (cv_traj_os != NULL) {
cvm::log("Closing trajectory file \""+cv_traj_name+"\".\n");
proxy->close_output_stream(cv_traj_name); proxy->close_output_stream(cv_traj_name);
cv_traj_os = NULL; cv_traj_os = NULL;
} }
@ -1668,7 +1674,7 @@ std::ostream & colvarmodule::write_traj(std::ostream &os)
} }
void cvm::log(std::string const &message, int min_log_level) void colvarmodule::log(std::string const &message, int min_log_level)
{ {
if (cvm::log_level() < min_log_level) return; if (cvm::log_level() < min_log_level) return;
// allow logging when the module is not fully initialized // allow logging when the module is not fully initialized
@ -1681,13 +1687,13 @@ void cvm::log(std::string const &message, int min_log_level)
} }
void cvm::increase_depth() void colvarmodule::increase_depth()
{ {
(depth())++; (depth())++;
} }
void cvm::decrease_depth() void colvarmodule::decrease_depth()
{ {
if (depth() > 0) { if (depth() > 0) {
(depth())--; (depth())--;
@ -1695,7 +1701,7 @@ void cvm::decrease_depth()
} }
size_t & cvm::depth() size_t & colvarmodule::depth()
{ {
// NOTE: do not call log() or error() here, to avoid recursion // NOTE: do not call log() or error() here, to avoid recursion
colvarmodule *cv = cvm::main(); colvarmodule *cv = cvm::main();
@ -1726,16 +1732,19 @@ void colvarmodule::set_error_bits(int code)
proxy->smp_unlock(); proxy->smp_unlock();
} }
bool colvarmodule::get_error_bit(int code) bool colvarmodule::get_error_bit(int code)
{ {
return bool(errorCode & code); return bool(errorCode & code);
} }
void colvarmodule::clear_error() void colvarmodule::clear_error()
{ {
proxy->smp_lock(); proxy->smp_lock();
errorCode = COLVARS_OK; errorCode = COLVARS_OK;
proxy->smp_unlock(); proxy->smp_unlock();
proxy->clear_error_msgs();
} }
@ -1749,9 +1758,7 @@ int colvarmodule::error(std::string const &message, int code)
int colvarmodule::fatal_error(std::string const &message) int colvarmodule::fatal_error(std::string const &message)
{ {
set_error_bits(FATAL_ERROR); return error(message, FATAL_ERROR);
proxy->fatal_error(message);
return get_error();
} }
@ -1793,7 +1800,7 @@ int cvm::read_index_file(char const *filename)
std::vector<int> *new_index_group = new std::vector<int>(); std::vector<int> *new_index_group = new std::vector<int>();
int atom_number = 1; int atom_number = 1;
size_t pos = is.tellg(); std::streampos pos = is.tellg();
while ( (is >> atom_number) && (atom_number > 0) ) { while ( (is >> atom_number) && (atom_number > 0) ) {
new_index_group->push_back(atom_number); new_index_group->push_back(atom_number);
pos = is.tellg(); pos = is.tellg();

View File

@ -221,7 +221,6 @@ public:
static void clear_error(); static void clear_error();
/// Current step number /// Current step number
static step_number it; static step_number it;
/// Starting step number for this run /// Starting step number for this run
@ -371,6 +370,9 @@ public:
/// anything that triggers another call /// anything that triggers another call
int append_new_config(std::string const &conf); int append_new_config(std::string const &conf);
/// Signals to the module object that the configuration has changed
void config_changed();
private: private:
/// Configuration string read so far by the module (includes comments) /// Configuration string read so far by the module (includes comments)
@ -441,6 +443,9 @@ public:
/// Write the output restart file /// Write the output restart file
std::ostream & write_restart(std::ostream &os); std::ostream & write_restart(std::ostream &os);
/// Strips .colvars.state from filename and checks that it is not empty
static std::string state_file_prefix(char const *filename);
/// Open a trajectory file if requested (and leave it open) /// Open a trajectory file if requested (and leave it open)
int open_traj_file(std::string const &file_name); int open_traj_file(std::string const &file_name);
/// Close it (note: currently unused) /// Close it (note: currently unused)
@ -459,6 +464,9 @@ public:
/// Backup a file before writing it /// Backup a file before writing it
static int backup_file(char const *filename); static int backup_file(char const *filename);
/// Write the state into a string
int write_restart_string(std::string &output);
/// Look up a bias by name; returns NULL if not found /// Look up a bias by name; returns NULL if not found
static colvarbias * bias_by_name(std::string const &name); static colvarbias * bias_by_name(std::string const &name);
@ -479,15 +487,6 @@ public:
/// currently works for harmonic (force constant and/or centers) /// currently works for harmonic (force constant and/or centers)
real energy_difference(std::string const &bias_name, std::string const &conf); real energy_difference(std::string const &bias_name, std::string const &conf);
/// Give the total number of bins for a given bias.
int bias_bin_num(std::string const &bias_name);
/// Calculate the bin index for a given bias.
int bias_current_bin(std::string const &bias_name);
//// Give the count at a given bin index.
int bias_bin_count(std::string const &bias_name, size_t bin_index);
//// Share among replicas.
int bias_share(std::string const &bias_name);
/// Main worker function /// Main worker function
int calc(); int calc();

View File

@ -853,7 +853,7 @@ colvarparse::read_block::~read_block()
std::istream & operator>> (std::istream &is, colvarparse::read_block const &rb) std::istream & operator>> (std::istream &is, colvarparse::read_block const &rb)
{ {
size_t start_pos = is.tellg(); std::streampos start_pos = is.tellg();
std::string read_key, next; std::string read_key, next;
if ( !(is >> read_key) || !(read_key == rb.key) || if ( !(is >> read_key) || !(read_key == rb.key) ||

View File

@ -20,11 +20,6 @@
#include <omp.h> #include <omp.h>
#endif #endif
#if defined(NAMD_TCL) || defined(VMDTCL)
#define COLVARS_TCL
#include <tcl.h>
#endif
#include "colvarmodule.h" #include "colvarmodule.h"
#include "colvarproxy.h" #include "colvarproxy.h"
#include "colvarscript.h" #include "colvarscript.h"
@ -33,8 +28,9 @@
colvarproxy_system::colvarproxy_system() colvarproxy_system::colvarproxy_system()
: angstrom_value(0.)
{ {
angstrom_value = 0.0;
total_force_requested = false;
reset_pbc_lattice(); reset_pbc_lattice();
} }
@ -67,7 +63,7 @@ bool colvarproxy_system::total_forces_same_step() const
inline int round_to_integer(cvm::real x) inline int round_to_integer(cvm::real x)
{ {
return cvm::floor(x+0.5); return int(cvm::floor(x+0.5));
} }
@ -135,6 +131,14 @@ cvm::rvector colvarproxy_system::position_distance(cvm::atom_pos const &pos1,
} }
int colvarproxy_system::get_molid(int &)
{
cvm::error("Error: only VMD allows the use of multiple \"molecules\", "
"i.e. multiple molecular systems.", COLVARS_NOT_IMPLEMENTED);
return -1;
}
colvarproxy_atoms::colvarproxy_atoms() colvarproxy_atoms::colvarproxy_atoms()
{ {
@ -505,144 +509,12 @@ int colvarproxy_script::run_colvar_gradient_callback(std::string const & /* name
colvarproxy_tcl::colvarproxy_tcl() colvarproxy_io::colvarproxy_io()
{ {
tcl_interp_ = NULL; input_buffer_ = NULL;
} }
colvarproxy_tcl::~colvarproxy_tcl()
{
}
void colvarproxy_tcl::init_tcl_pointers()
{
cvm::error("Error: Tcl support is currently unavailable "
"outside NAMD or VMD.\n", COLVARS_NOT_IMPLEMENTED);
}
char const *colvarproxy_tcl::tcl_obj_to_str(unsigned char *obj)
{
#if defined(COLVARS_TCL)
return Tcl_GetString(reinterpret_cast<Tcl_Obj *>(obj));
#else
return NULL;
#endif
}
int colvarproxy_tcl::tcl_run_force_callback()
{
#if defined(COLVARS_TCL)
Tcl_Interp *const tcl_interp = reinterpret_cast<Tcl_Interp *>(tcl_interp_);
std::string cmd = std::string("calc_colvar_forces ")
+ cvm::to_str(cvm::step_absolute());
int err = Tcl_Eval(tcl_interp, cmd.c_str());
if (err != TCL_OK) {
cvm::log(std::string("Error while executing calc_colvar_forces:\n"));
cvm::error(Tcl_GetStringResult(tcl_interp));
return COLVARS_ERROR;
}
return cvm::get_error();
#else
return COLVARS_NOT_IMPLEMENTED;
#endif
}
int colvarproxy_tcl::tcl_run_colvar_callback(
std::string const & name,
std::vector<const colvarvalue *> const & cvc_values,
colvarvalue & value)
{
#if defined(COLVARS_TCL)
Tcl_Interp *const tcl_interp = reinterpret_cast<Tcl_Interp *>(tcl_interp_);
size_t i;
std::string cmd = std::string("calc_") + name;
for (i = 0; i < cvc_values.size(); i++) {
cmd += std::string(" {") + (*(cvc_values[i])).to_simple_string() +
std::string("}");
}
int err = Tcl_Eval(tcl_interp, cmd.c_str());
const char *result = Tcl_GetStringResult(tcl_interp);
if (err != TCL_OK) {
return cvm::error(std::string("Error while executing ")
+ cmd + std::string(":\n") +
std::string(Tcl_GetStringResult(tcl_interp)), COLVARS_ERROR);
}
std::istringstream is(result);
if (value.from_simple_string(is.str()) != COLVARS_OK) {
cvm::log("Error parsing colvar value from script:");
cvm::error(result);
return COLVARS_ERROR;
}
return cvm::get_error();
#else
return COLVARS_NOT_IMPLEMENTED;
#endif
}
int colvarproxy_tcl::tcl_run_colvar_gradient_callback(
std::string const & name,
std::vector<const colvarvalue *> const & cvc_values,
std::vector<cvm::matrix2d<cvm::real> > & gradient)
{
#if defined(COLVARS_TCL)
Tcl_Interp *const tcl_interp = reinterpret_cast<Tcl_Interp *>(tcl_interp_);
size_t i;
std::string cmd = std::string("calc_") + name + "_gradient";
for (i = 0; i < cvc_values.size(); i++) {
cmd += std::string(" {") + (*(cvc_values[i])).to_simple_string() +
std::string("}");
}
int err = Tcl_Eval(tcl_interp, cmd.c_str());
if (err != TCL_OK) {
return cvm::error(std::string("Error while executing ")
+ cmd + std::string(":\n") +
std::string(Tcl_GetStringResult(tcl_interp)), COLVARS_ERROR);
}
Tcl_Obj **list;
int n;
Tcl_ListObjGetElements(tcl_interp, Tcl_GetObjResult(tcl_interp),
&n, &list);
if (n != int(gradient.size())) {
cvm::error("Error parsing list of gradient values from script: found "
+ cvm::to_str(n) + " values instead of " +
cvm::to_str(gradient.size()));
return COLVARS_ERROR;
}
for (i = 0; i < gradient.size(); i++) {
std::istringstream is(Tcl_GetString(list[i]));
if (gradient[i].from_simple_string(is.str()) != COLVARS_OK) {
cvm::log("Gradient matrix size: " + cvm::to_str(gradient[i].size()));
cvm::log("Gradient string: " + cvm::to_str(Tcl_GetString(list[i])));
cvm::error("Error parsing gradient value from script", COLVARS_ERROR);
return COLVARS_ERROR;
}
}
return cvm::get_error();
#else
return COLVARS_NOT_IMPLEMENTED;
#endif
}
colvarproxy_io::colvarproxy_io() {}
colvarproxy_io::~colvarproxy_io() {} colvarproxy_io::~colvarproxy_io() {}
@ -658,78 +530,6 @@ int colvarproxy_io::set_frame(long int)
} }
std::ostream * colvarproxy_io::output_stream(std::string const &output_name,
std::ios_base::openmode mode)
{
if (cvm::debug()) {
cvm::log("Using colvarproxy::output_stream()\n");
}
std::ostream *os = get_output_stream(output_name);
if (os != NULL) return os;
if (!(mode & (std::ios_base::app | std::ios_base::ate))) {
backup_file(output_name);
}
std::ofstream *osf = new std::ofstream(output_name.c_str(), mode);
if (!osf->is_open()) {
cvm::error("Error: cannot write to file/channel \""+output_name+"\".\n",
FILE_ERROR);
return NULL;
}
output_stream_names.push_back(output_name);
output_files.push_back(osf);
return osf;
}
std::ostream *colvarproxy_io::get_output_stream(std::string const &output_name)
{
std::list<std::ostream *>::iterator osi = output_files.begin();
std::list<std::string>::iterator osni = output_stream_names.begin();
for ( ; osi != output_files.end(); osi++, osni++) {
if (*osni == output_name) {
return *osi;
}
}
return NULL;
}
int colvarproxy_io::flush_output_stream(std::ostream *os)
{
std::list<std::ostream *>::iterator osi = output_files.begin();
std::list<std::string>::iterator osni = output_stream_names.begin();
for ( ; osi != output_files.end(); osi++, osni++) {
if (*osi == os) {
((std::ofstream *) (*osi))->flush();
return COLVARS_OK;
}
}
return cvm::error("Error: trying to flush an output file/channel "
"that wasn't open.\n", BUG_ERROR);
}
int colvarproxy_io::close_output_stream(std::string const &output_name)
{
std::list<std::ostream *>::iterator osi = output_files.begin();
std::list<std::string>::iterator osni = output_stream_names.begin();
for ( ; osi != output_files.end(); osi++, osni++) {
if (*osni == output_name) {
((std::ofstream *) (*osi))->close();
delete *osi;
output_files.erase(osi);
output_stream_names.erase(osni);
return COLVARS_OK;
}
}
return cvm::error("Error: trying to close an output file/channel "
"that wasn't open.\n", BUG_ERROR);
}
int colvarproxy_io::backup_file(char const * /* filename */) int colvarproxy_io::backup_file(char const * /* filename */)
{ {
// TODO implement this using rename_file() // TODO implement this using rename_file()
@ -796,11 +596,33 @@ colvarproxy::colvarproxy()
{ {
colvars = NULL; colvars = NULL;
b_simulation_running = true; b_simulation_running = true;
b_simulation_continuing = false;
b_delete_requested = false; b_delete_requested = false;
} }
colvarproxy::~colvarproxy() {} colvarproxy::~colvarproxy()
{
close_files();
}
int colvarproxy::close_files()
{
if (smp_enabled() == COLVARS_OK && smp_thread_id() > 0) {
// Nothing to do on non-master threads
return COLVARS_OK;
}
std::list<std::string>::iterator osni = output_stream_names.begin();
std::list<std::ostream *>::iterator osi = output_files.begin();
for ( ; osi != output_files.end(); osi++, osni++) {
((std::ofstream *) (*osi))->close();
delete *osi;
}
output_files.clear();
output_stream_names.clear();
return COLVARS_OK;
}
int colvarproxy::reset() int colvarproxy::reset()
@ -838,9 +660,37 @@ int colvarproxy::update_output()
} }
size_t colvarproxy::restart_frequency() int colvarproxy::post_run()
{ {
return 0; int error_code = COLVARS_OK;
if (colvars->output_prefix().size()) {
error_code |= colvars->write_restart_file(cvm::output_prefix()+".colvars.state");
error_code |= colvars->write_output_files();
}
error_code |= flush_output_streams();
return error_code;
}
void colvarproxy::add_error_msg(std::string const &message)
{
std::istringstream is(message);
std::string line;
while (std::getline(is, line)) {
error_output += line+"\n";
}
}
void colvarproxy::clear_error_msgs()
{
error_output.clear();
}
std::string const & colvarproxy::get_error_msgs()
{
return error_output;
} }
@ -852,3 +702,105 @@ int colvarproxy::get_version_from_string(char const *version_string)
is >> newint; is >> newint;
return newint; return newint;
} }
void colvarproxy::smp_stream_error()
{
cvm::error("Error: trying to access an output stream from a "
"multi-threaded region (bug). For a quick workaround, use "
"\"smp off\" in the Colvars config.\n", BUG_ERROR);
}
std::ostream * colvarproxy::output_stream(std::string const &output_name,
std::ios_base::openmode mode)
{
if (cvm::debug()) {
cvm::log("Using colvarproxy::output_stream()\n");
}
std::ostream *os = get_output_stream(output_name);
if (os != NULL) return os;
if (!(mode & (std::ios_base::app | std::ios_base::ate))) {
backup_file(output_name);
}
std::ofstream *osf = new std::ofstream(output_name.c_str(), mode);
if (!osf->is_open()) {
cvm::error("Error: cannot write to file/channel \""+output_name+"\".\n",
FILE_ERROR);
return NULL;
}
output_stream_names.push_back(output_name);
output_files.push_back(osf);
return osf;
}
std::ostream *colvarproxy::get_output_stream(std::string const &output_name)
{
if (smp_enabled() == COLVARS_OK) {
if (smp_thread_id() > 0) smp_stream_error();
}
std::list<std::ostream *>::iterator osi = output_files.begin();
std::list<std::string>::iterator osni = output_stream_names.begin();
for ( ; osi != output_files.end(); osi++, osni++) {
if (*osni == output_name) {
return *osi;
}
}
return NULL;
}
int colvarproxy::flush_output_stream(std::ostream *os)
{
if (smp_enabled() == COLVARS_OK) {
if (smp_thread_id() > 0) smp_stream_error();
}
std::list<std::ostream *>::iterator osi = output_files.begin();
std::list<std::string>::iterator osni = output_stream_names.begin();
for ( ; osi != output_files.end(); osi++, osni++) {
if (*osi == os) {
((std::ofstream *) (*osi))->flush();
return COLVARS_OK;
}
}
return cvm::error("Error: trying to flush an output file/channel "
"that wasn't open.\n", BUG_ERROR);
}
int colvarproxy::flush_output_streams()
{
if (smp_enabled() == COLVARS_OK && smp_thread_id() > 0)
return COLVARS_OK;
std::list<std::ostream *>::iterator osi = output_files.begin();
for ( ; osi != output_files.end(); osi++) {
((std::ofstream *) (*osi))->flush();
}
return COLVARS_OK;
}
int colvarproxy::close_output_stream(std::string const &output_name)
{
if (smp_enabled() == COLVARS_OK) {
if (smp_thread_id() > 0) smp_stream_error();
}
std::list<std::ostream *>::iterator osi = output_files.begin();
std::list<std::string>::iterator osni = output_stream_names.begin();
for ( ; osi != output_files.end(); osi++, osni++) {
if (*osni == output_name) {
((std::ofstream *) (*osi))->close();
delete *osi;
output_files.erase(osi);
output_stream_names.erase(osni);
return COLVARS_OK;
}
}
return cvm::error("Error: trying to close an output file/channel "
"that wasn't open.\n", BUG_ERROR);
}

View File

@ -16,7 +16,8 @@
#include "colvarmodule.h" #include "colvarmodule.h"
#include "colvartypes.h" #include "colvartypes.h"
#include "colvarvalue.h" #include "colvarvalue.h"
#include "colvarproxy_tcl.h"
#include "colvarproxy_volmaps.h"
/// \file colvarproxy.h /// \file colvarproxy.h
/// \brief Colvars proxy classes /// \brief Colvars proxy classes
@ -29,7 +30,7 @@
/// ///
/// To interface to a new MD engine, the simplest solution is to derive a new /// To interface to a new MD engine, the simplest solution is to derive a new
/// class from \link colvarproxy \endlink. Currently implemented are: \link /// class from \link colvarproxy \endlink. Currently implemented are: \link
/// colvarproxy_lammps \endlink, \link colvarproxy_namd \endlink, \link /// colvarproxy_lammps, \endlink, \link colvarproxy_namd, \endlink, \link
/// colvarproxy_vmd \endlink. /// colvarproxy_vmd \endlink.
@ -121,8 +122,15 @@ public:
/// Are total forces from the current step available? /// Are total forces from the current step available?
virtual bool total_forces_same_step() const; virtual bool total_forces_same_step() const;
/// Get the molecule ID when called in VMD; raise error otherwise
/// \param molid Set this argument equal to the current VMD molid
virtual int get_molid(int &molid);
protected: protected:
/// Whether the total forces have been requested
bool total_force_requested;
/// \brief Type of boundary conditions /// \brief Type of boundary conditions
/// ///
/// Orthogonal and triclinic cells are made available to objects. /// Orthogonal and triclinic cells are made available to objects.
@ -542,46 +550,6 @@ public:
}; };
/// Methods for using Tcl within Colvars
class colvarproxy_tcl {
public:
/// Constructor
colvarproxy_tcl();
/// Destructor
virtual ~colvarproxy_tcl();
/// Is Tcl available? (trigger initialization if needed)
int tcl_available();
/// Tcl implementation of script_obj_to_str()
char const *tcl_obj_to_str(unsigned char *obj);
/// Run a user-defined colvar forces script
int tcl_run_force_callback();
int tcl_run_colvar_callback(
std::string const &name,
std::vector<const colvarvalue *> const &cvcs,
colvarvalue &value);
int tcl_run_colvar_gradient_callback(
std::string const &name,
std::vector<const colvarvalue *> const &cvcs,
std::vector<cvm::matrix2d<cvm::real> > &gradient);
protected:
/// Pointer to Tcl interpreter object
void *tcl_interp_;
/// Set Tcl pointers
virtual void init_tcl_pointers();
};
/// Methods for data input/output /// Methods for data input/output
class colvarproxy_io { class colvarproxy_io {
@ -601,21 +569,6 @@ public:
// Returns error code // Returns error code
virtual int set_frame(long int); virtual int set_frame(long int);
/// \brief Returns a reference to the given output channel;
/// if this is not open already, then open it
virtual std::ostream *output_stream(std::string const &output_name,
std::ios_base::openmode mode =
std::ios_base::out);
/// Returns a reference to output_name if it exists, NULL otherwise
virtual std::ostream *get_output_stream(std::string const &output_name);
/// \brief Flushes the given output channel
virtual int flush_output_stream(std::ostream *os);
/// \brief Closes the given output channel
virtual int close_output_stream(std::string const &output_name);
/// \brief Rename the given file, before overwriting it /// \brief Rename the given file, before overwriting it
virtual int backup_file(char const *filename); virtual int backup_file(char const *filename);
@ -644,30 +597,49 @@ public:
return rename_file(filename.c_str(), newfilename.c_str()); return rename_file(filename.c_str(), newfilename.c_str());
} }
/// \brief Prefix of the input state file /// Prefix of the input state file to be read next
inline std::string & input_prefix() inline std::string & input_prefix()
{ {
return input_prefix_str; return input_prefix_str;
} }
/// \brief Prefix to be used for output restart files /// Default prefix to be used for all output files (final configuration)
inline std::string & restart_output_prefix()
{
return restart_output_prefix_str;
}
/// \brief Prefix to be used for output files (final system
/// configuration)
inline std::string & output_prefix() inline std::string & output_prefix()
{ {
return output_prefix_str; return output_prefix_str;
} }
/// Prefix of the restart (checkpoint) file to be written next
inline std::string & restart_output_prefix()
{
return restart_output_prefix_str;
}
/// Default restart frequency (as set by the simulation engine)
inline int default_restart_frequency() const
{
return restart_frequency_engine;
}
/// Buffer from which the input state information may be read
inline char const * & input_buffer()
{
return input_buffer_;
}
protected: protected:
/// \brief Prefix to be used for input files (restarts, not /// Prefix of the input state file to be read next
/// configuration) std::string input_prefix_str;
std::string input_prefix_str, output_prefix_str, restart_output_prefix_str;
/// Default prefix to be used for all output files (final configuration)
std::string output_prefix_str;
/// Prefix of the restart (checkpoint) file to be written next
std::string restart_output_prefix_str;
/// How often the simulation engine will write its own restart
int restart_frequency_engine;
/// \brief Currently opened output files: by default, these are ofstream objects. /// \brief Currently opened output files: by default, these are ofstream objects.
/// Allows redefinition to implement different output mechanisms /// Allows redefinition to implement different output mechanisms
@ -675,6 +647,8 @@ protected:
/// \brief Identifiers for output_stream objects: by default, these are the names of the files /// \brief Identifiers for output_stream objects: by default, these are the names of the files
std::list<std::string> output_stream_names; std::list<std::string> output_stream_names;
/// Buffer from which the input state information may be read
char const *input_buffer_;
}; };
@ -687,6 +661,7 @@ class colvarproxy
: public colvarproxy_system, : public colvarproxy_system,
public colvarproxy_atoms, public colvarproxy_atoms,
public colvarproxy_atom_groups, public colvarproxy_atom_groups,
public colvarproxy_volmaps,
public colvarproxy_smp, public colvarproxy_smp,
public colvarproxy_replicas, public colvarproxy_replicas,
public colvarproxy_script, public colvarproxy_script,
@ -717,6 +692,9 @@ public:
/// \brief Reset proxy state, e.g. requested atoms /// \brief Reset proxy state, e.g. requested atoms
virtual int reset(); virtual int reset();
/// Close any open files to prevent data loss
int close_files();
/// (Re)initialize required member data after construction /// (Re)initialize required member data after construction
virtual int setup(); virtual int setup();
@ -731,14 +709,17 @@ public:
/// Print a message to the main log /// Print a message to the main log
virtual void log(std::string const &message) = 0; virtual void log(std::string const &message) = 0;
/// Print a message to the main log and let the rest of the program handle the error /// Print a message to the main log and/or let the host code know about it
virtual void error(std::string const &message) = 0; virtual void error(std::string const &message) = 0;
/// Print a message to the main log and exit with error code /// Record error message (used by VMD to collect them after a script call)
virtual void fatal_error(std::string const &message) = 0; void add_error_msg(std::string const &message);
/// \brief Restarts will be written each time this number of steps has passed /// Retrieve accumulated error messages
virtual size_t restart_frequency(); std::string const & get_error_msgs();
/// As the name says
void clear_error_msgs();
/// Whether a simulation is running (warn against irrecovarable errors) /// Whether a simulation is running (warn against irrecovarable errors)
inline bool simulation_running() const inline bool simulation_running() const
@ -746,6 +727,17 @@ public:
return b_simulation_running; return b_simulation_running;
} }
/// Is the current step a repetition of a step just executed?
/// This is set to true when the step 0 of a new "run" command is being
/// executed, regardless of whether a state file has been loaded.
inline bool simulation_continuing() const
{
return b_simulation_continuing;
}
/// Called at the end of a simulation segment (i.e. "run" command)
int post_run();
/// Convert a version string "YYYY-MM-DD" into an integer /// Convert a version string "YYYY-MM-DD" into an integer
int get_version_from_string(char const *version_string); int get_version_from_string(char const *version_string);
@ -755,17 +747,46 @@ public:
return version_int; return version_int;
} }
/// \brief Returns a reference to the given output channel;
/// if this is not open already, then open it
virtual std::ostream *output_stream(std::string const &output_name,
std::ios_base::openmode mode =
std::ios_base::out);
/// Returns a reference to output_name if it exists, NULL otherwise
virtual std::ostream *get_output_stream(std::string const &output_name);
/// \brief Flushes the given output channel
virtual int flush_output_stream(std::ostream *os);
/// \brief Flushes all output channels
virtual int flush_output_streams();
/// \brief Closes the given output channel
virtual int close_output_stream(std::string const &output_name);
protected: protected:
/// Collected error messages
std::string error_output;
/// Whether a simulation is running (warn against irrecovarable errors) /// Whether a simulation is running (warn against irrecovarable errors)
bool b_simulation_running; bool b_simulation_running;
/// Is the current step a repetition of a step just executed?
/// This is set to true when the step 0 of a new "run" command is being
/// executed, regardless of whether a state file has been loaded.
bool b_simulation_continuing;
/// Whether the entire module should be deallocated by the host engine /// Whether the entire module should be deallocated by the host engine
bool b_delete_requested; bool b_delete_requested;
/// Integer representing the version string (allows comparisons) /// Integer representing the version string (allows comparisons)
int version_int; int version_int;
/// Raise when the output stream functions are used on threads other than 0
void smp_stream_error();
}; };

View File

@ -0,0 +1,160 @@
// -*- c++ -*-
// This file is part of the Collective Variables module (Colvars).
// The original version of Colvars and its updates are located at:
// https://github.com/Colvars/colvars
// Please update all Colvars source files before making any changes.
// If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub.
#include <sstream>
#if defined(NAMD_TCL) || defined(VMDTCL)
#define COLVARS_TCL
#include <tcl.h>
#endif
#include "colvarmodule.h"
#include "colvarproxy.h"
#include "colvarproxy_tcl.h"
#include "colvaratoms.h"
colvarproxy_tcl::colvarproxy_tcl()
{
tcl_interp_ = NULL;
}
colvarproxy_tcl::~colvarproxy_tcl()
{
}
void colvarproxy_tcl::init_tcl_pointers()
{
cvm::error("Error: Tcl support is not available in this build.\n",
COLVARS_NOT_IMPLEMENTED);
}
char const *colvarproxy_tcl::tcl_get_str(void *obj)
{
#if defined(COLVARS_TCL)
return Tcl_GetString(reinterpret_cast<Tcl_Obj *>(obj));
#else
return NULL;
#endif
}
int colvarproxy_tcl::tcl_run_force_callback()
{
#if defined(COLVARS_TCL)
Tcl_Interp *const tcl_interp =
reinterpret_cast<Tcl_Interp *>(get_tcl_interp());
std::string cmd = std::string("calc_colvar_forces ")
+ cvm::to_str(cvm::step_absolute());
int err = Tcl_Eval(tcl_interp, cmd.c_str());
if (err != TCL_OK) {
cvm::log(std::string("Error while executing calc_colvar_forces:\n"));
cvm::error(Tcl_GetStringResult(tcl_interp));
return COLVARS_ERROR;
}
return cvm::get_error();
#else
return COLVARS_NOT_IMPLEMENTED;
#endif
}
int colvarproxy_tcl::tcl_run_colvar_callback(
std::string const &name,
std::vector<const colvarvalue *> const &cvc_values,
colvarvalue &value)
{
#if defined(COLVARS_TCL)
Tcl_Interp *const tcl_interp =
reinterpret_cast<Tcl_Interp *>(get_tcl_interp());
size_t i;
std::string cmd = std::string("calc_") + name;
for (i = 0; i < cvc_values.size(); i++) {
cmd += std::string(" {") + (*(cvc_values[i])).to_simple_string() +
std::string("}");
}
int err = Tcl_Eval(tcl_interp, cmd.c_str());
const char *result = Tcl_GetStringResult(tcl_interp);
if (err != TCL_OK) {
return cvm::error(std::string("Error while executing ")
+ cmd + std::string(":\n") +
std::string(Tcl_GetStringResult(tcl_interp)),
COLVARS_ERROR);
}
std::istringstream is(result);
if (value.from_simple_string(is.str()) != COLVARS_OK) {
cvm::log("Error parsing colvar value from script:");
cvm::error(result);
return COLVARS_ERROR;
}
return cvm::get_error();
#else
return COLVARS_NOT_IMPLEMENTED;
#endif
}
int colvarproxy_tcl::tcl_run_colvar_gradient_callback(
std::string const &name,
std::vector<const colvarvalue *> const &cvc_values,
std::vector<cvm::matrix2d<cvm::real> > &gradient)
{
#if defined(COLVARS_TCL)
Tcl_Interp *const tcl_interp =
reinterpret_cast<Tcl_Interp *>(get_tcl_interp());
size_t i;
std::string cmd = std::string("calc_") + name + "_gradient";
for (i = 0; i < cvc_values.size(); i++) {
cmd += std::string(" {") + (*(cvc_values[i])).to_simple_string() +
std::string("}");
}
int err = Tcl_Eval(tcl_interp, cmd.c_str());
if (err != TCL_OK) {
return cvm::error(std::string("Error while executing ")
+ cmd + std::string(":\n") +
std::string(Tcl_GetStringResult(tcl_interp)),
COLVARS_ERROR);
}
Tcl_Obj **list;
int n;
Tcl_ListObjGetElements(tcl_interp, Tcl_GetObjResult(tcl_interp),
&n, &list);
if (n != int(gradient.size())) {
cvm::error("Error parsing list of gradient values from script: found "
+ cvm::to_str(n) + " values instead of " +
cvm::to_str(gradient.size()));
return COLVARS_ERROR;
}
for (i = 0; i < gradient.size(); i++) {
std::istringstream is(Tcl_GetString(list[i]));
if (gradient[i].from_simple_string(is.str()) != COLVARS_OK) {
cvm::log("Gradient matrix size: " + cvm::to_str(gradient[i].size()));
cvm::log("Gradient string: " + cvm::to_str(Tcl_GetString(list[i])));
cvm::error("Error parsing gradient value from script", COLVARS_ERROR);
return COLVARS_ERROR;
}
}
return cvm::get_error();
#else
return COLVARS_NOT_IMPLEMENTED;
#endif
}

View File

@ -0,0 +1,64 @@
// -*- c++ -*-
// This file is part of the Collective Variables module (Colvars).
// The original version of Colvars and its updates are located at:
// https://github.com/Colvars/colvars
// Please update all Colvars source files before making any changes.
// If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub.
#ifndef COLVARPROXY_TCL_H
#define COLVARPROXY_TCL_H
#include <vector>
/// Methods for using Tcl within Colvars
class colvarproxy_tcl {
public:
/// Constructor
colvarproxy_tcl();
/// Destructor
virtual ~colvarproxy_tcl();
/// Is Tcl available? (trigger initialization if needed)
int tcl_available();
/// Tcl implementation of script_obj_to_str()
char const *tcl_get_str(void *obj);
/// Tcl implementation of run_force_callback()
int tcl_run_force_callback();
/// Tcl implementation of run_colvar_callback()
int tcl_run_colvar_callback(
std::string const &name,
std::vector<const colvarvalue *> const &cvcs,
colvarvalue &value);
/// Tcl implementation of run_colvar_gradient_callback()
int tcl_run_colvar_gradient_callback(
std::string const &name,
std::vector<const colvarvalue *> const &cvcs,
std::vector<cvm::matrix2d<cvm::real> > &gradient);
/// Get a pointer to the Tcl interpreter
inline void *get_tcl_interp()
{
return tcl_interp_;
}
protected:
/// Pointer to Tcl interpreter object
void *tcl_interp_;
/// Set Tcl pointers
virtual void init_tcl_pointers();
};
#endif

View File

@ -0,0 +1,81 @@
// -*- c++ -*-
// This file is part of the Collective Variables module (Colvars).
// The original version of Colvars and its updates are located at:
// https://github.com/Colvars/colvars
// Please update all Colvars source files before making any changes.
// If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub.
#include "colvarmodule.h"
#include "colvarproxy_volmaps.h"
colvarproxy_volmaps::colvarproxy_volmaps() {}
colvarproxy_volmaps::~colvarproxy_volmaps() {}
int colvarproxy_volmaps::volmaps_available()
{
return COLVARS_NOT_IMPLEMENTED;
}
int colvarproxy_volmaps::reset()
{
for (size_t i = 0; i < volmaps_ids.size(); i++) {
clear_volmap(i);
}
volmaps_ids.clear();
volmaps_ncopies.clear();
volmaps_values.clear();
volmaps_new_colvar_forces.clear();
return COLVARS_OK;
}
int colvarproxy_volmaps::add_volmap_slot(int volmap_id)
{
volmaps_ids.push_back(volmap_id);
volmaps_ncopies.push_back(1);
volmaps_values.push_back(0.0);
volmaps_new_colvar_forces.push_back(0.0);
return (volmaps_ids.size() - 1);
}
int colvarproxy_volmaps::init_volmap(int volmap_id)
{
return cvm::error("Error: access to volumetric maps is unavailable "
"in this build.\n",
COLVARS_NOT_IMPLEMENTED);
}
int colvarproxy_volmaps::init_volmap(const char *volmap_name)
{
return cvm::error("Error: access to volumetric maps is unavailable "
"in this build.\n",
COLVARS_NOT_IMPLEMENTED);
}
int colvarproxy_volmaps::init_volmap(const std::string &volmap_name)
{
return init_volmap(volmap_name.c_str());
}
void colvarproxy_volmaps::clear_volmap(int index)
{
if (((size_t) index) >= volmaps_ids.size()) {
cvm::error("Error: trying to unrequest a volumetric map that was not "
"previously requested.\n", INPUT_ERROR);
}
if (volmaps_ncopies[index] > 0) {
volmaps_ncopies[index] -= 1;
}
}

View File

@ -0,0 +1,76 @@
// -*- c++ -*-
#ifndef COLVARPROXY_VOLMAPS_H
#define COLVARPROXY_VOLMAPS_H
/// \brief Container of grid-based objects
class colvarproxy_volmaps {
public:
/// Contructor
colvarproxy_volmaps();
/// Destructor
virtual ~colvarproxy_volmaps();
/// Clear volumetric map data
int reset();
/// \brief Whether this implementation has capability to use volumetric maps
virtual int volmaps_available();
/// Create a slot for a volumetric map not requested yet
int add_volmap_slot(int volmap_id);
/// Request and prepare this volumetric map for use by Colvars
virtual int init_volmap(int volmap_id);
/// Request and prepare this volumetric map for use by Colvars
virtual int init_volmap(char const *volmap_name);
/// Request and prepare this volumetric map for use by Colvars
int init_volmap(std::string const &volmap_name);
/// \brief Used by the CVC destructors
virtual void clear_volmap(int index);
/// Get the numeric ID of the given volumetric map (for the MD program)
inline int get_volmap_id(int index) const
{
return volmaps_ids[index];
}
/// Read the current value of the volumetric map
inline cvm::real get_volmap_value(int index) const
{
return volmaps_values[index];
}
/// Request that this force is applied to the given volumetric map
inline void apply_volmap_force(int index, cvm::real const &new_force)
{
volmaps_new_colvar_forces[index] += new_force;
}
protected:
/// \brief Array of numeric IDs of volumetric maps
std::vector<int> volmaps_ids;
/// \brief Keep track of how many times each vol map is used by a
/// separate colvar object
std::vector<size_t> volmaps_ncopies;
/// \brief Current values of the vol maps
std::vector<cvm::real> volmaps_values;
/// \brief Forces applied from colvars, to be communicated to the MD
/// integrator
std::vector<cvm::real> volmaps_new_colvar_forces;
};
#endif

View File

@ -1,3 +1,3 @@
#ifndef COLVARS_VERSION #ifndef COLVARS_VERSION
#define COLVARS_VERSION "2020-02-25" #define COLVARS_VERSION "2020-09-17"
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
// Colvars repository at GitHub. // Colvars repository at GitHub.
#ifndef COLVARSCRIPT_H #ifndef COLVARSCRIPT_H
//#define COLVARSCRIPT_H // Delay definition until later #define COLVARSCRIPT_H
#include <string> #include <string>
#include <vector> #include <vector>
@ -29,7 +29,7 @@ class colvarscript {
private: private:
colvarproxy *proxy; colvarproxy *proxy_;
colvarmodule *colvars; colvarmodule *colvars;
inline colvarscript() {} // no-argument construction forbidden inline colvarscript() {} // no-argument construction forbidden
@ -39,7 +39,8 @@ public:
friend class colvarproxy; friend class colvarproxy;
colvarscript(colvarproxy *p); colvarscript(colvarproxy *p);
inline ~colvarscript() {}
~colvarscript();
/// If an error is caught by the proxy through fatal_error(), this is set to /// If an error is caught by the proxy through fatal_error(), this is set to
/// COLVARSCRIPT_ERROR /// COLVARSCRIPT_ERROR
@ -49,112 +50,196 @@ public:
/// error message /// error message
std::string result; std::string result;
/// Run script command with given positional arguments (objects) /// Run a script command with space-separated positional arguments (objects)
int run(int objc, unsigned char *const objv[]); int run(int objc, unsigned char *const objv[]);
/// Set the return value of the script command to the given string /// Get the string result of the current scripting call
inline void set_str_result(std::string const &s) inline std::string const &str_result() const
{ {
result = s; return result;
} }
/// Build and return a short help /// Modify the string result of the current scripting call
std::string help_string(void) const; inline std::string &modify_str_result()
{
return result;
}
/// Set the return value to the given string
int set_result_str(std::string const &s);
/// Clear the string result
int clear_str_result();
/// Add the given string to the error message of the script interface
void add_error_msg(std::string const &s);
/// Commands available
enum command {
#define CVSCRIPT_ENUM_COMM(COMM) COMM,
#undef CVSCRIPT
#define CVSCRIPT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
CVSCRIPT_ENUM_COMM(COMM)
#ifdef COLVARSCRIPT_COMMANDS_H
#undef COLVARSCRIPT_COMMANDS_H
#endif
#include "colvarscript_commands.h"
#undef COLVARSCRIPT_COMMANDS_H
#undef CVSCRIPT
#undef CVSCRIPT_ENUM_COMM
cv_n_commands
};
/// Type of object handling a script command
enum Object_type {
use_module,
use_colvar,
use_bias
};
/// Return the prefix of the individual command for each object function
std::string get_cmd_prefix(Object_type t);
/// Get a pointer to the i-th argument of the command (NULL if not given)
template<Object_type T>
unsigned char *get_cmd_arg(int iarg, int objc, unsigned char *const objv[]);
/// Instantiation of get_cmd_arg<> for module-level commands
unsigned char *get_module_cmd_arg(int iarg, int objc,
unsigned char *const objv[]);
/// Instantiation of get_cmd_arg<> for colvar-level commands
unsigned char *get_colvar_cmd_arg(int iarg, int objc,
unsigned char *const objv[]);
/// Instantiation of get_cmd_arg<> for bias-level commands
unsigned char *get_bias_cmd_arg(int iarg, int objc,
unsigned char *const objv[]);
/// Check the argument count of the command
template<Object_type T>
int check_cmd_nargs(char const *cmd, int objc,
int n_args_min, int n_args_max);
/// Instantiation of check_cmd_nargs<> for module-level commands
int check_module_cmd_nargs(char const *cmd, int objc,
int n_args_min, int n_args_max);
/// Instantiation of check_cmd_nargs<> for colvar-level commands
int check_colvar_cmd_nargs(char const *cmd, int objc,
int n_args_min, int n_args_max);
/// Instantiation of get_cmd_arg<> for bias-level commands
int check_bias_cmd_nargs(char const *cmd, int objc,
int n_args_min, int n_args_max);
/// Number of positional arguments to shift for each object type
template<colvarscript::Object_type T>
int cmd_arg_shift();
/// Use scripting language to get the string representation of an object /// Use scripting language to get the string representation of an object
inline char const *obj_to_str(unsigned char *const obj) inline char const *obj_to_str(unsigned char *const obj)
{ {
return cvm::proxy->script_obj_to_str(obj); return (obj == NULL ? NULL : proxy_->script_obj_to_str(obj));
} }
enum command { /// Get names of all commands
cv_help, inline char const **get_command_names() const
cv_version, {
cv_config, return cmd_names;
cv_getconfig, }
cv_configfile,
cv_reset, /// Get help string for a command (does not specify how it is launched)
cv_resetindexgroups, /// \param cmd Name of the command's function (e.g. "cv_units")
cv_delete, std::string get_command_help(char const *cmd);
cv_list,
cv_list_biases, /// Get summary of command line syntax for all commands of a given context
cv_load, /// \param t One of use_module, use_colvar or use_bias
cv_save, std::string get_cmdline_help_summary(Object_type t);
cv_update,
cv_addenergy, /// Get a description of how the command should be used in a command line
cv_getenergy, /// \param t One of use_module, use_colvar or use_bias
cv_printframe, /// \param c Value of the \link command \endlink enum
cv_printframelabels, std::string get_command_cmdline_syntax(Object_type t, command c);
cv_frame,
cv_units, /// Get the command line syntax following by the help string
cv_colvar, /// \param t One of use_module, use_colvar or use_bias
cv_colvar_value, /// \param cmd Name of the subcommand (e.g. "units")
cv_colvar_update, std::string get_command_cmdline_help(Object_type t, std::string const &cmd);
cv_colvar_type,
cv_colvar_delete, /// Set error code for unsupported script operation
cv_colvar_addforce, int unsupported_op();
cv_colvar_getappliedforce,
cv_colvar_gettotalforce, /// Pointer to the Colvars main object
cv_colvar_cvcflags, inline colvarmodule *module()
cv_colvar_getconfig, {
cv_colvar_get, return this->colvars;
cv_colvar_set, }
cv_bias,
cv_bias_energy, /// Pointer to the colvarproxy object (interface with host engine)
cv_bias_update, inline colvarproxy *proxy()
cv_bias_delete, {
cv_bias_getconfig, return this->proxy_;
cv_bias_get, }
cv_bias_set,
cv_n_commands private:
};
/// Set up all script API functions
int init_commands();
/// Set up a single script API function
int init_command(colvarscript::command const &comm,
char const *name, char const *help,
int n_args_min, int n_args_max, char const *arghelp,
int (*fn)(void *, int, unsigned char * const *));
/// Execute a script command /// Execute a script command
inline int exec_command(command c, inline int exec_command(command c,
void *pobj, void *pobj,
int objc, unsigned char * const *objv) int objc, unsigned char * const *objv)
{ {
return (*(comm_fns[c]))(pobj, objc, objv); return (*(cmd_fns[c]))(pobj, objc, objv);
} }
/// Get help for a command (TODO reformat for each language?) public: // TODO this function will be removed soon
inline std::string command_help(colvarscript::command c) const
{
return comm_help[c];
}
/// Clear all object results
inline void clear_results()
{
result.clear();
}
private:
/// Run subcommands on colvar
int proc_colvar(colvar *cv, int argc, unsigned char *const argv[]);
/// Run subcommands on bias
int proc_bias(colvarbias *b, int argc, unsigned char *const argv[]);
/// Run subcommands on base colvardeps object (colvar, bias, ...) /// Run subcommands on base colvardeps object (colvar, bias, ...)
int proc_features(colvardeps *obj, int proc_features(colvardeps *obj,
int argc, unsigned char *const argv[]); int argc, unsigned char *const argv[]);
private: // TODO
/// Internal identifiers of command strings /// Internal identifiers of command strings
std::map<std::string, command> comm_str_map; std::map<std::string, command> cmd_str_map;
/// Inverse of cmd_str_map (to be exported outside this class)
char const **cmd_names;
/// Help strings for each command /// Help strings for each command
std::vector<std::string> comm_help; std::vector<std::string> cmd_help;
/// Number of arguments for each command /// Minimum number of arguments for each command
std::vector<size_t> comm_n_args; std::vector<size_t> cmd_n_args_min;
/// Arguments for each command /// Maximum number of arguments for each command
std::vector< std::vector<std::string> > comm_args; std::vector<size_t> cmd_n_args_max;
/// Help strings for each command argument
std::vector< std::vector<std::string> > cmd_arghelp;
/// Implementations of each command /// Implementations of each command
std::vector<int (*)(void *, int, unsigned char * const *)> comm_fns; std::vector<int (*)(void *, int, unsigned char * const *)> cmd_fns;
/// Get a pointer to the implementation of the given command
inline int (*get_cmd_fn(std::string const &cmd_key))(void *,
int,
unsigned char * const *)
{
if (cmd_str_map.count(cmd_key) > 0) {
return cmd_fns[cmd_str_map[cmd_key]];
}
return NULL;
}
}; };
@ -165,12 +250,14 @@ inline static colvarscript *colvarscript_obj()
return cvm::main()->proxy->script; return cvm::main()->proxy->script;
} }
/// Get a pointer to the colvar object pointed to by pobj /// Get a pointer to the colvar object pointed to by pobj
inline static colvar *colvar_obj(void *pobj) inline static colvar *colvar_obj(void *pobj)
{ {
return reinterpret_cast<colvar *>(pobj); return reinterpret_cast<colvar *>(pobj);
} }
/// Get a pointer to the colvarbias object pointed to by pobj /// Get a pointer to the colvarbias object pointed to by pobj
inline static colvarbias *colvarbias_obj(void *pobj) inline static colvarbias *colvarbias_obj(void *pobj)
{ {
@ -178,137 +265,124 @@ inline static colvarbias *colvarbias_obj(void *pobj)
} }
#define CVSCRIPT_COMM_FNAME(COMM) cvscript_ ## COMM
#define CVSCRIPT_COMM_PROTO(COMM) \ template<colvarscript::Object_type T>
int CVSCRIPT_COMM_FNAME(COMM)(void *, int, unsigned char *const *); unsigned char *colvarscript::get_cmd_arg(int iarg,
int objc,
#define CVSCRIPT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \ unsigned char *const objv[])
CVSCRIPT_COMM_PROTO(COMM) {
int const shift = cmd_arg_shift<T>();
#undef COLVARSCRIPT_H return (shift+iarg < objc) ? objv[shift+iarg] : NULL;
#endif // #ifndef COLVARSCRIPT_H
#ifdef COLVARSCRIPT_CPP
#define CVSCRIPT_COMM_FN(COMM,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
extern "C" int CVSCRIPT_COMM_FNAME(COMM)(void *pobj, \
int objc, \
unsigned char *const objv[]) \
{ \
colvarscript *script = colvarscript_obj(); \
script->clear_results(); \
if (objc < 2+N_ARGS_MIN) /* "cv" and "COMM" are 1st and 2nd */ { \
script->set_str_result("Missing arguments\n" + \
script->command_help(colvarscript::COMM)); \
return COLVARSCRIPT_ERROR; \
} \
if (objc > 2+N_ARGS_MAX) { \
script->set_str_result("Too many arguments\n" + \
script->command_help(colvarscript::COMM)); \
return COLVARSCRIPT_ERROR; \
} \
FN_BODY; \
} }
#undef CVSCRIPT
#define CVSCRIPT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
CVSCRIPT_COMM_FN(COMM,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY)
#endif // #ifdef COLVARSCRIPT_CPP
#ifdef COLVARSCRIPT_INIT_FN inline unsigned char *colvarscript::get_module_cmd_arg(int iarg, int objc,
#define CVSCRIPT_COMM_INIT(COMM,HELP,ARGS) { \ unsigned char *const objv[])
comm_str_map[#COMM] = COMM; \ {
comm_help[COMM] = HELP; \ return get_cmd_arg<use_module>(iarg, objc, objv);
comm_fns[COMM] = &(CVSCRIPT_COMM_FNAME(COMM)); \
} }
#undef CVSCRIPT
#define CVSCRIPT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
CVSCRIPT_COMM_INIT(COMM,HELP,ARGS)
#endif
#if !defined(COLVARSCRIPT_H) || defined(COLVARSCRIPT_INIT_FN) inline unsigned char *colvarscript::get_colvar_cmd_arg(int iarg, int objc,
#define COLVARSCRIPT_H unsigned char *const objv[])
{
#ifndef COLVARSCRIPT_INIT_FN return get_cmd_arg<use_colvar>(iarg, objc, objv);
#ifdef __cplusplus
extern "C" {
#endif
#endif
// Add optional arguments for command-specific help?
CVSCRIPT(cv_help,
"Print the help message",
0, 0,
{},
script->set_str_result(script->help_string());
return COLVARS_OK;
)
CVSCRIPT(cv_config,
"Read configuration from the given string",
1, 1,
{ "conf (str) - Configuration string" },
std::string const conf(script->obj_to_str(objv[2]));
if (cvm::main()->read_config_string(conf) == COLVARS_OK) {
return COLVARS_OK;
} }
script->set_str_result("Error parsing configuration string");
inline unsigned char *colvarscript::get_bias_cmd_arg(int iarg, int objc,
unsigned char *const objv[])
{
return get_cmd_arg<use_bias>(iarg, objc, objv);
}
template<colvarscript::Object_type T>
int colvarscript::check_cmd_nargs(char const *cmd,
int objc,
int n_args_min,
int n_args_max)
{
int const shift = cmd_arg_shift<T>();
if (objc < shift+n_args_min) {
add_error_msg("Missing arguments for script function \""+std::string(cmd)+
"\":\n"+get_command_help(cmd));
return COLVARSCRIPT_ERROR; return COLVARSCRIPT_ERROR;
)
CVSCRIPT(cv_getconfig,
"Get the module's configuration string read so far",
0, 0,
{ },
script->set_str_result(cvm::main()->get_config());
return COLVARS_OK;
)
CVSCRIPT(cv_resetindexgroups,
"Clear the index groups loaded so far, allowing to replace them",
0, 0,
{ },
return cvm::main()->reset_index_groups();
)
CVSCRIPT(cv_addenergy,
"Add an energy to the MD engine",
1, 1,
{ "E (float) - Amount of energy to add" },
cvm::main()->total_bias_energy +=
strtod(script->obj_to_str(objv[2]), NULL);
return COLVARS_OK;
)
CVSCRIPT(cv_getenergy,
"Get the current Colvars energy",
1, 1,
{ "E (float) - Store the energy in this variable" },
double *energy = reinterpret_cast<double *>(objv[2]);
*energy = cvm::main()->total_bias_energy;
return COLVARS_OK;
)
CVSCRIPT(cv_units,
"Get the current Colvars unit system",
0, 1,
{ },
if (objc < 3) {
script->set_str_result(cvm::proxy->units);
return COLVARS_OK;
} else {
return cvm::proxy->set_unit_system(script->obj_to_str(objv[2]) , false);
} }
) if (objc > shift+n_args_max) {
add_error_msg("Too many arguments for script function \""+std::string(cmd)+
"\":\n"+get_command_help(cmd));
return COLVARSCRIPT_ERROR;
}
return COLVARSCRIPT_OK;
}
#ifndef COLVARSCRIPT_INIT_FN
#ifdef __cplusplus
} // extern "C"
#endif
#endif
#undef CVSCRIPT inline int colvarscript::check_module_cmd_nargs(char const *cmd,
int objc,
int n_args_min,
int n_args_max)
{
return check_cmd_nargs<use_module>(cmd, objc, n_args_min, n_args_max);
}
inline int colvarscript::check_colvar_cmd_nargs(char const *cmd,
int objc,
int n_args_min,
int n_args_max)
{
return check_cmd_nargs<use_colvar>(cmd, objc, n_args_min, n_args_max);
}
inline int colvarscript::check_bias_cmd_nargs(char const *cmd,
int objc,
int n_args_min,
int n_args_max)
{
return check_cmd_nargs<use_bias>(cmd, objc, n_args_min, n_args_max);
}
template<colvarscript::Object_type T>
int colvarscript::cmd_arg_shift()
{
int shift = 0;
if (T == use_module) {
// "cv" and "COMMAND" are 1st and 2nd argument, and shift is equal to 2
shift = 2;
} else if (T == use_colvar) {
// Same as above with additional arguments "colvar" and "NAME"
shift = 4;
} else if (T == use_bias) {
shift = 4;
}
return shift;
}
extern "C" {
#if defined(COLVARS_TCL)
/// Run the script API via Tcl command-line interface
/// \param clientData Not used
/// \param my_interp Pointer to Tcl_Interp object (read from Colvars if NULL)
/// \param objc Number of Tcl command parameters
/// \param objv Array of command parameters
/// \return Result of the script command
int tcl_run_colvarscript_command(ClientData clientData,
Tcl_Interp *interp_in,
int objc, Tcl_Obj *const objv[]);
#endif // #if defined(COLVARS_TCL)
/// Generic wrapper for string-based scripting
int run_colvarscript_command(int objc, unsigned char *const objv[]);
/// Get the string result of a script call
const char * get_colvarscript_result();
}
#endif // #ifndef COLVARSCRIPT_H #endif // #ifndef COLVARSCRIPT_H

View File

@ -0,0 +1,65 @@
// -*- c++ -*-
// This file is part of the Collective Variables module (Colvars).
// The original version of Colvars and its updates are located at:
// https://github.com/Colvars/colvars
// Please update all Colvars source files before making any changes.
// If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub.
#include <vector>
#include <cstdlib>
#include <string.h>
#include "colvarproxy.h"
#include "colvardeps.h"
#include "colvarscript.h"
#include "colvarscript_commands.h"
extern "C"
int cvscript_n_commands()
{
return static_cast<int>(colvarscript::cv_n_commands);
}
extern "C"
char const **cvscript_command_names()
{
colvarscript *script = colvarscript_obj();
return script->get_command_names();
}
// Instantiate the body of all script commands
#define CVSCRIPT_COMM_FN(COMM,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
int CVSCRIPT_COMM_FNAME(COMM)(void *pobj, \
int objc, unsigned char *const objv[]) \
{ \
if (cvm::debug()) { \
cvm::log("Executing script function \""+std::string(#COMM)+"\""); \
} \
colvarscript *script = colvarscript_obj(); \
script->clear_str_result(); \
if (script->check_module_cmd_nargs(#COMM, \
objc, N_ARGS_MIN, N_ARGS_MAX) != \
COLVARSCRIPT_OK) { \
return COLVARSCRIPT_ERROR; \
} \
FN_BODY; \
}
#undef CVSCRIPT
#define CVSCRIPT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
CVSCRIPT_COMM_FN(COMM,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY)
// Skips the colvar- and bias- specific commands
#define COLVARSCRIPT_COMMANDS_GLOBAL
#undef COLVARSCRIPT_COMMANDS_H
#include "colvarscript_commands.h"
#undef CVSCRIPT_COMM_FN
#undef CVSCRIPT

View File

@ -0,0 +1,407 @@
// -*- c++ -*-
// This file is part of the Collective Variables module (Colvars).
// The original version of Colvars and its updates are located at:
// https://github.com/Colvars/colvars
// Please update all Colvars source files before making any changes.
// If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub.
#ifndef COLVARSCRIPT_COMMANDS_H
#define COLVARSCRIPT_COMMANDS_H
// The following is a complete definition of the scripting API.
// The CVSCRIPT macro is used in four distinct contexts:
// 1) Expand to the functions' prototypes (when included generically)
// 2) List colvarscript::command entries (when included in colvarscript.h)
// 3) Implement colvarscript::init() (when included in colvarscript.cpp)
// 4) Define the functions' bodies (when included in colvarscript_commands.cpp)
// Each command is created by an instance of the CVSCRIPT macro
// The arguments of the CVSCRIPT macro are:
// COMM = the id of the command (must be a member of colvarscript::command)
// HELP = a one-line description (C string literal) for the command
// N_ARGS_MIN = the lowest number of arguments allowed
// N_ARGS_MAX = the highest number of arguments allowed
// ARGS = multi-line string literal describing each parameter; each line
// follows the format "name : type - description"
// FN_BODY = the implementation of the function; this should be a thin wrapper
// over existing functions; the "script" pointer to the colvarscript
// object is already set by the CVSCRIPT_COMM_FN macro; see also the
// functions in colvarscript_commands.h.
#ifndef CVSCRIPT_COMM_FNAME
#define CVSCRIPT_COMM_FNAME(COMM) cvscript_ ## COMM
#endif
// If CVSCRIPT is not defined, this file yields the function prototypes
#ifndef CVSCRIPT
#ifdef __cplusplus
#define CVSCRIPT_COMM_PROTO(COMM) \
extern "C" int CVSCRIPT_COMM_FNAME(COMM)(void *, \
int, unsigned char *const *);
#else
#define CVSCRIPT_COMM_PROTO(COMM) \
int CVSCRIPT_COMM_FNAME(COMM)(void *, int, unsigned char *const *);
#endif
#define CVSCRIPT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
CVSCRIPT_COMM_PROTO(COMM)
// Utility functions used to query the command database
extern "C" {
/// Get the number of colvarscript commands
int cvscript_n_commands();
/// Get the names of all commands (array of strings)
char const ** cvscript_command_names();
}
#endif
CVSCRIPT(cv_addenergy,
"Add an energy to the MD engine (no effect in VMD)",
1, 1,
"E : float - Amount of energy to add",
char const *Earg =
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
cvm::main()->total_bias_energy += strtod(Earg, NULL);
return cvm::get_error(); // TODO Make this multi-language
)
CVSCRIPT(cv_bias,
"Prefix for bias-specific commands",
0, 0,
"",
// This cannot be executed from a command line
return COLVARS_OK;
)
CVSCRIPT(cv_colvar,
"Prefix for colvar-specific commands",
0, 0,
"",
// This cannot be executed from a command line
return COLVARS_OK;
)
CVSCRIPT(cv_config,
"Read configuration from the given string",
1, 1,
"conf : string - Configuration string",
char const *conf_str =
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
std::string const conf(conf_str);
if (cvm::main()->read_config_string(conf) == COLVARS_OK) {
return COLVARS_OK;
}
script->add_error_msg("Error parsing configuration string");
return COLVARSCRIPT_ERROR;
)
CVSCRIPT(cv_configfile,
"Read configuration from a file",
1, 1,
"conf_file : string - Path to configuration file",
char const *conf_file_name =
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
if (script->module()->read_config_file(conf_file_name) == COLVARS_OK) {
return COLVARS_OK;
} else {
script->add_error_msg("Error parsing configuration file");
return COLVARSCRIPT_ERROR;
}
)
CVSCRIPT(cv_delete,
"Delete this Colvars module instance (VMD only)",
0, 0,
"",
return script->proxy()->request_deletion();
)
CVSCRIPT(cv_frame,
"Get or set current frame number (VMD only)",
0, 1,
"frame : integer - Frame number",
char const *arg =
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
if (arg == NULL) {
long int f = -1;
if (script->proxy()->get_frame(f) == COLVARS_OK) {
script->set_result_str(cvm::to_str(f));
return COLVARS_OK;
} else {
script->add_error_msg("Frame number is not available");
return COLVARSCRIPT_ERROR;
}
} else {
int const f = strtol(const_cast<char *>(arg), NULL, 10);
int error_code = script->proxy()->set_frame(f);
if (error_code == COLVARS_NO_SUCH_FRAME) {
script->add_error_msg("Invalid frame number: \""+std::string(arg)+
"\"\n");
}
return error_code;
}
return COLVARS_OK;
)
CVSCRIPT(cv_getconfig,
"Get the module's configuration string read so far",
0, 0,
"",
script->set_result_str(cvm::main()->get_config());
return COLVARS_OK;
)
CVSCRIPT(cv_getenergy,
"Get the current Colvars energy",
0, 0,
"",
script->set_result_str(cvm::to_str(cvm::main()->total_bias_energy));
return COLVARS_OK;
)
CVSCRIPT(cv_help,
"Get the help string of the Colvars scripting interface",
0, 1,
"command : string - Get the help string of this specific command",
unsigned char *const cmdobj =
script->get_module_cmd_arg(0, objc, objv);
if (cmdobj) {
std::string const cmdstr(script->obj_to_str(cmdobj));
if (cmdstr.size()) {
if (cmdstr == std::string("colvar")) {
script->set_result_str(script->get_cmdline_help_summary(colvarscript::use_colvar));
} else if (cmdstr == std::string("bias")) {
script->set_result_str(script->get_cmdline_help_summary(colvarscript::use_bias));
} else {
script->set_result_str(script->get_command_cmdline_help(colvarscript::use_module,
cmdstr));
}
return cvm::get_error();
} else {
return COLVARSCRIPT_ERROR;
}
} else {
script->set_result_str(script->get_cmdline_help_summary(colvarscript::use_module));
return COLVARS_OK;
}
)
CVSCRIPT(cv_list,
"Return a list of all variables or biases",
0, 1,
"param : string - \"colvars\" or \"biases\"; default is \"colvars\"",
std::string res;
unsigned char *const kwarg = script->get_module_cmd_arg(0, objc, objv);
std::string const kwstr = kwarg ? script->obj_to_str(kwarg) :
std::string("colvars");
if (kwstr == "colvars") {
for (std::vector<colvar *>::iterator cvi = script->module()->variables()->begin();
cvi != script->module()->variables()->end();
++cvi) {
res += (cvi == script->module()->variables()->begin() ? "" : " ") + (*cvi)->name;
}
script->set_result_str(res);
return COLVARS_OK;
} else if (kwstr == "biases") {
for (std::vector<colvarbias *>::iterator bi = script->module()->biases.begin();
bi != script->module()->biases.end();
++bi) {
res += (bi == script->module()->biases.begin() ? "" : " ") + (*bi)->name;
}
script->set_result_str(res);
return COLVARS_OK;
} else {
script->add_error_msg("Wrong arguments to command \"list\"\n");
return COLVARSCRIPT_ERROR;
}
)
CVSCRIPT(cv_listcommands,
"Get the list of script functions, prefixed with \"cv_\", \"colvar_\" or \"bias_\"",
0, 0,
"",
int const n_commands = cvscript_n_commands();
char const **command_names = cvscript_command_names();
std::string result;
for (int i = 0; i < n_commands; i++) {
if (i > 0) result.append(1, ' ');
result.append(std::string(command_names[i]));
}
script->set_result_str(result);
return COLVARS_OK;
)
CVSCRIPT(cv_load,
"Load data from a state file into all matching colvars and biases",
1, 1,
"prefix : string - Path to existing state file or input prefix",
char const *arg =
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
script->proxy()->input_prefix() = cvm::state_file_prefix(arg);
if (script->module()->setup_input() == COLVARS_OK) {
return COLVARS_OK;
} else {
script->add_error_msg("Error loading state file");
return COLVARSCRIPT_ERROR;
}
)
CVSCRIPT(cv_loadfromstring,
"Load state data from a string into all matching colvars and biases",
1, 1,
"buffer : string - String buffer containing the state information",
char const *arg =
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
script->proxy()->input_buffer() = arg;
if (script->module()->setup_input() == COLVARS_OK) {
return COLVARS_OK;
} else {
script->add_error_msg("Error loading state string");
return COLVARSCRIPT_ERROR;
}
)
CVSCRIPT(cv_molid,
"Get or set the molecule ID on which Colvars is defined (VMD only)",
0, 1,
"molid : integer - Molecule ID; -1 means undefined",
char const *arg =
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
if (arg == NULL) {
int molid = -1;
script->proxy()->get_molid(molid);
script->set_result_str(cvm::to_str(molid));
return COLVARS_OK;
} else {
script->add_error_msg("Error: To change the molecule ID in VMD, use cv delete first.");
return COLVARS_NOT_IMPLEMENTED;
}
)
CVSCRIPT(cv_printframe,
"Return the values that would be written to colvars.traj",
0, 0,
"",
std::ostringstream os;
script->module()->write_traj(os);
script->set_result_str(os.str());
return COLVARS_OK;
)
CVSCRIPT(cv_printframelabels,
"Return the labels that would be written to colvars.traj",
0, 0,
"",
std::ostringstream os;
script->module()->write_traj_label(os);
script->set_result_str(os.str());
return COLVARS_OK;
)
CVSCRIPT(cv_reset,
"Delete all internal configuration",
0, 0,
"",
return script->module()->reset();
)
CVSCRIPT(cv_resetindexgroups,
"Clear the index groups loaded so far, allowing to replace them",
0, 0,
"",
cvm::main()->index_group_names.clear();
cvm::main()->index_groups.clear();
return COLVARS_OK;
)
CVSCRIPT(cv_save,
"Change the prefix of all output files and save them",
1, 1,
"prefix : string - Output prefix with trailing \".colvars.state\" gets removed)",
std::string const prefix =
cvm::state_file_prefix(script->obj_to_str(script->get_module_cmd_arg(0, objc, objv)));
script->proxy()->output_prefix() = prefix;
int error_code = COLVARS_OK;
error_code |= script->module()->setup_output();
error_code |= script->module()->write_restart_file(prefix+
".colvars.state");
error_code |= script->module()->write_output_files();
return error_code;
)
CVSCRIPT(cv_savetostring,
"Write the Colvars state to a string and return it",
0, 0,
"",
return script->module()->write_restart_string(script->modify_str_result());
)
CVSCRIPT(cv_units,
"Get or set the current Colvars unit system",
0, 1,
"units : string - The new unit system",
char const *argstr =
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
if (argstr) {
return cvm::proxy->set_unit_system(argstr, false);
} else {
script->set_result_str(cvm::proxy->units);
return COLVARS_OK;
}
)
CVSCRIPT(cv_update,
"Recalculate colvars and biases",
0, 0,
"",
int error_code = script->proxy()->update_input();
if (error_code) {
script->add_error_msg("Error updating the Colvars module (input)");
return error_code;
}
error_code |= script->module()->calc();
if (error_code) {
script->add_error_msg("Error updating the Colvars module (calc)");
return error_code;
}
error_code |= script->proxy()->update_output();
if (error_code) {
script->add_error_msg("Error updating the Colvars module (output)");
}
return error_code;
)
CVSCRIPT(cv_version,
"Get the Colvars Module version number",
0, 0,
"",
script->set_result_str(COLVARS_VERSION);
return COLVARS_OK;
)
// This guard allows compiling colvar and bias function bodies in their
// respecitve files instead of colvarscript_commands.o
#ifndef COLVARSCRIPT_COMMANDS_GLOBAL
#include "colvarscript_commands_colvar.h"
#include "colvarscript_commands_bias.h"
#endif
#endif // #ifndef COLVARSCRIPT_COMMANDS_H

View File

@ -0,0 +1,49 @@
// -*- c++ -*-
// This file is part of the Collective Variables module (Colvars).
// The original version of Colvars and its updates are located at:
// https://github.com/Colvars/colvars
// Please update all Colvars source files before making any changes.
// If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub.
#include <vector>
#include <cstdlib>
#include <stdlib.h>
#include <string.h>
#include "colvarproxy.h"
#include "colvardeps.h"
#include "colvarscript.h"
#include "colvarscript_commands.h"
// Instantiate the body of all bias-specific script commands
#define CVSCRIPT_COMM_FN(COMM,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
int CVSCRIPT_COMM_FNAME(COMM)(void *pobj, \
int objc, unsigned char *const objv[]) \
{ \
if (cvm::debug()) { \
cvm::log("Executing script function \""+std::string(#COMM)+"\""); \
} \
colvarscript *script = colvarscript_obj(); \
script->clear_str_result(); \
if (script->check_bias_cmd_nargs(#COMM, \
objc, N_ARGS_MIN, N_ARGS_MAX) != \
COLVARSCRIPT_OK) { \
return COLVARSCRIPT_ERROR; \
} \
colvarbias *this_bias = colvarbias_obj(pobj); \
FN_BODY; \
}
#undef CVSCRIPT
#define CVSCRIPT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
CVSCRIPT_COMM_FN(COMM,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY)
#include "colvarscript_commands_bias.h"
#undef CVSCRIPT_COMM_FN
#undef CVSCRIPT

View File

@ -0,0 +1,173 @@
// -*- c++ -*-
// This file is part of the Collective Variables module (Colvars).
// The original version of Colvars and its updates are located at:
// https://github.com/Colvars/colvars
// Please update all Colvars source files before making any changes.
// If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub.
CVSCRIPT(bias_bin,
"Get the current grid bin index (1D ABF only for now)",
0, 0,
"",
script->set_result_str(cvm::to_str(this_bias->current_bin()));
return COLVARS_OK;
)
CVSCRIPT(bias_bincount,
"Get the number of samples at the given grid bin (1D ABF only for now)",
0, 1,
"index : integer - Grid index; defaults to current bin",
int index = this_bias->current_bin();
char const *indexarg =
script->obj_to_str(script->get_bias_cmd_arg(0, objc, objv));
if (indexarg) {
std::string const param(indexarg);
if (!(std::istringstream(param) >> index)) {
script->add_error_msg("bincount: error parsing bin index");
return COLVARSCRIPT_ERROR;
}
}
script->set_result_str(cvm::to_str(this_bias->bin_count(index)));
return COLVARS_OK;
)
CVSCRIPT(bias_binnum,
"Get the total number of grid points of this bias (1D ABF only for now)",
0, 0,
"",
int r = this_bias->bin_num();
if (r < 0) {
script->add_error_msg("Error: calling bin_num() for bias " +
this_bias->name);
return COLVARSCRIPT_ERROR;
}
script->set_result_str(cvm::to_str(r));
return COLVARS_OK;
)
CVSCRIPT(bias_delete,
"Delete this bias",
0, 0,
"",
delete this_bias;
return COLVARS_OK;
)
CVSCRIPT(bias_energy,
"Get the current energy of this bias",
0, 0,
"",
script->set_result_str(cvm::to_str(this_bias->get_energy()));
return COLVARS_OK;
)
CVSCRIPT(bias_get,
"Get the value of the given feature for this bias",
1, 1,
"feature : string - Name of the feature",
return script->proc_features(this_bias, objc, objv);
)
CVSCRIPT(bias_getconfig,
"Return the configuration string of this bias",
0, 0,
"",
script->set_result_str(this_bias->get_config());
return COLVARS_OK;
)
CVSCRIPT(bias_help,
"Get a help summary or the help string of one bias subcommand",
0, 1,
"command : string - Get the help string of this specific command",
unsigned char *const cmdobj =
script->get_colvar_cmd_arg(0, objc, objv);
if (this_bias) {
}
if (cmdobj) {
std::string const cmdstr(script->obj_to_str(cmdobj));
if (cmdstr.size()) {
script->set_result_str(script->get_command_cmdline_help(colvarscript::use_bias,
cmdstr));
return COLVARS_OK;
} else {
return COLVARSCRIPT_ERROR;
}
} else {
script->set_result_str(script->get_cmdline_help_summary(colvarscript::use_bias));
return COLVARS_OK;
}
)
CVSCRIPT(bias_load,
"Load data into this bias",
1, 1,
"prefix : string - Read from a file with this name or prefix",
char const *arg =
script->obj_to_str(script->get_bias_cmd_arg(0, objc, objv));
return this_bias->read_state_prefix(std::string(arg));
)
CVSCRIPT(bias_loadfromstring,
"Load state data into this bias from a string",
1, 1,
"buffer : string - String buffer containing the state information",
char const *buffer = script->obj_to_str(script->get_bias_cmd_arg(0, objc, objv));
return this_bias->read_state_string(buffer);
)
CVSCRIPT(bias_save,
"Save data from this bias into a file with the given prefix",
1, 1,
"prefix : string - Prefix for the state file of this bias",
std::string const prefix =
cvm::state_file_prefix(script->obj_to_str(script->get_bias_cmd_arg(0, objc, objv)));
return this_bias->write_state_prefix(prefix);
)
CVSCRIPT(bias_savetostring,
"Save data from this bias into a string and return it",
0, 0,
"",
return this_bias->write_state_string(script->modify_str_result());
)
CVSCRIPT(bias_set,
"Set the given feature of this bias to a new value",
2, 2,
"feature : string - Name of the feature\n"
"value : string - String representation of the new feature value",
return script->proc_features(this_bias, objc, objv);
)
CVSCRIPT(bias_share,
"Share bias information with other replicas (multiple-walker scheme)",
0, 0,
"",
if (this_bias->replica_share() != COLVARS_OK) {
script->add_error_msg("Error: calling replica_share() for bias " +
this_bias->name);
return COLVARSCRIPT_ERROR;
}
return COLVARS_OK;
)
CVSCRIPT(bias_state,
"Print a string representation of the feature state of this bias",
0, 0,
"",
this_bias->print_state();
return COLVARS_OK;
)
CVSCRIPT(bias_update,
"Recompute this bias and return its up-to-date energy",
0, 0,
"",
this_bias->update();
script->set_result_str(cvm::to_str(this_bias->get_energy()));
return COLVARS_OK;
)

View File

@ -0,0 +1,49 @@
// -*- c++ -*-
// This file is part of the Collective Variables module (Colvars).
// The original version of Colvars and its updates are located at:
// https://github.com/Colvars/colvars
// Please update all Colvars source files before making any changes.
// If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub.
#include <vector>
#include <cstdlib>
#include <stdlib.h>
#include <string.h>
#include "colvarproxy.h"
#include "colvardeps.h"
#include "colvarscript.h"
#include "colvarscript_commands.h"
// Instantiate the body of all colvar-specific script commands
#define CVSCRIPT_COMM_FN(COMM,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
int CVSCRIPT_COMM_FNAME(COMM)(void *pobj, \
int objc, unsigned char *const objv[]) \
{ \
if (cvm::debug()) { \
cvm::log("Executing script function \""+std::string(#COMM)+"\""); \
} \
colvarscript *script = colvarscript_obj(); \
script->clear_str_result(); \
if (script->check_colvar_cmd_nargs(#COMM, \
objc, N_ARGS_MIN, N_ARGS_MAX) != \
COLVARSCRIPT_OK) { \
return COLVARSCRIPT_ERROR; \
} \
colvar *this_colvar = colvar_obj(pobj); \
FN_BODY; \
}
#undef CVSCRIPT
#define CVSCRIPT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
CVSCRIPT_COMM_FN(COMM,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY)
#include "colvarscript_commands_colvar.h"
#undef CVSCRIPT_COMM_FN
#undef CVSCRIPT

View File

@ -0,0 +1,239 @@
// -*- c++ -*-
// This file is part of the Collective Variables module (Colvars).
// The original version of Colvars and its updates are located at:
// https://github.com/Colvars/colvars
// Please update all Colvars source files before making any changes.
// If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub.
CVSCRIPT(colvar_addforce,
"Apply the given force onto this colvar and return the same",
1, 1,
"force : float or array - Applied force; must match colvar dimensionality",
std::string const f_str(script->obj_to_str(script->get_colvar_cmd_arg(0, objc, objv)));
std::istringstream is(f_str);
is.width(cvm::cv_width);
is.precision(cvm::cv_prec);
colvarvalue force(this_colvar->value());
force.is_derivative();
if (force.from_simple_string(is.str()) != COLVARS_OK) {
script->add_error_msg("addforce : error parsing force value");
return COLVARSCRIPT_ERROR;
}
this_colvar->add_bias_force(force);
script->set_result_str(force.to_simple_string());
return COLVARS_OK;
)
CVSCRIPT(colvar_cvcflags,
"Enable or disable individual components by setting their active flags",
1, 1,
"flags : integer array - Zero/nonzero value disables/enables the CVC",
std::string const flags_str(script->obj_to_str(script->get_colvar_cmd_arg(0, objc, objv)));
std::istringstream is(flags_str);
std::vector<bool> flags;
int flag;
while (is >> flag) {
flags.push_back(flag != 0);
}
int res = this_colvar->set_cvc_flags(flags);
if (res != COLVARS_OK) {
script->add_error_msg("Error setting CVC flags");
return COLVARSCRIPT_ERROR;
}
script->set_result_str("0");
return COLVARS_OK;
)
CVSCRIPT(colvar_delete,
"Delete this colvar, along with all biases that depend on it",
0, 0,
"",
delete this_colvar;
return COLVARS_OK;
)
CVSCRIPT(colvar_get,
"Get the value of the given feature for this colvar",
1, 1,
"feature : string - Name of the feature",
return script->proc_features(this_colvar, objc, objv);
)
CVSCRIPT(colvar_getappliedforce,
"Return the total of the forces applied to this colvar",
0, 0,
"",
script->set_result_str((this_colvar->applied_force()).to_simple_string());
return COLVARS_OK;
)
CVSCRIPT(colvar_getatomgroups,
"Return the atom indices used by this colvar as a list of lists",
0, 0,
"",
std::string result;
std::vector<std::vector<int> > lists = this_colvar->get_atom_lists();
std::vector<std::vector<int> >::iterator li = lists.begin();
for ( ; li != lists.end(); ++li) {
result += "{";
std::vector<int>::iterator lj = (*li).begin();
for ( ; lj != (*li).end(); ++lj) {
result += cvm::to_str(*lj);
result += " ";
}
result += "} ";
}
script->set_result_str(result);
return COLVARS_OK;
)
CVSCRIPT(colvar_getatomids,
"Return the list of atom indices used by this colvar",
0, 0,
"",
std::string result;
std::vector<int>::iterator li = this_colvar->atom_ids.begin();
for ( ; li != this_colvar->atom_ids.end(); ++li) {
result += cvm::to_str(*li);
result += " ";
}
script->set_result_str(result);
return COLVARS_OK;
)
CVSCRIPT(colvar_getconfig,
"Return the configuration string of this colvar",
0, 0,
"",
script->set_result_str(this_colvar->get_config());
return COLVARS_OK;
)
CVSCRIPT(colvar_getgradients,
"Return the atomic gradients of this colvar",
0, 0,
"",
std::string result;
std::vector<cvm::rvector>::iterator li =
this_colvar->atomic_gradients.begin();
for ( ; li != this_colvar->atomic_gradients.end(); ++li) {
result += "{";
int j;
for (j = 0; j < 3; ++j) {
result += cvm::to_str((*li)[j]);
result += " ";
}
result += "} ";
}
script->set_result_str(result);
return COLVARS_OK;
)
CVSCRIPT(colvar_gettotalforce,
"Return the sum of internal and external forces to this colvar",
0, 0,
"",
script->set_result_str((this_colvar->total_force()).to_simple_string());
return COLVARS_OK;
)
CVSCRIPT(colvar_help,
"Get a help summary or the help string of one colvar subcommand",
0, 1,
"command : string - Get the help string of this specific command",
unsigned char *const cmdobj =
script->get_colvar_cmd_arg(0, objc, objv);
if (this_colvar) {
}
if (cmdobj) {
std::string const cmdstr(script->obj_to_str(cmdobj));
if (cmdstr.size()) {
script->set_result_str(script->get_command_cmdline_help(colvarscript::use_colvar,
cmdstr));
return cvm::get_error();
} else {
return COLVARSCRIPT_ERROR;
}
} else {
script->set_result_str(script->get_cmdline_help_summary(colvarscript::use_colvar));
return COLVARS_OK;
}
)
CVSCRIPT(colvar_modifycvcs,
"Modify configuration of individual components by passing string arguments",
1, 1,
"confs : sequence of strings - New configurations; empty strings are skipped",
std::vector<std::string> const confs(script->proxy()->script_obj_to_str_vector(script->get_colvar_cmd_arg(0, objc, objv)));
cvm::increase_depth();
int res = this_colvar->update_cvc_config(confs);
cvm::decrease_depth();
if (res != COLVARS_OK) {
script->add_error_msg("Error setting CVC flags");
return COLVARSCRIPT_ERROR;
}
script->set_result_str("0");
return COLVARS_OK;
)
CVSCRIPT(colvar_run_ave,
"Get the current running average of the value of this colvar",
0, 0,
"",
script->set_result_str(this_colvar->run_ave().to_simple_string());
return COLVARS_OK;
)
CVSCRIPT(colvar_set,
"Set the given feature of this colvar to a new value",
2, 2,
"feature : string - Name of the feature\n"
"value : string - String representation of the new feature value",
return script->proc_features(this_colvar, objc, objv);
)
CVSCRIPT(colvar_state,
"Print a string representation of the feature state of this colvar",
0, 0,
"",
this_colvar->print_state();
return COLVARS_OK;
)
CVSCRIPT(colvar_type,
"Get the type description of this colvar",
0, 0,
"",
script->set_result_str(this_colvar->value().type_desc(this_colvar->value().value_type));
return COLVARS_OK;
)
CVSCRIPT(colvar_update,
"Recompute this colvar and return its up-to-date value",
0, 0,
"",
this_colvar->calc();
this_colvar->update_forces_energy();
script->set_result_str((this_colvar->value()).to_simple_string());
return COLVARS_OK;
)
CVSCRIPT(colvar_value,
"Get the current value of this colvar",
0, 0,
"",
script->set_result_str(this_colvar->value().to_simple_string());
return COLVARS_OK;
)
CVSCRIPT(colvar_width,
"Get the width of this colvar",
0, 0,
"",
script->set_result_str(cvm::to_str(this_colvar->width, 0,
cvm::cv_prec));
return COLVARS_OK;
)

View File

@ -14,25 +14,19 @@
#include "colvartypes.h" #include "colvartypes.h"
#include "colvarparse.h" #include "colvarparse.h"
#ifdef COLVARS_LAMMPS
// Use open-source Jacobi implementation
#include "math_eigen_impl.h"
#else
// Fall back to NR routine
#include "nr_jacobi.h"
#endif
bool colvarmodule::rotation::monitor_crossings = false; bool colvarmodule::rotation::monitor_crossings = false;
cvm::real colvarmodule::rotation::crossing_threshold = 1.0E-02; cvm::real colvarmodule::rotation::crossing_threshold = 1.0E-02;
namespace {
/// Numerical recipes diagonalization
static int jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot);
/// Eigenvector sort
static int eigsrt(cvm::real *d, cvm::real **v);
/// Transpose the matrix
static int transpose(cvm::real **v);
}
std::string cvm::rvector::to_simple_string() const std::string cvm::rvector::to_simple_string() const
{ {
std::ostringstream os; std::ostringstream os;
@ -74,7 +68,7 @@ std::ostream & operator << (std::ostream &os, colvarmodule::rvector const &v)
std::istream & operator >> (std::istream &is, colvarmodule::rvector &v) std::istream & operator >> (std::istream &is, colvarmodule::rvector &v)
{ {
size_t const start_pos = is.tellg(); std::streampos const start_pos = is.tellg();
char sep; char sep;
if ( !(is >> sep) || !(sep == '(') || if ( !(is >> sep) || !(sep == '(') ||
!(is >> v.x) || !(is >> sep) || !(sep == ',') || !(is >> v.x) || !(is >> sep) || !(sep == ',') ||
@ -130,7 +124,7 @@ std::ostream & operator << (std::ostream &os, colvarmodule::quaternion const &q)
std::istream & operator >> (std::istream &is, colvarmodule::quaternion &q) std::istream & operator >> (std::istream &is, colvarmodule::quaternion &q)
{ {
size_t const start_pos = is.tellg(); std::streampos const start_pos = is.tellg();
std::string euler(""); std::string euler("");
@ -248,6 +242,66 @@ cvm::quaternion::position_derivative_inner(cvm::rvector const &pos,
// Seok C, Dill KA. Using quaternions to calculate RMSD. J Comput // Seok C, Dill KA. Using quaternions to calculate RMSD. J Comput
// Chem. 25(15):1849-57 (2004) DOI: 10.1002/jcc.20110 PubMed: 15376254 // Chem. 25(15):1849-57 (2004) DOI: 10.1002/jcc.20110 PubMed: 15376254
#ifdef COLVARS_LAMMPS
namespace {
inline void *new_Jacobi_solver(int size) {
return reinterpret_cast<void *>(new MathEigen::Jacobi<cvm::real,
cvm::vector1d<cvm::real> &,
cvm::matrix2d<cvm::real> &>(4));
}
}
#endif
colvarmodule::rotation::rotation()
{
b_debug_gradients = false;
#ifdef COLVARS_LAMMPS
jacobi = new_Jacobi_solver(4);
#else
jacobi = NULL;
#endif
}
colvarmodule::rotation::rotation(cvm::quaternion const &qi)
: q(qi)
{
b_debug_gradients = false;
#ifdef COLVARS_LAMMPS
jacobi = new_Jacobi_solver(4);
#else
jacobi = NULL;
#endif
}
colvarmodule::rotation::rotation(cvm::real angle, cvm::rvector const &axis)
{
b_debug_gradients = false;
cvm::rvector const axis_n = axis.unit();
cvm::real const sina = cvm::sin(angle/2.0);
q = cvm::quaternion(cvm::cos(angle/2.0),
sina * axis_n.x, sina * axis_n.y, sina * axis_n.z);
#ifdef COLVARS_LAMMPS
jacobi = new_Jacobi_solver(4);
#else
jacobi = NULL;
#endif
}
colvarmodule::rotation::~rotation()
{
#ifdef COLVARS_LAMMPS
delete reinterpret_cast<
MathEigen::Jacobi<cvm::real,
cvm::vector1d<cvm::real> &,
cvm::matrix2d<cvm::real> &> *>(jacobi);
#endif
}
void colvarmodule::rotation::build_correlation_matrix( void colvarmodule::rotation::build_correlation_matrix(
std::vector<cvm::atom_pos> const &pos1, std::vector<cvm::atom_pos> const &pos1,
std::vector<cvm::atom_pos> const &pos2) std::vector<cvm::atom_pos> const &pos2)
@ -291,8 +345,10 @@ void colvarmodule::rotation::compute_overlap_matrix()
} }
void colvarmodule::rotation::diagonalize_matrix( #ifndef COLVARS_LAMMPS
cvm::matrix2d<cvm::real> &m, namespace {
void diagonalize_matrix(cvm::matrix2d<cvm::real> &m,
cvm::vector1d<cvm::real> &eigval, cvm::vector1d<cvm::real> &eigval,
cvm::matrix2d<cvm::real> &eigvec) cvm::matrix2d<cvm::real> &eigvec)
{ {
@ -303,15 +359,15 @@ void colvarmodule::rotation::diagonalize_matrix(
// diagonalize // diagonalize
int jac_nrot = 0; int jac_nrot = 0;
if (jacobi(m.c_array(), eigval.c_array(), eigvec.c_array(), &jac_nrot) != if (NR_Jacobi::jacobi(m.c_array(), eigval.c_array(), eigvec.c_array(), &jac_nrot) !=
COLVARS_OK) { COLVARS_OK) {
cvm::error("Too many iterations in routine jacobi.\n" cvm::error("Too many iterations in jacobi diagonalization.\n"
"This is usually the result of an ill-defined set of atoms for " "This is usually the result of an ill-defined set of atoms for "
"rotational alignment (RMSD, rotateReference, etc).\n"); "rotational alignment (RMSD, rotateReference, etc).\n");
} }
eigsrt(eigval.c_array(), eigvec.c_array()); NR_Jacobi::eigsrt(eigval.c_array(), eigvec.c_array());
// jacobi saves eigenvectors by columns // jacobi saves eigenvectors by columns
transpose(eigvec.c_array()); NR_Jacobi::transpose(eigvec.c_array());
// normalize eigenvectors // normalize eigenvectors
for (size_t ie = 0; ie < 4; ie++) { for (size_t ie = 0; ie < 4; ie++) {
@ -327,6 +383,9 @@ void colvarmodule::rotation::diagonalize_matrix(
} }
} }
}
#endif
// Calculate the rotation, plus its derivatives // Calculate the rotation, plus its derivatives
@ -349,7 +408,28 @@ void colvarmodule::rotation::calc_optimal_rotation(
cvm::log("S = "+cvm::to_str(S_backup, cvm::cv_width, cvm::cv_prec)+"\n"); cvm::log("S = "+cvm::to_str(S_backup, cvm::cv_width, cvm::cv_prec)+"\n");
} }
S_eigval.resize(4);
S_eigvec.resize(4, 4);
#ifdef COLVARS_LAMMPS
MathEigen::Jacobi<cvm::real,
cvm::vector1d<cvm::real> &,
cvm::matrix2d<cvm::real> &> *ecalc =
reinterpret_cast<MathEigen::Jacobi<cvm::real,
cvm::vector1d<cvm::real> &,
cvm::matrix2d<cvm::real> &> *>(jacobi);
int ierror = ecalc->Diagonalize(S, S_eigval, S_eigvec);
if (ierror) {
cvm::error("Too many iterations in jacobi diagonalization.\n"
"This is usually the result of an ill-defined set of atoms for "
"rotational alignment (RMSD, rotateReference, etc).\n");
}
#else
diagonalize_matrix(S, S_eigval, S_eigvec); diagonalize_matrix(S, S_eigval, S_eigvec);
#endif
// eigenvalues and eigenvectors // eigenvalues and eigenvectors
cvm::real const L0 = S_eigval[0]; cvm::real const L0 = S_eigval[0];
cvm::real const L1 = S_eigval[1]; cvm::real const L1 = S_eigval[1];
@ -521,7 +601,11 @@ void colvarmodule::rotation::calc_optimal_rotation(
// cvm::log("S_new = "+cvm::to_str(cvm::to_str (S_new), cvm::cv_width, cvm::cv_prec)+"\n"); // cvm::log("S_new = "+cvm::to_str(cvm::to_str (S_new), cvm::cv_width, cvm::cv_prec)+"\n");
#ifdef COLVARS_LAMMPS
ecalc->Diagonalize(S_new, S_new_eigval, S_new_eigvec);
#else
diagonalize_matrix(S_new, S_new_eigval, S_new_eigvec); diagonalize_matrix(S_new, S_new_eigval, S_new_eigvec);
#endif
cvm::real const &L0_new = S_new_eigval[0]; cvm::real const &L0_new = S_new_eigval[0];
cvm::quaternion const Q0_new(S_new_eigvec[0]); cvm::quaternion const Q0_new(S_new_eigvec[0]);
@ -544,138 +628,3 @@ void colvarmodule::rotation::calc_optimal_rotation(
// Numerical Recipes routine for diagonalization
#define ROTATE(a,i,j,k,l) g=a[i][j]; \
h=a[k][l]; \
a[i][j]=g-s*(h+g*tau); \
a[k][l]=h+s*(g-h*tau);
#define n 4
namespace {
int jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot)
{
int j,iq,ip,i;
cvm::real tresh,theta,tau,t,sm,s,h,g,c;
cvm::vector1d<cvm::real> b(n);
cvm::vector1d<cvm::real> z(n);
for (ip=0;ip<n;ip++) {
for (iq=0;iq<n;iq++) {
v[ip][iq]=0.0;
}
v[ip][ip]=1.0;
}
for (ip=0;ip<n;ip++) {
b[ip]=d[ip]=a[ip][ip];
z[ip]=0.0;
}
*nrot=0;
for (i=0;i<=50;i++) {
sm=0.0;
for (ip=0;ip<n-1;ip++) {
for (iq=ip+1;iq<n;iq++)
sm += cvm::fabs(a[ip][iq]);
}
if (sm == 0.0) {
return COLVARS_OK;
}
if (i < 4)
tresh=0.2*sm/(n*n);
else
tresh=0.0;
for (ip=0;ip<n-1;ip++) {
for (iq=ip+1;iq<n;iq++) {
g=100.0*cvm::fabs(a[ip][iq]);
if (i > 4 && (cvm::real)(cvm::fabs(d[ip])+g) == (cvm::real)cvm::fabs(d[ip])
&& (cvm::real)(cvm::fabs(d[iq])+g) == (cvm::real)cvm::fabs(d[iq]))
a[ip][iq]=0.0;
else if (cvm::fabs(a[ip][iq]) > tresh) {
h=d[iq]-d[ip];
if ((cvm::real)(cvm::fabs(h)+g) == (cvm::real)cvm::fabs(h))
t=(a[ip][iq])/h;
else {
theta=0.5*h/(a[ip][iq]);
t=1.0/(cvm::fabs(theta)+cvm::sqrt(1.0+theta*theta));
if (theta < 0.0) t = -t;
}
c=1.0/cvm::sqrt(1+t*t);
s=t*c;
tau=s/(1.0+c);
h=t*a[ip][iq];
z[ip] -= h;
z[iq] += h;
d[ip] -= h;
d[iq] += h;
a[ip][iq]=0.0;
for (j=0;j<=ip-1;j++) {
ROTATE(a,j,ip,j,iq)
}
for (j=ip+1;j<=iq-1;j++) {
ROTATE(a,ip,j,j,iq)
}
for (j=iq+1;j<n;j++) {
ROTATE(a,ip,j,iq,j)
}
for (j=0;j<n;j++) {
ROTATE(v,j,ip,j,iq)
}
++(*nrot);
}
}
}
for (ip=0;ip<n;ip++) {
b[ip] += z[ip];
d[ip]=b[ip];
z[ip]=0.0;
}
}
return COLVARS_ERROR;
}
int eigsrt(cvm::real *d, cvm::real **v)
{
int k,j,i;
cvm::real p;
for (i=0;i<n;i++) {
p=d[k=i];
for (j=i+1;j<n;j++)
if (d[j] >= p) p=d[k=j];
if (k != i) {
d[k]=d[i];
d[i]=p;
for (j=0;j<n;j++) {
p=v[j][i];
v[j][i]=v[j][k];
v[j][k]=p;
}
}
}
return COLVARS_OK;
}
int transpose(cvm::real **v)
{
cvm::real p;
int i,j;
for (i=0;i<n;i++) {
for (j=i+1;j<n;j++) {
p=v[i][j];
v[i][j]=v[j][i];
v[j][i]=p;
}
}
return COLVARS_OK;
}
}
#undef n
#undef ROTATE

View File

@ -270,7 +270,7 @@ public:
cvm::vector1d<T> &v) cvm::vector1d<T> &v)
{ {
if (v.size() == 0) return is; if (v.size() == 0) return is;
size_t const start_pos = is.tellg(); std::streampos const start_pos = is.tellg();
char sep; char sep;
if ( !(is >> sep) || !(sep == '(') ) { if ( !(is >> sep) || !(sep == '(') ) {
is.clear(); is.clear();
@ -1389,30 +1389,16 @@ public:
std::vector<atom_pos> const &pos2); std::vector<atom_pos> const &pos2);
/// Default constructor /// Default constructor
inline rotation() rotation();
: b_debug_gradients(false)
{}
/// Constructor after a quaternion /// Constructor after a quaternion
inline rotation(cvm::quaternion const &qi) rotation(cvm::quaternion const &qi);
: q(qi),
b_debug_gradients(false)
{
}
/// Constructor after an axis of rotation and an angle (in radians) /// Constructor after an axis of rotation and an angle (in radians)
inline rotation(cvm::real angle, cvm::rvector const &axis) rotation(cvm::real angle, cvm::rvector const &axis);
: b_debug_gradients(false)
{
cvm::rvector const axis_n = axis.unit();
cvm::real const sina = cvm::sin(angle/2.0);
q = cvm::quaternion(cvm::cos(angle/2.0),
sina * axis_n.x, sina * axis_n.y, sina * axis_n.z);
}
/// Destructor /// Destructor
inline ~rotation() ~rotation();
{}
/// Return the rotated vector /// Return the rotated vector
inline cvm::rvector rotate(cvm::rvector const &v) const inline cvm::rvector rotate(cvm::rvector const &v) const
@ -1432,7 +1418,6 @@ public:
return q.rotation_matrix(); return q.rotation_matrix();
} }
/// \brief Return the spin angle (in degrees) with respect to the /// \brief Return the spin angle (in degrees) with respect to the
/// provided axis (which MUST be normalized) /// provided axis (which MUST be normalized)
inline cvm::real spin_angle(cvm::rvector const &axis) const inline cvm::real spin_angle(cvm::rvector const &axis) const
@ -1537,10 +1522,8 @@ protected:
/// Compute the overlap matrix S (used by calc_optimal_rotation()) /// Compute the overlap matrix S (used by calc_optimal_rotation())
void compute_overlap_matrix(); void compute_overlap_matrix();
/// Diagonalize a given matrix m (used by calc_optimal_rotation()) /// Pointer to instance of Jacobi solver
static void diagonalize_matrix(cvm::matrix2d<cvm::real> &m, void *jacobi;
cvm::vector1d<cvm::real> &eigval,
cvm::matrix2d<cvm::real> &eigvec);
}; };

View File

@ -57,7 +57,7 @@ CUDA_INCLUDE = -I$(CUDA_HOME)/include
CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs
CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC
CUDR_CPP = mpicxx -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK -DOMPI_SKIP_MPICXX=1 -fPIC CUDR_CPP = mpicxx -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK -DOMPI_SKIP_MPICXX=1 -fPIC -std=c++11
CUDR_OPTS = -O2 $(LMP_INC) # -xHost -no-prec-div -ansi-alias CUDR_OPTS = -O2 $(LMP_INC) # -xHost -no-prec-div -ansi-alias
BIN_DIR = ./ BIN_DIR = ./

View File

@ -57,8 +57,8 @@ CUDA_INCLUDE = -I$(CUDA_HOME)/include
CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs
CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC
CUDR_CPP = mpic++ -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK CUDR_CPP = mpicxx -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK -DOMPI_SKIP_MPICXX=1 -fPIC -std=c++11
CUDR_OPTS = -O2 # -xHost -no-prec-div -ansi-alias CUDR_OPTS = -O2 $(LMP_INC) # -xHost -no-prec-div -ansi-alias
BIN_DIR = ./ BIN_DIR = ./
OBJ_DIR = ./ OBJ_DIR = ./

View File

@ -58,8 +58,8 @@ CUDA_INCLUDE = -I$(CUDA_HOME)/include
CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs
CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC
CUDR_CPP = mpic++ -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK CUDR_CPP = mpicxx -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK -DOMPI_SKIP_MPICXX=1 -fPIC -std=c++11
CUDR_OPTS = -O2 # -xHost -no-prec-div -ansi-alias CUDR_OPTS = -O2 $(LMP_INC) # -xHost -no-prec-div -ansi-alias
BIN_DIR = ./ BIN_DIR = ./
OBJ_DIR = ./ OBJ_DIR = ./

View File

@ -57,8 +57,8 @@ CUDA_INCLUDE = -I$(CUDA_HOME)/include
CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs
CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC
CUDR_CPP = mpic++ -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK CUDR_CPP = mpicxx -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK -DOMPI_SKIP_MPICXX=1 -fPIC -std=c++11
CUDR_OPTS = -O2 # -xHost -no-prec-div -ansi-alias CUDR_OPTS = -O2 $(LMP_INC) # -xHost -no-prec-div -ansi-alias
BIN_DIR = ./ BIN_DIR = ./
OBJ_DIR = ./ OBJ_DIR = ./

View File

@ -51,9 +51,9 @@ CUDA_PRECISION = -D_SINGLE_DOUBLE
CUDA_INCLUDE = -I$(CUDA_HOME)/include CUDA_INCLUDE = -I$(CUDA_HOME)/include
CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs
CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler "-fPIC -std=c++98" CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC
CUDR_CPP = mpicxx -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK -DOMPI_SKIP_MPICXX=1 -fPIC CUDR_CPP = mpicxx -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK -DOMPI_SKIP_MPICXX=1 -fPIC -std=c++11
CUDR_OPTS = -O2 $(LMP_INC) # -xHost -no-prec-div -ansi-alias CUDR_OPTS = -O2 $(LMP_INC) # -xHost -no-prec-div -ansi-alias
BIN_DIR = ./ BIN_DIR = ./

View File

@ -17,8 +17,8 @@ OCL_TUNE = -DGENERIC_OCL # -- Uncomment for generic device
LMP_INC = -DLAMMPS_SMALLBIG LMP_INC = -DLAMMPS_SMALLBIG
OCL_INC = -I/usr/local/cuda/include # Path to CL directory OCL_INC = -I/usr/local/cuda/include # Path to CL directory
OCL_CPP = mpic++ $(DEFAULT_DEVICE) -O3 -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK $(LMP_INC) $(OCL_INC) OCL_CPP = mpic++ $(DEFAULT_DEVICE) -O3 -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK $(LMP_INC) $(OCL_INC) -std=c++11
OCL_LINK = -lOpenCL OCL_LINK = -L/usr/local/cuda/lib64 -lOpenCL
OCL_PREC = -D_SINGLE_DOUBLE OCL_PREC = -D_SINGLE_DOUBLE
BIN_DIR = ./ BIN_DIR = ./

View File

@ -1,32 +0,0 @@
# /* ----------------------------------------------------------------------
# Generic Mac Makefile for CUDA
# - 32-bit (requires adding -m32 to LAMMPS Makefile)
# - Change CUDA_ARCH for your GPU
# ------------------------------------------------------------------------- */
# which file will be copied to Makefile.lammps
EXTRAMAKE = Makefile.lammps.standard
CUDA_HOME = /usr/local/cuda
NVCC = nvcc -m64
CUDA_ARCH = -arch=sm_11
CUDA_PRECISION = -D_SINGLE_SINGLE
CUDA_INCLUDE = -I$(CUDA_HOME)/include
CUDA_LIB = -L$(CUDA_HOME)/lib -L$(CUDA_HOME)/lib/stubs
CUDA_OPTS = -DUNIX -DUCL_NO_EXIT -O3 --use_fast_math
CUDR_CPP = mpic++ -m64
CUDR_OPTS = -O2 -g
BIN_DIR = ./
OBJ_DIR = ./
LIB_DIR = ./
AR = ar
BSH = /bin/sh
CUDPP_OPT = -DUSE_CUDPP -Icudpp_mini
include Nvidia.makefile

View File

@ -57,7 +57,7 @@ CUDA_INCLUDE = -I$(CUDA_HOME)/include
CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs -L../../src/STUBS -lmpi_stubs CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs -L../../src/STUBS -lmpi_stubs
CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC CUDA_OPTS = -DUNIX -O3 --use_fast_math $(LMP_INC) -Xcompiler -fPIC
CUDR_CPP = g++ -DMPI_GERYON -DUCL_NO_EXIT -fPIC -I../../src/STUBS CUDR_CPP = g++ -DMPI_GERYON -DUCL_NO_EXIT -fPIC -I../../src/STUBS -std=c++11
CUDR_OPTS = -O2 $(LMP_INC) # -xHost -no-prec-div -ansi-alias CUDR_OPTS = -O2 $(LMP_INC) # -xHost -no-prec-div -ansi-alias
BIN_DIR = ./ BIN_DIR = ./

View File

@ -1,50 +0,0 @@
# /* ----------------------------------------------------------------------
# Generic Linux Makefile for CUDA
# - Change CUDA_ARCH for your GPU
# ------------------------------------------------------------------------- */
# which file will be copied to Makefile.lammps
EXTRAMAKE = Makefile.lammps.standard
CUDA_HOME = ${CUDA_ROOT}
NVCC = nvcc
# Kepler CUDA
CUDA_ARCH = -arch=sm_35
# Tesla CUDA
#CUDA_ARCH = -arch=sm_21
# newer CUDA
#CUDA_ARCH = -arch=sm_13
# older CUDA
#CUDA_ARCH = -arch=sm_10 -DCUDA_PRE_THREE
# this setting should match LAMMPS Makefile
# one of LAMMPS_SMALLBIG (default), LAMMPS_BIGBIG and LAMMPS_SMALLSMALL
LMP_INC = -DLAMMPS_SMALLBIG
# precision for GPU calculations
# -D_SINGLE_SINGLE # Single precision for all calculations
# -D_DOUBLE_DOUBLE # Double precision for all calculations
# -D_SINGLE_DOUBLE # Accumulation of forces, etc. in double
CUDA_PRECISION = -D_DOUBLE_DOUBLE
CUDA_INCLUDE = -I$(CUDA_HOME)/include
CUDA_LIB = -L$(CUDA_HOME)/lib64 -L$(CUDA_HOME)/lib64/stubs
CUDA_OPTS = -DUNIX -O3 --use_fast_math
CUDR_CPP = mpic++ -DMPI_GERYON -DUCL_NO_EXIT -DMPICH_IGNORE_CXX_SEEK
CUDR_OPTS = -O2 # -xHost -no-prec-div -ansi-alias
BIN_DIR = ./
OBJ_DIR = ./
LIB_DIR = ./
AR = ar
BSH = /bin/sh
CUDPP_OPT = -DUSE_CUDPP -Icudpp_mini
include Nvidia.makefile

View File

@ -60,11 +60,9 @@ __kernel void k_gauss(const __global numtyp4 *restrict x_,
numtyp4 ix; fetch4(ix,i,pos_tex); //x_[i]; numtyp4 ix; fetch4(ix,i,pos_tex); //x_[i];
int itype=ix.w; int itype=ix.w;
numtyp factor_lj;
for ( ; nbor<nbor_end; nbor+=n_stride) { for ( ; nbor<nbor_end; nbor+=n_stride) {
int j=dev_packed[nbor]; int j=dev_packed[nbor];
factor_lj = sp_lj[sbmask(j)];
j &= NEIGHMASK; j &= NEIGHMASK;
numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j]; numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j];
@ -148,11 +146,9 @@ __kernel void k_gauss_fast(const __global numtyp4 *restrict x_,
int iw=ix.w; int iw=ix.w;
int itype=fast_mul((int)MAX_SHARED_TYPES,iw); int itype=fast_mul((int)MAX_SHARED_TYPES,iw);
numtyp factor_lj;
for ( ; nbor<nbor_end; nbor+=n_stride) { for ( ; nbor<nbor_end; nbor+=n_stride) {
int j=dev_packed[nbor]; int j=dev_packed[nbor];
factor_lj = sp_lj[sbmask(j)];
j &= NEIGHMASK; j &= NEIGHMASK;
numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j]; numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j];

Some files were not shown because too many files have changed in this diff Show More