Merge branch 'master' into fix_numerical_differentiation

This commit is contained in:
Sievers
2020-03-05 09:58:50 -07:00
32 changed files with 527 additions and 399 deletions

View File

@ -2,7 +2,7 @@
# CMake build system # CMake build system
# This file is part of LAMMPS # This file is part of LAMMPS
# Created by Christoph Junghans and Richard Berger # Created by Christoph Junghans and Richard Berger
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 3.10)
project(lammps CXX) project(lammps CXX)
set(SOVERSION 0) set(SOVERSION 0)
@ -55,12 +55,9 @@ if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -restrict -std=c++11") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -restrict -std=c++11")
endif() endif()
option(DISABLE_CXX11_REQUIREMENT "Disable check that requires C++11 for compiling LAMMPS" OFF) # we require C++11
if(DISABLE_CXX11_REQUIREMENT) set(CMAKE_CXX_STANDARD 11)
add_definitions(-DLAMMPS_CXX98) set(CMAKE_CXX_STANDARD_REQUIRED ON)
# else()
# set(CMAKE_CXX_STANDARD 11)
endif()
# GNU compiler features # GNU compiler features
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
@ -355,9 +352,6 @@ endforeach(HEADER)
set(MATH_LIBRARIES "m" CACHE STRING "math library") set(MATH_LIBRARIES "m" CACHE STRING "math library")
mark_as_advanced( MATH_LIBRARIES ) mark_as_advanced( MATH_LIBRARIES )
include(CheckLibraryExists) include(CheckLibraryExists)
if (CMAKE_VERSION VERSION_LESS "3.4")
enable_language(C) # check_library_exists isn't supported without a C compiler before v3.4
endif()
# RB: disabled this check because it breaks with KOKKOS CUDA enabled # RB: disabled this check because it breaks with KOKKOS CUDA enabled
#foreach(FUNC sin cos) #foreach(FUNC sin cos)
# check_library_exists(${MATH_LIBRARIES} ${FUNC} "" FOUND_${FUNC}_${MATH_LIBRARIES}) # check_library_exists(${MATH_LIBRARIES} ${FUNC} "" FOUND_${FUNC}_${MATH_LIBRARIES})

View File

