This update consists exclusively of bugfixes or maintenance-related changes. The following is a list of pull requests in the Colvars repository since the previous update to LAMMPS: - 532 Add XYZ trajectory reading feature https://github.com/Colvars/colvars/pull/532 (@jhenin, @giacomofiorin) - 531 Delete objects quietly, unless explicitly requested via script (including VMD) https://github.com/Colvars/colvars/pull/531 (@giacomofiorin) - 530 Append newline to log and error messages if not already present https://github.com/Colvars/colvars/pull/530 (@giacomofiorin) - 528 Forward-declare OpenMP lock https://github.com/Colvars/colvars/pull/528 (@giacomofiorin) - 527 Remove unneeded STL container https://github.com/Colvars/colvars/pull/527 (@giacomofiorin) - 526 Allow collecting configuration files and strings before setting up interface https://github.com/Colvars/colvars/pull/526 (@giacomofiorin, @jhenin) - 523 Fallback to linearCombination when customFunction is missing in customColvar https://github.com/Colvars/colvars/pull/523 (@HanatoK, @giacomofiorin) - 522 Use iostream::fail() to check for I/O error https://github.com/Colvars/colvars/pull/522 (@jhenin) - 520 Fix ref count https://github.com/Colvars/colvars/pull/520 (@giacomofiorin) - 513 Set target temperature through a common code path https://github.com/Colvars/colvars/pull/513 (@giacomofiorin, @jhenin) - 509 Safer detection of Windows with recent Microsoft Visual Studio versions https://github.com/Colvars/colvars/pull/509 (@akohlmey) - 508 Update LAMMPS patching method to reflect Lepton availability https://github.com/Colvars/colvars/pull/508 (@giacomofiorin) - 497 Increase the precision of write_multicol https://github.com/Colvars/colvars/pull/497 (@HanatoK) - 496 Only perform MTS automatic enable/disable for timeStepFactor > 1 https://github.com/Colvars/colvars/pull/496 (@giacomofiorin) - 493 Remove unused branch of quaternion input function https://github.com/Colvars/colvars/pull/493 (@giacomofiorin) - 489 Ensure there are spaces between the fields in the header https://github.com/Colvars/colvars/pull/489 (@HanatoK) - 487 Use map of output streams, and return references to its elements https://github.com/Colvars/colvars/pull/487 (@giacomofiorin, @jhenin) - 486 Remember first step of moving restraint https://github.com/Colvars/colvars/pull/486 (@jhenin) - 485 Add decoupling option for moving restraints https://github.com/Colvars/colvars/pull/485 (@jhenin) - 483 Update Lepton via patching procedure https://github.com/Colvars/colvars/pull/483 (@giacomofiorin) - 481 Make file-reading operations of input data abstractable https://github.com/Colvars/colvars/pull/481 (@giacomofiorin) Authors: @akohlmey, @giacomofiorin, @HanatoK, @jhenin
226 lines
6.1 KiB
C++
226 lines
6.1 KiB
C++
// -*- 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>
|
|
#include <iostream>
|
|
|
|
#include "colvarmodule.h"
|
|
#include "colvarproxy.h"
|
|
#include "colvarproxy_tcl.h"
|
|
#include "colvaratoms.h"
|
|
|
|
#ifdef COLVARS_TCL
|
|
#include <tcl.h>
|
|
#endif
|
|
|
|
|
|
|
|
colvarproxy_tcl::colvarproxy_tcl()
|
|
{
|
|
tcl_interp_ = NULL;
|
|
}
|
|
|
|
|
|
colvarproxy_tcl::~colvarproxy_tcl()
|
|
{
|
|
}
|
|
|
|
|
|
void colvarproxy_tcl::init_tcl_pointers()
|
|
{
|
|
// This is overloaded by NAMD and VMD proxies to use the local interpreters
|
|
#if defined(COLVARS_TCL)
|
|
if (tcl_interp_ == NULL) {
|
|
// Allocate a dedicated Tcl interpreter for Colvars
|
|
std::cout << "colvars: Allocating Tcl interpreter." << std::endl;
|
|
set_tcl_interp(Tcl_CreateInterp());
|
|
} else {
|
|
std::cerr << "Error: init_tcl_pointers called with non-NULL tcl_interp_" << std::endl;
|
|
}
|
|
#else
|
|
std::cerr << "Error: Tcl support is not available in this build." << std::endl;
|
|
#endif
|
|
}
|
|
|
|
|
|
char const *colvarproxy_tcl::tcl_get_str(void *obj)
|
|
{
|
|
#if defined(COLVARS_TCL)
|
|
return Tcl_GetString(reinterpret_cast<Tcl_Obj *>(obj));
|
|
#else
|
|
(void) obj;
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
|
|
int colvarproxy_tcl::tcl_run_script(std::string const &script)
|
|
{
|
|
#if defined(COLVARS_TCL)
|
|
Tcl_Interp *const interp = get_tcl_interp();
|
|
int err = Tcl_Eval(interp, script.c_str());
|
|
if (err != TCL_OK) {
|
|
cvm::log("Error while executing Tcl script:\n");
|
|
cvm::error(Tcl_GetStringResult(interp));
|
|
return COLVARS_ERROR;
|
|
}
|
|
return cvm::get_error();
|
|
#else
|
|
return COLVARS_NOT_IMPLEMENTED;
|
|
#endif
|
|
}
|
|
|
|
|
|
int colvarproxy_tcl::tcl_run_file(std::string const &fileName)
|
|
{
|
|
#if defined(COLVARS_TCL)
|
|
Tcl_Interp *const interp = get_tcl_interp();
|
|
int err = Tcl_EvalFile(interp, fileName.c_str());
|
|
if (err != TCL_OK) {
|
|
cvm::log("Error while executing Tcl script file" + fileName + ":\n");
|
|
cvm::error(Tcl_GetStringResult(interp));
|
|
return COLVARS_ERROR;
|
|
}
|
|
return cvm::get_error();
|
|
#else
|
|
return COLVARS_NOT_IMPLEMENTED;
|
|
#endif
|
|
}
|
|
|
|
|
|
int colvarproxy_tcl::tcl_run_force_callback()
|
|
{
|
|
#if defined(COLVARS_TCL)
|
|
Tcl_Interp *const interp = get_tcl_interp();
|
|
if (Tcl_FindCommand(interp, "calc_colvar_forces", NULL, 0) == NULL) {
|
|
cvm::error("Error: Colvars force procedure calc_colvar_forces is not defined.\n");
|
|
return COLVARS_ERROR;
|
|
}
|
|
|
|
std::string cmd = std::string("calc_colvar_forces ")
|
|
+ cvm::to_str(cvm::step_absolute());
|
|
int err = Tcl_Eval(interp, cmd.c_str());
|
|
if (err != TCL_OK) {
|
|
cvm::log("Error while executing calc_colvar_forces:\n");
|
|
cvm::error(Tcl_GetStringResult(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 interp = get_tcl_interp();
|
|
size_t i;
|
|
|
|
std::string cmd = std::string("calc_") + name;
|
|
if (Tcl_FindCommand(interp, cmd.c_str(), NULL, 0) == NULL) {
|
|
cvm::error("Error: scripted colvar procedure \"" + cmd + "\" is not defined.\n");
|
|
return COLVARS_ERROR;
|
|
}
|
|
|
|
for (i = 0; i < cvc_values.size(); i++) {
|
|
cmd += std::string(" {") + (*(cvc_values[i])).to_simple_string() +
|
|
std::string("}");
|
|
}
|
|
int err = Tcl_Eval(interp, cmd.c_str());
|
|
const char *result = Tcl_GetStringResult(interp);
|
|
if (err != TCL_OK) {
|
|
return cvm::error(std::string("Error while executing ")
|
|
+ cmd + std::string(":\n") +
|
|
std::string(Tcl_GetStringResult(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
|
|
|
|
(void) name;
|
|
(void) cvc_values;
|
|
(void) value;
|
|
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 interp = get_tcl_interp();
|
|
size_t i;
|
|
|
|
std::string cmd = std::string("calc_") + name + "_gradient";
|
|
if (Tcl_FindCommand(interp, cmd.c_str(), NULL, 0) == NULL) {
|
|
cvm::error("Error: scripted colvar gradient procedure \"" + cmd + "\" is not defined.\n");
|
|
return COLVARS_ERROR;
|
|
}
|
|
|
|
for (i = 0; i < cvc_values.size(); i++) {
|
|
cmd += std::string(" {") + (*(cvc_values[i])).to_simple_string() +
|
|
std::string("}");
|
|
}
|
|
int err = Tcl_Eval(interp, cmd.c_str());
|
|
if (err != TCL_OK) {
|
|
return cvm::error(std::string("Error while executing ")
|
|
+ cmd + std::string(":\n") +
|
|
std::string(Tcl_GetStringResult(interp)),
|
|
COLVARS_ERROR);
|
|
}
|
|
Tcl_Obj **list;
|
|
int n;
|
|
Tcl_ListObjGetElements(interp, Tcl_GetObjResult(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
|
|
|
|
(void) name;
|
|
(void) cvc_values;
|
|
(void) gradient;
|
|
return COLVARS_NOT_IMPLEMENTED;
|
|
|
|
#endif
|
|
}
|