@ -1,7 +1,4 @@
if(PKG_GPU) if(PKG_GPU)
if (CMAKE_VERSION VERSION_LESS "3.1")
message(FATAL_ERROR "For the GPU package you need at least cmake-3.1")
endif()
set(GPU_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/GPU) set(GPU_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/GPU)
set(GPU_SOURCES ${GPU_SOURCES_DIR}/gpu_extra.h set(GPU_SOURCES ${GPU_SOURCES_DIR}/gpu_extra.h
${GPU_SOURCES_DIR}/fix_gpu.h ${GPU_SOURCES_DIR}/fix_gpu.h

View File

@ -8,9 +8,6 @@ if(PKG_LATTE)
endif() endif()
option(DOWNLOAD_LATTE "Download the LATTE library instead of using an already installed one" ${DOWNLOAD_LATTE_DEFAULT}) option(DOWNLOAD_LATTE "Download the LATTE library instead of using an already installed one" ${DOWNLOAD_LATTE_DEFAULT})
if(DOWNLOAD_LATTE) if(DOWNLOAD_LATTE)
if (CMAKE_VERSION VERSION_LESS "3.7") # due to SOURCE_SUBDIR
message(FATAL_ERROR "For downlading LATTE you need at least cmake-3.7")
endif()
if(CMAKE_GENERATOR STREQUAL "Ninja") if(CMAKE_GENERATOR STREQUAL "Ninja")
message(FATAL_ERROR "Cannot build downloaded LATTE library with Ninja build tool") message(FATAL_ERROR "Cannot build downloaded LATTE library with Ninja build tool")
endif() endif()

View File

@ -8,9 +8,6 @@ if(PKG_MSCG)
endif() endif()
option(DOWNLOAD_MSCG "Download MSCG library instead of using an already installed one)" ${DOWNLOAD_MSCG_DEFAULT}) option(DOWNLOAD_MSCG "Download MSCG library instead of using an already installed one)" ${DOWNLOAD_MSCG_DEFAULT})
if(DOWNLOAD_MSCG) if(DOWNLOAD_MSCG)
if (CMAKE_VERSION VERSION_LESS "3.7") # due to SOURCE_SUBDIR
message(FATAL_ERROR "For downlading MSCG you need at least cmake-3.7")
endif()
if(CMAKE_GENERATOR STREQUAL "Ninja") if(CMAKE_GENERATOR STREQUAL "Ninja")
message(FATAL_ERROR "Cannot build downloaded MSCG library with Ninja build tool") message(FATAL_ERROR "Cannot build downloaded MSCG library with Ninja build tool")
endif() endif()

View File

@ -1,8 +1,4 @@
if(PKG_USER-MOLFILE) if(PKG_USER-MOLFILE)
if (CMAKE_VERSION VERSION_LESS "3.10") # due to INTERFACE without a library
message(FATAL_ERROR "For configuring USER-MOLFILE you need CMake 3.10 or later")
endif()
set(MOLFILE_INCLUDE_DIRS "${LAMMPS_LIB_SOURCE_DIR}/molfile" CACHE STRING "Path to VMD molfile plugin headers") set(MOLFILE_INCLUDE_DIRS "${LAMMPS_LIB_SOURCE_DIR}/molfile" CACHE STRING "Path to VMD molfile plugin headers")
add_library(molfile INTERFACE) add_library(molfile INTERFACE)
target_include_directories(molfile INTERFACE ${MOLFILE_INCLUDE_DIRS}) target_include_directories(molfile INTERFACE ${MOLFILE_INCLUDE_DIRS})

View File

@ -95,10 +95,8 @@ this directory or sub-directories within it that CMake creates.
directory to un-install all packages. The purge removes all the \*.h directory to un-install all packages. The purge removes all the \*.h
files auto-generated by make. files auto-generated by make.
You must have CMake version 2.8 or later on your system to build You must have CMake version 3.10 or later on your system to build
LAMMPS. A handful of LAMMPS packages (KOKKOS, LATTE, MSCG) require a LAMMPS. Installation instructions for CMake are below.
later version. CMake will print a message telling you if a later
version is required. Installation instructions for CMake are below.
After the initial build, if you edit LAMMPS source files, or add your After the initial build, if you edit LAMMPS source files, or add your
own new files to the source directory, you can just re-type make from own new files to the source directory, you can just re-type make from

View File

@ -23,11 +23,11 @@ explain how to do this for building both with CMake and make.
C++11 standard compliance C++11 standard compliance
------------------------------------------ ------------------------------------------
The LAMMPS developers plan to transition to make the C++11 standard the A C++11 standard compatible compiler is a requirement for compiling LAMMPS.
minimum requirement for compiling LAMMPS. Currently this only applies to LAMMPS version 3 March 2020 is the last version compatible with the previous
some packages like KOKKOS while the rest aims to be compatible with the C++98 C++98 standard for the core code and most packages. Most currently used
standard. Most currently used compilers are compatible with C++11; some need C++ compilers are compatible with C++11, but some older ones may need extra
to set extra flags to enable C++11 compliance. Example for GNU c++: flags to enable C++11 compliance. Example for GNU c++ 4.8.x:
.. code-block:: make .. code-block:: make

View File

@ -27,46 +27,58 @@ $(COLVARS_OBJ_DIR)colvarbias_restraint.o: colvarbias_restraint.cpp \
$(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 colvarcomp.h colvaratoms.h \
colvarproxy.h colvar_arithmeticpath.h colvarproxy.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_apath.o: colvarcomp_apath.cpp $(COLVARS_OBJ_DIR)colvarcomp_apath.o: colvarcomp_apath.cpp colvarmodule.h \
colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \
colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \
colvarproxy.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 colvardeps.h \
colvar.h colvarcomp.h colvar_arithmeticpath.h colvar.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 colvarcomp.h colvaratoms.h colvarproxy.h \
colvar_arithmeticpath.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 colvarcomp.h \
colvaratoms.h colvarproxy.h colvar_arithmeticpath.h colvaratoms.h colvarproxy.h colvar_arithmeticpath.h \
$(COLVARS_OBJ_DIR)colvarcomp_gpath.o: colvarcomp_gpath.cpp colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_gpath.o: colvarcomp_gpath.cpp colvarmodule.h \
colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \
colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \
colvarproxy.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 colvarcomp.h \
colvaratoms.h colvarproxy.h colvar_arithmeticpath.h colvaratoms.h colvarproxy.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 colvarcomp.h \
colvaratoms.h colvarproxy.h colvar_arithmeticpath.h colvaratoms.h colvarproxy.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 colvarcomp.h colvaratoms.h colvarproxy.h \
colvar_arithmeticpath.h colvarscript.h colvarbias.h colvar_arithmeticpath.h colvar_geometricpath.h colvarscript.h \
colvarbias.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 colvardeps.h \
colvarparse.h colvarparams.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 colvarcomp.h colvaratoms.h \
colvarproxy.h colvar_arithmeticpath.h colvargrid.h colvarproxy.h colvar_arithmeticpath.h colvar_geometricpath.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 colvar.h colvardeps.h colvarbias.h \
colvarbias_abf.h colvargrid.h colvar_UIestimator.h colvarbias_alb.h \ colvarbias_abf.h colvargrid.h colvar_UIestimator.h colvarbias_alb.h \
colvarbias_histogram.h colvarbias_meta.h colvarbias_restraint.h \ colvarbias_histogram.h colvarbias_meta.h colvarbias_restraint.h \
colvarscript.h colvaratoms.h colvarcomp.h colvar_arithmeticpath.h colvarscript.h colvaratoms.h colvarcomp.h colvar_arithmeticpath.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
$(COLVARS_OBJ_DIR)colvarparse.o: colvarparse.cpp colvarmodule.h \ $(COLVARS_OBJ_DIR)colvarparse.o: colvarparse.cpp colvarmodule.h \

View File

@ -33,6 +33,8 @@ colvar::colvar()
dev_null = 0.0; dev_null = 0.0;
#endif #endif
expand_boundaries = false;
description = "uninitialized colvar"; description = "uninitialized colvar";
init_dependencies(); init_dependencies();
} }
@ -474,6 +476,8 @@ int colvar::init_custom_function(std::string const &conf)
int colvar::init_grid_parameters(std::string const &conf) int colvar::init_grid_parameters(std::string const &conf)
{ {
int error_code = COLVARS_OK;
colvarmodule *cv = cvm::main(); colvarmodule *cv = cvm::main();
cvm::real default_width = width; cvm::real default_width = width;
@ -527,15 +531,18 @@ int colvar::init_grid_parameters(std::string const &conf)
disable(f_cv_hard_upper_boundary); disable(f_cv_hard_upper_boundary);
} }
// Parse legacy wall options and set up a harmonicWalls bias if needed
cvm::real lower_wall_k = 0.0, upper_wall_k = 0.0;
cvm::real lower_wall = 0.0, upper_wall = 0.0;
std::string lw_conf, uw_conf; std::string lw_conf, uw_conf;
if (get_keyval(conf, "lowerWallConstant", lower_wall_k, 0.0, if (get_keyval(conf, "lowerWallConstant", lower_wall_k, 0.0,
parse_silent)) { parse_silent)) {
cvm::log("Reading legacy options lowerWall and lowerWallConstant: " cvm::log("Reading legacy options lowerWall and lowerWallConstant: "
"consider using a harmonicWalls restraint\n(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");
lower_wall.type(value()); if (!get_keyval(conf, "lowerWall", lower_wall)) {
if (!get_keyval(conf, "lowerWall", lower_wall, lower_boundary)) { error_code != cvm::error("Error: the value of lowerWall must be set "
cvm::log("Warning: lowerWall will need to be " "explicitly.\n", INPUT_ERROR);
"defined explicitly in the next release.\n");
} }
lw_conf = std::string("\n\ lw_conf = std::string("\n\
lowerWallConstant "+cvm::to_str(lower_wall_k*width*width)+"\n\ lowerWallConstant "+cvm::to_str(lower_wall_k*width*width)+"\n\
@ -545,11 +552,10 @@ int colvar::init_grid_parameters(std::string const &conf)
if (get_keyval(conf, "upperWallConstant", upper_wall_k, 0.0, if (get_keyval(conf, "upperWallConstant", upper_wall_k, 0.0,
parse_silent)) { parse_silent)) {
cvm::log("Reading legacy options upperWall and upperWallConstant: " cvm::log("Reading legacy options upperWall and upperWallConstant: "
"consider using a harmonicWalls restraint\n(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");
upper_wall.type(value()); if (!get_keyval(conf, "upperWall", upper_wall)) {
if (!get_keyval(conf, "upperWall", upper_wall, upper_boundary)) { error_code != cvm::error("Error: the value of upperWall must be set "
cvm::log("Warning: upperWall will need to be " "explicitly.\n", INPUT_ERROR);
"defined explicitly in the next release.\n");
} }
uw_conf = std::string("\n\ uw_conf = std::string("\n\
upperWallConstant "+cvm::to_str(upper_wall_k*width*width)+"\n\ upperWallConstant "+cvm::to_str(upper_wall_k*width*width)+"\n\
@ -558,12 +564,11 @@ int colvar::init_grid_parameters(std::string const &conf)
if (lw_conf.size() && uw_conf.size()) { if (lw_conf.size() && uw_conf.size()) {
if (lower_wall >= upper_wall) { if (lower_wall >= upper_wall) {
cvm::error("Error: the upper wall, "+ error_code |= cvm::error("Error: the upper wall, "+
cvm::to_str(upper_wall)+ cvm::to_str(upper_wall)+
", is not higher than the lower wall, "+ ", is not higher than the lower wall, "+
cvm::to_str(lower_wall)+".\n", cvm::to_str(lower_wall)+".\n",
INPUT_ERROR); INPUT_ERROR);
return INPUT_ERROR;
} }
} }
@ -575,7 +580,7 @@ harmonicWalls {\n\
colvars "+this->name+"\n"+lw_conf+uw_conf+"\ colvars "+this->name+"\n"+lw_conf+uw_conf+"\
timeStepFactor "+cvm::to_str(time_step_factor)+"\n"+ timeStepFactor "+cvm::to_str(time_step_factor)+"\n"+
"}\n"); "}\n");
cv->append_new_config(walls_conf); error_code |= cv->append_new_config(walls_conf);
} }
} }
@ -588,29 +593,27 @@ harmonicWalls {\n\
// consistency checks for boundaries and walls // consistency checks for boundaries and walls
if (is_enabled(f_cv_lower_boundary) && is_enabled(f_cv_upper_boundary)) { if (is_enabled(f_cv_lower_boundary) && is_enabled(f_cv_upper_boundary)) {
if (lower_boundary >= upper_boundary) { if (lower_boundary >= upper_boundary) {
cvm::error("Error: the upper boundary, "+ error_code |= cvm::error("Error: the upper boundary, "+
cvm::to_str(upper_boundary)+ cvm::to_str(upper_boundary)+
", is not higher than the lower boundary, "+ ", is not higher than the lower boundary, "+
cvm::to_str(lower_boundary)+".\n", cvm::to_str(lower_boundary)+".\n",
INPUT_ERROR); INPUT_ERROR);
return INPUT_ERROR;
} }
} }
get_keyval(conf, "expandBoundaries", expand_boundaries, false); get_keyval(conf, "expandBoundaries", expand_boundaries, expand_boundaries);
if (expand_boundaries && periodic_boundaries()) { if (expand_boundaries && periodic_boundaries()) {
cvm::error("Error: trying to expand boundaries that already " error_code |= cvm::error("Error: trying to expand boundaries that already "
"cover a whole period of a periodic colvar.\n", "cover a whole period of a periodic colvar.\n",
INPUT_ERROR); INPUT_ERROR);
return INPUT_ERROR;
} }
if (expand_boundaries && is_enabled(f_cv_hard_lower_boundary) && if (expand_boundaries && is_enabled(f_cv_hard_lower_boundary) &&
is_enabled(f_cv_hard_upper_boundary)) { is_enabled(f_cv_hard_upper_boundary)) {
cvm::error("Error: inconsistent configuration " error_code |= cvm::error("Error: inconsistent configuration "
"(trying to expand boundaries with both " "(trying to expand boundaries, but both "
"hardLowerBoundary and hardUpperBoundary enabled).\n", "hardLowerBoundary and hardUpperBoundary "
INPUT_ERROR); "are enabled).\n", INPUT_ERROR);
return INPUT_ERROR;
} }
return COLVARS_OK; return COLVARS_OK;
@ -2077,12 +2080,12 @@ void colvar::wrap(colvarvalue &x_unwrapped) const
// ******************** INPUT FUNCTIONS ******************** // ******************** INPUT FUNCTIONS ********************
std::istream & colvar::read_restart(std::istream &is) std::istream & colvar::read_state(std::istream &is)
{ {
size_t const start_pos = is.tellg(); size_t 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)) ) {
// this is not a colvar block // this is not a colvar block
is.clear(); is.clear();
is.seekg(start_pos, std::ios::beg); is.seekg(start_pos, std::ios::beg);
@ -2092,15 +2095,24 @@ std::istream & colvar::read_restart(std::istream &is)
{ {
std::string check_name = ""; std::string check_name = "";
if ( (get_keyval(conf, "name", check_name, get_keyval(conf, "name", check_name,
std::string(""), colvarparse::parse_silent)) && std::string(""), colvarparse::parse_silent);
(check_name != name) ) {
cvm::error("Error: the state file does not match the "
"configuration file, at colvar \""+name+"\".\n");
}
if (check_name.size() == 0) { if (check_name.size() == 0) {
cvm::error("Error: Collective variable in the " cvm::error("Error: Collective variable in the "
"restart file without any identifier.\n"); "restart file without any identifier.\n", INPUT_ERROR);
is.clear();
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
if (check_name != name) {
if (cvm::debug()) {
cvm::log("Ignoring state of colvar \""+check_name+
"\": this colvar is named \""+name+"\".\n");
}
is.seekg(start_pos, std::ios::beg);
return is;
} }
} }
@ -2199,7 +2211,7 @@ std::istream & colvar::read_traj(std::istream &is)
// ******************** OUTPUT FUNCTIONS ******************** // ******************** OUTPUT FUNCTIONS ********************
std::ostream & colvar::write_restart(std::ostream &os) { std::ostream & colvar::write_state(std::ostream &os) {
os << "colvar {\n" os << "colvar {\n"
<< " name " << name << "\n" << " name " << name << "\n"

View File

@ -229,17 +229,9 @@ public:
/// \brief Location of the lower boundary /// \brief Location of the lower boundary
colvarvalue lower_boundary; colvarvalue lower_boundary;
/// \brief Location of the lower wall
colvarvalue lower_wall;
/// \brief Force constant for the lower boundary potential (|x-xb|^2)
cvm::real lower_wall_k;
/// \brief Location of the upper boundary /// \brief Location of the upper boundary
colvarvalue upper_boundary; colvarvalue upper_boundary;
/// \brief Location of the upper wall
colvarvalue upper_wall;
/// \brief Force constant for the upper boundary potential (|x-xb|^2)
cvm::real upper_wall_k;
/// \brief Is the interval defined by the two boundaries periodic? /// \brief Is the interval defined by the two boundaries periodic?
bool periodic_boundaries() const; bool periodic_boundaries() const;
@ -453,9 +445,9 @@ public:
std::ostream & write_traj_label(std::ostream &os); std::ostream & write_traj_label(std::ostream &os);
/// Read the collective variable from a restart file /// Read the collective variable from a restart file
std::istream & read_restart(std::istream &is); std::istream & read_state(std::istream &is);
/// Write the collective variable to a restart file /// Write the collective variable to a restart file
std::ostream & write_restart(std::ostream &os); std::ostream & write_state(std::ostream &os);
/// Write output files (if defined, e.g. in analysis mode) /// Write output files (if defined, e.g. in analysis mode)
int write_output_files(); int write_output_files();

View File

@ -15,8 +15,10 @@
colvarbias::colvarbias(char const *key) colvarbias::colvarbias(char const *key)
: bias_type(to_lower_cppstr(key))
{ {
bias_type = to_lower_cppstr(key);
state_keyword = bias_type;
description = "uninitialized " + cvm::to_str(key) + " bias"; description = "uninitialized " + cvm::to_str(key) + " bias";
init_dependencies(); init_dependencies();
rank = 1; rank = 1;
@ -25,6 +27,7 @@ colvarbias::colvarbias(char const *key)
b_output_energy = false; b_output_energy = false;
reset(); reset();
state_file_step = 0L; state_file_step = 0L;
matching_state = false;
} }
@ -80,10 +83,21 @@ int colvarbias::init(std::string const &conf)
cvm::log("Reinitializing bias \""+name+"\".\n"); cvm::log("Reinitializing bias \""+name+"\".\n");
} }
colvar_values.resize(num_variables());
for (i = 0; i < num_variables(); i++) {
colvar_values[i].type(colvars[i]->value().type());
colvar_forces[i].type(colvar_values[i].type());
previous_colvar_forces[i].type(colvar_values[i].type());
}
output_prefix = cvm::output_prefix(); output_prefix = cvm::output_prefix();
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
get_keyval_feature(this, conf, "bypassExtendedLagrangian", f_cvb_bypass_ext_lagrangian, is_enabled(f_cvb_bypass_ext_lagrangian), parse_silent);
get_keyval(conf, "timeStepFactor", time_step_factor, 1); get_keyval(conf, "timeStepFactor", time_step_factor, 1);
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");
@ -114,6 +128,11 @@ int colvarbias::init_dependencies() {
init_feature(f_cvb_apply_force, "apply force", 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);
// The exclusion below prevents the inconsistency where biasing forces are applied onto
// 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);
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);
@ -158,6 +177,12 @@ int colvarbias::init_dependencies() {
// only compute TI samples when deriving from colvarbias_ti // only compute TI samples when deriving from colvarbias_ti
feature_states[f_cvb_calc_ti_samples].available = false; feature_states[f_cvb_calc_ti_samples].available = false;
// The feature f_cvb_bypass_ext_lagrangian is only implemented by some derived classes
// (initially, harmonicWalls)
feature_states[f_cvb_bypass_ext_lagrangian].available = false;
// disabled by default; can be changed by derived classes that implement it
feature_states[f_cvb_bypass_ext_lagrangian].enabled = false;
return COLVARS_OK; return COLVARS_OK;
} }
@ -265,6 +290,11 @@ int colvarbias::update()
has_data = true; has_data = true;
// Update the cached colvar values
for (size_t i = 0; i < num_variables(); i++) {
colvar_values[i] = colvars[i]->value();
}
error_code |= calc_energy(NULL); error_code |= calc_energy(NULL);
error_code |= calc_forces(NULL); error_code |= calc_forces(NULL);
@ -304,9 +334,11 @@ void colvarbias::communicate_forces()
// may send forces to the same colvar // may send forces to the same colvar
// which is why rescaling has to happen now: the colvar is not // which is why rescaling has to happen now: the colvar is not
// aware of this bias' time_step_factor // aware of this bias' time_step_factor
if (is_enabled(f_cvb_bypass_ext_lagrangian)) {
variables(i)->add_bias_force_actual_value(cvm::real(time_step_factor) * colvar_forces[i]);
} else {
variables(i)->add_bias_force(cvm::real(time_step_factor) * colvar_forces[i]); variables(i)->add_bias_force(cvm::real(time_step_factor) * colvar_forces[i]);
} }
for (i = 0; i < num_variables(); i++) {
previous_colvar_forces[i] = colvar_forces[i]; previous_colvar_forces[i] = colvar_forces[i];
} }
} }
@ -368,20 +400,27 @@ std::string const colvarbias::get_state_params() const
int colvarbias::set_state_params(std::string const &conf) int colvarbias::set_state_params(std::string const &conf)
{ {
std::string new_name = ""; matching_state = false;
if (colvarparse::get_keyval(conf, "name", new_name,
std::string(""), colvarparse::parse_silent) &&
(new_name != this->name)) {
cvm::error("Error: in the state file, the "
"\""+bias_type+"\" block has a different name, \""+new_name+
"\": different system?\n", INPUT_ERROR);
}
if (name.size() == 0) { std::string check_name = "";
colvarparse::get_keyval(conf, "name", check_name,
std::string(""), colvarparse::parse_silent);
if (check_name.size() == 0) {
cvm::error("Error: \""+bias_type+"\" block within the restart file " cvm::error("Error: \""+bias_type+"\" block within the restart file "
"has no identifiers.\n", INPUT_ERROR); "has no identifiers.\n", INPUT_ERROR);
} }
if (check_name != this->name) {
if (cvm::debug()) {
cvm::log("Ignoring state of bias \""+check_name+
"\": this bias is named \""+name+"\".\n");
}
return COLVARS_OK;
}
matching_state = true;
colvarparse::get_keyval(conf, "step", state_file_step, colvarparse::get_keyval(conf, "step", state_file_step,
cvm::step_absolute(), colvarparse::parse_silent); cvm::step_absolute(), colvarparse::parse_silent);
@ -396,7 +435,7 @@ std::ostream & colvarbias::write_state(std::ostream &os)
} }
os.setf(std::ios::scientific, std::ios::floatfield); os.setf(std::ios::scientific, std::ios::floatfield);
os.precision(cvm::cv_prec); os.precision(cvm::cv_prec);
os << bias_type << " {\n" os << state_keyword << " {\n"
<< " configuration {\n"; << " configuration {\n";
std::istringstream is(get_state_params()); std::istringstream is(get_state_params());
std::string line; std::string line;
@ -415,13 +454,12 @@ std::istream & colvarbias::read_state(std::istream &is)
size_t const start_pos = is.tellg(); size_t const start_pos = is.tellg();
std::string key, brace, conf; std::string key, brace, conf;
if ( !(is >> key) || !(key == bias_type) || if ( !(is >> key) || !(key == state_keyword || key == bias_type) ||
!(is >> brace) || !(brace == "{") || !(is >> brace) || !(brace == "{") ||
!(is >> colvarparse::read_block("configuration", conf)) || !(is >> colvarparse::read_block("configuration", &conf)) ||
(set_state_params(conf) != COLVARS_OK) ) { (set_state_params(conf) != COLVARS_OK) ) {
if (key != bias_type) cvm::error("Error: in reading state configuration for \""+bias_type+
cvm::log("Found key \"" + key + "\" instead of \"" + bias_type + "\"\n"); "\" bias \""+
cvm::error("Error: in reading state configuration for \""+bias_type+"\" bias \""+
this->name+"\" at position "+ this->name+"\" at position "+
cvm::to_str(static_cast<size_t>(is.tellg()))+ cvm::to_str(static_cast<size_t>(is.tellg()))+
" in stream.\n", INPUT_ERROR); " in stream.\n", INPUT_ERROR);
@ -431,6 +469,15 @@ std::istream & colvarbias::read_state(std::istream &is)
return is; return is;
} }
if (matching_state == false) {
// This state is not for this bias
is.seekg(start_pos, std::ios::beg);
return is;
}
cvm::log("Restarting "+bias_type+" bias \""+name+"\" from step number "+
cvm::to_str(state_file_step)+".\n");
if (!read_state_data(is)) { if (!read_state_data(is)) {
cvm::error("Error: in reading state data for \""+bias_type+"\" bias \""+ cvm::error("Error: in reading state data for \""+bias_type+"\" bias \""+
this->name+"\" at position "+ this->name+"\" at position "+

View File

@ -23,9 +23,12 @@ public:
/// Name of this bias /// Name of this bias
std::string name; std::string name;
/// Type of this bias /// Keyword indicating the type of this bias
std::string bias_type; std::string bias_type;
/// Keyword used in state files (== bias_type most of the time)
std::string state_keyword;
/// If there is more than one bias of this type, record its rank /// If there is more than one bias of this type, record its rank
int rank; int rank;
@ -65,7 +68,7 @@ public:
virtual int calc_forces(std::vector<colvarvalue> const *values); virtual int calc_forces(std::vector<colvarvalue> const *values);
/// Send forces to the collective variables /// Send forces to the collective variables
virtual void communicate_forces(); void communicate_forces();
/// Carry out operations needed before next step is run /// Carry out operations needed before next step is run
virtual int end_of_step(); virtual int end_of_step();
@ -144,10 +147,10 @@ public:
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 restart file or other stream
virtual 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
virtual std::istream & read_state(std::istream &is); std::istream & read_state(std::istream &is);
/// 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);
@ -207,6 +210,9 @@ protected:
/// through each colvar object /// through each colvar object
std::vector<colvar *> colvars; std::vector<colvar *> colvars;
/// \brief Up to date value of each colvar
std::vector<colvarvalue> colvar_values;
/// \brief Current forces from this bias to the variables /// \brief Current forces from this bias to the variables
std::vector<colvarvalue> colvar_forces; std::vector<colvarvalue> colvar_forces;
@ -226,6 +232,9 @@ protected:
/// \brief Step number read from the last state file /// \brief Step number read from the last state file
cvm::step_number state_file_step; cvm::step_number state_file_step;
/// Flag used to tell if the state string being read is for this bias
bool matching_state;
}; };

View File

@ -115,7 +115,7 @@ int colvarbias_abf::init(std::string const &conf)
if (colvars[i]->value().type() != colvarvalue::type_scalar) { if (colvars[i]->value().type() != colvarvalue::type_scalar) {
cvm::error("Error: ABF bias can only use scalar-type variables.\n"); cvm::error("Error: ABF bias can only use scalar-type variables.\n");
} }
colvars[i]->enable(f_cv_grid); colvars[i]->enable(f_cv_grid); // Could be a child dependency of a f_cvb_use_grids feature
if (hide_Jacobian) { if (hide_Jacobian) {
colvars[i]->enable(f_cv_hide_Jacobian); colvars[i]->enable(f_cv_hide_Jacobian);
} }

View File

@ -246,6 +246,12 @@ int colvarbias_alb::update()
int colvarbias_alb::set_state_params(std::string const &conf) int colvarbias_alb::set_state_params(std::string const &conf)
{ {
int error_code = colvarbias::set_state_params(conf);
if (error_code != COLVARS_OK) {
return error_code;
}
if (!get_keyval(conf, "setCoupling", set_coupling)) if (!get_keyval(conf, "setCoupling", set_coupling))
cvm::fatal_error("Error: current setCoupling is missing from the restart.\n"); cvm::fatal_error("Error: current setCoupling is missing from the restart.\n");

View File

@ -17,6 +17,7 @@ colvarbias_histogram::colvarbias_histogram(char const *key)
: colvarbias(key), : colvarbias(key),
grid(NULL), out_name("") grid(NULL), out_name("")
{ {
provide(f_cvb_bypass_ext_lagrangian); // Allow histograms of actual cv for extended-Lagrangian
} }
@ -84,6 +85,10 @@ int colvarbias_histogram::init(std::string const &conf)
grid = new colvar_grid_scalar(); grid = new colvar_grid_scalar();
grid->init_from_colvars(colvars); grid->init_from_colvars(colvars);
if (is_enabled(f_cvb_bypass_ext_lagrangian)) {
grid->request_actual_value();
}
{ {
std::string grid_conf; std::string grid_conf;
if (key_lookup(conf, "histogramGrid", &grid_conf)) { if (key_lookup(conf, "histogramGrid", &grid_conf)) {

View File

@ -38,7 +38,12 @@ colvarbias_meta::colvarbias_meta(char const *key)
new_hills_begin = hills.end(); new_hills_begin = hills.end();
hills_traj_os = NULL; hills_traj_os = NULL;
hill_width = 0.0;
new_hill_freq = 1000;
use_grids = true; use_grids = true;
grids_freq = 0;
rebin_grids = false; rebin_grids = false;
hills_energy = NULL; hills_energy = NULL;
hills_energy_gradients = NULL; hills_energy_gradients = NULL;
@ -48,6 +53,8 @@ colvarbias_meta::colvarbias_meta(char const *key)
dump_fes_save = false; dump_fes_save = false;
dump_replica_fes = false; dump_replica_fes = false;
b_hills_traj = false;
ebmeta_equil_steps = 0L; ebmeta_equil_steps = 0L;
replica_update_freq = 0; replica_update_freq = 0;
@ -58,6 +65,7 @@ colvarbias_meta::colvarbias_meta(char const *key)
int colvarbias_meta::init(std::string const &conf) int colvarbias_meta::init(std::string const &conf)
{ {
int error_code = COLVARS_OK; int error_code = COLVARS_OK;
size_t i = 0;
error_code |= colvarbias::init(conf); error_code |= colvarbias::init(conf);
error_code |= colvarbias_ti::init(conf); error_code |= colvarbias_ti::init(conf);
@ -71,16 +79,38 @@ int colvarbias_meta::init(std::string const &conf)
cvm::error("Error: hillWeight must be provided, and a positive number.\n", INPUT_ERROR); cvm::error("Error: hillWeight must be provided, and a positive number.\n", INPUT_ERROR);
} }
get_keyval(conf, "newHillFrequency", new_hill_freq, 1000); get_keyval(conf, "newHillFrequency", new_hill_freq, new_hill_freq);
if (new_hill_freq > 0) { if (new_hill_freq > 0) {
enable(f_cvb_history_dependent); enable(f_cvb_history_dependent);
if (grids_freq == 0) {
grids_freq = new_hill_freq;
}
} }
get_keyval(conf, "hillWidth", hill_width, cvm::sqrt(2.0 * PI) / 2.0); get_keyval(conf, "gaussianSigmas", colvar_sigmas, colvar_sigmas);
get_keyval(conf, "hillWidth", hill_width, hill_width);
if ((colvar_sigmas.size() > 0) && (hill_width > 0.0)) {
error_code |= cvm::error("Error: hillWidth and gaussianSigmas are "
"mutually exclusive.", INPUT_ERROR);
}
if (hill_width > 0.0) {
colvar_sigmas.resize(num_variables());
// Print the calculated sigma parameters
cvm::log("Half-widths of the Gaussian hills (sigma's):\n"); cvm::log("Half-widths of the Gaussian hills (sigma's):\n");
for (size_t i = 0; i < num_variables(); i++) { for (i = 0; i < num_variables(); i++) {
colvar_sigmas[i] = variables(i)->width * hill_width / 2.0;
cvm::log(variables(i)->name+std::string(": ")+ cvm::log(variables(i)->name+std::string(": ")+
cvm::to_str(0.5 * variables(i)->width * hill_width)); cvm::to_str(colvar_sigmas[i]));
}
}
if (colvar_sigmas.size() == 0) {
error_code |= cvm::error("Error: positive values are required for "
"either hillWidth or gaussianSigmas.",
INPUT_ERROR);
} }
{ {
@ -95,11 +125,18 @@ int colvarbias_meta::init(std::string const &conf)
get_keyval(conf, "useGrids", use_grids, use_grids); get_keyval(conf, "useGrids", use_grids, use_grids);
if (use_grids) { if (use_grids) {
get_keyval(conf, "gridsUpdateFrequency", grids_freq, new_hill_freq);
for (i = 0; i < num_variables(); i++) {
if (2.0*colvar_sigmas[i] < variables(i)->width) {
cvm::log("Warning: gaussianSigmas is too narrow for the grid "
"spacing along "+variables(i)->name+".");
}
}
get_keyval(conf, "gridsUpdateFrequency", grids_freq, grids_freq);
get_keyval(conf, "rebinGrids", rebin_grids, rebin_grids); get_keyval(conf, "rebinGrids", rebin_grids, rebin_grids);
expand_grids = false; expand_grids = false;
size_t i;
for (i = 0; i < num_variables(); i++) { for (i = 0; i < num_variables(); i++) {
variables(i)->enable(f_cv_grid); // Could be a child dependency of a f_cvb_use_grids feature variables(i)->enable(f_cv_grid); // Could be a child dependency of a f_cvb_use_grids feature
if (variables(i)->expand_boundaries) { if (variables(i)->expand_boundaries) {
@ -116,15 +153,17 @@ int colvarbias_meta::init(std::string const &conf)
get_keyval(conf, "keepHills", keep_hills, keep_hills); get_keyval(conf, "keepHills", keep_hills, keep_hills);
get_keyval(conf, "keepFreeEnergyFiles", dump_fes_save, dump_fes_save); get_keyval(conf, "keepFreeEnergyFiles", dump_fes_save, dump_fes_save);
if (hills_energy == NULL) {
hills_energy = new colvar_grid_scalar(colvars); hills_energy = new colvar_grid_scalar(colvars);
hills_energy_gradients = new colvar_grid_gradient(colvars); hills_energy_gradients = new colvar_grid_gradient(colvars);
}
} else { } else {
dump_fes = false; dump_fes = false;
} }
get_keyval(conf, "writeHillsTrajectory", b_hills_traj, false); get_keyval(conf, "writeHillsTrajectory", b_hills_traj, b_hills_traj);
error_code |= init_replicas_params(conf); error_code |= init_replicas_params(conf);
error_code |= init_well_tempered_params(conf); error_code |= init_well_tempered_params(conf);
@ -323,7 +362,7 @@ int colvarbias_meta::clear_state_data()
// ********************************************************************** // **********************************************************************
std::list<colvarbias_meta::hill>::const_iterator std::list<colvarbias_meta::hill>::const_iterator
colvarbias_meta::create_hill(colvarbias_meta::hill const &h) colvarbias_meta::add_hill(colvarbias_meta::hill const &h)
{ {
hill_iter const hills_end = hills.end(); hill_iter const hills_end = hills.end();
hills.push_back(h); hills.push_back(h);
@ -563,12 +602,14 @@ int colvarbias_meta::update_bias()
case single_replica: case single_replica:
create_hill(hill(hill_weight*hills_scale, colvars, hill_width)); add_hill(hill(cvm::step_absolute(), hill_weight*hills_scale,
colvar_values, colvar_sigmas));
break; break;
case multiple_replicas: case multiple_replicas:
create_hill(hill(hill_weight*hills_scale, colvars, hill_width, replica_id)); add_hill(hill(cvm::step_absolute(), hill_weight*hills_scale,
colvar_values, colvar_sigmas, replica_id));
std::ostream *replica_hills_os = std::ostream *replica_hills_os =
cvm::proxy->get_output_stream(replica_hills_file); cvm::proxy->get_output_stream(replica_hills_file);
if (replica_hills_os) { if (replica_hills_os) {
@ -730,35 +771,21 @@ void colvarbias_meta::calc_hills(colvarbias_meta::hill_iter h_first,
std::vector<colvarvalue> const *values) std::vector<colvarvalue> const *values)
{ {
size_t i = 0; size_t i = 0;
std::vector<colvarvalue> curr_values(num_variables());
for (i = 0; i < num_variables(); i++) {
curr_values[i].type(variables(i)->value());
}
if (values) {
for (i = 0; i < num_variables(); i++) {
curr_values[i] = (*values)[i];
}
} else {
for (i = 0; i < num_variables(); i++) {
curr_values[i] = variables(i)->value();
}
}
for (hill_iter h = h_first; h != h_last; h++) { for (hill_iter h = h_first; h != h_last; h++) {
// compute the gaussian exponent // compute the gaussian exponent
cvm::real cv_sqdev = 0.0; cvm::real cv_sqdev = 0.0;
for (i = 0; i < num_variables(); i++) { for (i = 0; i < num_variables(); i++) {
colvarvalue const &x = curr_values[i]; colvarvalue const &x = values ? (*values)[i] : colvar_values[i];
colvarvalue const &center = h->centers[i]; colvarvalue const &center = h->centers[i];
cvm::real const half_width = 0.5 * h->widths[i]; cvm::real const sigma = h->sigmas[i];
cv_sqdev += (variables(i)->dist2(x, center)) / (half_width*half_width); cv_sqdev += (variables(i)->dist2(x, center)) / (sigma*sigma);
} }
// compute the gaussian // compute the gaussian
if (cv_sqdev > 23.0) { if (cv_sqdev > 23.0) {
// set it to zero if the exponent is more negative than log(1.0E-05) // set it to zero if the exponent is more negative than log(1.0E-06)
h->value(0.0); h->value(0.0);
} else { } else {
h->value(cvm::exp(-0.5*cv_sqdev)); h->value(cvm::exp(-0.5*cv_sqdev));
@ -775,22 +802,22 @@ void colvarbias_meta::calc_hills_force(size_t const &i,
std::vector<colvarvalue> const *values) std::vector<colvarvalue> const *values)
{ {
// Retrieve the value of the colvar // Retrieve the value of the colvar
colvarvalue const x(values ? (*values)[i] : variables(i)->value()); colvarvalue const x(values ? (*values)[i] : colvar_values[i]);
// do the type check only once (all colvarvalues in the hills series // do the type check only once (all colvarvalues in the hills series
// were already saved with their types matching those in the // were already saved with their types matching those in the
// colvars) // colvars)
hill_iter h; hill_iter h;
switch (variables(i)->value().type()) { switch (x.type()) {
case colvarvalue::type_scalar: case colvarvalue::type_scalar:
for (h = h_first; h != h_last; h++) { for (h = h_first; h != h_last; h++) {
if (h->value() == 0.0) continue; if (h->value() == 0.0) continue;
colvarvalue const &center = h->centers[i]; colvarvalue const &center = h->centers[i];
cvm::real const half_width = 0.5 * h->widths[i]; cvm::real const sigma = h->sigmas[i];
forces[i].real_value += forces[i].real_value +=
( h->weight() * h->value() * (0.5 / (half_width*half_width)) * ( h->weight() * h->value() * (0.5 / (sigma*sigma)) *
(variables(i)->dist2_lgrad(x, center)).real_value ); (variables(i)->dist2_lgrad(x, center)).real_value );
} }
break; break;
@ -801,9 +828,9 @@ void colvarbias_meta::calc_hills_force(size_t const &i,
for (h = h_first; h != h_last; h++) { for (h = h_first; h != h_last; h++) {
if (h->value() == 0.0) continue; if (h->value() == 0.0) continue;
colvarvalue const &center = h->centers[i]; colvarvalue const &center = h->centers[i];
cvm::real const half_width = 0.5 * h->widths[i]; cvm::real const sigma = h->sigmas[i];
forces[i].rvector_value += forces[i].rvector_value +=
( h->weight() * h->value() * (0.5 / (half_width*half_width)) * ( h->weight() * h->value() * (0.5 / (sigma*sigma)) *
(variables(i)->dist2_lgrad(x, center)).rvector_value ); (variables(i)->dist2_lgrad(x, center)).rvector_value );
} }
break; break;
@ -813,9 +840,9 @@ void colvarbias_meta::calc_hills_force(size_t const &i,
for (h = h_first; h != h_last; h++) { for (h = h_first; h != h_last; h++) {
if (h->value() == 0.0) continue; if (h->value() == 0.0) continue;
colvarvalue const &center = h->centers[i]; colvarvalue const &center = h->centers[i];
cvm::real const half_width = 0.5 * h->widths[i]; cvm::real const sigma = h->sigmas[i];
forces[i].quaternion_value += forces[i].quaternion_value +=
( h->weight() * h->value() * (0.5 / (half_width*half_width)) * ( h->weight() * h->value() * (0.5 / (sigma*sigma)) *
(variables(i)->dist2_lgrad(x, center)).quaternion_value ); (variables(i)->dist2_lgrad(x, center)).quaternion_value );
} }
break; break;
@ -824,9 +851,9 @@ void colvarbias_meta::calc_hills_force(size_t const &i,
for (h = h_first; h != h_last; h++) { for (h = h_first; h != h_last; h++) {
if (h->value() == 0.0) continue; if (h->value() == 0.0) continue;
colvarvalue const &center = h->centers[i]; colvarvalue const &center = h->centers[i];
cvm::real const half_width = 0.5 * h->widths[i]; cvm::real const sigma = h->sigmas[i];
forces[i].vector1d_value += forces[i].vector1d_value +=
( h->weight() * h->value() * (0.5 / (half_width*half_width)) * ( h->weight() * h->value() * (0.5 / (sigma*sigma)) *
(variables(i)->dist2_lgrad(x, center)).vector1d_value ); (variables(i)->dist2_lgrad(x, center)).vector1d_value );
} }
break; break;
@ -1246,14 +1273,20 @@ void colvarbias_meta::read_replica_files()
int colvarbias_meta::set_state_params(std::string const &state_conf) int colvarbias_meta::set_state_params(std::string const &state_conf)
{ {
std::string new_replica = ""; int error_code = colvarbias::set_state_params(state_conf);
if (colvarparse::get_keyval(state_conf, "replicaID", new_replica,
if (error_code != COLVARS_OK) {
return error_code;
}
std::string check_replica = "";
if (colvarparse::get_keyval(state_conf, "replicaID", check_replica,
std::string(""), colvarparse::parse_silent) && std::string(""), colvarparse::parse_silent) &&
(new_replica != this->replica_id)) { (check_replica != this->replica_id)) {
cvm::error("Error: in the state file, the " return cvm::error("Error: in the state file , the "
"\"metadynamics\" block has a different replicaID: different system?\n", "\"metadynamics\" block has a different replicaID ("+
check_replica+" instead of "+replica_id+").\n",
INPUT_ERROR); INPUT_ERROR);
return INPUT_ERROR;
} }
return COLVARS_OK; return COLVARS_OK;
@ -1479,17 +1512,18 @@ 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(); size_t const start_pos = is.tellg();
size_t i = 0;
std::string data; std::string data;
if ( !(is >> read_block("hill", data)) ) { if ( !(is >> read_block("hill", &data)) ) {
is.clear(); is.clear();
is.seekg(start_pos, std::ios::beg); is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit); is.setstate(std::ios::failbit);
return is; return is;
} }
cvm::step_number h_it; cvm::step_number h_it = 0L;
get_keyval(data, "step", h_it, 0L, parse_silent); get_keyval(data, "step", h_it, h_it, parse_restart);
if (h_it <= state_file_step) { if (h_it <= state_file_step) {
if (cvm::debug()) if (cvm::debug())
cvm::log("Skipping a hill older than the state file for metadynamics bias \""+ cvm::log("Skipping a hill older than the state file for metadynamics bias \""+
@ -1499,31 +1533,24 @@ std::istream & colvarbias_meta::read_hill(std::istream &is)
} }
cvm::real h_weight; cvm::real h_weight;
get_keyval(data, "weight", h_weight, hill_weight, parse_silent); get_keyval(data, "weight", h_weight, hill_weight, parse_restart);
std::vector<colvarvalue> h_centers(num_variables()); std::vector<colvarvalue> h_centers(num_variables());
for (size_t i = 0; i < num_variables(); i++) { for (i = 0; i < num_variables(); i++) {
h_centers[i].type(variables(i)->value()); h_centers[i].type(variables(i)->value());
} }
{ get_keyval(data, "centers", h_centers, h_centers, parse_restart);
// it is safer to read colvarvalue objects one at a time;
// TODO: change this it later
std::string centers_input;
key_lookup(data, "centers", &centers_input);
std::istringstream centers_is(centers_input);
for (size_t i = 0; i < num_variables(); i++) {
centers_is >> h_centers[i];
}
}
std::vector<cvm::real> h_widths(num_variables()); std::vector<cvm::real> h_sigmas(num_variables());
get_keyval(data, "widths", h_widths, get_keyval(data, "widths", h_sigmas, h_sigmas, parse_restart);
std::vector<cvm::real>(num_variables(), (cvm::sqrt(2.0 * PI) / 2.0)), for (i = 0; i < num_variables(); i++) {
parse_silent); // For backward compatibility, read the widths instead of the sigmas
h_sigmas[i] /= 2.0;
}
std::string h_replica = ""; std::string h_replica = "";
if (comm != single_replica) { if (comm != single_replica) {
get_keyval(data, "replicaID", h_replica, replica_id, parse_silent); get_keyval(data, "replicaID", h_replica, replica_id, parse_restart);
if (h_replica != replica_id) if (h_replica != replica_id)
cvm::fatal_error("Error: trying to read a hill created by replica \""+h_replica+ cvm::fatal_error("Error: trying to read a hill created by replica \""+h_replica+
"\" for replica \""+replica_id+ "\" for replica \""+replica_id+
@ -1531,7 +1558,7 @@ std::istream & colvarbias_meta::read_hill(std::istream &is)
} }
hill_iter const hills_end = hills.end(); hill_iter const hills_end = hills.end();
hills.push_back(hill(h_it, h_weight, h_centers, h_widths, h_replica)); hills.push_back(hill(h_it, h_weight, h_centers, h_sigmas, h_replica));
if (new_hills_begin == hills_end) { if (new_hills_begin == hills_end) {
// if new_hills_begin is unset, set it for the first time // if new_hills_begin is unset, set it for the first time
new_hills_begin = hills.end(); new_hills_begin = hills.end();
@ -1753,8 +1780,8 @@ void colvarbias_meta::write_pmf()
if (ebmeta) { if (ebmeta) {
int nt_points=pmf->number_of_points(); int nt_points=pmf->number_of_points();
for (int i = 0; i < nt_points; i++) { for (int i = 0; i < nt_points; i++) {
cvm:: real pmf_val=0.0; cvm::real pmf_val=0.0;
cvm:: real target_val=target_dist->value(i); cvm::real target_val=target_dist->value(i);
if (target_val>0) { if (target_val>0) {
pmf_val=pmf->value(i); pmf_val=pmf->value(i);
pmf_val=pmf_val+cvm::temperature() * cvm::boltzmann() * cvm::logn(target_val); pmf_val=pmf_val+cvm::temperature() * cvm::boltzmann() * cvm::logn(target_val);
@ -1794,8 +1821,8 @@ void colvarbias_meta::write_pmf()
if (ebmeta) { if (ebmeta) {
int nt_points=pmf->number_of_points(); int nt_points=pmf->number_of_points();
for (int i = 0; i < nt_points; i++) { for (int i = 0; i < nt_points; i++) {
cvm:: real pmf_val=0.0; cvm::real pmf_val=0.0;
cvm:: real target_val=target_dist->value(i); cvm::real target_val=target_dist->value(i);
if (target_val>0) { if (target_val>0) {
pmf_val=pmf->value(i); pmf_val=pmf->value(i);
pmf_val=pmf_val+cvm::temperature() * cvm::boltzmann() * cvm::logn(target_val); pmf_val=pmf_val+cvm::temperature() * cvm::boltzmann() * cvm::logn(target_val);
@ -1889,10 +1916,10 @@ std::string colvarbias_meta::hill::output_traj()
} }
os << " "; os << " ";
for (i = 0; i < widths.size(); i++) { for (i = 0; i < sigmas.size(); i++) {
os << " "; os << " ";
os << std::setprecision(cvm::cv_prec) os << std::setprecision(cvm::cv_prec)
<< std::setw(cvm::cv_width) << widths[i]; << std::setw(cvm::cv_width) << sigmas[i];
} }
os << " "; os << " ";
@ -1903,6 +1930,47 @@ std::string colvarbias_meta::hill::output_traj()
} }
colvarbias_meta::hill::hill(cvm::step_number it_in,
cvm::real W_in,
std::vector<colvarvalue> const &cv_values,
std::vector<cvm::real> const &cv_sigmas,
std::string const &replica_in)
: it(it_in),
sW(1.0),
W(W_in),
centers(cv_values.size()),
sigmas(cv_values.size()),
replica(replica_in)
{
for (size_t i = 0; i < cv_values.size(); i++) {
centers[i].type(cv_values[i]);
centers[i] = cv_values[i];
sigmas[i] = cv_sigmas[i];
}
if (cvm::debug()) {
cvm::log("New hill, applied to "+cvm::to_str(cv_values.size())+
" collective variables, with centers "+
cvm::to_str(centers)+", sigmas "+
cvm::to_str(sigmas)+" and weight "+
cvm::to_str(W)+".\n");
}
}
colvarbias_meta::hill::hill(colvarbias_meta::hill const &h)
: sW(1.0),
W(h.W),
centers(h.centers),
sigmas(h.sigmas),
it(h.it),
replica(h.replica)
{}
colvarbias_meta::hill::~hill()
{}
std::ostream & operator << (std::ostream &os, colvarbias_meta::hill const &h) std::ostream & operator << (std::ostream &os, colvarbias_meta::hill const &h)
{ {
os.setf(std::ios::scientific, std::ios::floatfield); os.setf(std::ios::scientific, std::ios::floatfield);
@ -1927,12 +1995,13 @@ std::ostream & operator << (std::ostream &os, colvarbias_meta::hill const &h)
} }
os << "\n"; os << "\n";
// For backward compatibility, write the widths instead of the sigmas
os << " widths "; os << " widths ";
for (i = 0; i < (h.widths).size(); i++) { for (i = 0; i < (h.sigmas).size(); i++) {
os << " " os << " "
<< std::setprecision(cvm::cv_prec) << std::setprecision(cvm::cv_prec)
<< std::setw(cvm::cv_width) << std::setw(cvm::cv_width)
<< h.widths[i]; << 2.0 * h.sigmas[i];
} }
os << "\n"; os << "\n";

View File

@ -71,12 +71,15 @@ public:
protected: protected:
/// \brief width of a hill /// Width of a hill in number of grid points
/// ///
/// The local width of each collective variable, multiplied by this /// The local width of each collective variable, multiplied by this
/// number, provides the hill width along that direction /// number, provides the hill width along that direction
cvm::real hill_width; cvm::real hill_width;
/// The sigma parameters of the Gaussian hills
std::vector<cvm::real> colvar_sigmas;
/// \brief Number of simulation steps between two hills /// \brief Number of simulation steps between two hills
size_t new_hill_freq; size_t new_hill_freq;
@ -113,11 +116,11 @@ protected:
/// \brief Add a new hill; if a .hills trajectory is written, /// \brief Add a new hill; if a .hills trajectory is written,
/// write it there; if there is more than one replica, communicate /// write it there; if there is more than one replica, communicate
/// it to the others /// it to the others
virtual std::list<hill>::const_iterator create_hill(hill const &h); std::list<hill>::const_iterator add_hill(hill const &h);
/// \brief Remove a previously saved hill (returns an iterator for /// \brief Remove a previously saved hill (returns an iterator for
/// the next hill in the list) /// the next hill in the list)
virtual std::list<hill>::const_iterator delete_hill(hill_iter &h); std::list<hill>::const_iterator delete_hill(hill_iter &h);
/// \brief Calculate the values of the hills, incrementing /// \brief Calculate the values of the hills, incrementing
/// bias_energy /// bias_energy
@ -266,6 +269,9 @@ class colvarbias_meta::hill {
protected: protected:
/// Time step at which this hill was added
cvm::step_number it;
/// Value of the hill function (ranges between 0 and 1) /// Value of the hill function (ranges between 0 and 1)
cvm::real hill_value; cvm::real hill_value;
@ -275,83 +281,35 @@ protected:
/// Maximum height in energy of the hill /// Maximum height in energy of the hill
cvm::real W; cvm::real W;
/// Center of the hill in the collective variable space /// Centers of the hill in the collective variable space
std::vector<colvarvalue> centers; std::vector<colvarvalue> centers;
/// Widths of the hill in the collective variable space /// Half-widths of the hill in the collective variable space
std::vector<cvm::real> widths; std::vector<cvm::real> sigmas;
/// Identity of the replica who added this hill
std::string replica;
public: public:
friend class colvarbias_meta; friend class colvarbias_meta;
/// Time step at which this hill was added /// Constructor of a hill object
cvm::step_number it; /// \param it Step number at which the hill was added
/// \param W Weight of the hill (energy units)
/// Identity of the replica who added this hill (only in multiple replica simulations) /// \param cv_values Array of collective variable values
std::string replica; /// \param cv_sigmas Array of collective variable values
/// \param replica ID of the replica that creates the hill (optional)
/// \brief Runtime constructor: data are read directly from hill(cvm::step_number it, cvm::real W,
/// collective variables \param weight Weight of the hill \param std::vector<colvarvalue> const &cv_values,
/// cv Pointer to the array of collective variables involved \param std::vector<cvm::real> const &cv_sigmas,
/// replica (optional) Identity of the replica which creates the std::string const &replica = "");
/// hill
inline hill(cvm::real const &W_in,
std::vector<colvar *> &cv,
cvm::real const &hill_width,
std::string const &replica_in = "")
: sW(1.0),
W(W_in),
centers(cv.size()),
widths(cv.size()),
it(cvm::step_absolute()),
replica(replica_in)
{
for (size_t i = 0; i < cv.size(); i++) {
centers[i].type(cv[i]->value());
centers[i] = cv[i]->value();
widths[i] = cv[i]->width * hill_width;
}
if (cvm::debug())
cvm::log("New hill, applied to "+cvm::to_str(cv.size())+
" collective variables, with centers "+
cvm::to_str(centers)+", widths "+
cvm::to_str(widths)+" and weight "+
cvm::to_str(W)+".\n");
}
/// \brief General constructor: all data are explicitly passed as
/// arguments (used for instance when reading hills saved on a
/// file) \param it Time step of creation of the hill \param
/// weight Weight of the hill \param centers Center of the hill
/// \param widths Width of the hill around centers \param replica
/// (optional) Identity of the replica which creates the hill
inline hill(cvm::step_number const &it_in,
cvm::real const &W_in,
std::vector<colvarvalue> const &centers_in,
std::vector<cvm::real> const &widths_in,
std::string const &replica_in = "")
: sW(1.0),
W(W_in),
centers(centers_in),
widths(widths_in),
it(it_in),
replica(replica_in)
{}
/// Copy constructor /// Copy constructor
inline hill(colvarbias_meta::hill const &h) hill(colvarbias_meta::hill const &h);
: sW(1.0),
W(h.W),
centers(h.centers),
widths(h.widths),
it(h.it),
replica(h.replica)
{}
/// Destructor /// Destructor
inline ~hill() ~hill();
{}
/// Get the energy /// Get the energy
inline cvm::real energy() inline cvm::real energy()
@ -440,8 +398,7 @@ public:
std::string output_traj(); std::string output_traj();
/// Write the hill to an output stream /// Write the hill to an output stream
inline friend std::ostream & operator << (std::ostream &os, friend std::ostream & operator << (std::ostream &os, hill const &h);
hill const &h);
}; };

View File

@ -17,6 +17,7 @@
colvarbias_restraint::colvarbias_restraint(char const *key) colvarbias_restraint::colvarbias_restraint(char const *key)
: colvarbias(key), colvarbias_ti(key) : colvarbias(key), colvarbias_ti(key)
{ {
state_keyword = "restraint";
} }
@ -705,67 +706,6 @@ std::ostream & colvarbias_restraint_k_moving::write_traj(std::ostream &os)
// redefined due to legacy state file keyword "harmonic"
std::istream & colvarbias_restraint::read_state(std::istream &is)
{
size_t const start_pos = is.tellg();
std::string key, brace, conf;
if ( !(is >> key) || !(key == "restraint" || key == "harmonic") ||
!(is >> brace) || !(brace == "{") ||
!(is >> colvarparse::read_block("configuration", conf)) ||
(set_state_params(conf) != COLVARS_OK) ) {
cvm::error("Error: in reading state configuration for \""+bias_type+"\" bias \""+
this->name+"\" at position "+
cvm::to_str(static_cast<size_t>(is.tellg()))+
" in stream.\n", INPUT_ERROR);
is.clear();
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
if (!read_state_data(is)) {
cvm::error("Error: in reading state data for \""+bias_type+"\" bias \""+
this->name+"\" at position "+
cvm::to_str(static_cast<size_t>(is.tellg()))+
" in stream.\n", INPUT_ERROR);
is.clear();
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
}
is >> brace;
if (brace != "}") {
cvm::log("brace = "+brace+"\n");
cvm::error("Error: corrupt restart information for \""+bias_type+"\" bias \""+
this->name+"\": no matching brace at position "+
cvm::to_str(static_cast<size_t>(is.tellg()))+" in stream.\n");
is.setstate(std::ios::failbit);
}
return is;
}
std::ostream & colvarbias_restraint::write_state(std::ostream &os)
{
os.setf(std::ios::scientific, std::ios::floatfield);
os << "restraint {\n"
<< " configuration {\n";
std::istringstream is(get_state_params());
std::string line;
while (std::getline(is, line)) {
os << " " << line << "\n";
}
os << " }\n";
write_state_data(os);
os << "}\n\n";
return os;
}
colvarbias_restraint_harmonic::colvarbias_restraint_harmonic(char const *key) colvarbias_restraint_harmonic::colvarbias_restraint_harmonic(char const *key)
: colvarbias(key), : colvarbias(key),
colvarbias_ti(key), colvarbias_ti(key),
@ -928,6 +868,9 @@ colvarbias_restraint_harmonic_walls::colvarbias_restraint_harmonic_walls(char co
{ {
lower_wall_k = -1.0; lower_wall_k = -1.0;
upper_wall_k = -1.0; upper_wall_k = -1.0;
// This bias implements the bias_actual_colvars feature (most others do not)
provide(f_cvb_bypass_ext_lagrangian);
set_enabled(f_cvb_bypass_ext_lagrangian); // Defaults to enabled
} }
@ -1075,23 +1018,13 @@ int colvarbias_restraint_harmonic_walls::update()
} }
void colvarbias_restraint_harmonic_walls::communicate_forces()
{
for (size_t i = 0; i < num_variables(); i++) {
if (cvm::debug()) {
cvm::log("Communicating a force to colvar \""+
variables(i)->name+"\".\n");
}
// Impulse-style multiple timestep
variables(i)->add_bias_force_actual_value(cvm::real(time_step_factor) * colvar_forces[i]);
}
}
cvm::real colvarbias_restraint_harmonic_walls::colvar_distance(size_t i) const cvm::real colvarbias_restraint_harmonic_walls::colvar_distance(size_t i) const
{ {
colvar *cv = variables(i); colvar *cv = variables(i);
colvarvalue const &cvv = variables(i)->actual_value();
colvarvalue const &cvv = is_enabled(f_cvb_bypass_ext_lagrangian) ?
variables(i)->actual_value() :
variables(i)->value();
// For a periodic colvar, both walls may be applicable at the same time // For a periodic colvar, both walls may be applicable at the same time
// in which case we pick the closer one // in which case we pick the closer one

View File

@ -35,8 +35,6 @@ public:
virtual int set_state_params(std::string const &conf); virtual int set_state_params(std::string const &conf);
// virtual std::ostream & write_state_data(std::ostream &os); // virtual std::ostream & write_state_data(std::ostream &os);
// virtual std::istream & read_state_data(std::istream &os); // virtual std::istream & read_state_data(std::istream &os);
virtual std::ostream & write_state(std::ostream &os);
virtual std::istream & read_state(std::istream &is);
virtual std::ostream & write_traj_label(std::ostream &os); virtual std::ostream & write_traj_label(std::ostream &os);
virtual std::ostream & write_traj(std::ostream &os); virtual std::ostream & write_traj(std::ostream &os);
@ -258,7 +256,6 @@ public:
colvarbias_restraint_harmonic_walls(char const *key); colvarbias_restraint_harmonic_walls(char const *key);
virtual int init(std::string const &conf); virtual int init(std::string const &conf);
virtual int update(); virtual int update();
virtual void communicate_forces();
virtual std::string const get_state_params() const; virtual std::string const get_state_params() const;
virtual int set_state_params(std::string const &conf); virtual int set_state_params(std::string const &conf);
virtual std::ostream & write_state_data(std::ostream &os); virtual std::ostream & write_state_data(std::ostream &os);

View File

@ -428,10 +428,10 @@ void colvardeps::require_feature_alt(int f, int g, int h, int i, int j) {
void colvardeps::print_state() { void colvardeps::print_state() {
size_t i; size_t i;
cvm::log("Enabled features of \"" + description + "\" (with reference count)"); cvm::log("Features of \"" + description + "\" ON/OFF (refcount)");
for (i = 0; i < feature_states.size(); i++) { for (i = 0; i < feature_states.size(); i++) {
if (is_enabled(i)) std::string onoff = is_enabled(i) ? "ON" : "OFF";
cvm::log("- " + features()[i]->description + " (" cvm::log("- " + features()[i]->description + " " + onoff + " ("
+ cvm::to_str(feature_states[i].ref_count) + ")"); + cvm::to_str(feature_states[i].ref_count) + ")");
} }
cvm::increase_depth(); cvm::increase_depth();

View File

@ -229,6 +229,8 @@ public:
f_cvb_awake, f_cvb_awake,
/// \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
f_cvb_bypass_ext_lagrangian,
/// \brief requires total forces /// \brief requires total forces
f_cvb_get_total_force, f_cvb_get_total_force,
/// \brief whether this bias should record the accumulated work /// \brief whether this bias should record the accumulated work

View File

@ -932,7 +932,7 @@ public:
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);
is >> colvarparse::read_block("grid_parameters", conf); is >> colvarparse::read_block("grid_parameters", &conf);
parse_params(conf, colvarparse::parse_silent); parse_params(conf, colvarparse::parse_silent);
} else { } else {
cvm::log("Grid parameters are missing in the restart file, using those from the configuration.\n"); cvm::log("Grid parameters are missing in the restart file, using those from the configuration.\n");

View File

@ -1284,7 +1284,7 @@ std::istream & colvarmodule::read_restart(std::istream &is)
{ {
// read global restart information // read global restart information
std::string restart_conf; std::string restart_conf;
if (is >> colvarparse::read_block("configuration", restart_conf)) { if (is >> colvarparse::read_block("configuration", &restart_conf)) {
parse->get_keyval(restart_conf, "step", parse->get_keyval(restart_conf, "step",
it_restart, static_cast<step_number>(0), it_restart, static_cast<step_number>(0),
@ -1329,30 +1329,84 @@ std::istream & colvarmodule::read_restart(std::istream &is)
parse->clear_keyword_registry(); parse->clear_keyword_registry();
} }
// colvars restart print_total_forces_errning(warn_total_forces);
read_objects_state(is);
return is;
}
std::istream & colvarmodule::read_objects_state(std::istream &is)
{
size_t pos = 0;
std::string word;
while (is.good()) {
pos = is.tellg();
word.clear();
is >> word;
if (word.size()) {
is.seekg(pos, std::ios::beg);
if (word == "colvar") {
cvm::increase_depth(); cvm::increase_depth();
for (std::vector<colvar *>::iterator cvi = colvars.begin(); for (std::vector<colvar *>::iterator cvi = colvars.begin();
cvi != colvars.end(); cvi != colvars.end();
cvi++) { cvi++) {
if ( !((*cvi)->read_restart(is)) ) { if ( !((*cvi)->read_state(is)) ) {
cvm::error("Error: in reading restart configuration for collective variable \""+ // Here an error signals that the variable is a match, but the
(*cvi)->name+"\".\n", // state is corrupt; otherwise, the variable rewinds is silently
cvm::error("Error: in reading restart configuration for "
"collective variable \""+(*cvi)->name+"\".\n",
INPUT_ERROR); INPUT_ERROR);
} }
if (static_cast<size_t>(is.tellg()) > pos) break; // found it
} }
cvm::decrease_depth();
// biases restart } else {
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++) {
if (((*bi)->state_keyword != word) && (*bi)->bias_type != word) {
// Skip biases with different type; state_keyword is used to
// support different versions of the state file format
continue;
}
if (!((*bi)->read_state(is))) { if (!((*bi)->read_state(is))) {
// Same as above, an error means a match but the state is incorrect
cvm::error("Error: in reading restart configuration for bias \""+ cvm::error("Error: in reading restart configuration for bias \""+
(*bi)->name+"\".\n", (*bi)->name+"\".\n",
INPUT_ERROR); INPUT_ERROR);
} }
if (static_cast<size_t>(is.tellg()) > pos) break; // found it
} }
cvm::decrease_depth(); cvm::decrease_depth();
}
}
if (static_cast<size_t>(is.tellg()) == pos) {
// This block has not been read by any object: discard it and move on
// to the next one
is >> colvarparse::read_block(word, NULL);
}
if (!is) break;
}
return is;
}
int colvarmodule::print_total_forces_errning(bool warn_total_forces)
{
if (warn_total_forces) { if (warn_total_forces) {
cvm::log(cvm::line_marker); cvm::log(cvm::line_marker);
cvm::log("WARNING: The definition of system forces has changed. Please see:\n"); cvm::log("WARNING: The definition of system forces has changed. Please see:\n");
@ -1367,10 +1421,11 @@ to:\n\
and load it to continue this simulation.\n"); and load it to continue this simulation.\n");
output_prefix() = output_prefix()+".tmp"; output_prefix() = output_prefix()+".tmp";
write_restart_file(output_prefix()+".colvars.state"); write_restart_file(output_prefix()+".colvars.state");
cvm::error("Exiting with error until issue is addressed.\n", INPUT_ERROR); return cvm::error("Exiting with error until issue is addressed.\n",
INPUT_ERROR);
} }
return is; return COLVARS_OK;
} }
@ -1499,7 +1554,7 @@ std::ostream & colvarmodule::write_restart(std::ostream &os)
for (std::vector<colvar *>::iterator cvi = colvars.begin(); for (std::vector<colvar *>::iterator cvi = colvars.begin();
cvi != colvars.end(); cvi != colvars.end();
cvi++) { cvi++) {
(*cvi)->write_restart(os); (*cvi)->write_state(os);
} }
for (std::vector<colvarbias *>::iterator bi = biases.begin(); for (std::vector<colvarbias *>::iterator bi = biases.begin();

View File

@ -429,8 +429,15 @@ public:
/// (Re)initialize the output trajectory and state file (does not write it yet) /// (Re)initialize the output trajectory and state file (does not write it yet)
int setup_output(); int setup_output();
/// Read the input restart file /// Read a restart file
std::istream & read_restart(std::istream &is); std::istream & read_restart(std::istream &is);
/// Read the states of individual objects; allows for changes
std::istream & read_objects_state(std::istream &is);
/// If needed (old restart file), print the warning that cannot be ignored
int print_total_forces_errning(bool warn_total_forces);
/// Write the output restart file /// Write the output restart file
std::ostream & write_restart(std::ostream &os); std::ostream & write_restart(std::ostream &os);

View File

@ -840,6 +840,17 @@ bool colvarparse::key_lookup(std::string const &conf,
} }
colvarparse::read_block::read_block(std::string const &key_in,
std::string *data_in)
: key(key_in), data(data_in)
{
}
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(); size_t start_pos = is.tellg();
@ -856,7 +867,9 @@ std::istream & operator>> (std::istream &is, colvarparse::read_block const &rb)
} }
if (next != "{") { if (next != "{") {
(*rb.data) = next; if (rb.data) {
*(rb.data) = next;
}
return is; return is;
} }
@ -870,9 +883,15 @@ std::istream & operator>> (std::istream &is, colvarparse::read_block const &rb)
br_old = br; br_old = br;
br++; br++;
} }
if (brace_count) (*rb.data).append(line + "\n"); if (brace_count) {
if (rb.data) {
(rb.data)->append(line + "\n");
}
}
else { else {
(*rb.data).append(line, 0, br_old); if (rb.data) {
(rb.data)->append(line, 0, br_old);
}
break; break;
} }
} }

View File

@ -272,14 +272,18 @@ public:
/// skipping other blocks /// skipping other blocks
class read_block { class read_block {
/// The keyword that identifies the block
std::string const key; std::string const key;
/// Where to keep the data (may be NULL)
std::string * const data; std::string * const data;
public: public:
inline read_block(std::string const &key_in, std::string &data_in)
: key(key_in), data(&data_in) read_block(std::string const &key_in, std::string *data_in = NULL);
{}
inline ~read_block() {} ~read_block();
friend std::istream & operator >> (std::istream &is, read_block const &rb); friend std::istream & operator >> (std::istream &is, read_block const &rb);
}; };

View File

@ -1,3 +1,3 @@
#ifndef COLVARS_VERSION #ifndef COLVARS_VERSION
#define COLVARS_VERSION "2020-01-27" #define COLVARS_VERSION "2020-02-25"
#endif #endif

View File

@ -160,14 +160,20 @@ void colvarproxy_lammps::init(const char *conf_file)
} }
} }
void colvarproxy_lammps::add_config_file(const char *conf_file) int colvarproxy_lammps::add_config_file(const char *conf_file)
{ {
colvars->read_config_file(conf_file); return colvars->read_config_file(conf_file);
} }
void colvarproxy_lammps::add_config_string(const std::string &conf) int colvarproxy_lammps::add_config_string(const std::string &conf)
{ {
colvars->read_config_string(conf); return colvars->read_config_string(conf);
}
int colvarproxy_lammps::read_state_file(char const *state_filename)
{
input_prefix() = std::string(state_filename);
return colvars->setup_input();
} }
colvarproxy_lammps::~colvarproxy_lammps() colvarproxy_lammps::~colvarproxy_lammps()

View File

@ -86,10 +86,13 @@ class colvarproxy_lammps : public colvarproxy {
void write_output_files(); void write_output_files();
// read additional config from file // read additional config from file
void add_config_file(char const *config_filename); int add_config_file(char const *config_filename);
// read additional config from string // read additional config from string
void add_config_string(const std::string &config); int add_config_string(const std::string &config);
// load a state file
int read_state_file(char const *state_filename);
// Request to set the units used internally by Colvars // Request to set the units used internally by Colvars
int set_unit_system(std::string const &units_in, bool check_only); int set_unit_system(std::string const &units_in, bool check_only);

View File

@ -502,7 +502,7 @@ int FixColvars::modify_param(int narg, char **arg)
if (me == 0) { if (me == 0) {
if (! proxy) if (! proxy)
error->one(FLERR,"Cannot use fix_modify before initialization"); error->one(FLERR,"Cannot use fix_modify before initialization");
proxy->add_config_file(arg[1]); return proxy->add_config_file(arg[1]) == COLVARS_OK ? 0 : 2;
} }
return 2; return 2;
} else if (strcmp(arg[0],"config") == 0) { } else if (strcmp(arg[0],"config") == 0) {
@ -510,8 +510,16 @@ int FixColvars::modify_param(int narg, char **arg)
if (me == 0) { if (me == 0) {
if (! proxy) if (! proxy)
error->one(FLERR,"Cannot use fix_modify before initialization"); error->one(FLERR,"Cannot use fix_modify before initialization");
std::string conf(arg[1]); std::string const conf(arg[1]);
proxy->add_config_string(conf); return proxy->add_config_string(conf) == COLVARS_OK ? 0 : 2;
}
return 2;
} else if (strcmp(arg[0],"load") == 0) {
if (narg < 2) error->all(FLERR,"Illegal fix_modify command");
if (me == 0) {
if (! proxy)
error->one(FLERR,"Cannot use fix_modify before initialization");
return proxy->read_state_file(arg[1]) == COLVARS_OK ? 0 : 2;
} }
return 2; return 2;
} }

View File

@ -28,6 +28,12 @@
#ifndef LMP_LMPTYPE_H #ifndef LMP_LMPTYPE_H
#define LMP_LMPTYPE_H #define LMP_LMPTYPE_H
// C++11 check
#if __cplusplus < 201103L
#error LAMMPS requires a C++11 (or later) compliant compiler. Enable C++11 compatibility or upgrade the compiler.
#endif
#ifndef __STDC_LIMIT_MACROS #ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS
#endif #endif
@ -38,8 +44,8 @@
#include <climits> #include <climits>
#include <cstdlib> #include <cstdlib>
#include <stdint.h> // <cstdint> requires C++-11 #include <cstdint>
#include <inttypes.h> // <cinttypes> requires C++-11 #include <cinttypes>
// grrr - IBM Power6 does not provide this def in their system header files // grrr - IBM Power6 does not provide this def in their system header files