Update Colvars library to version 2024-06-04
This commit is contained in:
Binary file not shown.
@ -25,6 +25,7 @@ COLVARS_INCFLAGS = -DCOLVARS_LAMMPS $(COLVARS_DEBUG_INCFLAGS) $(COLVARS_PYTHON_I
|
|||||||
COLVARS_SRCS = \
|
COLVARS_SRCS = \
|
||||||
colvaratoms.cpp \
|
colvaratoms.cpp \
|
||||||
colvarbias_abf.cpp \
|
colvarbias_abf.cpp \
|
||||||
|
colvarbias_abmd.cpp \
|
||||||
colvarbias_alb.cpp \
|
colvarbias_alb.cpp \
|
||||||
colvarbias.cpp \
|
colvarbias.cpp \
|
||||||
colvarbias_histogram.cpp \
|
colvarbias_histogram.cpp \
|
||||||
@ -59,6 +60,7 @@ COLVARS_SRCS = \
|
|||||||
colvarscript_commands.cpp \
|
colvarscript_commands.cpp \
|
||||||
colvarscript_commands_bias.cpp \
|
colvarscript_commands_bias.cpp \
|
||||||
colvarscript_commands_colvar.cpp \
|
colvarscript_commands_colvar.cpp \
|
||||||
|
colvars_memstream.cpp \
|
||||||
colvartypes.cpp \
|
colvartypes.cpp \
|
||||||
colvarvalue.cpp \
|
colvarvalue.cpp \
|
||||||
colvar_neuralnetworkcompute.cpp
|
colvar_neuralnetworkcompute.cpp
|
||||||
|
|||||||
@ -1,201 +1,230 @@
|
|||||||
|
|
||||||
$(COLVARS_OBJ_DIR)colvaratoms.o: colvaratoms.cpp colvarmodule.h \
|
$(COLVARS_OBJ_DIR)colvaratoms.o: colvaratoms.cpp colvardeps.h \
|
||||||
colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \
|
colvarmodule.h colvars_version.h colvarparse.h colvarvalue.h \
|
||||||
|
colvartypes.h ../../src/math_eigen_impl.h colvarparams.h colvarproxy.h \
|
||||||
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
||||||
colvarproxy_volmaps.h colvarparse.h colvarparams.h colvaratoms.h \
|
colvarproxy_volmaps.h colvaratoms.h colvar_rotation_derivative.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 colvar.h colvarvalue.h colvartypes.h colvarparse.h \
|
colvars_version.h colvar.h colvarvalue.h colvartypes.h \
|
||||||
colvarparams.h colvardeps.h colvarbias_abf.h colvarproxy.h \
|
../../src/math_eigen_impl.h colvarparse.h colvarparams.h colvardeps.h \
|
||||||
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
colvarbias_abf.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
colvarproxy_volmaps.h colvarbias.h colvargrid.h colvar_UIestimator.h
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvarbias.h colvargrid.h \
|
||||||
|
colvar_UIestimator.h colvars_memstream.h
|
||||||
|
$(COLVARS_OBJ_DIR)colvarbias_abmd.o: colvarbias_abmd.cpp \
|
||||||
|
colvarbias_abmd.h colvarbias_restraint.h colvarbias.h colvar.h \
|
||||||
|
colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
|
||||||
|
../../src/math_eigen_impl.h colvarparse.h colvarparams.h colvardeps.h \
|
||||||
|
colvarproxy.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
||||||
|
colvarproxy_volmaps.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 colvarproxy.h colvartypes.h \
|
||||||
colvarparse.h colvarparams.h colvardeps.h colvarbias_alb.h
|
../../src/math_eigen_impl.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvarbias.h colvar.h \
|
||||||
|
colvarvalue.h colvarparse.h colvarparams.h colvardeps.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 \
|
colvars_version.h colvarproxy.h colvartypes.h \
|
||||||
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
../../src/math_eigen_impl.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
colvarproxy_volmaps.h colvarbias.h colvar.h colvarparse.h colvarparams.h \
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvarvalue.h colvarbias.h \
|
||||||
colvardeps.h colvargrid.h
|
colvar.h colvarparse.h colvarparams.h colvardeps.h colvargrid.h \
|
||||||
|
colvars_memstream.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 colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
../../src/math_eigen_impl.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
colvarproxy_volmaps.h colvar.h colvarparse.h colvarparams.h colvardeps.h \
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvar.h colvarvalue.h \
|
||||||
colvarbias_histogram.h colvarbias.h colvargrid.h
|
colvarparse.h colvarparams.h colvardeps.h colvarbias_histogram.h \
|
||||||
|
colvarbias.h colvargrid.h colvars_memstream.h
|
||||||
$(COLVARS_OBJ_DIR)colvarbias_histogram_reweight_amd.o: \
|
$(COLVARS_OBJ_DIR)colvarbias_histogram_reweight_amd.o: \
|
||||||
colvarbias_histogram_reweight_amd.cpp \
|
colvarbias_histogram_reweight_amd.cpp \
|
||||||
colvarbias_histogram_reweight_amd.h colvarbias_histogram.h colvarbias.h \
|
colvarbias_histogram_reweight_amd.h colvarbias_histogram.h colvarbias.h \
|
||||||
colvar.h colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
|
colvar.h colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
|
||||||
colvarparse.h colvarparams.h colvardeps.h colvargrid.h colvarproxy.h \
|
../../src/math_eigen_impl.h colvarparse.h colvarparams.h colvardeps.h \
|
||||||
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
colvargrid.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
colvarproxy_volmaps.h
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvars_memstream.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 \
|
colvars_version.h colvarproxy.h colvartypes.h \
|
||||||
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
../../src/math_eigen_impl.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
colvarproxy_volmaps.h colvar.h colvarparse.h colvarparams.h colvardeps.h \
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvar.h colvarvalue.h \
|
||||||
colvarbias_meta.h colvarbias.h colvargrid.h
|
colvarparse.h colvarparams.h colvardeps.h colvarbias_meta.h colvarbias.h \
|
||||||
|
colvargrid.h colvars_memstream.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 colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
../../src/math_eigen_impl.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
colvarproxy_volmaps.h colvarbias_restraint.h colvarbias.h colvar.h \
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvarvalue.h \
|
||||||
colvarparse.h colvarparams.h colvardeps.h
|
colvarbias_restraint.h colvarbias.h colvar.h colvarparse.h \
|
||||||
|
colvarparams.h colvardeps.h
|
||||||
$(COLVARS_OBJ_DIR)colvarcomp_alchlambda.o: colvarcomp_alchlambda.cpp \
|
$(COLVARS_OBJ_DIR)colvarcomp_alchlambda.o: colvarcomp_alchlambda.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 \
|
../../src/math_eigen_impl.h colvar.h colvarparse.h colvarparams.h \
|
||||||
colvaratoms.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \
|
colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \
|
||||||
colvarproxy_tcl.h colvarproxy_volmaps.h colvar_arithmeticpath.h \
|
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
||||||
colvar_geometricpath.h
|
colvar_geometricpath.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 \
|
../../src/math_eigen_impl.h colvarparse.h colvarparams.h colvardeps.h \
|
||||||
colvarproxy.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \
|
||||||
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
|
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
||||||
$(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 colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
|
||||||
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
|
|
||||||
$(COLVARS_OBJ_DIR)colvarcomp_coordnums.o: colvarcomp_coordnums.cpp \
|
|
||||||
colvarmodule.h colvars_version.h colvarparse.h colvarvalue.h \
|
|
||||||
colvartypes.h colvarparams.h colvaratoms.h colvarproxy.h \
|
|
||||||
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
|
||||||
colvarproxy_volmaps.h colvardeps.h colvar.h colvarcomp.h \
|
|
||||||
colvar_arithmeticpath.h colvar_geometricpath.h
|
|
||||||
$(COLVARS_OBJ_DIR)colvarcomp.o: colvarcomp.cpp colvarmodule.h \
|
|
||||||
colvars_version.h colvarvalue.h colvartypes.h colvar.h colvarparse.h \
|
|
||||||
colvarparams.h colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h \
|
|
||||||
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
|
||||||
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
|
|
||||||
$(COLVARS_OBJ_DIR)colvarcomp_distances.o: colvarcomp_distances.cpp \
|
|
||||||
colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
|
|
||||||
colvarparse.h colvarparams.h colvar.h colvardeps.h colvarcomp.h \
|
|
||||||
colvaratoms.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \
|
|
||||||
colvarproxy_tcl.h colvarproxy_volmaps.h colvar_arithmeticpath.h \
|
|
||||||
colvar_geometricpath.h
|
colvar_geometricpath.h
|
||||||
$(COLVARS_OBJ_DIR)colvarcomp_gpath.o: colvarcomp_gpath.cpp colvarmodule.h \
|
$(COLVARS_OBJ_DIR)colvarcomp_apath.o: colvarcomp_apath.cpp colvarvalue.h \
|
||||||
colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \
|
colvarmodule.h colvars_version.h colvartypes.h \
|
||||||
colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \
|
../../src/math_eigen_impl.h colvar.h colvarparse.h colvarparams.h \
|
||||||
colvarproxy.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
|
||||||
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
|
|
||||||
$(COLVARS_OBJ_DIR)colvarcomp_neuralnetwork.o: \
|
|
||||||
colvarcomp_neuralnetwork.cpp colvarmodule.h colvars_version.h \
|
|
||||||
colvarvalue.h colvartypes.h colvarparse.h colvarparams.h colvar.h \
|
|
||||||
colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \
|
colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \
|
||||||
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
||||||
colvar_arithmeticpath.h colvar_geometricpath.h \
|
colvar_geometricpath.h colvar_arithmeticpath.h
|
||||||
|
$(COLVARS_OBJ_DIR)colvarcomp_coordnums.o: colvarcomp_coordnums.cpp \
|
||||||
|
colvarmodule.h colvars_version.h colvaratoms.h colvarproxy.h \
|
||||||
|
colvartypes.h ../../src/math_eigen_impl.h colvarproxy_io.h \
|
||||||
|
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
||||||
|
colvarparse.h colvarvalue.h colvarparams.h colvardeps.h colvar.h \
|
||||||
|
colvarcomp.h colvar_geometricpath.h
|
||||||
|
$(COLVARS_OBJ_DIR)colvarcomp.o: colvarcomp.cpp colvarmodule.h \
|
||||||
|
colvars_version.h colvarvalue.h colvartypes.h \
|
||||||
|
../../src/math_eigen_impl.h colvar.h colvarparse.h colvarparams.h \
|
||||||
|
colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \
|
||||||
|
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
||||||
|
colvar_geometricpath.h
|
||||||
|
$(COLVARS_OBJ_DIR)colvarcomp_distances.o: colvarcomp_distances.cpp \
|
||||||
|
colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
|
||||||
|
../../src/math_eigen_impl.h colvar.h colvarparse.h colvarparams.h \
|
||||||
|
colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \
|
||||||
|
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
||||||
|
colvar_geometricpath.h colvar_rotation_derivative.h
|
||||||
|
$(COLVARS_OBJ_DIR)colvarcomp_gpath.o: colvarcomp_gpath.cpp colvarmodule.h \
|
||||||
|
colvars_version.h colvarvalue.h colvartypes.h \
|
||||||
|
../../src/math_eigen_impl.h colvar.h colvarparse.h colvarparams.h \
|
||||||
|
colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \
|
||||||
|
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
||||||
|
colvar_geometricpath.h
|
||||||
|
$(COLVARS_OBJ_DIR)colvarcomp_neuralnetwork.o: \
|
||||||
|
colvarcomp_neuralnetwork.cpp colvarmodule.h colvars_version.h \
|
||||||
|
colvarvalue.h colvartypes.h ../../src/math_eigen_impl.h colvar.h \
|
||||||
|
colvarparse.h colvarparams.h colvardeps.h colvarcomp.h colvaratoms.h \
|
||||||
|
colvarproxy.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
||||||
|
colvarproxy_volmaps.h colvar_geometricpath.h \
|
||||||
colvar_neuralnetworkcompute.h
|
colvar_neuralnetworkcompute.h
|
||||||
$(COLVARS_OBJ_DIR)colvarcomp_combination.o: colvarcomp_combination.cpp \
|
$(COLVARS_OBJ_DIR)colvarcomp_combination.o: colvarcomp_combination.cpp \
|
||||||
colvarcomp.h colvarmodule.h colvars_version.h colvar.h colvarvalue.h \
|
colvarcomp.h colvarmodule.h colvars_version.h colvaratoms.h \
|
||||||
colvartypes.h colvarparse.h colvarparams.h colvardeps.h colvaratoms.h \
|
colvarproxy.h colvartypes.h ../../src/math_eigen_impl.h colvarproxy_io.h \
|
||||||
colvarproxy.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
||||||
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h
|
colvarparse.h colvarvalue.h colvarparams.h colvardeps.h colvar.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 \
|
../../src/math_eigen_impl.h colvar.h colvarparse.h colvarparams.h \
|
||||||
colvaratoms.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \
|
colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \
|
||||||
colvarproxy_tcl.h colvarproxy_volmaps.h colvar_arithmeticpath.h \
|
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
||||||
colvar_geometricpath.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 \
|
../../src/math_eigen_impl.h colvar.h colvarparse.h colvarparams.h \
|
||||||
colvaratoms.h colvarproxy.h colvarproxy_io.h colvarproxy_system.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 colvarcomp.h \
|
|
||||||
colvaratoms.h colvarproxy.h colvarproxy_io.h colvarproxy_system.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 \
|
|
||||||
colvarvalue.h colvartypes.h colvarparse.h colvarparams.h colvar.h \
|
|
||||||
colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \
|
colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \
|
||||||
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
||||||
colvar_arithmeticpath.h colvar_geometricpath.h colvarscript.h \
|
colvar_geometricpath.h colvar_rotation_derivative.h
|
||||||
colvarbias.h colvarscript_commands.h colvarscript_commands_colvar.h \
|
$(COLVARS_OBJ_DIR)colvarcomp_volmaps.o: colvarcomp_volmaps.cpp \
|
||||||
colvarscript_commands_bias.h
|
colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
|
||||||
|
../../src/math_eigen_impl.h colvar.h colvarparse.h colvarparams.h \
|
||||||
|
colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \
|
||||||
|
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
||||||
|
colvar_geometricpath.h
|
||||||
|
$(COLVARS_OBJ_DIR)colvar.o: colvar.cpp colvarmodule.h colvars_version.h \
|
||||||
|
colvarvalue.h colvartypes.h ../../src/math_eigen_impl.h colvarparse.h \
|
||||||
|
colvarparams.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \
|
||||||
|
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
||||||
|
colvardeps.h colvar.h colvar_geometricpath.h colvarbias.h \
|
||||||
|
colvars_memstream.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 \
|
colvars_version.h colvarproxy.h colvartypes.h \
|
||||||
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
../../src/math_eigen_impl.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
colvarproxy_volmaps.h colvardeps.h colvarparse.h colvarparams.h
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvardeps.h colvarparse.h \
|
||||||
|
colvarvalue.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 \
|
||||||
colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \
|
../../src/math_eigen_impl.h colvarparse.h colvarparams.h colvar.h \
|
||||||
colvarproxy.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
colvardeps.h colvargrid.h colvargrid_def.h colvarproxy.h \
|
||||||
colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h \
|
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
||||||
colvargrid.h colvargrid_def.h
|
colvarproxy_volmaps.h colvars_memstream.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 colvarproxy_io.h colvarproxy_system.h \
|
../../src/math_eigen_impl.h colvarparams.h colvarproxy.h \
|
||||||
colvarproxy_tcl.h colvarproxy_volmaps.h colvar.h colvardeps.h \
|
|
||||||
colvarbias.h colvarbias_abf.h colvargrid.h colvar_UIestimator.h \
|
|
||||||
colvarbias_alb.h colvarbias_histogram.h \
|
|
||||||
colvarbias_histogram_reweight_amd.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 colvarmodule_refs.h
|
|
||||||
$(COLVARS_OBJ_DIR)colvarparams.o: colvarparams.cpp colvarmodule.h \
|
|
||||||
colvars_version.h colvarvalue.h colvartypes.h colvarparams.h
|
|
||||||
$(COLVARS_OBJ_DIR)colvarparse.o: colvarparse.cpp colvarmodule.h \
|
|
||||||
colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \
|
|
||||||
colvarparams.h
|
|
||||||
$(COLVARS_OBJ_DIR)colvarproxy.o: colvarproxy.cpp colvarmodule.h \
|
|
||||||
colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \
|
|
||||||
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
||||||
colvarproxy_volmaps.h colvarscript.h colvarbias.h colvar.h colvarparse.h \
|
colvarproxy_volmaps.h colvar.h colvardeps.h colvarbias.h \
|
||||||
colvarparams.h colvardeps.h colvarscript_commands.h \
|
colvarbias_abf.h colvargrid.h colvar_UIestimator.h colvarbias_abmd.h \
|
||||||
colvarscript_commands_colvar.h colvarscript_commands_bias.h \
|
colvarbias_restraint.h colvarbias_alb.h colvarbias_histogram.h \
|
||||||
colvaratoms.h colvarmodule_utils.h
|
colvarbias_histogram_reweight_amd.h colvarbias_meta.h colvarscript.h \
|
||||||
|
colvarscript_commands.h colvarscript_commands_colvar.h \
|
||||||
|
colvarscript_commands_bias.h colvaratoms.h colvarcomp.h \
|
||||||
|
colvar_geometricpath.h colvars_memstream.h colvarmodule_refs.h
|
||||||
|
$(COLVARS_OBJ_DIR)colvarparams.o: colvarparams.cpp colvarmodule.h \
|
||||||
|
colvars_version.h colvarvalue.h colvartypes.h \
|
||||||
|
../../src/math_eigen_impl.h colvarparams.h
|
||||||
|
$(COLVARS_OBJ_DIR)colvarparse.o: colvarparse.cpp colvarmodule.h \
|
||||||
|
colvars_version.h colvarvalue.h colvartypes.h \
|
||||||
|
../../src/math_eigen_impl.h colvarparse.h colvarparams.h \
|
||||||
|
colvars_memstream.h
|
||||||
|
$(COLVARS_OBJ_DIR)colvarproxy.o: colvarproxy.cpp colvarmodule.h \
|
||||||
|
colvars_version.h colvarproxy.h colvartypes.h \
|
||||||
|
../../src/math_eigen_impl.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvar.h colvarvalue.h \
|
||||||
|
colvarparse.h colvarparams.h colvardeps.h colvarbias.h colvarscript.h \
|
||||||
|
colvarscript_commands.h colvarscript_commands_colvar.h \
|
||||||
|
colvarscript_commands_bias.h colvarmodule_utils.h
|
||||||
$(COLVARS_OBJ_DIR)colvarproxy_io.o: colvarproxy_io.cpp colvarmodule.h \
|
$(COLVARS_OBJ_DIR)colvarproxy_io.o: colvarproxy_io.cpp colvarmodule.h \
|
||||||
colvars_version.h colvarproxy_io.h
|
colvars_version.h colvarproxy_io.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 colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
../../src/math_eigen_impl.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
colvarproxy_volmaps.h
|
colvarproxy_tcl.h colvarproxy_volmaps.h
|
||||||
$(COLVARS_OBJ_DIR)colvarproxy_system.o: colvarproxy_system.cpp \
|
$(COLVARS_OBJ_DIR)colvarproxy_system.o: colvarproxy_system.cpp \
|
||||||
colvarmodule.h colvars_version.h colvartypes.h colvarproxy_system.h
|
colvarmodule.h colvars_version.h colvartypes.h \
|
||||||
|
../../src/math_eigen_impl.h colvarproxy_system.h
|
||||||
$(COLVARS_OBJ_DIR)colvarproxy_tcl.o: colvarproxy_tcl.cpp colvarmodule.h \
|
$(COLVARS_OBJ_DIR)colvarproxy_tcl.o: colvarproxy_tcl.cpp colvarmodule.h \
|
||||||
colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \
|
colvars_version.h colvarproxy.h colvartypes.h \
|
||||||
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
../../src/math_eigen_impl.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
colvarproxy_volmaps.h colvaratoms.h colvarparse.h colvarparams.h \
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvaratoms.h colvarparse.h \
|
||||||
colvardeps.h
|
colvarvalue.h colvarparams.h colvardeps.h
|
||||||
$(COLVARS_OBJ_DIR)colvarproxy_volmaps.o: colvarproxy_volmaps.cpp \
|
$(COLVARS_OBJ_DIR)colvarproxy_volmaps.o: colvarproxy_volmaps.cpp \
|
||||||
colvarmodule.h colvars_version.h colvarproxy_volmaps.h \
|
colvarmodule.h colvars_version.h colvarproxy_volmaps.h \
|
||||||
colvarmodule_utils.h
|
colvarmodule_utils.h
|
||||||
$(COLVARS_OBJ_DIR)colvarscript.o: colvarscript.cpp colvarproxy.h \
|
$(COLVARS_OBJ_DIR)colvarscript.o: colvarscript.cpp colvarproxy.h \
|
||||||
colvarmodule.h colvars_version.h colvartypes.h colvarvalue.h \
|
colvarmodule.h colvars_version.h colvartypes.h \
|
||||||
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
../../src/math_eigen_impl.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
colvarproxy_volmaps.h colvardeps.h colvarparse.h colvarparams.h \
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvardeps.h colvarparse.h \
|
||||||
colvarscript.h colvarbias.h colvar.h colvarscript_commands.h \
|
colvarvalue.h colvarparams.h colvarscript.h colvarscript_commands.h \
|
||||||
colvarscript_commands_colvar.h colvarscript_commands_bias.h
|
colvarscript_commands_colvar.h colvarscript_commands_bias.h
|
||||||
$(COLVARS_OBJ_DIR)colvarscript_commands.o: colvarscript_commands.cpp \
|
$(COLVARS_OBJ_DIR)colvarscript_commands.o: colvarscript_commands.cpp \
|
||||||
colvarproxy.h colvarmodule.h colvars_version.h colvartypes.h \
|
colvar.h colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
|
||||||
colvarvalue.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
../../src/math_eigen_impl.h colvarparse.h colvarparams.h colvardeps.h \
|
||||||
colvarproxy_volmaps.h colvardeps.h colvarparse.h colvarparams.h \
|
colvarbias.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
colvarscript.h colvarbias.h colvar.h colvarscript_commands.h \
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvarscript.h \
|
||||||
colvarscript_commands_colvar.h colvarscript_commands_bias.h
|
colvarscript_commands.h colvarscript_commands_colvar.h \
|
||||||
|
colvarscript_commands_bias.h
|
||||||
$(COLVARS_OBJ_DIR)colvarscript_commands_bias.o: \
|
$(COLVARS_OBJ_DIR)colvarscript_commands_bias.o: \
|
||||||
colvarscript_commands_bias.cpp colvarproxy.h colvarmodule.h \
|
colvarscript_commands_bias.cpp colvarproxy.h colvarmodule.h \
|
||||||
colvars_version.h colvartypes.h colvarvalue.h colvarproxy_io.h \
|
colvars_version.h colvartypes.h ../../src/math_eigen_impl.h \
|
||||||
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
||||||
colvardeps.h colvarparse.h colvarparams.h colvarscript.h colvarbias.h \
|
colvarproxy_volmaps.h colvarbias.h colvar.h colvarvalue.h colvarparse.h \
|
||||||
colvar.h colvarscript_commands.h colvarscript_commands_colvar.h \
|
colvarparams.h colvardeps.h colvarscript.h colvarscript_commands.h \
|
||||||
colvarscript_commands_bias.h
|
colvarscript_commands_colvar.h colvarscript_commands_bias.h
|
||||||
$(COLVARS_OBJ_DIR)colvarscript_commands_colvar.o: \
|
$(COLVARS_OBJ_DIR)colvarscript_commands_colvar.o: \
|
||||||
colvarscript_commands_colvar.cpp colvarproxy.h colvarmodule.h \
|
colvarscript_commands_colvar.cpp colvar.h colvarmodule.h \
|
||||||
colvars_version.h colvartypes.h colvarvalue.h colvarproxy_io.h \
|
colvars_version.h colvarvalue.h colvartypes.h \
|
||||||
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \
|
../../src/math_eigen_impl.h colvarparse.h colvarparams.h colvardeps.h \
|
||||||
colvardeps.h colvarparse.h colvarparams.h colvarscript.h colvarbias.h \
|
colvarproxy.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
||||||
colvar.h colvarscript_commands.h colvarscript_commands_colvar.h \
|
colvarproxy_volmaps.h colvarscript.h colvarscript_commands.h \
|
||||||
colvarscript_commands_bias.h
|
colvarscript_commands_colvar.h colvarscript_commands_bias.h
|
||||||
|
$(COLVARS_OBJ_DIR)colvars_memstream.o: colvars_memstream.cpp \
|
||||||
|
colvarmodule.h colvars_version.h colvartypes.h \
|
||||||
|
../../src/math_eigen_impl.h colvarvalue.h colvars_memstream.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 ../../src/math_eigen_impl.h \
|
||||||
colvarparams.h ../../src/math_eigen_impl.h
|
colvaratoms.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \
|
||||||
|
colvarproxy_tcl.h colvarproxy_volmaps.h colvarparse.h colvarvalue.h \
|
||||||
|
colvarparams.h colvardeps.h colvar_rotation_derivative.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 \
|
||||||
|
../../src/math_eigen_impl.h colvars_memstream.h
|
||||||
$(COLVARS_OBJ_DIR)colvar_neuralnetworkcompute.o: \
|
$(COLVARS_OBJ_DIR)colvar_neuralnetworkcompute.o: \
|
||||||
colvar_neuralnetworkcompute.cpp colvar_neuralnetworkcompute.h \
|
colvar_neuralnetworkcompute.cpp colvar_neuralnetworkcompute.h \
|
||||||
colvarparse.h colvarmodule.h colvars_version.h colvarvalue.h \
|
colvarparse.h colvarmodule.h colvars_version.h colvarvalue.h \
|
||||||
colvartypes.h colvarparams.h colvarproxy.h colvarproxy_io.h \
|
colvartypes.h ../../src/math_eigen_impl.h colvarparams.h colvarproxy.h \
|
||||||
colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h
|
colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \
|
||||||
|
colvarproxy_volmaps.h
|
||||||
|
|||||||
@ -16,13 +16,18 @@
|
|||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvarparse.h"
|
#include "colvarparse.h"
|
||||||
#include "colvar.h"
|
|
||||||
#include "colvarcomp.h"
|
#include "colvarcomp.h"
|
||||||
#include "colvarscript.h"
|
#include "colvar.h"
|
||||||
|
#include "colvarbias.h"
|
||||||
|
#include "colvars_memstream.h"
|
||||||
|
|
||||||
|
|
||||||
|
std::map<std::string, std::function<colvar::cvc *()>> colvar::global_cvc_map =
|
||||||
|
std::map<std::string, std::function<colvar::cvc *()>>();
|
||||||
|
|
||||||
|
std::map<std::string, std::string> colvar::global_cvc_desc_map =
|
||||||
|
std::map<std::string, std::string>();
|
||||||
|
|
||||||
#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()
|
||||||
{
|
{
|
||||||
@ -36,6 +41,8 @@ colvar::colvar()
|
|||||||
dev_null = 0.0;
|
dev_null = 0.0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
matching_state = false;
|
||||||
|
|
||||||
expand_boundaries = false;
|
expand_boundaries = false;
|
||||||
|
|
||||||
description = "uninitialized colvar";
|
description = "uninitialized colvar";
|
||||||
@ -131,7 +138,14 @@ int colvar::init(std::string const &conf)
|
|||||||
|
|
||||||
// Sort array of cvcs based on their names
|
// Sort array of cvcs based on their names
|
||||||
// Note: default CVC names are in input order for same type of CVC
|
// Note: default CVC names are in input order for same type of CVC
|
||||||
std::sort(cvcs.begin(), cvcs.end(), colvar::compare_cvc);
|
std::sort(cvcs.begin(), cvcs.end(),
|
||||||
|
[](std::shared_ptr<colvar::cvc> const &cvc1,
|
||||||
|
std::shared_ptr<colvar::cvc> const &cvc2) -> bool {
|
||||||
|
if (cvc1 && cvc2) {
|
||||||
|
return cvc1->name < cvc2->name;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
if(cvcs.size() > 1) {
|
if(cvcs.size() > 1) {
|
||||||
cvm::log("Sorted list of components for this scripted colvar:\n");
|
cvm::log("Sorted list of components for this scripted colvar:\n");
|
||||||
@ -186,9 +200,9 @@ int colvar::init(std::string const &conf)
|
|||||||
|
|
||||||
if ((cvcs[i])->sup_np < 0) {
|
if ((cvcs[i])->sup_np < 0) {
|
||||||
cvm::log("Warning: you chose a negative exponent in the combination; "
|
cvm::log("Warning: you chose a negative exponent in the combination; "
|
||||||
"if you apply forces, the simulation may become unstable "
|
"if you apply forces, the simulation may become unstable "
|
||||||
"when the component \""+
|
"when the component \""+
|
||||||
(cvcs[i])->function_type+"\" approaches zero.\n");
|
(cvcs[i])->function_type()+"\" approaches zero.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,7 +309,7 @@ int colvar::init(std::string const &conf)
|
|||||||
error_code |= init_grid_parameters(conf);
|
error_code |= init_grid_parameters(conf);
|
||||||
|
|
||||||
// Detect if we have a single component that is an alchemical lambda
|
// Detect if we have a single component that is an alchemical lambda
|
||||||
if (is_enabled(f_cv_single_cvc) && cvcs[0]->function_type == "alchLambda") {
|
if (is_enabled(f_cv_single_cvc) && cvcs[0]->function_type() == "alchLambda") {
|
||||||
enable(f_cv_external);
|
enable(f_cv_external);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,13 +482,6 @@ int colvar::init_custom_function(std::string const &conf)
|
|||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
if (key_lookup(conf, "customFunction", &expr, &pos)) {
|
if (key_lookup(conf, "customFunction", &expr, &pos)) {
|
||||||
std::string msg("Error: customFunction requires the Lepton library.");
|
std::string msg("Error: customFunction requires the Lepton library.");
|
||||||
#if (__cplusplus < 201103L)
|
|
||||||
// NOTE: this is not ideal; testing for the Lepton library's version would
|
|
||||||
// be more accurate, but also less portable
|
|
||||||
msg +=
|
|
||||||
std::string(" Note also that recent versions of Lepton require C++11: "
|
|
||||||
"please see https://colvars.github.io/README-c++11.html.");
|
|
||||||
#endif
|
|
||||||
return cvm::error(msg, COLVARS_NOT_IMPLEMENTED);
|
return cvm::error(msg, COLVARS_NOT_IMPLEMENTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,9 +704,14 @@ int colvar::init_extended_Lagrangian(std::string const &conf)
|
|||||||
}
|
}
|
||||||
if (ext_gamma != 0.0) {
|
if (ext_gamma != 0.0) {
|
||||||
enable(f_cv_Langevin);
|
enable(f_cv_Langevin);
|
||||||
|
cvm::main()->cite_feature("BAOA integrator");
|
||||||
ext_gamma *= 1.0e-3; // correct as long as input is required in ps-1 and cvm::dt() is in fs
|
ext_gamma *= 1.0e-3; // correct as long as input is required in ps-1 and cvm::dt() is in fs
|
||||||
// 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 * proxy->boltzmann() * temp * ext_gamma * ext_mass / (cvm::dt() * cvm::real(time_step_factor)));
|
// Eq. (6a) in https://doi.org/10.1021/acs.jctc.2c00585
|
||||||
|
ext_sigma = cvm::sqrt((1.0 - cvm::exp(-2.0 * ext_gamma * cvm::dt() * cvm::real(time_step_factor)))
|
||||||
|
* ext_mass * proxy->boltzmann() * temp);
|
||||||
|
} else {
|
||||||
|
ext_sigma = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_keyval_feature(this, conf, "reflectingLowerBoundary", f_cv_reflecting_lower_boundary, false);
|
get_keyval_feature(this, conf, "reflectingLowerBoundary", f_cv_reflecting_lower_boundary, false);
|
||||||
@ -744,75 +756,56 @@ int colvar::init_output_flags(std::string const &conf)
|
|||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (__cplusplus >= 201103L)
|
|
||||||
// C++11
|
template <typename def_class_name>
|
||||||
template<typename def_class_name> int colvar::init_components_type(std::string const &,
|
void colvar::add_component_type(char const *def_description, char const *def_config_key)
|
||||||
char const * /* def_desc */,
|
{
|
||||||
char const *def_config_key) {
|
if (global_cvc_map.count(def_config_key) == 0) {
|
||||||
// global_cvc_map is only supported in the C++11 case
|
global_cvc_map[def_config_key] = []() {
|
||||||
global_cvc_map[def_config_key] = [](const std::string& cvc_conf){return new def_class_name(cvc_conf);};
|
return new def_class_name();
|
||||||
// TODO: maybe it is better to do more check to avoid duplication in the map?
|
};
|
||||||
return COLVARS_OK;
|
global_cvc_desc_map[def_config_key] = std::string(def_description);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int colvar::init_components_type_from_global_map(const std::string& conf,
|
|
||||||
const char* def_config_key) {
|
int colvar::init_components_type(const std::string& conf, const char* def_config_key) {
|
||||||
#else
|
|
||||||
template<typename def_class_name> int colvar::init_components_type(std::string const & conf,
|
|
||||||
char const * /* def_desc */,
|
|
||||||
char const *def_config_key) {
|
|
||||||
#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;
|
||||||
|
int error_code = COLVARS_OK;
|
||||||
while ( this->key_lookup(conf,
|
while ( this->key_lookup(conf,
|
||||||
def_config_key,
|
def_config_key,
|
||||||
&def_conf,
|
&def_conf,
|
||||||
&pos) ) {
|
&pos) ) {
|
||||||
if (!def_conf.size()) continue;
|
|
||||||
cvm::log("Initializing "
|
cvm::log("Initializing "
|
||||||
"a new \""+std::string(def_config_key)+"\" component"+
|
"a new \""+std::string(def_config_key)+"\" component"+
|
||||||
(cvm::debug() ? ", with configuration:\n"+def_conf
|
(cvm::debug() ? ", with configuration:\n"+def_conf
|
||||||
: ".\n"));
|
: ".\n"));
|
||||||
|
cvc *cvcp = global_cvc_map[def_config_key]();
|
||||||
|
if (!cvcp) {
|
||||||
|
return cvm::error("Error: in creating object of type \"" + std::string(def_config_key) +
|
||||||
|
"\".\n",
|
||||||
|
COLVARS_MEMORY_ERROR);
|
||||||
|
}
|
||||||
|
cvcs.push_back(std::shared_ptr<colvar::cvc>(cvcp));
|
||||||
|
|
||||||
cvm::increase_depth();
|
cvm::increase_depth();
|
||||||
// only the following line is different from init_components_type
|
int error_code_this = cvcp->init(def_conf);
|
||||||
// in the non-C++11 case
|
if (error_code_this == COLVARS_OK) {
|
||||||
#if (__cplusplus >= 201103L)
|
// Checking for invalid keywords only if the parsing was successful, otherwise any
|
||||||
cvc *cvcp = global_cvc_map.at(def_config_key)(def_conf);
|
// early-returns due to errors would raise false positives
|
||||||
#else
|
error_code_this |= cvcp->check_keywords(def_conf, def_config_key);
|
||||||
cvc *cvcp = new def_class_name(def_conf);
|
}
|
||||||
#endif
|
cvm::decrease_depth();
|
||||||
if (cvcp != NULL) {
|
if (error_code_this != COLVARS_OK) {
|
||||||
cvcs.push_back(cvcp);
|
error_code |=
|
||||||
cvcp->check_keywords(def_conf, def_config_key);
|
cvm::error("Error: in setting up component \"" + std::string(def_config_key) + "\".\n",
|
||||||
cvcp->set_function_type(def_config_key);
|
COLVARS_INPUT_ERROR);
|
||||||
if (cvm::get_error()) {
|
|
||||||
cvm::error("Error: in setting up component \""+
|
|
||||||
std::string(def_config_key)+"\".\n", COLVARS_INPUT_ERROR);
|
|
||||||
return COLVARS_INPUT_ERROR;
|
|
||||||
}
|
|
||||||
cvm::decrease_depth();
|
|
||||||
} else {
|
|
||||||
cvm::decrease_depth();
|
|
||||||
cvm::error("Error: in allocating component \""+
|
|
||||||
std::string(def_config_key)+"\".\n",
|
|
||||||
COLVARS_MEMORY_ERROR);
|
|
||||||
return COLVARS_MEMORY_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (cvcp->period != 0.0) || (cvcp->wrap_center != 0.0) ) {
|
|
||||||
if (! cvcp->is_enabled(f_cvc_periodic)) {
|
|
||||||
cvm::error("Error: invalid use of period and/or "
|
|
||||||
"wrapAround in a \""+
|
|
||||||
std::string(def_config_key)+
|
|
||||||
"\" component.\n"+
|
|
||||||
"Period: "+cvm::to_str(cvcp->period) +
|
|
||||||
" wrapAround: "+cvm::to_str(cvcp->wrap_center),
|
|
||||||
COLVARS_INPUT_ERROR);
|
|
||||||
return COLVARS_INPUT_ERROR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set default name if it doesn't have one
|
||||||
if ( ! cvcs.back()->name.size()) {
|
if ( ! cvcs.back()->name.size()) {
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
s << def_config_key << std::setfill('0') << std::setw(4) << ++def_count;
|
s << def_config_key << std::setfill('0') << std::setw(4) << ++def_count;
|
||||||
@ -822,135 +815,138 @@ template<typename def_class_name> int colvar::init_components_type(std::string c
|
|||||||
|
|
||||||
cvcs.back()->setup();
|
cvcs.back()->setup();
|
||||||
if (cvm::debug()) {
|
if (cvm::debug()) {
|
||||||
cvm::log("Done initializing a \""+
|
cvm::log("Done initializing a \"" + std::string(def_config_key) + "\" component" +
|
||||||
std::string(def_config_key)+
|
(cvm::debug() ? ", named \"" + cvcs.back()->name + "\"" : "") + ".\n");
|
||||||
"\" component"+
|
|
||||||
(cvm::debug() ?
|
|
||||||
", named \""+cvcs.back()->name+"\""
|
|
||||||
: "")+".\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def_conf = "";
|
def_conf = "";
|
||||||
if (cvm::debug()) {
|
if (cvm::debug()) {
|
||||||
cvm::log("Parsed "+cvm::to_str(cvcs.size())+
|
cvm::log("Parsed " + cvm::to_str(cvcs.size()) + " components at this time.\n");
|
||||||
" components at this time.\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return COLVARS_OK;
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void colvar::define_component_types()
|
||||||
|
{
|
||||||
|
colvarproxy *proxy = cvm::main()->proxy;
|
||||||
|
|
||||||
|
add_component_type<distance>("distance", "distance");
|
||||||
|
add_component_type<distance_vec>("distance vector", "distanceVec");
|
||||||
|
add_component_type<cartesian>("Cartesian coordinates", "cartesian");
|
||||||
|
add_component_type<distance_dir>("distance vector direction", "distanceDir");
|
||||||
|
add_component_type<distance_z>("distance projection on an axis", "distanceZ");
|
||||||
|
add_component_type<distance_xy>("distance projection on a plane", "distanceXY");
|
||||||
|
add_component_type<polar_theta>("spherical polar angle theta", "polarTheta");
|
||||||
|
add_component_type<polar_phi>("spherical azimuthal angle phi", "polarPhi");
|
||||||
|
add_component_type<distance_inv>("average distance weighted by inverse power", "distanceInv");
|
||||||
|
add_component_type<distance_pairs>("N1xN2-long vector of pairwise distances", "distancePairs");
|
||||||
|
add_component_type<dipole_magnitude>("dipole magnitude", "dipoleMagnitude");
|
||||||
|
add_component_type<coordnum>("coordination number", "coordNum");
|
||||||
|
add_component_type<selfcoordnum>("self-coordination number", "selfCoordNum");
|
||||||
|
add_component_type<groupcoordnum>("group-coordination number", "groupCoord");
|
||||||
|
add_component_type<angle>("angle", "angle");
|
||||||
|
add_component_type<dipole_angle>("dipole angle", "dipoleAngle");
|
||||||
|
add_component_type<dihedral>("dihedral", "dihedral");
|
||||||
|
add_component_type<h_bond>("hydrogen bond", "hBond");
|
||||||
|
|
||||||
|
if (proxy->check_atom_name_selections_available() == COLVARS_OK) {
|
||||||
|
add_component_type<alpha_angles>("alpha helix", "alpha");
|
||||||
|
add_component_type<dihedPC>("dihedral principal component", "dihedralPC");
|
||||||
|
}
|
||||||
|
|
||||||
|
add_component_type<orientation>("orientation", "orientation");
|
||||||
|
add_component_type<orientation_angle>("orientation angle", "orientationAngle");
|
||||||
|
add_component_type<orientation_proj>("orientation projection", "orientationProj");
|
||||||
|
add_component_type<tilt>("tilt", "tilt");
|
||||||
|
add_component_type<spin_angle>("spin angle", "spinAngle");
|
||||||
|
add_component_type<rmsd>("RMSD", "rmsd");
|
||||||
|
add_component_type<gyration>("radius of gyration", "gyration");
|
||||||
|
add_component_type<inertia>("moment of inertia", "inertia");
|
||||||
|
add_component_type<inertia_z>("moment of inertia around an axis", "inertiaZ");
|
||||||
|
add_component_type<eigenvector>("eigenvector", "eigenvector");
|
||||||
|
add_component_type<alch_lambda>("alchemical coupling parameter", "alchLambda");
|
||||||
|
add_component_type<alch_Flambda>("force on alchemical coupling parameter", "alchFLambda");
|
||||||
|
add_component_type<aspath>("arithmetic path collective variables (s)", "aspath");
|
||||||
|
add_component_type<azpath>("arithmetic path collective variables (z)", "azpath");
|
||||||
|
add_component_type<gspath>("geometrical path collective variables (s)", "gspath");
|
||||||
|
add_component_type<gzpath>("geometrical path collective variables (z)", "gzpath");
|
||||||
|
add_component_type<linearCombination>("linear combination of other collective variables", "linearCombination");
|
||||||
|
add_component_type<gspathCV>("geometrical path collective variables (s) for other CVs", "gspathCV");
|
||||||
|
add_component_type<gzpathCV>("geometrical path collective variables (z) for other CVs", "gzpathCV");
|
||||||
|
add_component_type<aspathCV>("arithmetic path collective variables (s) for other CVs", "aspathCV");
|
||||||
|
add_component_type<azpathCV>("arithmetic path collective variables (s) for other CVs", "azpathCV");
|
||||||
|
add_component_type<euler_phi>("euler phi angle of the optimal orientation", "eulerPhi");
|
||||||
|
add_component_type<euler_psi>("euler psi angle of the optimal orientation", "eulerPsi");
|
||||||
|
add_component_type<euler_theta>("euler theta angle of the optimal orientation", "eulerTheta");
|
||||||
|
|
||||||
|
#ifdef LEPTON
|
||||||
|
add_component_type<customColvar>("CV with support of the Lepton custom function", "customColvar");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
add_component_type<neuralNetwork>("neural network CV for other CVs", "neuralNetwork");
|
||||||
|
|
||||||
|
if (proxy->check_volmaps_available() == COLVARS_OK) {
|
||||||
|
add_component_type<map_total>("total value of atomic map", "mapTotal");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvar::init_components(std::string const &conf)
|
int colvar::init_components(std::string const &conf)
|
||||||
{
|
{
|
||||||
int error_code = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
size_t i = 0, j = 0;
|
size_t i = 0, j = 0;
|
||||||
|
|
||||||
// in the non-C++11 case, the components are initialized directly by init_components_type;
|
if (global_cvc_map.empty()) {
|
||||||
// in the C++11 case, the components are stored in the global_cvc_map at first
|
define_component_types();
|
||||||
// by init_components_type, and then the map is iterated to initialize all components.
|
}
|
||||||
error_code |= init_components_type<distance>(conf, "distance", "distance");
|
|
||||||
error_code |= init_components_type<distance_vec>(conf, "distance vector", "distanceVec");
|
|
||||||
error_code |= init_components_type<cartesian>(conf, "Cartesian coordinates", "cartesian");
|
|
||||||
error_code |= init_components_type<distance_dir>(conf, "distance vector "
|
|
||||||
"direction", "distanceDir");
|
|
||||||
error_code |= init_components_type<distance_z>(conf, "distance projection "
|
|
||||||
"on an axis", "distanceZ");
|
|
||||||
error_code |= init_components_type<distance_xy>(conf, "distance projection "
|
|
||||||
"on a plane", "distanceXY");
|
|
||||||
error_code |= init_components_type<polar_theta>(conf, "spherical polar angle theta",
|
|
||||||
"polarTheta");
|
|
||||||
error_code |= init_components_type<polar_phi>(conf, "spherical azimuthal angle phi",
|
|
||||||
"polarPhi");
|
|
||||||
error_code |= init_components_type<distance_inv>(conf, "average distance "
|
|
||||||
"weighted by inverse power", "distanceInv");
|
|
||||||
error_code |= init_components_type<distance_pairs>(conf, "N1xN2-long vector "
|
|
||||||
"of pairwise distances", "distancePairs");
|
|
||||||
error_code |= init_components_type<dipole_magnitude>(conf, "dipole magnitude",
|
|
||||||
"dipoleMagnitude");
|
|
||||||
error_code |= init_components_type<coordnum>(conf, "coordination "
|
|
||||||
"number", "coordNum");
|
|
||||||
error_code |= init_components_type<selfcoordnum>(conf, "self-coordination "
|
|
||||||
"number", "selfCoordNum");
|
|
||||||
error_code |= init_components_type<groupcoordnum>(conf, "group-coordination "
|
|
||||||
"number", "groupCoord");
|
|
||||||
error_code |= init_components_type<angle>(conf, "angle", "angle");
|
|
||||||
error_code |= init_components_type<dipole_angle>(conf, "dipole angle", "dipoleAngle");
|
|
||||||
error_code |= init_components_type<dihedral>(conf, "dihedral", "dihedral");
|
|
||||||
error_code |= init_components_type<h_bond>(conf, "hydrogen bond", "hBond");
|
|
||||||
error_code |= init_components_type<alpha_angles>(conf, "alpha helix", "alpha");
|
|
||||||
error_code |= init_components_type<dihedPC>(conf, "dihedral "
|
|
||||||
"principal component", "dihedralPC");
|
|
||||||
error_code |= init_components_type<orientation>(conf, "orientation", "orientation");
|
|
||||||
error_code |= init_components_type<orientation_angle>(conf, "orientation "
|
|
||||||
"angle", "orientationAngle");
|
|
||||||
error_code |= init_components_type<orientation_proj>(conf, "orientation "
|
|
||||||
"projection", "orientationProj");
|
|
||||||
error_code |= init_components_type<tilt>(conf, "tilt", "tilt");
|
|
||||||
error_code |= init_components_type<spin_angle>(conf, "spin angle", "spinAngle");
|
|
||||||
error_code |= init_components_type<rmsd>(conf, "RMSD", "rmsd");
|
|
||||||
error_code |= init_components_type<gyration>(conf, "radius of "
|
|
||||||
"gyration", "gyration");
|
|
||||||
error_code |= init_components_type<inertia>(conf, "moment of "
|
|
||||||
"inertia", "inertia");
|
|
||||||
error_code |= init_components_type<inertia_z>(conf, "moment of inertia around an axis", "inertiaZ");
|
|
||||||
error_code |= init_components_type<eigenvector>(conf, "eigenvector", "eigenvector");
|
|
||||||
error_code |= init_components_type<alch_lambda>(conf, "alchemical coupling parameter", "alchLambda");
|
|
||||||
error_code |= init_components_type<alch_Flambda>(conf, "force on alchemical coupling parameter", "alchFLambda");
|
|
||||||
error_code |= init_components_type<gspath>(conf, "geometrical path collective variables (s)", "gspath");
|
|
||||||
error_code |= init_components_type<gzpath>(conf, "geometrical path collective variables (z)", "gzpath");
|
|
||||||
error_code |= init_components_type<linearCombination>(conf, "linear combination of other collective variables", "linearCombination");
|
|
||||||
error_code |= init_components_type<gspathCV>(conf, "geometrical path collective variables (s) for other CVs", "gspathCV");
|
|
||||||
error_code |= init_components_type<gzpathCV>(conf, "geometrical path collective variables (z) for other CVs", "gzpathCV");
|
|
||||||
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<euler_phi>(conf, "euler phi angle of the optimal orientation", "eulerPhi");
|
|
||||||
error_code |= init_components_type<euler_psi>(conf, "euler psi angle of the optimal orientation", "eulerPsi");
|
|
||||||
error_code |= init_components_type<euler_theta>(conf, "euler theta angle of the optimal orientation", "eulerTheta");
|
|
||||||
#ifdef LEPTON
|
|
||||||
error_code |= init_components_type<customColvar>(conf, "CV with support of the lepton custom function", "customColvar");
|
|
||||||
#endif
|
|
||||||
error_code |= init_components_type<neuralNetwork>(conf, "neural network CV for other CVs", "NeuralNetwork");
|
|
||||||
|
|
||||||
error_code |= init_components_type<map_total>(conf, "total value of atomic map", "mapTotal");
|
|
||||||
#if (__cplusplus >= 201103L)
|
|
||||||
// iterate over all available CVC in the map
|
// iterate over all available CVC in the map
|
||||||
for (auto it = global_cvc_map.begin(); it != global_cvc_map.end(); ++it) {
|
for (auto it = global_cvc_map.begin(); it != global_cvc_map.end(); ++it) {
|
||||||
error_code |= init_components_type_from_global_map(conf, it->first.c_str());
|
error_code |= init_components_type(conf, it->first.c_str());
|
||||||
// TODO: is it better to check the error code here?
|
// TODO: is it better to check the error code here?
|
||||||
if (error_code != COLVARS_OK) {
|
if (error_code != COLVARS_OK) {
|
||||||
cvm::log("Failed to initialize " + it->first + " with the following configuration:\n");
|
cvm::log("Failed to initialize " + it->first + " with the following configuration:\n");
|
||||||
cvm::log(conf);
|
cvm::log(conf);
|
||||||
// TODO: should it stop here?
|
// TODO: should it stop here?
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (!cvcs.size() || (error_code != COLVARS_OK)) {
|
if (!cvcs.size()) {
|
||||||
cvm::error("Error: no valid components were provided "
|
std::string msg("Error: no valid components were provided for this collective variable.\n");
|
||||||
"for this collective variable.\n",
|
msg += "Currently available component types are: \n";
|
||||||
COLVARS_INPUT_ERROR);
|
for (auto it = global_cvc_desc_map.begin(); it != global_cvc_desc_map.end(); ++it) {
|
||||||
return COLVARS_INPUT_ERROR;
|
msg += " " + it->first + " -- " + it->second + "\n";
|
||||||
|
}
|
||||||
|
msg += "\nPlease note that some of the above types may still be unavailable, irrespective of this error.\n";
|
||||||
|
error_code |= cvm::error(msg, COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for uniqueness of CVC names (esp. if user-provided)
|
// Check for uniqueness of CVC names (esp. if user-provided)
|
||||||
for (i = 0; i < cvcs.size(); i++) {
|
for (i = 0; i < cvcs.size(); i++) {
|
||||||
for (j = i+1; j < cvcs.size(); j++) {
|
for (j = i + 1; j < cvcs.size(); j++) {
|
||||||
if (cvcs[i]->name == cvcs[j]->name) {
|
if (cvcs[i]->name == cvcs[j]->name) {
|
||||||
cvm::error("Components " + cvm::to_str(i) + " and " + cvm::to_str(j) +\
|
error_code |= cvm::error("Components " + cvm::to_str(i) + " and " + cvm::to_str(j) +
|
||||||
" cannot have the same name \"" + cvcs[i]->name+ "\".\n", COLVARS_INPUT_ERROR);
|
" cannot have the same name \"" + cvcs[i]->name + "\".\n",
|
||||||
return COLVARS_INPUT_ERROR;
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n_active_cvcs = cvcs.size();
|
if (error_code == COLVARS_OK) {
|
||||||
|
// Store list of children cvcs for dependency checking purposes
|
||||||
// Store list of children cvcs for dependency checking purposes
|
for (i = 0; i < cvcs.size(); i++) {
|
||||||
for (i = 0; i < cvcs.size(); i++) {
|
add_child(cvcs[i].get());
|
||||||
add_child(cvcs[i]);
|
}
|
||||||
|
// By default all CVCs are active at the start
|
||||||
|
n_active_cvcs = cvcs.size();
|
||||||
|
cvm::log("All components initialized.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
cvm::log("All components initialized.\n");
|
return error_code;
|
||||||
|
|
||||||
return COLVARS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1220,7 +1216,7 @@ int colvar::init_dependencies() {
|
|||||||
|
|
||||||
// Initialize feature_states for each instance
|
// Initialize feature_states for each instance
|
||||||
feature_states.reserve(f_cv_ntot);
|
feature_states.reserve(f_cv_ntot);
|
||||||
for (i = 0; i < f_cv_ntot; i++) {
|
for (i = feature_states.size(); i < f_cv_ntot; i++) {
|
||||||
feature_states.push_back(feature_state(true, false));
|
feature_states.push_back(feature_state(true, false));
|
||||||
// Most features are available, so we set them so
|
// Most features are available, so we set them so
|
||||||
// and list exceptions below
|
// and list exceptions below
|
||||||
@ -1283,14 +1279,10 @@ colvar::~colvar()
|
|||||||
// for dependency purposes
|
// for dependency purposes
|
||||||
remove_all_children();
|
remove_all_children();
|
||||||
|
|
||||||
for (std::vector<cvc *>::reverse_iterator ci = cvcs.rbegin();
|
for (auto ci = cvcs.rbegin(); ci != cvcs.rend(); ++ci) {
|
||||||
ci != cvcs.rend();
|
// Clear all children of this cvc (i.e. its atom groups), because the cvc base class destructor
|
||||||
++ci) {
|
// can't do it early enough and we don't want to have each cvc derived class do it separately
|
||||||
// clear all children of this cvc (i.e. its atom groups)
|
|
||||||
// because the cvc base class destructor can't do it early enough
|
|
||||||
// and we don't want to have each cvc derived class do it separately
|
|
||||||
(*ci)->remove_all_children();
|
(*ci)->remove_all_children();
|
||||||
delete *ci;
|
|
||||||
}
|
}
|
||||||
cvcs.clear();
|
cvcs.clear();
|
||||||
|
|
||||||
@ -1512,6 +1504,7 @@ int colvar::collect_cvc_values()
|
|||||||
cvm::to_str(x, cvm::cv_width, cvm::cv_prec)+".\n");
|
cvm::to_str(x, cvm::cv_width, cvm::cv_prec)+".\n");
|
||||||
|
|
||||||
if (after_restart) {
|
if (after_restart) {
|
||||||
|
x_old = x_restart;
|
||||||
if (cvm::proxy->simulation_running()) {
|
if (cvm::proxy->simulation_running()) {
|
||||||
cvm::real const jump2 = dist2(x, x_restart) / (width*width);
|
cvm::real const jump2 = dist2(x, x_restart) / (width*width);
|
||||||
if (jump2 > 0.25) {
|
if (jump2 > 0.25) {
|
||||||
@ -1555,12 +1548,12 @@ int colvar::calc_cvc_gradients(int first_cvc, size_t num_cvcs)
|
|||||||
(cvcs[i])->debug_gradients();
|
(cvcs[i])->debug_gradients();
|
||||||
}
|
}
|
||||||
|
|
||||||
cvm::decrease_depth();
|
|
||||||
|
|
||||||
if (cvm::debug())
|
if (cvm::debug())
|
||||||
cvm::log("Done calculating gradients of colvar \""+this->name+"\".\n");
|
cvm::log("Done calculating gradients of colvar \""+this->name+"\".\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cvm::decrease_depth();
|
||||||
|
|
||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1706,12 +1699,13 @@ int colvar::calc_colvar_properties()
|
|||||||
// Do the same if no simulation is running (eg. VMD postprocessing)
|
// Do the same if no simulation is running (eg. VMD postprocessing)
|
||||||
if ((cvm::step_relative() == 0 && !after_restart) || x_ext.type() == colvarvalue::type_notset || !cvm::proxy->simulation_running()) {
|
if ((cvm::step_relative() == 0 && !after_restart) || x_ext.type() == colvarvalue::type_notset || !cvm::proxy->simulation_running()) {
|
||||||
x_ext = x;
|
x_ext = x;
|
||||||
|
cvm::log("Initializing extended coordinate to colvar value.\n");
|
||||||
if (is_enabled(f_cv_reflecting_lower_boundary) && x_ext < lower_boundary) {
|
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.");
|
cvm::log("Warning: initializing extended coordinate to reflective lower boundary, as colvar value is below.\n");
|
||||||
x_ext = lower_boundary;
|
x_ext = lower_boundary;
|
||||||
}
|
}
|
||||||
if (is_enabled(f_cv_reflecting_upper_boundary) && x_ext > upper_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.");
|
cvm::log("Warning: initializing extended coordinate to reflective upper boundary, as colvar value is above.\n");
|
||||||
x_ext = upper_boundary;
|
x_ext = upper_boundary;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1721,8 +1715,18 @@ int colvar::calc_colvar_properties()
|
|||||||
// Special case of a repeated timestep (eg. multiple NAMD "run" statements)
|
// Special case of a repeated timestep (eg. multiple NAMD "run" statements)
|
||||||
// revert values of the extended coordinate and velocity prior to latest integration
|
// revert values of the extended coordinate and velocity prior to latest integration
|
||||||
if (cvm::proxy->simulation_running() && cvm::step_relative() == prev_timestep) {
|
if (cvm::proxy->simulation_running() && cvm::step_relative() == prev_timestep) {
|
||||||
x_ext = prev_x_ext;
|
// Detect jumps due to discrete changes in coordinates (eg. in replica exchange schemes)
|
||||||
v_ext = prev_v_ext;
|
cvm::real const jump2 = dist2(x, x_old) / (width*width);
|
||||||
|
if (jump2 > 0.25) {
|
||||||
|
cvm::log("Detected discrete jump in colvar value from "
|
||||||
|
+ cvm::to_str(x_old) + " to " + cvm::to_str(x) + ".\n");
|
||||||
|
cvm::log("Reinitializing extended coordinate to colvar value.\n");
|
||||||
|
x_ext = x;
|
||||||
|
} else {
|
||||||
|
cvm::log("Reinitializing extended coordinate to last value.\n");
|
||||||
|
x_ext = prev_x_ext;
|
||||||
|
v_ext = prev_v_ext;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// report the restraint center as "value"
|
// report the restraint center as "value"
|
||||||
// These position and velocities come from integration at the _previous timestep_ in update_forces_energy()
|
// These position and velocities come from integration at the _previous timestep_ in update_forces_energy()
|
||||||
@ -1830,9 +1834,11 @@ void colvar::update_extended_Lagrangian()
|
|||||||
f += fb_actual;
|
f += fb_actual;
|
||||||
}
|
}
|
||||||
|
|
||||||
fr = f;
|
// fr: bias force on extended variable (without harmonic spring), for output in trajectory
|
||||||
// External force has been scaled for a 1-timestep impulse, scale it back because we will
|
fr = f;
|
||||||
// integrate it with the colvar's own timestep factor
|
|
||||||
|
// External force has been scaled for an inner-timestep impulse (for the back-end integrator)
|
||||||
|
// here we scale it back because this integrator uses only the outer (long) timestep
|
||||||
f_ext = f / cvm::real(time_step_factor);
|
f_ext = f / cvm::real(time_step_factor);
|
||||||
|
|
||||||
colvarvalue f_system(fr.type()); // force exterted by the system on the extended DOF
|
colvarvalue f_system(fr.type()); // force exterted by the system on the extended DOF
|
||||||
@ -1845,15 +1851,14 @@ void colvar::update_extended_Lagrangian()
|
|||||||
} else {
|
} else {
|
||||||
// the total force is applied to the fictitious mass, while the
|
// the total force is applied to the fictitious mass, while the
|
||||||
// atoms only feel the harmonic force + wall force
|
// atoms only feel the harmonic force + wall force
|
||||||
// fr: bias force on extended variable (without harmonic spring), for output in trajectory
|
|
||||||
// f_ext: total force on extended variable (including harmonic spring)
|
// f_ext: total force on extended variable (including harmonic spring)
|
||||||
// f: - initially, external biasing force
|
// f: - initially, external biasing force
|
||||||
// - after this code block, colvar force to be applied to atomic coordinates
|
// - after this code block, colvar force to be applied to atomic coordinates
|
||||||
// ie. spring force (fb_actual will be added just below)
|
// ie. spring force (fb_actual will be added just below)
|
||||||
f_system = (-0.5 * ext_force_k) * this->dist2_lgrad(x_ext, x);
|
f_system = (-0.5 * ext_force_k) * this->dist2_lgrad(x_ext, x);
|
||||||
f = -1.0 * f_system;
|
f = -1.0 * f_system;
|
||||||
// Coupling force is a slow force, to be applied to atomic coords impulse-style
|
// Coupling force will be applied to atomic coords impulse-style
|
||||||
// over a single MD timestep
|
// over an inner timestep of the back-end integrator
|
||||||
f *= cvm::real(time_step_factor);
|
f *= cvm::real(time_step_factor);
|
||||||
}
|
}
|
||||||
f_ext += f_system;
|
f_ext += f_system;
|
||||||
@ -1873,34 +1878,57 @@ void colvar::update_extended_Lagrangian()
|
|||||||
prev_x_ext = x_ext;
|
prev_x_ext = x_ext;
|
||||||
prev_v_ext = v_ext;
|
prev_v_ext = v_ext;
|
||||||
|
|
||||||
// leapfrog: starting from x_i, f_i, v_(i-1/2)
|
// BAOA (GSD) integrator as formulated in https://doi.org/10.1021/acs.jctc.2c00585
|
||||||
v_ext += (0.5 * dt) * f_ext / ext_mass;
|
// starting from x_t, f_t, v_(t-1/2)
|
||||||
// Because of leapfrog, kinetic energy at time i is approximate
|
// Variation: the velocity step is split in two to estimate the kinetic energy at time t
|
||||||
|
// so this is more of a "BBAOA" scheme: a rearranged BAOAB where the second B is deferred
|
||||||
|
// to the next time step for implementation reasons (waiting for the force calculation)
|
||||||
|
|
||||||
|
// [B] Eq. (10a) split into two half-steps
|
||||||
|
// would reduce to leapfrog when gamma = 0 if this was the reported velocity
|
||||||
|
v_ext += 0.5 * dt * f_ext / ext_mass;
|
||||||
|
|
||||||
|
// Kinetic energy at t
|
||||||
kinetic_energy = 0.5 * ext_mass * v_ext * v_ext;
|
kinetic_energy = 0.5 * ext_mass * v_ext * v_ext;
|
||||||
|
|
||||||
|
// Potential energy at t
|
||||||
potential_energy = 0.5 * ext_force_k * this->dist2(x_ext, x);
|
potential_energy = 0.5 * ext_force_k * this->dist2(x_ext, x);
|
||||||
// leap to v_(i+1/2)
|
|
||||||
|
// Total energy will lag behind position by one timestep
|
||||||
|
// (current kinetic energy is not accessible before the next force calculation)
|
||||||
|
|
||||||
|
v_ext += 0.5 * dt * f_ext / ext_mass;
|
||||||
|
// Final v_ext lags behind x_ext by half a timestep
|
||||||
|
|
||||||
|
// [A] Half step in position (10b)
|
||||||
|
x_ext += dt * v_ext / 2.0;
|
||||||
|
|
||||||
|
// [O] leap to v_(i+1/2) (10c)
|
||||||
if (is_enabled(f_cv_Langevin)) {
|
if (is_enabled(f_cv_Langevin)) {
|
||||||
v_ext -= dt * ext_gamma * v_ext;
|
|
||||||
colvarvalue rnd(x);
|
colvarvalue rnd(x);
|
||||||
rnd.set_random();
|
rnd.set_random();
|
||||||
v_ext += dt * ext_sigma * rnd / ext_mass;
|
// ext_sigma has been computed at init time according to (10c)
|
||||||
|
v_ext = cvm::exp(- 1.0 * dt * ext_gamma) * v_ext + ext_sigma * rnd / ext_mass;
|
||||||
}
|
}
|
||||||
v_ext += (0.5 * dt) * f_ext / ext_mass;
|
// [A] Second half step in position (10d)
|
||||||
x_ext += dt * v_ext;
|
x_ext += dt * v_ext / 2.0;
|
||||||
|
|
||||||
cvm::real delta = 0; // Length of overshoot past either reflecting boundary
|
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) ||
|
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)) {
|
(is_enabled(f_cv_reflecting_upper_boundary) && (delta = x_ext - upper_boundary) > 0)) {
|
||||||
|
// Reflect arrival position
|
||||||
x_ext -= 2.0 * delta;
|
x_ext -= 2.0 * delta;
|
||||||
v_ext *= -1.0;
|
// Bounce happened on average at t+1/2 -> reflect velocity at t+1/2
|
||||||
if ((is_enabled(f_cv_reflecting_lower_boundary) && (delta = x_ext - lower_boundary) < 0) ||
|
v_ext = -0.5 * (prev_v_ext + v_ext);
|
||||||
(is_enabled(f_cv_reflecting_upper_boundary) && (delta = x_ext - upper_boundary) > 0)) {
|
if ((is_enabled(f_cv_reflecting_lower_boundary) && (x_ext - lower_boundary) < 0.0) ||
|
||||||
|
(is_enabled(f_cv_reflecting_upper_boundary) && (x_ext - upper_boundary) > 0.0)) {
|
||||||
cvm::error("Error: extended coordinate value " + cvm::to_str(x_ext) + " is still outside boundaries after reflection.\n");
|
cvm::error("Error: extended coordinate value " + cvm::to_str(x_ext) + " is still outside boundaries after reflection.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x_ext.apply_constraints();
|
x_ext.apply_constraints();
|
||||||
this->wrap(x_ext);
|
this->wrap(x_ext);
|
||||||
|
|
||||||
if (is_enabled(f_cv_external)) {
|
if (is_enabled(f_cv_external)) {
|
||||||
// Colvar value is constrained to the extended value
|
// Colvar value is constrained to the extended value
|
||||||
x = x_ext;
|
x = x_ext;
|
||||||
@ -1914,9 +1942,8 @@ int colvar::end_of_step()
|
|||||||
if (cvm::debug())
|
if (cvm::debug())
|
||||||
cvm::log("End of step for colvar \""+this->name+"\".\n");
|
cvm::log("End of step for colvar \""+this->name+"\".\n");
|
||||||
|
|
||||||
if (is_enabled(f_cv_fdiff_velocity)) {
|
// Used for fdiff_velocity and for detecting jumps for extended Lagrangian colvars
|
||||||
x_old = x;
|
x_old = x;
|
||||||
}
|
|
||||||
|
|
||||||
if (is_enabled(f_cv_subtract_applied_force)) {
|
if (is_enabled(f_cv_subtract_applied_force)) {
|
||||||
f_old = f;
|
f_old = f;
|
||||||
@ -2256,44 +2283,65 @@ void colvar::wrap(colvarvalue &x_unwrapped) const
|
|||||||
|
|
||||||
std::istream & colvar::read_state(std::istream &is)
|
std::istream & colvar::read_state(std::istream &is)
|
||||||
{
|
{
|
||||||
std::streampos const start_pos = is.tellg();
|
auto 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)) ||
|
||||||
|
(check_matching_state(conf) != COLVARS_OK) ) {
|
||||||
// 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);
|
||||||
is.setstate(std::ios::failbit);
|
is.setstate(std::ios::failbit);
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if (!matching_state) {
|
||||||
std::string check_name = "";
|
// No errors reading, but this state is not for this colvar; rewind
|
||||||
get_keyval(conf, "name", check_name,
|
is.seekg(start_pos);
|
||||||
std::string(""), colvarparse::parse_silent);
|
return is;
|
||||||
if (check_name.size() == 0) {
|
|
||||||
cvm::error("Error: Collective variable in the "
|
|
||||||
"restart file without any identifier.\n", COLVARS_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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (set_state_params(conf) != COLVARS_OK) {
|
||||||
|
is.clear();
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::check_matching_state(std::string const &conf)
|
||||||
|
{
|
||||||
|
std::string check_name = "";
|
||||||
|
get_keyval(conf, "name", check_name, std::string(""), colvarparse::parse_silent);
|
||||||
|
|
||||||
|
if (check_name.size() == 0) {
|
||||||
|
return cvm::error("Error: Collective variable in the "
|
||||||
|
"state file without any identifier.\n", COLVARS_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_name != name) {
|
||||||
|
if (cvm::debug()) {
|
||||||
|
cvm::log("Ignoring state of colvar \""+check_name+
|
||||||
|
"\": this colvar is named \""+name+"\".\n");
|
||||||
|
}
|
||||||
|
matching_state = false;
|
||||||
|
} else {
|
||||||
|
matching_state = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::set_state_params(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = COLVARS_OK;
|
||||||
if ( !(get_keyval(conf, "x", x, x, colvarparse::parse_silent)) ) {
|
if ( !(get_keyval(conf, "x", x, x, colvarparse::parse_silent)) ) {
|
||||||
cvm::log("Error: restart file does not contain "
|
error_code |= cvm::error("Error: restart file does not contain "
|
||||||
"the value of the colvar \""+
|
"the value of the colvar \""+
|
||||||
name+"\" .\n");
|
name+"\" .\n", COLVARS_INPUT_ERROR);
|
||||||
} else {
|
} else {
|
||||||
cvm::log("Restarting collective variable \""+name+"\" from value: "+
|
cvm::log("Restarting collective variable \""+name+"\" from value: "+
|
||||||
cvm::to_str(x)+"\n");
|
cvm::to_str(x)+"\n");
|
||||||
@ -2306,9 +2354,10 @@ std::istream & colvar::read_state(std::istream &is)
|
|||||||
colvarvalue(x.type()), colvarparse::parse_silent)) ||
|
colvarvalue(x.type()), colvarparse::parse_silent)) ||
|
||||||
!(get_keyval(conf, "extended_v", v_ext,
|
!(get_keyval(conf, "extended_v", v_ext,
|
||||||
colvarvalue(x.type()), colvarparse::parse_silent)) ) {
|
colvarvalue(x.type()), colvarparse::parse_silent)) ) {
|
||||||
cvm::log("Error: restart file does not contain "
|
error_code |= cvm::error("Error: restart file does not contain "
|
||||||
"\"extended_x\" or \"extended_v\" for the colvar \""+
|
"\"extended_x\" or \"extended_v\" for the colvar \""+
|
||||||
name+"\", but you requested \"extendedLagrangian\".\n");
|
name+"\", but you requested \"extendedLagrangian\".\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
x_reported = x_ext;
|
x_reported = x_ext;
|
||||||
} else {
|
} else {
|
||||||
@ -2319,9 +2368,10 @@ std::istream & colvar::read_state(std::istream &is)
|
|||||||
|
|
||||||
if ( !(get_keyval(conf, "v", v_fdiff,
|
if ( !(get_keyval(conf, "v", v_fdiff,
|
||||||
colvarvalue(x.type()), colvarparse::parse_silent)) ) {
|
colvarvalue(x.type()), colvarparse::parse_silent)) ) {
|
||||||
cvm::log("Error: restart file does not contain "
|
error_code |= cvm::error("Error: restart file does not contain "
|
||||||
"the velocity for the colvar \""+
|
"the velocity for the colvar \""+
|
||||||
name+"\", but you requested \"outputVelocity\".\n");
|
name+"\", but you requested \"outputVelocity\".\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_enabled(f_cv_extended_Lagrangian)) {
|
if (is_enabled(f_cv_extended_Lagrangian)) {
|
||||||
@ -2331,6 +2381,41 @@ std::istream & colvar::read_state(std::istream &is)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return error_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream &colvar::read_state(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
auto const start_pos = is.tellg();
|
||||||
|
std::string key, data;
|
||||||
|
if (is >> key) {
|
||||||
|
if (key == "colvar") {
|
||||||
|
// Read a formatted config string, then read the state parameters from it
|
||||||
|
if (is >> data) {
|
||||||
|
if (set_state_params(data) == COLVARS_OK) {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const error_pos = is.tellg();
|
||||||
|
|
||||||
|
is.clear();
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
|
||||||
|
std::string error_msg("Error: in reading state data for colvar \"" + name + " at position " +
|
||||||
|
cvm::to_str(error_pos) + " in unformatted stream.\n");
|
||||||
|
if (key.size() && key != "colvar") {
|
||||||
|
error_msg += "; the keyword read was \"" + key + "\", but \"colvar\" was expected";
|
||||||
|
}
|
||||||
|
if (data.size()) {
|
||||||
|
error_msg += "; the configuration string read was not recognized";
|
||||||
|
}
|
||||||
|
error_msg += ".\n";
|
||||||
|
cvm::error(error_msg, COLVARS_INPUT_ERROR);
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2345,7 +2430,7 @@ std::istream & colvar::read_traj(std::istream &is)
|
|||||||
cvm::log("Error: in reading the value of colvar \""+
|
cvm::log("Error: in reading the value of colvar \""+
|
||||||
this->name+"\" from trajectory.\n");
|
this->name+"\" from trajectory.\n");
|
||||||
is.clear();
|
is.clear();
|
||||||
is.seekg(start_pos, std::ios::beg);
|
is.seekg(start_pos);
|
||||||
is.setstate(std::ios::failbit);
|
is.setstate(std::ios::failbit);
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
@ -2385,10 +2470,23 @@ std::istream & colvar::read_traj(std::istream &is)
|
|||||||
|
|
||||||
// ******************** OUTPUT FUNCTIONS ********************
|
// ******************** OUTPUT FUNCTIONS ********************
|
||||||
|
|
||||||
std::ostream & colvar::write_state(std::ostream &os) {
|
std::ostream & colvar::write_state(std::ostream &os) const
|
||||||
|
{
|
||||||
|
os << "colvar {\n" << get_state_params() << "}\n\n";
|
||||||
|
|
||||||
os << "colvar {\n"
|
if (runave_outfile.size() > 0) {
|
||||||
<< " name " << name << "\n"
|
cvm::main()->proxy->flush_output_stream(runave_outfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string const colvar::get_state_params() const
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
os << " name " << name << "\n"
|
||||||
<< " x "
|
<< " x "
|
||||||
<< std::setprecision(cvm::cv_prec)
|
<< std::setprecision(cvm::cv_prec)
|
||||||
<< std::setw(cvm::cv_width)
|
<< std::setw(cvm::cv_width)
|
||||||
@ -2412,7 +2510,13 @@ std::ostream & colvar::write_state(std::ostream &os) {
|
|||||||
<< v_reported << "\n";
|
<< v_reported << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "}\n\n";
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream & colvar::write_state(cvm::memory_stream &os) const
|
||||||
|
{
|
||||||
|
os << std::string("colvar") << get_state_params();
|
||||||
|
|
||||||
if (runave_outfile.size() > 0) {
|
if (runave_outfile.size() > 0) {
|
||||||
cvm::main()->proxy->flush_output_stream(runave_outfile);
|
cvm::main()->proxy->flush_output_stream(runave_outfile);
|
||||||
@ -2875,14 +2979,11 @@ int colvar::calc_runave()
|
|||||||
runave_variance *= 1.0 / cvm::real(runave_length-1);
|
runave_variance *= 1.0 / cvm::real(runave_length-1);
|
||||||
|
|
||||||
if (runave_outfile.size() > 0) {
|
if (runave_outfile.size() > 0) {
|
||||||
std::ostream &runave_os = proxy->output_stream(runave_outfile);
|
std::ostream &runave_os =
|
||||||
runave_os << std::setw(cvm::it_width) << cvm::step_relative()
|
proxy->output_stream(runave_outfile, "running average output file");
|
||||||
<< " "
|
runave_os << std::setw(cvm::it_width) << cvm::step_relative() << " "
|
||||||
<< std::setprecision(cvm::cv_prec)
|
<< std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width) << runave << " "
|
||||||
<< std::setw(cvm::cv_width)
|
<< std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width)
|
||||||
<< runave << " "
|
|
||||||
<< std::setprecision(cvm::cv_prec)
|
|
||||||
<< std::setw(cvm::cv_width)
|
|
||||||
<< cvm::sqrt(runave_variance) << "\n";
|
<< cvm::sqrt(runave_variance) << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,12 +10,11 @@
|
|||||||
#ifndef COLVAR_H
|
#ifndef COLVAR_H
|
||||||
#define COLVAR_H
|
#define COLVAR_H
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#if (__cplusplus >= 201103L)
|
|
||||||
#include <map>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#endif
|
#include <list>
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
@ -91,7 +90,7 @@ public:
|
|||||||
/// calculations, \link colvarbias_abf \endlink, it is used to
|
/// calculations, \link colvarbias_abf \endlink, it is used to
|
||||||
/// calculate the grid spacing in the direction of this collective
|
/// calculate the grid spacing in the direction of this collective
|
||||||
/// variable.
|
/// variable.
|
||||||
cvm::real width;
|
cvm::real width = 1.0;
|
||||||
|
|
||||||
/// \brief Implementation of the feature list for colvar
|
/// \brief Implementation of the feature list for colvar
|
||||||
static std::vector<feature *> cv_features;
|
static std::vector<feature *> cv_features;
|
||||||
@ -184,13 +183,13 @@ protected:
|
|||||||
/// Previous velocity of the restraint center
|
/// Previous velocity of the restraint center
|
||||||
colvarvalue prev_v_ext;
|
colvarvalue prev_v_ext;
|
||||||
/// Mass of the restraint center
|
/// Mass of the restraint center
|
||||||
cvm::real ext_mass;
|
cvm::real ext_mass = 0.0;
|
||||||
/// Restraint force constant
|
/// Restraint force constant
|
||||||
cvm::real ext_force_k;
|
cvm::real ext_force_k = 0.0;
|
||||||
/// Friction coefficient for Langevin extended dynamics
|
/// Friction coefficient for Langevin extended dynamics
|
||||||
cvm::real ext_gamma;
|
cvm::real ext_gamma = 0.0;
|
||||||
/// Amplitude of Gaussian white noise for Langevin extended dynamics
|
/// Amplitude of Gaussian white noise for Langevin extended dynamics
|
||||||
cvm::real ext_sigma;
|
cvm::real ext_sigma = 0.0;
|
||||||
|
|
||||||
/// \brief Applied force on extended DOF, for output (unscaled if using MTS)
|
/// \brief Applied force on extended DOF, for output (unscaled if using MTS)
|
||||||
colvarvalue fr;
|
colvarvalue fr;
|
||||||
@ -224,14 +223,14 @@ public:
|
|||||||
colvarvalue ft;
|
colvarvalue ft;
|
||||||
|
|
||||||
/// Period, if this variable is periodic
|
/// Period, if this variable is periodic
|
||||||
cvm::real period;
|
cvm::real period = 0.0;
|
||||||
|
|
||||||
/// Center of wrapping, if this variable is periodic
|
/// Center of wrapping, if this variable is periodic
|
||||||
cvm::real wrap_center;
|
cvm::real wrap_center = 0.0;
|
||||||
|
|
||||||
/// \brief Expand the boundaries of multiples of width, to keep the
|
/// \brief Expand the boundaries of multiples of width, to keep the
|
||||||
/// value always within range
|
/// value always within range
|
||||||
bool expand_boundaries;
|
bool expand_boundaries = false;
|
||||||
|
|
||||||
/// \brief Location of the lower boundary
|
/// \brief Location of the lower boundary
|
||||||
colvarvalue lower_boundary;
|
colvarvalue lower_boundary;
|
||||||
@ -252,6 +251,9 @@ public:
|
|||||||
/// Main init function
|
/// Main init function
|
||||||
int init(std::string const &conf);
|
int init(std::string const &conf);
|
||||||
|
|
||||||
|
/// Populate the map of available CVC types
|
||||||
|
void define_component_types();
|
||||||
|
|
||||||
/// Parse the CVC configuration and allocate their data
|
/// Parse the CVC configuration and allocate their data
|
||||||
int init_components(std::string const &conf);
|
int init_components(std::string const &conf);
|
||||||
|
|
||||||
@ -271,17 +273,13 @@ public:
|
|||||||
virtual int init_dependencies();
|
virtual int init_dependencies();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Parse the CVC configuration for all components of a certain type
|
|
||||||
template<typename def_class_name> int init_components_type(std::string const & conf,
|
/// Declare an available CVC type and its description, register them in the global map
|
||||||
char const *def_desc,
|
template <typename def_class_name>
|
||||||
char const *def_config_key);
|
void add_component_type(char const *description, char const *config_key);
|
||||||
#if (__cplusplus >= 201103L)
|
|
||||||
/// For the C++11 case, the names of all available components are
|
/// Initialize any CVC objects matching the given key
|
||||||
/// registered in the global map at first, and then the CVC configuration
|
int init_components_type(const std::string &conf, const char *config_key);
|
||||||
/// is parsed by this function
|
|
||||||
int init_components_type_from_global_map(const std::string& conf,
|
|
||||||
const char* def_config_key);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -387,10 +385,10 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// \brief Number of CVC objects with an active flag
|
/// \brief Number of CVC objects with an active flag
|
||||||
size_t n_active_cvcs;
|
size_t n_active_cvcs = 0;
|
||||||
|
|
||||||
/// Sum of square coefficients for active cvcs
|
/// Sum of square coefficients for active cvcs
|
||||||
cvm::real active_cvc_square_norm;
|
cvm::real active_cvc_square_norm = 0.0;
|
||||||
|
|
||||||
/// Update the sum of square coefficients for active cvcs
|
/// Update the sum of square coefficients for active cvcs
|
||||||
void update_active_cvc_square_norm();
|
void update_active_cvc_square_norm();
|
||||||
@ -460,16 +458,35 @@ public:
|
|||||||
/// Write a label to the trajectory file (comment line)
|
/// Write a label to the trajectory file (comment line)
|
||||||
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 colvar's state from a formatted input stream
|
||||||
std::istream & read_state(std::istream &is);
|
std::istream & read_state(std::istream &is);
|
||||||
/// Write the collective variable to a restart file
|
|
||||||
std::ostream & write_state(std::ostream &os);
|
/// Read the colvar's state from an unformatted input stream
|
||||||
|
cvm::memory_stream & read_state(cvm::memory_stream &is);
|
||||||
|
|
||||||
|
/// Check the name of the bias vs. the given string, set the matching_state flag accordingly
|
||||||
|
int check_matching_state(std::string const &state_conf);
|
||||||
|
|
||||||
|
/// Read the values of colvar mutable data from a string (used by both versions of read_state())
|
||||||
|
int set_state_params(std::string const &state_conf);
|
||||||
|
|
||||||
|
/// Write the state information of this colvar in a block of text, suitable for later parsing
|
||||||
|
std::string const get_state_params() const;
|
||||||
|
|
||||||
|
/// Write the colvar's state to a formatted output stream
|
||||||
|
std::ostream & write_state(std::ostream &os) const;
|
||||||
|
|
||||||
|
/// Write the colvar's state to an unformatted output stream
|
||||||
|
cvm::memory_stream & write_state(cvm::memory_stream &os) const;
|
||||||
|
|
||||||
/// 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();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/// Flag used to tell if the state string being read is for this colvar
|
||||||
|
bool matching_state;
|
||||||
|
|
||||||
/// Previous value (to calculate velocities during analysis)
|
/// Previous value (to calculate velocities during analysis)
|
||||||
colvarvalue x_old;
|
colvarvalue x_old;
|
||||||
|
|
||||||
@ -554,15 +571,15 @@ protected:
|
|||||||
/// Current value of the running average
|
/// Current value of the running average
|
||||||
colvarvalue runave;
|
colvarvalue runave;
|
||||||
/// Current value of the square deviation from the running average
|
/// Current value of the square deviation from the running average
|
||||||
cvm::real runave_variance;
|
cvm::real runave_variance = 0.0;
|
||||||
|
|
||||||
/// Calculate the running average and its standard deviation
|
/// Calculate the running average and its standard deviation
|
||||||
int calc_runave();
|
int calc_runave();
|
||||||
|
|
||||||
/// If extended Lagrangian active: colvar kinetic energy
|
/// If extended Lagrangian active: colvar kinetic energy
|
||||||
cvm::real kinetic_energy;
|
cvm::real kinetic_energy = 0.0;
|
||||||
/// If extended Lagrangian active: colvar harmonic potential
|
/// If extended Lagrangian active: colvar harmonic potential
|
||||||
cvm::real potential_energy;
|
cvm::real potential_energy = 0.0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -601,8 +618,9 @@ public:
|
|||||||
class dihedPC;
|
class dihedPC;
|
||||||
class alch_lambda;
|
class alch_lambda;
|
||||||
class alch_Flambda;
|
class alch_Flambda;
|
||||||
class componentDisabled;
|
|
||||||
class CartesianBasedPath;
|
class CartesianBasedPath;
|
||||||
|
class aspath;
|
||||||
|
class azpath;
|
||||||
class gspath;
|
class gspath;
|
||||||
class gzpath;
|
class gzpath;
|
||||||
class linearCombination;
|
class linearCombination;
|
||||||
@ -626,21 +644,19 @@ public:
|
|||||||
// components that do not handle any atoms directly
|
// components that do not handle any atoms directly
|
||||||
class map_total;
|
class map_total;
|
||||||
|
|
||||||
/// getter of the global cvc map
|
|
||||||
#if (__cplusplus >= 201103L)
|
|
||||||
/// A global mapping of cvc names to the cvc constructors
|
/// 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() {
|
static const std::map<std::string, std::function<colvar::cvc *()>> &get_global_cvc_map()
|
||||||
return global_cvc_map;
|
{
|
||||||
|
return global_cvc_map;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/// \brief function for sorting cvcs by their names
|
/// \brief function for sorting cvcs by their names
|
||||||
static bool compare_cvc(const colvar::cvc* const i, const colvar::cvc* const j);
|
static bool compare_cvc(const colvar::cvc* const i, const colvar::cvc* const j);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// \brief Array of \link colvar::cvc \endlink objects
|
/// Array of components objects
|
||||||
std::vector<cvc *> cvcs;
|
std::vector<std::shared_ptr<colvar::cvc>> cvcs;
|
||||||
|
|
||||||
/// \brief Flags to enable or disable cvcs at next colvar evaluation
|
/// \brief Flags to enable or disable cvcs at next colvar evaluation
|
||||||
std::vector<bool> cvc_flags;
|
std::vector<bool> cvc_flags;
|
||||||
@ -671,10 +687,11 @@ protected:
|
|||||||
double dev_null;
|
double dev_null;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (__cplusplus >= 201103L)
|
|
||||||
/// A global mapping of cvc names to the cvc constructors
|
/// 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;
|
static std::map<std::string, std::function<colvar::cvc *()>> global_cvc_map;
|
||||||
#endif
|
|
||||||
|
/// A global mapping of cvc names to the corresponding descriptions
|
||||||
|
static std::map<std::string, std::string> global_cvc_desc_map;
|
||||||
|
|
||||||
/// Volmap numeric IDs, one for each CVC (-1 if not available)
|
/// Volmap numeric IDs, one for each CVC (-1 if not available)
|
||||||
std::vector<int> volmap_ids_;
|
std::vector<int> volmap_ids_;
|
||||||
@ -762,4 +779,3 @@ inline void colvar::reset_bias_force() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -7,126 +7,84 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace ArithmeticPathCV {
|
namespace ArithmeticPathCV {
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
enum path_sz {S, Z};
|
template <typename scalar_type>
|
||||||
|
|
||||||
template <typename element_type, typename scalar_type, path_sz path_type>
|
|
||||||
class ArithmeticPathBase {
|
class ArithmeticPathBase {
|
||||||
public:
|
public:
|
||||||
ArithmeticPathBase() {}
|
ArithmeticPathBase() {}
|
||||||
virtual ~ArithmeticPathBase() {}
|
~ArithmeticPathBase() {}
|
||||||
virtual void initialize(size_t p_num_elements, size_t p_total_frames, double p_lambda, const vector<element_type>& p_element, const vector<double>& p_weights);
|
void initialize(size_t p_num_elements, size_t p_total_frames, scalar_type p_lambda, const vector<scalar_type>& p_weights);
|
||||||
virtual void updateDistanceToReferenceFrames() = 0;
|
void reComputeLambda(const vector<scalar_type>& rmsd_between_refs);
|
||||||
virtual void computeValue();
|
template <typename element_type>
|
||||||
virtual void computeDerivatives();
|
void computeValue(const vector<vector<element_type>>& frame_element_distances, scalar_type *s = nullptr, scalar_type *z = nullptr);
|
||||||
virtual void compute();
|
// can only be called after computeValue() for element-wise derivatives and store derivatives of i-th frame to dsdx and dzdx
|
||||||
virtual void reComputeLambda(const vector<scalar_type>& rmsd_between_refs);
|
template <typename element_type>
|
||||||
|
void computeDerivatives(const vector<vector<element_type>>& frame_element_distances, vector<vector<element_type>> *dsdx = nullptr, vector<vector<element_type>> *dzdx = nullptr);
|
||||||
protected:
|
protected:
|
||||||
scalar_type lambda;
|
scalar_type lambda;
|
||||||
vector<scalar_type> weights;
|
vector<scalar_type> squared_weights;
|
||||||
size_t num_elements;
|
size_t num_elements;
|
||||||
size_t total_frames;
|
size_t total_frames;
|
||||||
vector< vector<element_type> > frame_element_distances;
|
vector<scalar_type> exponents;
|
||||||
scalar_type s;
|
scalar_type max_exponent;
|
||||||
scalar_type z;
|
scalar_type saved_exponent_sum;
|
||||||
vector<element_type> dsdx;
|
|
||||||
vector<element_type> dzdx;
|
|
||||||
private:
|
|
||||||
// intermediate variables
|
|
||||||
vector<scalar_type> s_numerator_frame;
|
|
||||||
vector<scalar_type> s_denominator_frame;
|
|
||||||
scalar_type numerator_s;
|
|
||||||
scalar_type denominator_s;
|
|
||||||
scalar_type normalization_factor;
|
scalar_type normalization_factor;
|
||||||
|
scalar_type saved_s;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename element_type, typename scalar_type, path_sz path_type>
|
template <typename scalar_type>
|
||||||
void ArithmeticPathBase<element_type, scalar_type, path_type>::initialize(size_t p_num_elements, size_t p_total_frames, double p_lambda, const vector<element_type>& p_element, const vector<double>& p_weights) {
|
void ArithmeticPathBase<scalar_type>::initialize(size_t p_num_elements, size_t p_total_frames, scalar_type p_lambda, const vector<scalar_type>& p_weights) {
|
||||||
lambda = p_lambda;
|
lambda = p_lambda;
|
||||||
weights = p_weights;
|
for (size_t i = 0; i < p_weights.size(); ++i) squared_weights.push_back(p_weights[i] * p_weights[i]);
|
||||||
num_elements = p_num_elements;
|
num_elements = p_num_elements;
|
||||||
total_frames = p_total_frames;
|
total_frames = p_total_frames;
|
||||||
frame_element_distances.resize(total_frames, p_element);
|
exponents.resize(total_frames);
|
||||||
for (size_t i_frame = 0; i_frame < frame_element_distances.size(); ++i_frame) {
|
|
||||||
for (size_t j_elem = 0; j_elem < num_elements; ++j_elem) {
|
|
||||||
frame_element_distances[i_frame][j_elem].reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s = scalar_type(0);
|
|
||||||
z = scalar_type(0);
|
|
||||||
dsdx = p_element;
|
|
||||||
dzdx = p_element;
|
|
||||||
s_numerator_frame.resize(total_frames, scalar_type(0));
|
|
||||||
s_denominator_frame.resize(total_frames, scalar_type(0));
|
|
||||||
numerator_s = scalar_type(0);
|
|
||||||
denominator_s = scalar_type(0);
|
|
||||||
normalization_factor = 1.0 / static_cast<scalar_type>(total_frames - 1);
|
normalization_factor = 1.0 / static_cast<scalar_type>(total_frames - 1);
|
||||||
|
saved_s = scalar_type();
|
||||||
|
saved_exponent_sum = scalar_type();
|
||||||
|
max_exponent = scalar_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename element_type, typename scalar_type, path_sz path_type>
|
template <typename scalar_type>
|
||||||
void ArithmeticPathBase<element_type, scalar_type, path_type>::computeValue() {
|
template <typename element_type>
|
||||||
updateDistanceToReferenceFrames();
|
void ArithmeticPathBase<scalar_type>::computeValue(
|
||||||
numerator_s = scalar_type(0);
|
const vector<vector<element_type>>& frame_element_distances,
|
||||||
denominator_s = scalar_type(0);
|
scalar_type *s, scalar_type *z)
|
||||||
for (size_t i_frame = 0; i_frame < frame_element_distances.size(); ++i_frame) {
|
{
|
||||||
scalar_type exponent_tmp = scalar_type(0);
|
for (size_t i_frame = 0; i_frame < total_frames; ++i_frame) {
|
||||||
|
scalar_type exponent_tmp = scalar_type();
|
||||||
for (size_t j_elem = 0; j_elem < num_elements; ++j_elem) {
|
for (size_t j_elem = 0; j_elem < num_elements; ++j_elem) {
|
||||||
exponent_tmp += weights[j_elem] * frame_element_distances[i_frame][j_elem] * weights[j_elem] * frame_element_distances[i_frame][j_elem];
|
exponent_tmp += squared_weights[j_elem] * frame_element_distances[i_frame][j_elem] * frame_element_distances[i_frame][j_elem];
|
||||||
}
|
}
|
||||||
exponent_tmp = exponent_tmp * -1.0 * lambda;
|
exponents[i_frame] = exponent_tmp * -1.0 * lambda;
|
||||||
// prevent underflow if the argument of cvm::exp is less than -708.4
|
if (i_frame == 0 || exponents[i_frame] > max_exponent) max_exponent = exponents[i_frame];
|
||||||
if (exponent_tmp > -708.4) {
|
|
||||||
exponent_tmp = cvm::exp(exponent_tmp);
|
|
||||||
} else {
|
|
||||||
exponent_tmp = 0;
|
|
||||||
}
|
|
||||||
numerator_s += static_cast<scalar_type>(i_frame) * exponent_tmp;
|
|
||||||
denominator_s += exponent_tmp;
|
|
||||||
s_numerator_frame[i_frame] = static_cast<scalar_type>(i_frame) * exponent_tmp;
|
|
||||||
s_denominator_frame[i_frame] = exponent_tmp;
|
|
||||||
}
|
}
|
||||||
s = numerator_s / denominator_s * normalization_factor;
|
scalar_type log_sum_exp_0 = scalar_type();
|
||||||
z = -1.0 / lambda * cvm::logn(denominator_s);
|
scalar_type log_sum_exp_1 = scalar_type();
|
||||||
}
|
for (size_t i_frame = 0; i_frame < total_frames; ++i_frame) {
|
||||||
|
exponents[i_frame] = cvm::exp(exponents[i_frame] - max_exponent);
|
||||||
template <typename element_type, typename scalar_type, path_sz path_type>
|
log_sum_exp_0 += exponents[i_frame];
|
||||||
void ArithmeticPathBase<element_type, scalar_type, path_type>::compute() {
|
log_sum_exp_1 += i_frame * exponents[i_frame];
|
||||||
computeValue();
|
}
|
||||||
computeDerivatives();
|
saved_exponent_sum = log_sum_exp_0;
|
||||||
}
|
log_sum_exp_0 = max_exponent + cvm::logn(log_sum_exp_0);
|
||||||
|
log_sum_exp_1 = max_exponent + cvm::logn(log_sum_exp_1);
|
||||||
template <typename element_type, typename scalar_type, path_sz path_type>
|
saved_s = normalization_factor * cvm::exp(log_sum_exp_1 - log_sum_exp_0);
|
||||||
void ArithmeticPathBase<element_type, scalar_type, path_type>::computeDerivatives() {
|
if (s != nullptr) {
|
||||||
for (size_t j_elem = 0; j_elem < num_elements; ++j_elem) {
|
*s = saved_s;
|
||||||
element_type dsdxj_numerator_part1(dsdx[j_elem]);
|
}
|
||||||
element_type dsdxj_numerator_part2(dsdx[j_elem]);
|
if (z != nullptr) {
|
||||||
element_type dzdxj_numerator(dsdx[j_elem]);
|
*z = -1.0 / lambda * log_sum_exp_0;
|
||||||
dsdxj_numerator_part1.reset();
|
|
||||||
dsdxj_numerator_part2.reset();
|
|
||||||
dzdxj_numerator.reset();
|
|
||||||
for (size_t i_frame = 0; i_frame < frame_element_distances.size(); ++i_frame) {
|
|
||||||
element_type derivative_tmp = -2.0 * lambda * weights[j_elem] * weights[j_elem] * frame_element_distances[i_frame][j_elem];
|
|
||||||
dsdxj_numerator_part1 += s_numerator_frame[i_frame] * derivative_tmp;
|
|
||||||
dsdxj_numerator_part2 += s_denominator_frame[i_frame] * derivative_tmp;
|
|
||||||
dzdxj_numerator += s_denominator_frame[i_frame] * derivative_tmp;
|
|
||||||
}
|
|
||||||
dsdxj_numerator_part1 *= denominator_s;
|
|
||||||
dsdxj_numerator_part2 *= numerator_s;
|
|
||||||
if ((dsdxj_numerator_part1 - dsdxj_numerator_part2).norm() < std::numeric_limits<scalar_type>::min()) {
|
|
||||||
dsdx[j_elem] = 0;
|
|
||||||
} else {
|
|
||||||
dsdx[j_elem] = (dsdxj_numerator_part1 - dsdxj_numerator_part2) / (denominator_s * denominator_s) * normalization_factor;
|
|
||||||
}
|
|
||||||
dzdx[j_elem] = -1.0 / lambda * dzdxj_numerator / denominator_s;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename element_type, typename scalar_type, path_sz path_type>
|
template <typename scalar_type>
|
||||||
void ArithmeticPathBase<element_type, scalar_type, path_type>::reComputeLambda(const vector<scalar_type>& rmsd_between_refs) {
|
void ArithmeticPathBase<scalar_type>::reComputeLambda(const vector<scalar_type>& rmsd_between_refs) {
|
||||||
scalar_type mean_square_displacements = 0.0;
|
scalar_type mean_square_displacements = 0.0;
|
||||||
for (size_t i_frame = 1; i_frame < total_frames; ++i_frame) {
|
for (size_t i_frame = 1; i_frame < total_frames; ++i_frame) {
|
||||||
cvm::log(std::string("Distance between frame ") + cvm::to_str(i_frame) + " and " + cvm::to_str(i_frame + 1) + " is " + cvm::to_str(rmsd_between_refs[i_frame - 1]) + std::string("\n"));
|
cvm::log(std::string("Distance between frame ") + cvm::to_str(i_frame) + " and " + cvm::to_str(i_frame + 1) + " is " + cvm::to_str(rmsd_between_refs[i_frame - 1]) + std::string("\n"));
|
||||||
@ -135,6 +93,45 @@ void ArithmeticPathBase<element_type, scalar_type, path_type>::reComputeLambda(c
|
|||||||
mean_square_displacements /= scalar_type(total_frames - 1);
|
mean_square_displacements /= scalar_type(total_frames - 1);
|
||||||
lambda = 1.0 / mean_square_displacements;
|
lambda = 1.0 / mean_square_displacements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// frame-wise derivatives for frames using optimal rotation
|
||||||
|
template <typename scalar_type>
|
||||||
|
template <typename element_type>
|
||||||
|
void ArithmeticPathBase<scalar_type>::computeDerivatives(
|
||||||
|
const vector<vector<element_type>>& frame_element_distances,
|
||||||
|
vector<vector<element_type>> *dsdx,
|
||||||
|
vector<vector<element_type>> *dzdx)
|
||||||
|
{
|
||||||
|
vector<scalar_type> softmax_out, tmps;
|
||||||
|
softmax_out.reserve(total_frames);
|
||||||
|
tmps.reserve(total_frames);
|
||||||
|
for (size_t i_frame = 0; i_frame < total_frames; ++i_frame) {
|
||||||
|
softmax_out.push_back(exponents[i_frame] / saved_exponent_sum);
|
||||||
|
tmps.push_back(
|
||||||
|
(static_cast<scalar_type>(i_frame) -
|
||||||
|
static_cast<scalar_type>(total_frames - 1) * saved_s) *
|
||||||
|
normalization_factor);
|
||||||
|
}
|
||||||
|
if (dsdx != nullptr) {
|
||||||
|
for (size_t i_frame = 0; i_frame < total_frames; ++i_frame) {
|
||||||
|
for (size_t j_elem = 0; j_elem < num_elements; ++j_elem) {
|
||||||
|
(*dsdx)[i_frame][j_elem] =
|
||||||
|
-2.0 * squared_weights[j_elem] * lambda *
|
||||||
|
frame_element_distances[i_frame][j_elem] *
|
||||||
|
softmax_out[i_frame] * tmps[i_frame];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dzdx != nullptr) {
|
||||||
|
for (size_t i_frame = 0; i_frame < total_frames; ++i_frame) {
|
||||||
|
for (size_t j_elem = 0; j_elem < num_elements; ++j_elem) {
|
||||||
|
(*dzdx)[i_frame][j_elem] =
|
||||||
|
2.0 * squared_weights[j_elem] * softmax_out[i_frame] *
|
||||||
|
frame_element_distances[i_frame][j_elem];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ARITHMETICPATHCV_H
|
#endif // ARITHMETICPATHCV_H
|
||||||
|
|||||||
@ -8,12 +8,13 @@
|
|||||||
// Colvars repository at GitHub.
|
// Colvars repository at GitHub.
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <cmath>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace GeometricPathCV {
|
namespace GeometricPathCV {
|
||||||
|
|
||||||
@ -171,10 +172,14 @@ void GeometricPathBase<element_type, scalar_type, path_type>::determineClosestFr
|
|||||||
sign = -1;
|
sign = -1;
|
||||||
}
|
}
|
||||||
if (cvm::fabs(static_cast<long>(frame_index[0]) - static_cast<long>(frame_index[1])) > 1) {
|
if (cvm::fabs(static_cast<long>(frame_index[0]) - static_cast<long>(frame_index[1])) > 1) {
|
||||||
std::cout << "Warning: Geometrical pathCV relies on the assumption that the second closest frame is the neighbouring frame\n";
|
std::string message(
|
||||||
std::cout << " Please check your configuration or increase restraint on z(σ)\n";
|
"Warning: Geometrical pathCV relies on the assumption that the second closest frame is "
|
||||||
|
"the neighbouring frame\n"
|
||||||
|
" Please check your configuration or increase restraint on z(σ)\n");
|
||||||
for (size_t i_frame = 0; i_frame < frame_index.size(); ++i_frame) {
|
for (size_t i_frame = 0; i_frame < frame_index.size(); ++i_frame) {
|
||||||
std::cout << "Frame index: " << frame_index[i_frame] << " ; optimal RMSD = " << frame_distances[frame_index[i_frame]] << "\n";
|
message += "Frame index: " + cvm::to_str(frame_index[i_frame]) +
|
||||||
|
" ; optimal RMSD = " + cvm::to_str(frame_distances[frame_index[i_frame]]) +
|
||||||
|
"\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
min_frame_index_1 = frame_index[0]; // s_m
|
min_frame_index_1 = frame_index[0]; // s_m
|
||||||
|
|||||||
@ -10,7 +10,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#if (__cplusplus >= 201103L)
|
|
||||||
#include "colvar_neuralnetworkcompute.h"
|
#include "colvar_neuralnetworkcompute.h"
|
||||||
#include "colvarparse.h"
|
#include "colvarparse.h"
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
@ -272,9 +271,12 @@ std::vector<std::vector<double>> neuralNetworkCompute::multiply_matrix(const std
|
|||||||
const size_t t = B[0].size();
|
const size_t t = B[0].size();
|
||||||
std::vector<std::vector<double>> C(m, std::vector<double>(t, 0.0));
|
std::vector<std::vector<double>> C(m, std::vector<double>(t, 0.0));
|
||||||
for (size_t i = 0; i < m; ++i) {
|
for (size_t i = 0; i < m; ++i) {
|
||||||
for (size_t j = 0; j < t; ++j) {
|
for (size_t k = 0; k < n; ++k) {
|
||||||
for (size_t k = 0; k < n; ++k) {
|
const auto tmp = A[i][k];
|
||||||
C[i][j] += A[i][k] * B[k][j];
|
auto& C_i = C[i];
|
||||||
|
auto& B_k = B[k];
|
||||||
|
for (size_t j = 0; j < t; ++j) {
|
||||||
|
C_i[j] += tmp * B_k[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,5 +308,3 @@ void neuralNetworkCompute::compute() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@ -7,7 +7,6 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
#if (__cplusplus >= 201103L)
|
|
||||||
#ifndef NEURALNETWORKCOMPUTE_H
|
#ifndef NEURALNETWORKCOMPUTE_H
|
||||||
#define NEURALNETWORKCOMPUTE_H
|
#define NEURALNETWORKCOMPUTE_H
|
||||||
|
|
||||||
@ -145,4 +144,3 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|||||||
627
lib/colvars/colvar_rotation_derivative.h
Normal file
627
lib/colvars/colvar_rotation_derivative.h
Normal file
@ -0,0 +1,627 @@
|
|||||||
|
#ifndef COLVAR_ROTATION_DERIVATIVE
|
||||||
|
#define COLVAR_ROTATION_DERIVATIVE
|
||||||
|
|
||||||
|
#include "colvartypes.h"
|
||||||
|
#include <type_traits>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
/// \brief Helper function for loading the ia-th atom in the vector pos to x, y and z (C++11 SFINAE is used)
|
||||||
|
template <typename T, typename std::enable_if<std::is_same<T, cvm::atom_pos>::value, bool>::type = true>
|
||||||
|
inline void read_atom_coord(
|
||||||
|
size_t ia, const std::vector<T>& pos,
|
||||||
|
cvm::real* x, cvm::real* y, cvm::real* z) {
|
||||||
|
*x = pos[ia].x;
|
||||||
|
*y = pos[ia].y;
|
||||||
|
*z = pos[ia].z;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename std::enable_if<std::is_same<T, cvm::atom>::value, bool>::type = true>
|
||||||
|
inline void read_atom_coord(
|
||||||
|
size_t ia, const std::vector<T>& pos,
|
||||||
|
cvm::real* x, cvm::real* y, cvm::real* z) {
|
||||||
|
*x = pos[ia].pos.x;
|
||||||
|
*y = pos[ia].pos.y;
|
||||||
|
*z = pos[ia].pos.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Helper enum class for specifying options in rotation_derivative::prepare_derivative
|
||||||
|
enum class rotation_derivative_dldq {
|
||||||
|
/// Require the derivative of the leading eigenvalue with respect to the atom coordinats
|
||||||
|
use_dl = 1 << 0,
|
||||||
|
/// Require the derivative of the leading eigenvector with respect to the atom coordinats
|
||||||
|
use_dq = 1 << 1
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr rotation_derivative_dldq operator|(rotation_derivative_dldq Lhs, rotation_derivative_dldq Rhs) {
|
||||||
|
return static_cast<rotation_derivative_dldq>(
|
||||||
|
static_cast<std::underlying_type<rotation_derivative_dldq>::type>(Lhs) |
|
||||||
|
static_cast<std::underlying_type<rotation_derivative_dldq>::type>(Rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr bool operator&(rotation_derivative_dldq Lhs, rotation_derivative_dldq Rhs)
|
||||||
|
{
|
||||||
|
return (static_cast<std::underlying_type<rotation_derivative_dldq>::type>(Lhs) &
|
||||||
|
static_cast<std::underlying_type<rotation_derivative_dldq>::type>(Rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Helper class for calculating the derivative of rotation
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
struct rotation_derivative {
|
||||||
|
static_assert(std::is_same<T1, cvm::atom_pos>::value || std::is_same<T1, cvm::atom>::value,
|
||||||
|
"class template rotation_derivative only supports cvm::atom_pos or cvm::atom types.");
|
||||||
|
static_assert(std::is_same<T2, cvm::atom_pos>::value || std::is_same<T2, cvm::atom>::value,
|
||||||
|
"class template rotation_derivative only supports cvm::atom_pos or cvm::atom types.");
|
||||||
|
/// \brief Reference to the rotation
|
||||||
|
const cvm::rotation &m_rot;
|
||||||
|
/// \brief Reference to the atom positions of group 1
|
||||||
|
const std::vector<T1> &m_pos1;
|
||||||
|
/// \brief Reference to the atom positions of group 2
|
||||||
|
const std::vector<T2> &m_pos2;
|
||||||
|
/// \brief Temporary variable that will be updated if prepare_derivative called
|
||||||
|
cvm::real tmp_Q0Q0[4][4];
|
||||||
|
cvm::real tmp_Q0Q0_L[4][4][4];
|
||||||
|
/*! @brief Constructor of the cvm::rotation::derivative class
|
||||||
|
* @param[in] rot The cvm::rotation object (must have called
|
||||||
|
* `calc_optimal_rotation` before calling
|
||||||
|
* `calc_derivative_wrt_group1` and
|
||||||
|
* `calc_derivative_wrt_group2`)
|
||||||
|
* @param[in] pos1 The atom positions of group 1
|
||||||
|
* @param[in] pos2 The atom positions of group 2
|
||||||
|
*/
|
||||||
|
rotation_derivative(
|
||||||
|
const cvm::rotation &rot,
|
||||||
|
const std::vector<T1> &pos1,
|
||||||
|
const std::vector<T2> &pos2):
|
||||||
|
m_rot(rot), m_pos1(pos1), m_pos2(pos2) {};
|
||||||
|
/*! @brief This function must be called before `calc_derivative_wrt_group1`
|
||||||
|
* and `calc_derivative_wrt_group2` in order to prepare the tmp_Q0Q0
|
||||||
|
* and tmp_Q0Q0_L.
|
||||||
|
* @param[in] require_dl_dq Require the calculation of the derivatives of L or/and Q
|
||||||
|
* with respect to atoms.
|
||||||
|
*/
|
||||||
|
void prepare_derivative(rotation_derivative_dldq require_dl_dq) {
|
||||||
|
if (require_dl_dq & rotation_derivative_dldq::use_dl) {
|
||||||
|
const auto &Q0 = m_rot.S_eigvec[0];
|
||||||
|
tmp_Q0Q0[0][0] = Q0[0] * Q0[0];
|
||||||
|
tmp_Q0Q0[0][1] = Q0[0] * Q0[1];
|
||||||
|
tmp_Q0Q0[0][2] = Q0[0] * Q0[2];
|
||||||
|
tmp_Q0Q0[0][3] = Q0[0] * Q0[3];
|
||||||
|
tmp_Q0Q0[1][0] = Q0[1] * Q0[0];
|
||||||
|
tmp_Q0Q0[1][1] = Q0[1] * Q0[1];
|
||||||
|
tmp_Q0Q0[1][2] = Q0[1] * Q0[2];
|
||||||
|
tmp_Q0Q0[1][3] = Q0[1] * Q0[3];
|
||||||
|
tmp_Q0Q0[2][0] = Q0[2] * Q0[0];
|
||||||
|
tmp_Q0Q0[2][1] = Q0[2] * Q0[1];
|
||||||
|
tmp_Q0Q0[2][2] = Q0[2] * Q0[2];
|
||||||
|
tmp_Q0Q0[2][3] = Q0[2] * Q0[3];
|
||||||
|
tmp_Q0Q0[3][0] = Q0[3] * Q0[0];
|
||||||
|
tmp_Q0Q0[3][1] = Q0[3] * Q0[1];
|
||||||
|
tmp_Q0Q0[3][2] = Q0[3] * Q0[2];
|
||||||
|
tmp_Q0Q0[3][3] = Q0[3] * Q0[3];
|
||||||
|
}
|
||||||
|
if (require_dl_dq & rotation_derivative_dldq::use_dq) {
|
||||||
|
const auto &Q0 = m_rot.S_eigvec[0];
|
||||||
|
const auto &Q1 = m_rot.S_eigvec[1];
|
||||||
|
const auto &Q2 = m_rot.S_eigvec[2];
|
||||||
|
const auto &Q3 = m_rot.S_eigvec[3];
|
||||||
|
cvm::real const L0 = m_rot.S_eigval[0];
|
||||||
|
cvm::real const L1 = m_rot.S_eigval[1];
|
||||||
|
cvm::real const L2 = m_rot.S_eigval[2];
|
||||||
|
cvm::real const L3 = m_rot.S_eigval[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][0][0] = (Q1[0] * Q0[0]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[0] * Q0[0]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[0] * Q0[0]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][0][0] = (Q1[0] * Q0[0]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[0] * Q0[0]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[0] * Q0[0]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][0][0] = (Q1[0] * Q0[0]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[0] * Q0[0]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[0] * Q0[0]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][0][0] = (Q1[0] * Q0[0]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[0] * Q0[0]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[0] * Q0[0]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][0][1] = (Q1[0] * Q0[1]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[0] * Q0[1]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[0] * Q0[1]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][0][1] = (Q1[0] * Q0[1]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[0] * Q0[1]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[0] * Q0[1]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][0][1] = (Q1[0] * Q0[1]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[0] * Q0[1]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[0] * Q0[1]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][0][1] = (Q1[0] * Q0[1]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[0] * Q0[1]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[0] * Q0[1]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][0][2] = (Q1[0] * Q0[2]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[0] * Q0[2]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[0] * Q0[2]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][0][2] = (Q1[0] * Q0[2]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[0] * Q0[2]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[0] * Q0[2]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][0][2] = (Q1[0] * Q0[2]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[0] * Q0[2]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[0] * Q0[2]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][0][2] = (Q1[0] * Q0[2]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[0] * Q0[2]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[0] * Q0[2]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][0][3] = (Q1[0] * Q0[3]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[0] * Q0[3]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[0] * Q0[3]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][0][3] = (Q1[0] * Q0[3]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[0] * Q0[3]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[0] * Q0[3]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][0][3] = (Q1[0] * Q0[3]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[0] * Q0[3]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[0] * Q0[3]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][0][3] = (Q1[0] * Q0[3]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[0] * Q0[3]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[0] * Q0[3]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][1][0] = (Q1[1] * Q0[0]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[1] * Q0[0]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[1] * Q0[0]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][1][0] = (Q1[1] * Q0[0]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[1] * Q0[0]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[1] * Q0[0]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][1][0] = (Q1[1] * Q0[0]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[1] * Q0[0]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[1] * Q0[0]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][1][0] = (Q1[1] * Q0[0]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[1] * Q0[0]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[1] * Q0[0]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][1][1] = (Q1[1] * Q0[1]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[1] * Q0[1]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[1] * Q0[1]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][1][1] = (Q1[1] * Q0[1]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[1] * Q0[1]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[1] * Q0[1]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][1][1] = (Q1[1] * Q0[1]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[1] * Q0[1]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[1] * Q0[1]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][1][1] = (Q1[1] * Q0[1]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[1] * Q0[1]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[1] * Q0[1]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][1][2] = (Q1[1] * Q0[2]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[1] * Q0[2]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[1] * Q0[2]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][1][2] = (Q1[1] * Q0[2]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[1] * Q0[2]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[1] * Q0[2]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][1][2] = (Q1[1] * Q0[2]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[1] * Q0[2]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[1] * Q0[2]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][1][2] = (Q1[1] * Q0[2]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[1] * Q0[2]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[1] * Q0[2]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][1][3] = (Q1[1] * Q0[3]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[1] * Q0[3]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[1] * Q0[3]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][1][3] = (Q1[1] * Q0[3]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[1] * Q0[3]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[1] * Q0[3]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][1][3] = (Q1[1] * Q0[3]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[1] * Q0[3]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[1] * Q0[3]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][1][3] = (Q1[1] * Q0[3]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[1] * Q0[3]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[1] * Q0[3]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][2][0] = (Q1[2] * Q0[0]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[2] * Q0[0]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[2] * Q0[0]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][2][0] = (Q1[2] * Q0[0]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[2] * Q0[0]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[2] * Q0[0]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][2][0] = (Q1[2] * Q0[0]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[2] * Q0[0]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[2] * Q0[0]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][2][0] = (Q1[2] * Q0[0]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[2] * Q0[0]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[2] * Q0[0]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][2][1] = (Q1[2] * Q0[1]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[2] * Q0[1]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[2] * Q0[1]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][2][1] = (Q1[2] * Q0[1]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[2] * Q0[1]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[2] * Q0[1]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][2][1] = (Q1[2] * Q0[1]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[2] * Q0[1]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[2] * Q0[1]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][2][1] = (Q1[2] * Q0[1]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[2] * Q0[1]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[2] * Q0[1]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][2][2] = (Q1[2] * Q0[2]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[2] * Q0[2]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[2] * Q0[2]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][2][2] = (Q1[2] * Q0[2]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[2] * Q0[2]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[2] * Q0[2]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][2][2] = (Q1[2] * Q0[2]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[2] * Q0[2]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[2] * Q0[2]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][2][2] = (Q1[2] * Q0[2]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[2] * Q0[2]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[2] * Q0[2]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][2][3] = (Q1[2] * Q0[3]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[2] * Q0[3]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[2] * Q0[3]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][2][3] = (Q1[2] * Q0[3]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[2] * Q0[3]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[2] * Q0[3]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][2][3] = (Q1[2] * Q0[3]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[2] * Q0[3]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[2] * Q0[3]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][2][3] = (Q1[2] * Q0[3]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[2] * Q0[3]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[2] * Q0[3]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][3][0] = (Q1[3] * Q0[0]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[3] * Q0[0]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[3] * Q0[0]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][3][0] = (Q1[3] * Q0[0]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[3] * Q0[0]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[3] * Q0[0]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][3][0] = (Q1[3] * Q0[0]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[3] * Q0[0]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[3] * Q0[0]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][3][0] = (Q1[3] * Q0[0]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[3] * Q0[0]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[3] * Q0[0]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][3][1] = (Q1[3] * Q0[1]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[3] * Q0[1]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[3] * Q0[1]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][3][1] = (Q1[3] * Q0[1]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[3] * Q0[1]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[3] * Q0[1]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][3][1] = (Q1[3] * Q0[1]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[3] * Q0[1]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[3] * Q0[1]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][3][1] = (Q1[3] * Q0[1]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[3] * Q0[1]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[3] * Q0[1]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][3][2] = (Q1[3] * Q0[2]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[3] * Q0[2]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[3] * Q0[2]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][3][2] = (Q1[3] * Q0[2]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[3] * Q0[2]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[3] * Q0[2]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][3][2] = (Q1[3] * Q0[2]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[3] * Q0[2]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[3] * Q0[2]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][3][2] = (Q1[3] * Q0[2]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[3] * Q0[2]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[3] * Q0[2]) / (L0-L3) * Q3[3];
|
||||||
|
|
||||||
|
tmp_Q0Q0_L[0][3][3] = (Q1[3] * Q0[3]) / (L0-L1) * Q1[0] +
|
||||||
|
(Q2[3] * Q0[3]) / (L0-L2) * Q2[0] +
|
||||||
|
(Q3[3] * Q0[3]) / (L0-L3) * Q3[0];
|
||||||
|
tmp_Q0Q0_L[1][3][3] = (Q1[3] * Q0[3]) / (L0-L1) * Q1[1] +
|
||||||
|
(Q2[3] * Q0[3]) / (L0-L2) * Q2[1] +
|
||||||
|
(Q3[3] * Q0[3]) / (L0-L3) * Q3[1];
|
||||||
|
tmp_Q0Q0_L[2][3][3] = (Q1[3] * Q0[3]) / (L0-L1) * Q1[2] +
|
||||||
|
(Q2[3] * Q0[3]) / (L0-L2) * Q2[2] +
|
||||||
|
(Q3[3] * Q0[3]) / (L0-L3) * Q3[2];
|
||||||
|
tmp_Q0Q0_L[3][3][3] = (Q1[3] * Q0[3]) / (L0-L1) * Q1[3] +
|
||||||
|
(Q2[3] * Q0[3]) / (L0-L2) * Q2[3] +
|
||||||
|
(Q3[3] * Q0[3]) / (L0-L3) * Q3[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*! @brief Actual implementation of the derivative calculation
|
||||||
|
* @param[in] ds The derivative of matrix S with respect to an atom of
|
||||||
|
* either group 1 or group 2
|
||||||
|
* @param[out] dl0_out The output of derivative of L
|
||||||
|
* @param[out] dq0_out The output of derivative of Q
|
||||||
|
* @param[out] ds_out The output of derivative of overlap matrix S
|
||||||
|
*/
|
||||||
|
void calc_derivative_impl(
|
||||||
|
const cvm::rvector (&ds)[4][4],
|
||||||
|
cvm::rvector* const dl0_out,
|
||||||
|
cvm::vector1d<cvm::rvector>* const dq0_out,
|
||||||
|
cvm::matrix2d<cvm::rvector>* const ds_out) const {
|
||||||
|
if (ds_out != nullptr) {
|
||||||
|
// this code path is for debug_gradients, so not necessary to unroll the loop
|
||||||
|
*ds_out = cvm::matrix2d<cvm::rvector>(4, 4);
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
for (int j = 0; j < 4; ++j) {
|
||||||
|
(*ds_out)[i][j] = ds[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dl0_out != nullptr) {
|
||||||
|
/* manually loop unrolling of the following loop:
|
||||||
|
dl0_1.reset();
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
for (size_t j = 0; j < 4; j++) {
|
||||||
|
dl0_1 += Q0[i] * ds_1[i][j] * Q0[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
*dl0_out = tmp_Q0Q0[0][0] * ds[0][0] +
|
||||||
|
tmp_Q0Q0[0][1] * ds[0][1] +
|
||||||
|
tmp_Q0Q0[0][2] * ds[0][2] +
|
||||||
|
tmp_Q0Q0[0][3] * ds[0][3] +
|
||||||
|
tmp_Q0Q0[1][0] * ds[1][0] +
|
||||||
|
tmp_Q0Q0[1][1] * ds[1][1] +
|
||||||
|
tmp_Q0Q0[1][2] * ds[1][2] +
|
||||||
|
tmp_Q0Q0[1][3] * ds[1][3] +
|
||||||
|
tmp_Q0Q0[2][0] * ds[2][0] +
|
||||||
|
tmp_Q0Q0[2][1] * ds[2][1] +
|
||||||
|
tmp_Q0Q0[2][2] * ds[2][2] +
|
||||||
|
tmp_Q0Q0[2][3] * ds[2][3] +
|
||||||
|
tmp_Q0Q0[3][0] * ds[3][0] +
|
||||||
|
tmp_Q0Q0[3][1] * ds[3][1] +
|
||||||
|
tmp_Q0Q0[3][2] * ds[3][2] +
|
||||||
|
tmp_Q0Q0[3][3] * ds[3][3];
|
||||||
|
}
|
||||||
|
if (dq0_out != nullptr) {
|
||||||
|
// we can skip this check if a fixed-size array is used
|
||||||
|
if (dq0_out->size() != 4) dq0_out->resize(4);
|
||||||
|
/* manually loop unrolling of the following loop:
|
||||||
|
dq0_1.reset();
|
||||||
|
for (size_t p = 0; p < 4; p++) {
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
for (size_t j = 0; j < 4; j++) {
|
||||||
|
dq0_1[p] +=
|
||||||
|
(Q1[i] * ds_1[i][j] * Q0[j]) / (L0-L1) * Q1[p] +
|
||||||
|
(Q2[i] * ds_1[i][j] * Q0[j]) / (L0-L2) * Q2[p] +
|
||||||
|
(Q3[i] * ds_1[i][j] * Q0[j]) / (L0-L3) * Q3[p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
(*dq0_out)[0] = tmp_Q0Q0_L[0][0][0] * ds[0][0] +
|
||||||
|
tmp_Q0Q0_L[0][0][1] * ds[0][1] +
|
||||||
|
tmp_Q0Q0_L[0][0][2] * ds[0][2] +
|
||||||
|
tmp_Q0Q0_L[0][0][3] * ds[0][3] +
|
||||||
|
tmp_Q0Q0_L[0][1][0] * ds[1][0] +
|
||||||
|
tmp_Q0Q0_L[0][1][1] * ds[1][1] +
|
||||||
|
tmp_Q0Q0_L[0][1][2] * ds[1][2] +
|
||||||
|
tmp_Q0Q0_L[0][1][3] * ds[1][3] +
|
||||||
|
tmp_Q0Q0_L[0][2][0] * ds[2][0] +
|
||||||
|
tmp_Q0Q0_L[0][2][1] * ds[2][1] +
|
||||||
|
tmp_Q0Q0_L[0][2][2] * ds[2][2] +
|
||||||
|
tmp_Q0Q0_L[0][2][3] * ds[2][3] +
|
||||||
|
tmp_Q0Q0_L[0][3][0] * ds[3][0] +
|
||||||
|
tmp_Q0Q0_L[0][3][1] * ds[3][1] +
|
||||||
|
tmp_Q0Q0_L[0][3][2] * ds[3][2] +
|
||||||
|
tmp_Q0Q0_L[0][3][3] * ds[3][3];
|
||||||
|
|
||||||
|
(*dq0_out)[1] = tmp_Q0Q0_L[1][0][0] * ds[0][0] +
|
||||||
|
tmp_Q0Q0_L[1][0][1] * ds[0][1] +
|
||||||
|
tmp_Q0Q0_L[1][0][2] * ds[0][2] +
|
||||||
|
tmp_Q0Q0_L[1][0][3] * ds[0][3] +
|
||||||
|
tmp_Q0Q0_L[1][1][0] * ds[1][0] +
|
||||||
|
tmp_Q0Q0_L[1][1][1] * ds[1][1] +
|
||||||
|
tmp_Q0Q0_L[1][1][2] * ds[1][2] +
|
||||||
|
tmp_Q0Q0_L[1][1][3] * ds[1][3] +
|
||||||
|
tmp_Q0Q0_L[1][2][0] * ds[2][0] +
|
||||||
|
tmp_Q0Q0_L[1][2][1] * ds[2][1] +
|
||||||
|
tmp_Q0Q0_L[1][2][2] * ds[2][2] +
|
||||||
|
tmp_Q0Q0_L[1][2][3] * ds[2][3] +
|
||||||
|
tmp_Q0Q0_L[1][3][0] * ds[3][0] +
|
||||||
|
tmp_Q0Q0_L[1][3][1] * ds[3][1] +
|
||||||
|
tmp_Q0Q0_L[1][3][2] * ds[3][2] +
|
||||||
|
tmp_Q0Q0_L[1][3][3] * ds[3][3];
|
||||||
|
|
||||||
|
(*dq0_out)[2] = tmp_Q0Q0_L[2][0][0] * ds[0][0] +
|
||||||
|
tmp_Q0Q0_L[2][0][1] * ds[0][1] +
|
||||||
|
tmp_Q0Q0_L[2][0][2] * ds[0][2] +
|
||||||
|
tmp_Q0Q0_L[2][0][3] * ds[0][3] +
|
||||||
|
tmp_Q0Q0_L[2][1][0] * ds[1][0] +
|
||||||
|
tmp_Q0Q0_L[2][1][1] * ds[1][1] +
|
||||||
|
tmp_Q0Q0_L[2][1][2] * ds[1][2] +
|
||||||
|
tmp_Q0Q0_L[2][1][3] * ds[1][3] +
|
||||||
|
tmp_Q0Q0_L[2][2][0] * ds[2][0] +
|
||||||
|
tmp_Q0Q0_L[2][2][1] * ds[2][1] +
|
||||||
|
tmp_Q0Q0_L[2][2][2] * ds[2][2] +
|
||||||
|
tmp_Q0Q0_L[2][2][3] * ds[2][3] +
|
||||||
|
tmp_Q0Q0_L[2][3][0] * ds[3][0] +
|
||||||
|
tmp_Q0Q0_L[2][3][1] * ds[3][1] +
|
||||||
|
tmp_Q0Q0_L[2][3][2] * ds[3][2] +
|
||||||
|
tmp_Q0Q0_L[2][3][3] * ds[3][3];
|
||||||
|
|
||||||
|
(*dq0_out)[3] = tmp_Q0Q0_L[3][0][0] * ds[0][0] +
|
||||||
|
tmp_Q0Q0_L[3][0][1] * ds[0][1] +
|
||||||
|
tmp_Q0Q0_L[3][0][2] * ds[0][2] +
|
||||||
|
tmp_Q0Q0_L[3][0][3] * ds[0][3] +
|
||||||
|
tmp_Q0Q0_L[3][1][0] * ds[1][0] +
|
||||||
|
tmp_Q0Q0_L[3][1][1] * ds[1][1] +
|
||||||
|
tmp_Q0Q0_L[3][1][2] * ds[1][2] +
|
||||||
|
tmp_Q0Q0_L[3][1][3] * ds[1][3] +
|
||||||
|
tmp_Q0Q0_L[3][2][0] * ds[2][0] +
|
||||||
|
tmp_Q0Q0_L[3][2][1] * ds[2][1] +
|
||||||
|
tmp_Q0Q0_L[3][2][2] * ds[2][2] +
|
||||||
|
tmp_Q0Q0_L[3][2][3] * ds[2][3] +
|
||||||
|
tmp_Q0Q0_L[3][3][0] * ds[3][0] +
|
||||||
|
tmp_Q0Q0_L[3][3][1] * ds[3][1] +
|
||||||
|
tmp_Q0Q0_L[3][3][2] * ds[3][2] +
|
||||||
|
tmp_Q0Q0_L[3][3][3] * ds[3][3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*! @brief Calculate the derivatives of S, the leading eigenvalue L and
|
||||||
|
* the leading eigenvector Q with respect to `m_pos1`
|
||||||
|
* @param[in] ia The index the of atom
|
||||||
|
* @param[out] dl0_1_out The output of derivative of L with respect to
|
||||||
|
* ia-th atom of group 1
|
||||||
|
* @param[out] dq0_1_out The output of derivative of Q with respect to
|
||||||
|
* ia-th atom of group 1
|
||||||
|
* @param[out] ds_1_out The output of derivative of overlap matrix S with
|
||||||
|
* respect to ia-th atom of group 1
|
||||||
|
*/
|
||||||
|
void calc_derivative_wrt_group1(
|
||||||
|
size_t ia, cvm::rvector* const dl0_1_out = nullptr,
|
||||||
|
cvm::vector1d<cvm::rvector>* const dq0_1_out = nullptr,
|
||||||
|
cvm::matrix2d<cvm::rvector>* const ds_1_out = nullptr) const {
|
||||||
|
if (dl0_1_out == nullptr && dq0_1_out == nullptr) return;
|
||||||
|
cvm::real a2x, a2y, a2z;
|
||||||
|
// we can get rid of the helper function read_atom_coord if C++17 (constexpr) is available
|
||||||
|
read_atom_coord(ia, m_pos2, &a2x, &a2y, &a2z);
|
||||||
|
cvm::rvector ds_1[4][4];
|
||||||
|
ds_1[0][0].set( a2x, a2y, a2z);
|
||||||
|
ds_1[1][0].set( 0.0, a2z, -a2y);
|
||||||
|
ds_1[0][1] = ds_1[1][0];
|
||||||
|
ds_1[2][0].set(-a2z, 0.0, a2x);
|
||||||
|
ds_1[0][2] = ds_1[2][0];
|
||||||
|
ds_1[3][0].set( a2y, -a2x, 0.0);
|
||||||
|
ds_1[0][3] = ds_1[3][0];
|
||||||
|
ds_1[1][1].set( a2x, -a2y, -a2z);
|
||||||
|
ds_1[2][1].set( a2y, a2x, 0.0);
|
||||||
|
ds_1[1][2] = ds_1[2][1];
|
||||||
|
ds_1[3][1].set( a2z, 0.0, a2x);
|
||||||
|
ds_1[1][3] = ds_1[3][1];
|
||||||
|
ds_1[2][2].set(-a2x, a2y, -a2z);
|
||||||
|
ds_1[3][2].set( 0.0, a2z, a2y);
|
||||||
|
ds_1[2][3] = ds_1[3][2];
|
||||||
|
ds_1[3][3].set(-a2x, -a2y, a2z);
|
||||||
|
calc_derivative_impl(ds_1, dl0_1_out, dq0_1_out, ds_1_out);
|
||||||
|
}
|
||||||
|
/*! @brief Calculate the derivatives of S, the leading eigenvalue L and
|
||||||
|
* the leading eigenvector Q with respect to `m_pos2`
|
||||||
|
* @param[in] ia The index the of atom
|
||||||
|
* @param[out] dl0_2_out The output of derivative of L with respect to
|
||||||
|
* ia-th atom of group 2
|
||||||
|
* @param[out] dq0_2_out The output of derivative of Q with respect to
|
||||||
|
* ia-th atom of group 2
|
||||||
|
* @param[out] ds_2_out The output of derivative of overlap matrix S with
|
||||||
|
* respect to ia-th atom of group 2
|
||||||
|
*/
|
||||||
|
void calc_derivative_wrt_group2(
|
||||||
|
size_t ia, cvm::rvector* const dl0_2_out = nullptr,
|
||||||
|
cvm::vector1d<cvm::rvector>* const dq0_2_out = nullptr,
|
||||||
|
cvm::matrix2d<cvm::rvector>* const ds_2_out = nullptr) const {
|
||||||
|
if (dl0_2_out == nullptr && dq0_2_out == nullptr) return;
|
||||||
|
cvm::real a1x, a1y, a1z;
|
||||||
|
// we can get rid of the helper function read_atom_coord if C++17 (constexpr) is available
|
||||||
|
read_atom_coord(ia, m_pos1, &a1x, &a1y, &a1z);
|
||||||
|
cvm::rvector ds_2[4][4];
|
||||||
|
ds_2[0][0].set( a1x, a1y, a1z);
|
||||||
|
ds_2[1][0].set( 0.0, -a1z, a1y);
|
||||||
|
ds_2[0][1] = ds_2[1][0];
|
||||||
|
ds_2[2][0].set( a1z, 0.0, -a1x);
|
||||||
|
ds_2[0][2] = ds_2[2][0];
|
||||||
|
ds_2[3][0].set(-a1y, a1x, 0.0);
|
||||||
|
ds_2[0][3] = ds_2[3][0];
|
||||||
|
ds_2[1][1].set( a1x, -a1y, -a1z);
|
||||||
|
ds_2[2][1].set( a1y, a1x, 0.0);
|
||||||
|
ds_2[1][2] = ds_2[2][1];
|
||||||
|
ds_2[3][1].set( a1z, 0.0, a1x);
|
||||||
|
ds_2[1][3] = ds_2[3][1];
|
||||||
|
ds_2[2][2].set(-a1x, a1y, -a1z);
|
||||||
|
ds_2[3][2].set( 0.0, a1z, a1y);
|
||||||
|
ds_2[2][3] = ds_2[3][2];
|
||||||
|
ds_2[3][3].set(-a1x, -a1y, a1z);
|
||||||
|
calc_derivative_impl(ds_2, dl0_2_out, dq0_2_out, ds_2_out);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! @brief Function for debugging gradients (allow using either
|
||||||
|
* std::vector<cvm::atom_pos> or std::vector<cvm::atom> for
|
||||||
|
* pos1 and pos2)
|
||||||
|
* @param[in] pos1 Atom positions of group 1
|
||||||
|
* @param[in] pos2 Atom positions of group 2
|
||||||
|
*/
|
||||||
|
template<typename T1, typename T2>
|
||||||
|
void debug_gradients(
|
||||||
|
cvm::rotation &rot,
|
||||||
|
const std::vector<T1> &pos1,
|
||||||
|
const std::vector<T2> &pos2) {
|
||||||
|
static_assert(std::is_same<T1, cvm::atom_pos>::value || std::is_same<T1, cvm::atom>::value, "");
|
||||||
|
static_assert(std::is_same<T2, cvm::atom_pos>::value || std::is_same<T2, cvm::atom>::value, "");
|
||||||
|
// eigenvalues and eigenvectors
|
||||||
|
cvm::real const L0 = rot.S_eigval[0];
|
||||||
|
cvm::real const L1 = rot.S_eigval[1];
|
||||||
|
cvm::real const L2 = rot.S_eigval[2];
|
||||||
|
cvm::real const L3 = rot.S_eigval[3];
|
||||||
|
cvm::quaternion const Q0(rot.S_eigvec[0]);
|
||||||
|
cvm::quaternion const Q1(rot.S_eigvec[1]);
|
||||||
|
cvm::quaternion const Q2(rot.S_eigvec[2]);
|
||||||
|
cvm::quaternion const Q3(rot.S_eigvec[3]);
|
||||||
|
|
||||||
|
cvm::log("L0 = "+cvm::to_str(L0, cvm::cv_width, cvm::cv_prec)+
|
||||||
|
", Q0 = "+cvm::to_str(Q0, cvm::cv_width, cvm::cv_prec)+
|
||||||
|
", Q0*Q0 = "+cvm::to_str(Q0.inner(Q0), cvm::cv_width, cvm::cv_prec)+
|
||||||
|
"\n");
|
||||||
|
cvm::log("L1 = "+cvm::to_str(L1, cvm::cv_width, cvm::cv_prec)+
|
||||||
|
", Q1 = "+cvm::to_str(Q1, cvm::cv_width, cvm::cv_prec)+
|
||||||
|
", Q0*Q1 = "+cvm::to_str(Q0.inner(Q1), cvm::cv_width, cvm::cv_prec)+
|
||||||
|
"\n");
|
||||||
|
cvm::log("L2 = "+cvm::to_str(L2, cvm::cv_width, cvm::cv_prec)+
|
||||||
|
", Q2 = "+cvm::to_str(Q2, cvm::cv_width, cvm::cv_prec)+
|
||||||
|
", Q0*Q2 = "+cvm::to_str(Q0.inner(Q2), cvm::cv_width, cvm::cv_prec)+
|
||||||
|
"\n");
|
||||||
|
cvm::log("L3 = "+cvm::to_str(L3, cvm::cv_width, cvm::cv_prec)+
|
||||||
|
", Q3 = "+cvm::to_str(Q3, cvm::cv_width, cvm::cv_prec)+
|
||||||
|
", Q0*Q3 = "+cvm::to_str(Q0.inner(Q3), cvm::cv_width, cvm::cv_prec)+
|
||||||
|
"\n");
|
||||||
|
|
||||||
|
rotation_derivative<T1, T2> deriv(rot, pos1, pos2);
|
||||||
|
cvm::rvector dl0_2;
|
||||||
|
cvm::vector1d<cvm::rvector> dq0_2(4);
|
||||||
|
cvm::matrix2d<cvm::rvector> ds_2;
|
||||||
|
#ifdef COLVARS_LAMMPS
|
||||||
|
MathEigen::Jacobi<cvm::real,
|
||||||
|
cvm::real[4],
|
||||||
|
cvm::real[4][4]> *ecalc =
|
||||||
|
reinterpret_cast<MathEigen::Jacobi<cvm::real,
|
||||||
|
cvm::real[4],
|
||||||
|
cvm::real[4][4]> *>(rot.jacobi);
|
||||||
|
#endif
|
||||||
|
deriv.prepare_derivative(rotation_derivative_dldq::use_dl | rotation_derivative_dldq::use_dq);
|
||||||
|
cvm::real S_new[4][4];
|
||||||
|
cvm::real S_new_eigval[4];
|
||||||
|
cvm::real S_new_eigvec[4][4];
|
||||||
|
for (size_t ia = 0; ia < pos2.size(); ++ia) {
|
||||||
|
// cvm::real const &a1x = pos1[ia].x;
|
||||||
|
// cvm::real const &a1y = pos1[ia].y;
|
||||||
|
// cvm::real const &a1z = pos1[ia].z;
|
||||||
|
deriv.calc_derivative_wrt_group2(ia, &dl0_2, &dq0_2, &ds_2);
|
||||||
|
// make an infitesimal move along each cartesian coordinate of
|
||||||
|
// this atom, and solve again the eigenvector problem
|
||||||
|
for (size_t comp = 0; comp < 3; comp++) {
|
||||||
|
std::memcpy(S_new, rot.S_backup, sizeof(cvm::real) * 4 * 4);
|
||||||
|
std::memset(S_new_eigval, 0, sizeof(cvm::real) * 4);
|
||||||
|
std::memset(S_new_eigvec, 0, sizeof(cvm::real) * 4 * 4);
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
for (size_t j = 0; j < 4; j++) {
|
||||||
|
S_new[i][j] +=
|
||||||
|
colvarmodule::debug_gradients_step_size * ds_2[i][j][comp];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef COLVARS_LAMMPS
|
||||||
|
ecalc->Diagonalize(S_new, S_new_eigval, S_new_eigvec);
|
||||||
|
#else
|
||||||
|
NR::diagonalize_matrix(S_new, S_new_eigval, S_new_eigvec);
|
||||||
|
#endif
|
||||||
|
cvm::real const &L0_new = S_new_eigval[0];
|
||||||
|
cvm::quaternion const Q0_new(S_new_eigvec[0]);
|
||||||
|
|
||||||
|
cvm::real const DL0 = (dl0_2[comp]) * colvarmodule::debug_gradients_step_size;
|
||||||
|
cvm::quaternion const DQ0(dq0_2[0][comp] * colvarmodule::debug_gradients_step_size,
|
||||||
|
dq0_2[1][comp] * colvarmodule::debug_gradients_step_size,
|
||||||
|
dq0_2[2][comp] * colvarmodule::debug_gradients_step_size,
|
||||||
|
dq0_2[3][comp] * colvarmodule::debug_gradients_step_size);
|
||||||
|
|
||||||
|
cvm::log( "|(l_0+dl_0) - l_0^new|/l_0 = "+
|
||||||
|
cvm::to_str(cvm::fabs(L0+DL0 - L0_new)/L0, cvm::cv_width, cvm::cv_prec)+
|
||||||
|
", |(q_0+dq_0) - q_0^new| = "+
|
||||||
|
cvm::to_str((Q0+DQ0 - Q0_new).norm(), cvm::cv_width, cvm::cv_prec)+
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // COLVAR_ROTATION_DERIVATIVE
|
||||||
@ -13,10 +13,12 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
|
#include "colvardeps.h"
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
#include "colvarparse.h"
|
#include "colvarparse.h"
|
||||||
#include "colvaratoms.h"
|
#include "colvaratoms.h"
|
||||||
|
#include "colvar_rotation_derivative.h"
|
||||||
|
|
||||||
|
|
||||||
cvm::atom::atom()
|
cvm::atom::atom()
|
||||||
@ -118,6 +120,11 @@ cvm::atom_group::~atom_group()
|
|||||||
fitting_group = NULL;
|
fitting_group = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rot_deriv != nullptr) {
|
||||||
|
delete rot_deriv;
|
||||||
|
rot_deriv = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
cvm::main()->unregister_named_atom_group(this);
|
cvm::main()->unregister_named_atom_group(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,6 +233,7 @@ int cvm::atom_group::init()
|
|||||||
b_dummy = false;
|
b_dummy = false;
|
||||||
b_user_defined_fit = false;
|
b_user_defined_fit = false;
|
||||||
fitting_group = NULL;
|
fitting_group = NULL;
|
||||||
|
rot_deriv = nullptr;
|
||||||
|
|
||||||
noforce = false;
|
noforce = false;
|
||||||
|
|
||||||
@ -278,7 +286,7 @@ int cvm::atom_group::init_dependencies() {
|
|||||||
// Initialize feature_states for each instance
|
// Initialize feature_states for each instance
|
||||||
// default as unavailable, not enabled
|
// default as unavailable, not enabled
|
||||||
feature_states.reserve(f_ag_ntot);
|
feature_states.reserve(f_ag_ntot);
|
||||||
for (i = 0; i < colvardeps::f_ag_ntot; i++) {
|
for (i = feature_states.size(); i < colvardeps::f_ag_ntot; i++) {
|
||||||
feature_states.push_back(feature_state(false, false));
|
feature_states.push_back(feature_state(false, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,6 +325,13 @@ int cvm::atom_group::setup()
|
|||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cvm::atom_group::setup_rotation_derivative() {
|
||||||
|
if (rot_deriv != nullptr) delete rot_deriv;
|
||||||
|
rot_deriv = new rotation_derivative<cvm::atom, cvm::atom_pos>(
|
||||||
|
rot, fitting_group ? fitting_group->atoms : this->atoms, ref_pos
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void cvm::atom_group::update_total_mass()
|
void cvm::atom_group::update_total_mass()
|
||||||
{
|
{
|
||||||
@ -383,7 +398,7 @@ int cvm::atom_group::parse(std::string const &group_conf)
|
|||||||
// }
|
// }
|
||||||
// colvarparse::Parse_Mode mode = parse_normal;
|
// colvarparse::Parse_Mode mode = parse_normal;
|
||||||
|
|
||||||
int parse_error = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
|
|
||||||
// Optional group name will let other groups reuse atom definition
|
// Optional group name will let other groups reuse atom definition
|
||||||
if (get_keyval(group_conf, "name", name)) {
|
if (get_keyval(group_conf, "name", name)) {
|
||||||
@ -433,7 +448,7 @@ int cvm::atom_group::parse(std::string const &group_conf)
|
|||||||
cvm::error("Error: cannot find atom group with name " + atoms_of + ".\n");
|
cvm::error("Error: cannot find atom group with name " + atoms_of + ".\n");
|
||||||
return COLVARS_ERROR;
|
return COLVARS_ERROR;
|
||||||
}
|
}
|
||||||
parse_error |= add_atoms_of_group(ag);
|
error_code |= add_atoms_of_group(ag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,7 +462,7 @@ int cvm::atom_group::parse(std::string const &group_conf)
|
|||||||
std::string numbers_conf = "";
|
std::string numbers_conf = "";
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
while (key_lookup(group_conf, "atomNumbers", &numbers_conf, &pos)) {
|
while (key_lookup(group_conf, "atomNumbers", &numbers_conf, &pos)) {
|
||||||
parse_error |= add_atom_numbers(numbers_conf);
|
error_code |= add_atom_numbers(numbers_conf);
|
||||||
numbers_conf = "";
|
numbers_conf = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,7 +471,7 @@ int cvm::atom_group::parse(std::string const &group_conf)
|
|||||||
std::string index_group_name;
|
std::string index_group_name;
|
||||||
if (get_keyval(group_conf, "indexGroup", index_group_name)) {
|
if (get_keyval(group_conf, "indexGroup", index_group_name)) {
|
||||||
// use an index group from the index file read globally
|
// use an index group from the index file read globally
|
||||||
parse_error |= add_index_group(index_group_name);
|
error_code |= add_index_group(index_group_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +480,7 @@ int cvm::atom_group::parse(std::string const &group_conf)
|
|||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
while (key_lookup(group_conf, "atomNumbersRange",
|
while (key_lookup(group_conf, "atomNumbersRange",
|
||||||
&range_conf, &pos)) {
|
&range_conf, &pos)) {
|
||||||
parse_error |= add_atom_numbers_range(range_conf);
|
error_code |= add_atom_numbers_range(range_conf);
|
||||||
range_conf = "";
|
range_conf = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -492,7 +507,7 @@ int cvm::atom_group::parse(std::string const &group_conf)
|
|||||||
cvm::error("Error: more instances of \"atomNameResidueRange\" than "
|
cvm::error("Error: more instances of \"atomNameResidueRange\" than "
|
||||||
"values of \"psfSegID\".\n", COLVARS_INPUT_ERROR);
|
"values of \"psfSegID\".\n", COLVARS_INPUT_ERROR);
|
||||||
} else {
|
} else {
|
||||||
parse_error |= add_atom_name_residue_range(psf_segids.size() ?
|
error_code |= add_atom_name_residue_range(psf_segids.size() ?
|
||||||
*psii : std::string(""), range_conf);
|
*psii : std::string(""), range_conf);
|
||||||
if (psf_segids.size()) psii++;
|
if (psf_segids.size()) psii++;
|
||||||
}
|
}
|
||||||
@ -517,26 +532,26 @@ int cvm::atom_group::parse(std::string const &group_conf)
|
|||||||
cvm::error("Error: atomsColValue, if provided, must be non-zero.\n", COLVARS_INPUT_ERROR);
|
cvm::error("Error: atomsColValue, if provided, must be non-zero.\n", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: calls to add_atom() and/or add_atom_id() are in the proxy-implemented function
|
error_code |= cvm::main()->proxy->load_atoms_pdb(atoms_file_name.c_str(), *this, atoms_col,
|
||||||
parse_error |= cvm::load_atoms(atoms_file_name.c_str(), *this, atoms_col, atoms_col_value);
|
atoms_col_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Catch any errors from all the initialization steps above
|
// Catch any errors from all the initialization steps above
|
||||||
if (parse_error || cvm::get_error()) return (parse_error || cvm::get_error());
|
if (error_code || cvm::get_error()) return (error_code || cvm::get_error());
|
||||||
|
|
||||||
// checks of doubly-counted atoms have been handled by add_atom() already
|
// checks of doubly-counted atoms have been handled by add_atom() already
|
||||||
|
|
||||||
if (get_keyval(group_conf, "dummyAtom", dummy_atom_pos, cvm::atom_pos())) {
|
if (get_keyval(group_conf, "dummyAtom", dummy_atom_pos, cvm::atom_pos())) {
|
||||||
|
|
||||||
parse_error |= set_dummy();
|
error_code |= set_dummy();
|
||||||
parse_error |= set_dummy_pos(dummy_atom_pos);
|
error_code |= set_dummy_pos(dummy_atom_pos);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (!(atoms_ids.size())) {
|
if (!(atoms_ids.size())) {
|
||||||
parse_error |= cvm::error("Error: no atoms defined for atom group \""+
|
error_code |= cvm::error("Error: no atoms defined for atom group \"" + key + "\".\n",
|
||||||
key+"\".\n", COLVARS_INPUT_ERROR);
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// whether these atoms will ever receive forces or not
|
// whether these atoms will ever receive forces or not
|
||||||
@ -546,7 +561,7 @@ int cvm::atom_group::parse(std::string const &group_conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now that atoms are defined we can parse the detailed fitting options
|
// Now that atoms are defined we can parse the detailed fitting options
|
||||||
parse_error |= parse_fitting_options(group_conf);
|
error_code |= parse_fitting_options(group_conf);
|
||||||
|
|
||||||
if (is_enabled(f_ag_scalable) && !b_dummy) {
|
if (is_enabled(f_ag_scalable) && !b_dummy) {
|
||||||
cvm::log("Enabling scalable calculation for group \""+this->key+"\".\n");
|
cvm::log("Enabling scalable calculation for group \""+this->key+"\".\n");
|
||||||
@ -583,7 +598,9 @@ int cvm::atom_group::parse(std::string const &group_conf)
|
|||||||
cvm::log(print_atom_ids());
|
cvm::log(print_atom_ids());
|
||||||
}
|
}
|
||||||
|
|
||||||
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
|
if (is_enabled(f_ag_rotate)) setup_rotation_derivative();
|
||||||
|
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -883,8 +900,6 @@ int cvm::atom_group::parse_fitting_options(std::string const &group_conf)
|
|||||||
"to its radius of gyration), the optimal rotation and its gradients may become discontinuous. "
|
"to its radius of gyration), the optimal rotation and its gradients may become discontinuous. "
|
||||||
"If that happens, use fittingGroup (or a different definition for it if already defined) "
|
"If that happens, use fittingGroup (or a different definition for it if already defined) "
|
||||||
"to align the coordinates.\n");
|
"to align the coordinates.\n");
|
||||||
// initialize rot member data
|
|
||||||
rot.request_group1_gradients(group_for_fit->size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -912,7 +927,6 @@ void cvm::atom_group::do_feature_side_effects(int id)
|
|||||||
if (is_enabled(f_ag_center) || is_enabled(f_ag_rotate)) {
|
if (is_enabled(f_ag_center) || is_enabled(f_ag_rotate)) {
|
||||||
atom_group *group_for_fit = fitting_group ? fitting_group : this;
|
atom_group *group_for_fit = fitting_group ? fitting_group : this;
|
||||||
group_for_fit->fit_gradients.assign(group_for_fit->size(), cvm::atom_pos(0.0, 0.0, 0.0));
|
group_for_fit->fit_gradients.assign(group_for_fit->size(), cvm::atom_pos(0.0, 0.0, 0.0));
|
||||||
rot.request_group1_gradients(group_for_fit->size());
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1045,17 +1059,18 @@ void cvm::atom_group::calc_apply_roto_translation()
|
|||||||
// rotate the group (around the center of geometry if f_ag_center is
|
// rotate the group (around the center of geometry if f_ag_center is
|
||||||
// enabled, around the origin otherwise)
|
// enabled, around the origin otherwise)
|
||||||
rot.calc_optimal_rotation(fitting_group ?
|
rot.calc_optimal_rotation(fitting_group ?
|
||||||
fitting_group->positions() :
|
fitting_group->atoms:
|
||||||
this->positions(),
|
this->atoms,
|
||||||
ref_pos);
|
ref_pos);
|
||||||
|
const auto rot_mat = rot.matrix();
|
||||||
|
|
||||||
cvm::atom_iter ai;
|
cvm::atom_iter ai;
|
||||||
for (ai = this->begin(); ai != this->end(); ai++) {
|
for (ai = this->begin(); ai != this->end(); ai++) {
|
||||||
ai->pos = rot.rotate(ai->pos);
|
ai->pos = rot_mat * ai->pos;
|
||||||
}
|
}
|
||||||
if (fitting_group) {
|
if (fitting_group) {
|
||||||
for (ai = fitting_group->begin(); ai != fitting_group->end(); ai++) {
|
for (ai = fitting_group->begin(); ai != fitting_group->end(); ai++) {
|
||||||
ai->pos = rot.rotate(ai->pos);
|
ai->pos = rot_mat * ai->pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1095,9 +1110,10 @@ void cvm::atom_group::read_velocities()
|
|||||||
|
|
||||||
if (is_enabled(f_ag_rotate)) {
|
if (is_enabled(f_ag_rotate)) {
|
||||||
|
|
||||||
|
const auto rot_mat = rot.matrix();
|
||||||
for (cvm::atom_iter ai = this->begin(); ai != this->end(); ai++) {
|
for (cvm::atom_iter ai = this->begin(); ai != this->end(); ai++) {
|
||||||
ai->read_velocity();
|
ai->read_velocity();
|
||||||
ai->vel = rot.rotate(ai->vel);
|
ai->vel = rot_mat * ai->vel;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -1116,9 +1132,10 @@ void cvm::atom_group::read_total_forces()
|
|||||||
|
|
||||||
if (is_enabled(f_ag_rotate)) {
|
if (is_enabled(f_ag_rotate)) {
|
||||||
|
|
||||||
|
const auto rot_mat = rot.matrix();
|
||||||
for (cvm::atom_iter ai = this->begin(); ai != this->end(); ai++) {
|
for (cvm::atom_iter ai = this->begin(); ai != this->end(); ai++) {
|
||||||
ai->read_total_force();
|
ai->read_total_force();
|
||||||
ai->total_force = rot.rotate(ai->total_force);
|
ai->total_force = rot_mat * ai->total_force;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -1200,52 +1217,71 @@ void cvm::atom_group::calc_fit_gradients()
|
|||||||
if (cvm::debug())
|
if (cvm::debug())
|
||||||
cvm::log("Calculating fit gradients.\n");
|
cvm::log("Calculating fit gradients.\n");
|
||||||
|
|
||||||
cvm::atom_group *group_for_fit = fitting_group ? fitting_group : this;
|
if (is_enabled(f_ag_center) && is_enabled(f_ag_rotate))
|
||||||
|
calc_fit_gradients_impl<true, true>();
|
||||||
if (is_enabled(f_ag_center)) {
|
if (is_enabled(f_ag_center) && !is_enabled(f_ag_rotate))
|
||||||
// add the center of geometry contribution to the gradients
|
calc_fit_gradients_impl<true, false>();
|
||||||
cvm::rvector atom_grad;
|
if (!is_enabled(f_ag_center) && is_enabled(f_ag_rotate))
|
||||||
|
calc_fit_gradients_impl<false, true>();
|
||||||
for (size_t i = 0; i < this->size(); i++) {
|
if (!is_enabled(f_ag_center) && !is_enabled(f_ag_rotate))
|
||||||
atom_grad += atoms[i].grad;
|
calc_fit_gradients_impl<false, false>();
|
||||||
}
|
|
||||||
if (is_enabled(f_ag_rotate)) atom_grad = (rot.inverse()).rotate(atom_grad);
|
|
||||||
atom_grad *= (-1.0)/(cvm::real(group_for_fit->size()));
|
|
||||||
|
|
||||||
for (size_t j = 0; j < group_for_fit->size(); j++) {
|
|
||||||
group_for_fit->fit_gradients[j] = atom_grad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_enabled(f_ag_rotate)) {
|
|
||||||
|
|
||||||
// add the rotation matrix contribution to the gradients
|
|
||||||
cvm::rotation const rot_inv = rot.inverse();
|
|
||||||
|
|
||||||
for (size_t i = 0; i < this->size(); i++) {
|
|
||||||
|
|
||||||
// compute centered, unrotated position
|
|
||||||
cvm::atom_pos const pos_orig =
|
|
||||||
rot_inv.rotate((is_enabled(f_ag_center) ? (atoms[i].pos - ref_pos_cog) : (atoms[i].pos)));
|
|
||||||
|
|
||||||
// calculate \partial(R(q) \vec{x}_i)/\partial q) \cdot \partial\xi/\partial\vec{x}_i
|
|
||||||
cvm::quaternion const dxdq =
|
|
||||||
rot.q.position_derivative_inner(pos_orig, atoms[i].grad);
|
|
||||||
|
|
||||||
for (size_t j = 0; j < group_for_fit->size(); j++) {
|
|
||||||
// multiply by {\partial q}/\partial\vec{x}_j and add it to the fit gradients
|
|
||||||
for (size_t iq = 0; iq < 4; iq++) {
|
|
||||||
group_for_fit->fit_gradients[j] += dxdq[iq] * rot.dQ0_1[j][iq];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cvm::debug())
|
if (cvm::debug())
|
||||||
cvm::log("Done calculating fit gradients.\n");
|
cvm::log("Done calculating fit gradients.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <bool B_ag_center, bool B_ag_rotate>
|
||||||
|
void cvm::atom_group::calc_fit_gradients_impl() {
|
||||||
|
cvm::atom_group *group_for_fit = fitting_group ? fitting_group : this;
|
||||||
|
// the center of geometry contribution to the gradients
|
||||||
|
cvm::rvector atom_grad;
|
||||||
|
// the rotation matrix contribution to the gradients
|
||||||
|
const auto rot_inv = rot.inverse().matrix();
|
||||||
|
// temporary variables for computing and summing derivatives
|
||||||
|
cvm::real sum_dxdq[4] = {0, 0, 0, 0};
|
||||||
|
cvm::vector1d<cvm::rvector> dq0_1(4);
|
||||||
|
// loop 1: iterate over the current atom group
|
||||||
|
for (size_t i = 0; i < size(); i++) {
|
||||||
|
cvm::atom_pos pos_orig;
|
||||||
|
if (B_ag_center) {
|
||||||
|
atom_grad += atoms[i].grad;
|
||||||
|
if (B_ag_rotate) pos_orig = rot_inv * (atoms[i].pos - ref_pos_cog);
|
||||||
|
} else {
|
||||||
|
if (B_ag_rotate) pos_orig = atoms[i].pos;
|
||||||
|
}
|
||||||
|
if (B_ag_rotate) {
|
||||||
|
// calculate \partial(R(q) \vec{x}_i)/\partial q) \cdot \partial\xi/\partial\vec{x}_i
|
||||||
|
cvm::quaternion const dxdq =
|
||||||
|
rot.q.position_derivative_inner(pos_orig, atoms[i].grad);
|
||||||
|
sum_dxdq[0] += dxdq[0];
|
||||||
|
sum_dxdq[1] += dxdq[1];
|
||||||
|
sum_dxdq[2] += dxdq[2];
|
||||||
|
sum_dxdq[3] += dxdq[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (B_ag_center) {
|
||||||
|
if (B_ag_rotate) atom_grad = rot.inverse().matrix() * atom_grad;
|
||||||
|
atom_grad *= (-1.0)/(cvm::real(group_for_fit->size()));
|
||||||
|
}
|
||||||
|
// loop 2: iterate over the fitting group
|
||||||
|
if (B_ag_rotate) rot_deriv->prepare_derivative(rotation_derivative_dldq::use_dq);
|
||||||
|
for (size_t j = 0; j < group_for_fit->size(); j++) {
|
||||||
|
if (B_ag_center) {
|
||||||
|
group_for_fit->fit_gradients[j] = atom_grad;
|
||||||
|
}
|
||||||
|
if (B_ag_rotate) {
|
||||||
|
rot_deriv->calc_derivative_wrt_group1(j, nullptr, &dq0_1);
|
||||||
|
// multiply by {\partial q}/\partial\vec{x}_j and add it to the fit gradients
|
||||||
|
group_for_fit->fit_gradients[j] += sum_dxdq[0] * dq0_1[0] +
|
||||||
|
sum_dxdq[1] * dq0_1[1] +
|
||||||
|
sum_dxdq[2] * dq0_1[2] +
|
||||||
|
sum_dxdq[3] * dq0_1[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<cvm::atom_pos> cvm::atom_group::positions() const
|
std::vector<cvm::atom_pos> cvm::atom_group::positions() const
|
||||||
{
|
{
|
||||||
if (b_dummy) {
|
if (b_dummy) {
|
||||||
@ -1373,9 +1409,9 @@ void cvm::atom_group::apply_colvar_force(cvm::real const &force)
|
|||||||
if (is_enabled(f_ag_rotate)) {
|
if (is_enabled(f_ag_rotate)) {
|
||||||
|
|
||||||
// rotate forces back to the original frame
|
// rotate forces back to the original frame
|
||||||
cvm::rotation const rot_inv = rot.inverse();
|
const auto rot_inv = rot.inverse().matrix();
|
||||||
for (cvm::atom_iter ai = this->begin(); ai != this->end(); ai++) {
|
for (cvm::atom_iter ai = this->begin(); ai != this->end(); ai++) {
|
||||||
ai->apply_force(rot_inv.rotate(force * ai->grad));
|
ai->apply_force(rot_inv * (force * ai->grad));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -1418,9 +1454,9 @@ void cvm::atom_group::apply_force(cvm::rvector const &force)
|
|||||||
|
|
||||||
if (is_enabled(f_ag_rotate)) {
|
if (is_enabled(f_ag_rotate)) {
|
||||||
|
|
||||||
cvm::rotation const rot_inv = rot.inverse();
|
const auto rot_inv = rot.inverse().matrix();
|
||||||
for (cvm::atom_iter ai = this->begin(); ai != this->end(); ai++) {
|
for (cvm::atom_iter ai = this->begin(); ai != this->end(); ai++) {
|
||||||
ai->apply_force(rot_inv.rotate((ai->mass/total_mass) * force));
|
ai->apply_force(rot_inv * ((ai->mass/total_mass) * force));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -15,6 +15,9 @@
|
|||||||
#include "colvarparse.h"
|
#include "colvarparse.h"
|
||||||
#include "colvardeps.h"
|
#include "colvardeps.h"
|
||||||
|
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
struct rotation_derivative;
|
||||||
|
|
||||||
|
|
||||||
/// \brief Stores numeric id, mass and all mutable data for an atom,
|
/// \brief Stores numeric id, mass and all mutable data for an atom,
|
||||||
/// mostly used by a \link colvar::cvc \endlink
|
/// mostly used by a \link colvar::cvc \endlink
|
||||||
@ -167,7 +170,7 @@ public:
|
|||||||
atom_group(std::vector<cvm::atom> const &atoms_in);
|
atom_group(std::vector<cvm::atom> const &atoms_in);
|
||||||
|
|
||||||
/// \brief Destructor
|
/// \brief Destructor
|
||||||
~atom_group();
|
~atom_group() override;
|
||||||
|
|
||||||
/// \brief Optional name to reuse properties of this in other groups
|
/// \brief Optional name to reuse properties of this in other groups
|
||||||
std::string name;
|
std::string name;
|
||||||
@ -180,7 +183,7 @@ public:
|
|||||||
int init();
|
int init();
|
||||||
|
|
||||||
/// \brief Initialize dependency tree
|
/// \brief Initialize dependency tree
|
||||||
virtual int init_dependencies();
|
int init_dependencies() override;
|
||||||
|
|
||||||
/// \brief Update data required to calculate cvc's
|
/// \brief Update data required to calculate cvc's
|
||||||
int setup();
|
int setup();
|
||||||
@ -221,16 +224,13 @@ public:
|
|||||||
static std::vector<feature *> ag_features;
|
static std::vector<feature *> ag_features;
|
||||||
|
|
||||||
/// \brief Implementation of the feature list accessor for atom group
|
/// \brief Implementation of the feature list accessor for atom group
|
||||||
virtual const std::vector<feature *> &features() const
|
const std::vector<feature *> &features() const override { return ag_features; }
|
||||||
|
|
||||||
|
std::vector<feature *> &modify_features() override { return ag_features; }
|
||||||
|
|
||||||
|
static void delete_features()
|
||||||
{
|
{
|
||||||
return ag_features;
|
for (size_t i = 0; i < ag_features.size(); i++) {
|
||||||
}
|
|
||||||
virtual std::vector<feature *> &modify_features()
|
|
||||||
{
|
|
||||||
return ag_features;
|
|
||||||
}
|
|
||||||
static void delete_features() {
|
|
||||||
for (size_t i=0; i < ag_features.size(); i++) {
|
|
||||||
delete ag_features[i];
|
delete ag_features[i];
|
||||||
}
|
}
|
||||||
ag_features.clear();
|
ag_features.clear();
|
||||||
@ -330,6 +330,9 @@ public:
|
|||||||
/// The rotation calculated automatically if f_ag_rotate is defined
|
/// The rotation calculated automatically if f_ag_rotate is defined
|
||||||
cvm::rotation rot;
|
cvm::rotation rot;
|
||||||
|
|
||||||
|
/// Rotation derivative;
|
||||||
|
rotation_derivative<cvm::atom, cvm::atom_pos>* rot_deriv;
|
||||||
|
|
||||||
/// \brief Indicates that the user has explicitly set centerToReference or
|
/// \brief Indicates that the user has explicitly set centerToReference or
|
||||||
/// rotateReference, and the corresponding reference:
|
/// rotateReference, and the corresponding reference:
|
||||||
/// cvc's (eg rmsd, eigenvector) will not override the user's choice
|
/// cvc's (eg rmsd, eigenvector) will not override the user's choice
|
||||||
@ -369,6 +372,8 @@ public:
|
|||||||
/// \brief (Re)calculate the optimal roto-translation
|
/// \brief (Re)calculate the optimal roto-translation
|
||||||
void calc_apply_roto_translation();
|
void calc_apply_roto_translation();
|
||||||
|
|
||||||
|
void setup_rotation_derivative();
|
||||||
|
|
||||||
/// \brief Save aside the center of geometry of the reference positions,
|
/// \brief Save aside the center of geometry of the reference positions,
|
||||||
/// then subtract it from them
|
/// then subtract it from them
|
||||||
///
|
///
|
||||||
@ -492,6 +497,16 @@ public:
|
|||||||
/// \brief Calculate the derivatives of the fitting transformation
|
/// \brief Calculate the derivatives of the fitting transformation
|
||||||
void calc_fit_gradients();
|
void calc_fit_gradients();
|
||||||
|
|
||||||
|
/*! @brief Actual implementation of `calc_fit_gradients`. The template is
|
||||||
|
* used to avoid branching inside the loops in case that the CPU
|
||||||
|
* branch prediction is broken (or further migration to GPU code).
|
||||||
|
* @tparam B_ag_center Centered the reference to origin? This should follow
|
||||||
|
* the value of `is_enabled(f_ag_center)`.
|
||||||
|
* @tparam B_ag_rotate Calculate the optimal rotation? This should follow
|
||||||
|
* the value of `is_enabled(f_ag_rotate)`.
|
||||||
|
*/
|
||||||
|
template <bool B_ag_center, bool B_ag_rotate> void calc_fit_gradients_impl();
|
||||||
|
|
||||||
/// \brief Derivatives of the fitting transformation
|
/// \brief Derivatives of the fitting transformation
|
||||||
std::vector<cvm::atom_pos> fit_gradients;
|
std::vector<cvm::atom_pos> fit_gradients;
|
||||||
|
|
||||||
@ -525,7 +540,7 @@ public:
|
|||||||
/// Implements possible actions to be carried out
|
/// Implements possible actions to be carried out
|
||||||
/// when a given feature is enabled
|
/// when a given feature is enabled
|
||||||
/// This overloads the base function in colvardeps
|
/// This overloads the base function in colvardeps
|
||||||
void do_feature_side_effects(int id);
|
void do_feature_side_effects(int id) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvarbias.h"
|
#include "colvarbias.h"
|
||||||
#include "colvargrid.h"
|
#include "colvargrid.h"
|
||||||
|
#include "colvars_memstream.h"
|
||||||
|
|
||||||
|
|
||||||
colvarbias::colvarbias(char const *key)
|
colvarbias::colvarbias(char const *key)
|
||||||
@ -166,6 +167,10 @@ int colvarbias::init_dependencies() {
|
|||||||
|
|
||||||
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);
|
||||||
|
// Depending on back-end, we may not obtain total force at step 0
|
||||||
|
if (!cvm::main()->proxy->total_forces_same_step()) {
|
||||||
|
exclude_feature_self(f_cvb_get_total_force, f_cvb_step_zero_data);
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -192,6 +197,8 @@ int colvarbias::init_dependencies() {
|
|||||||
init_feature(f_cvb_scale_biasing_force, "scale_biasing_force", f_type_user);
|
init_feature(f_cvb_scale_biasing_force, "scale_biasing_force", f_type_user);
|
||||||
require_feature_children(f_cvb_scale_biasing_force, f_cv_grid);
|
require_feature_children(f_cvb_scale_biasing_force, f_cv_grid);
|
||||||
|
|
||||||
|
init_feature(f_cvb_extended, "Bias on extended-Lagrangian variables", f_type_static);
|
||||||
|
|
||||||
// check that everything is initialized
|
// check that everything is initialized
|
||||||
for (i = 0; i < colvardeps::f_cvb_ntot; i++) {
|
for (i = 0; i < colvardeps::f_cvb_ntot; i++) {
|
||||||
if (is_not_set(i)) {
|
if (is_not_set(i)) {
|
||||||
@ -202,7 +209,7 @@ int colvarbias::init_dependencies() {
|
|||||||
|
|
||||||
// Initialize feature_states for each instance
|
// Initialize feature_states for each instance
|
||||||
feature_states.reserve(f_cvb_ntot);
|
feature_states.reserve(f_cvb_ntot);
|
||||||
for (i = 0; i < f_cvb_ntot; i++) {
|
for (i = feature_states.size(); i < f_cvb_ntot; i++) {
|
||||||
feature_states.push_back(feature_state(true, false));
|
feature_states.push_back(feature_state(true, false));
|
||||||
// Most features are available, so we set them so
|
// Most features are available, so we set them so
|
||||||
// and list exceptions below
|
// and list exceptions below
|
||||||
@ -436,43 +443,55 @@ int colvarbias::bin_num()
|
|||||||
cvm::error("Error: bin_num() not implemented.\n");
|
cvm::error("Error: bin_num() not implemented.\n");
|
||||||
return COLVARS_NOT_IMPLEMENTED;
|
return COLVARS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int colvarbias::current_bin()
|
int colvarbias::current_bin()
|
||||||
{
|
{
|
||||||
cvm::error("Error: current_bin() not implemented.\n");
|
cvm::error("Error: current_bin() not implemented.\n");
|
||||||
return COLVARS_NOT_IMPLEMENTED;
|
return COLVARS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int colvarbias::bin_count(int /* bin_index */)
|
int colvarbias::bin_count(int /* bin_index */)
|
||||||
{
|
{
|
||||||
cvm::error("Error: bin_count() not implemented.\n");
|
cvm::error("Error: bin_count() not implemented.\n");
|
||||||
return COLVARS_NOT_IMPLEMENTED;
|
return COLVARS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int colvarbias::local_sample_count(int /* radius */)
|
||||||
|
{
|
||||||
|
cvm::error("Error: local_sample_count() not implemented.\n");
|
||||||
|
return COLVARS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
int colvarbias::replica_share()
|
int colvarbias::replica_share()
|
||||||
{
|
{
|
||||||
cvm::error("Error: replica_share() not implemented.\n");
|
cvm::error("Error: replica_share() not implemented.\n");
|
||||||
return COLVARS_NOT_IMPLEMENTED;
|
return COLVARS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t colvarbias::replica_share_freq() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string const colvarbias::get_state_params() const
|
std::string const colvarbias::get_state_params() const
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << "step " << cvm::step_absolute() << "\n"
|
os << " step " << cvm::step_absolute() << "\n"
|
||||||
<< "name " << this->name << "\n";
|
<< " name " << this->name << "\n";
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarbias::set_state_params(std::string const &conf)
|
int colvarbias::check_matching_state(std::string const &conf)
|
||||||
{
|
{
|
||||||
matching_state = false;
|
|
||||||
|
|
||||||
std::string check_name = "";
|
std::string check_name = "";
|
||||||
colvarparse::get_keyval(conf, "name", check_name,
|
colvarparse::get_keyval(conf, "name", check_name,
|
||||||
std::string(""), colvarparse::parse_silent);
|
std::string(""), colvarparse::parse_silent);
|
||||||
|
|
||||||
if (check_name.size() == 0) {
|
if (check_name.size() == 0) {
|
||||||
cvm::error("Error: \""+bias_type+"\" block within the restart file "
|
return cvm::error("Error: \""+bias_type+"\" block within the state file "
|
||||||
"has no identifiers.\n", COLVARS_INPUT_ERROR);
|
"has no identifiers.\n", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_name != this->name) {
|
if (check_name != this->name) {
|
||||||
@ -480,11 +499,17 @@ int colvarbias::set_state_params(std::string const &conf)
|
|||||||
cvm::log("Ignoring state of bias \""+check_name+
|
cvm::log("Ignoring state of bias \""+check_name+
|
||||||
"\": this bias is named \""+name+"\".\n");
|
"\": this bias is named \""+name+"\".\n");
|
||||||
}
|
}
|
||||||
return COLVARS_OK;
|
matching_state = false;
|
||||||
|
} else {
|
||||||
|
matching_state = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
matching_state = true;
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarbias::set_state_params(std::string const &conf)
|
||||||
|
{
|
||||||
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);
|
||||||
|
|
||||||
@ -495,76 +520,119 @@ int colvarbias::set_state_params(std::string const &conf)
|
|||||||
std::ostream & colvarbias::write_state(std::ostream &os)
|
std::ostream & colvarbias::write_state(std::ostream &os)
|
||||||
{
|
{
|
||||||
if (cvm::debug()) {
|
if (cvm::debug()) {
|
||||||
cvm::log("Writing state file for bias \""+name+"\"\n");
|
cvm::log("Writing formatted state for bias \""+name+"\"\n");
|
||||||
}
|
}
|
||||||
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 << state_keyword << " {\n"
|
os << state_keyword << " {\n"
|
||||||
<< " configuration {\n";
|
<< " configuration {\n"
|
||||||
std::istringstream is(get_state_params());
|
<< get_state_params()
|
||||||
std::string line;
|
<< " }\n";
|
||||||
while (std::getline(is, line)) {
|
|
||||||
os << " " << line << "\n";
|
|
||||||
}
|
|
||||||
os << " }\n";
|
|
||||||
write_state_data(os);
|
write_state_data(os);
|
||||||
os << "}\n\n";
|
os << "}\n\n";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::istream & colvarbias::read_state(std::istream &is)
|
cvm::memory_stream & colvarbias::write_state(cvm::memory_stream &os)
|
||||||
{
|
{
|
||||||
std::streampos const start_pos = is.tellg();
|
if (cvm::debug()) {
|
||||||
|
cvm::log("Writing unformatted state for bias \""+name+"\"\n");
|
||||||
|
}
|
||||||
|
os << state_keyword << std::string("configuration") << get_state_params();
|
||||||
|
write_state_data(os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename IST, typename SPT>
|
||||||
|
void raise_error_rewind(IST &is, SPT start_pos, std::string const &bias_type,
|
||||||
|
std::string const &bias_name, std::string const added_msg = "")
|
||||||
|
{
|
||||||
|
auto state = is.rdstate();
|
||||||
|
is.clear();
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(state | std::ios::failbit);
|
||||||
|
cvm::error("Error: in reading state for \"" + bias_type + "\" bias \"" + bias_name +
|
||||||
|
"\" at position " + cvm::to_str(static_cast<size_t>(is.tellg())) + " in stream." +
|
||||||
|
added_msg + "\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename IST> IST & colvarbias::read_state_template_(IST &is)
|
||||||
|
{
|
||||||
|
auto 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) {
|
||||||
!(is >> brace) || !(brace == "{") ||
|
if (key == state_keyword || key == bias_type) {
|
||||||
!(is >> colvarparse::read_block("configuration", &conf)) ||
|
|
||||||
(set_state_params(conf) != COLVARS_OK) ) {
|
if (! std::is_same<IST, cvm::memory_stream>::value) {
|
||||||
cvm::error("Error: in reading state configuration for \""+bias_type+
|
// Formatted input only
|
||||||
"\" bias \""+
|
if (!(is >> brace) || !(brace == "{") ) {
|
||||||
this->name+"\" at position "+
|
raise_error_rewind(is, start_pos, bias_type, name);
|
||||||
cvm::to_str(static_cast<size_t>(is.tellg()))+
|
return is;
|
||||||
" in stream.\n", COLVARS_INPUT_ERROR);
|
}
|
||||||
is.clear();
|
}
|
||||||
is.seekg(start_pos, std::ios::beg);
|
|
||||||
is.setstate(std::ios::failbit);
|
if (!(is >> colvarparse::read_block("configuration", &conf)) ||
|
||||||
|
(check_matching_state(conf) != COLVARS_OK)) {
|
||||||
|
raise_error_rewind(is, start_pos, bias_type, name);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Not a match for this bias type, rewind without error
|
||||||
|
is.seekg(start_pos);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
raise_error_rewind(is, start_pos, bias_type, name);
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matching_state == false) {
|
if (!matching_state) {
|
||||||
// This state is not for this bias
|
// No errors, but not a match for this bias instance; rewind
|
||||||
is.seekg(start_pos, std::ios::beg);
|
is.seekg(start_pos);
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
cvm::log("Restarting "+bias_type+" bias \""+name+"\" from step number "+
|
if ((set_state_params(conf) != COLVARS_OK) || !read_state_data(is)) {
|
||||||
cvm::to_str(state_file_step)+".\n");
|
raise_error_rewind(is, start_pos, bias_type, name);
|
||||||
|
|
||||||
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", COLVARS_INPUT_ERROR);
|
|
||||||
is.clear();
|
|
||||||
is.seekg(start_pos, std::ios::beg);
|
|
||||||
is.setstate(std::ios::failbit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is >> brace;
|
if (! std::is_same<IST, cvm::memory_stream>::value) {
|
||||||
if (brace != "}") {
|
is >> brace;
|
||||||
cvm::error("Error: corrupt restart information for \""+bias_type+"\" bias \""+
|
if (brace != "}") {
|
||||||
this->name+"\": no matching brace at position "+
|
cvm::error("Error: corrupt restart information for \""+bias_type+"\" bias \""+
|
||||||
cvm::to_str(static_cast<size_t>(is.tellg()))+
|
this->name+"\": no matching brace at position "+
|
||||||
" in stream.\n");
|
cvm::to_str(static_cast<size_t>(is.tellg()))+
|
||||||
is.setstate(std::ios::failbit);
|
" in stream.\n");
|
||||||
|
raise_error_rewind(is, start_pos, bias_type, name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cvm::log("Restarted " + bias_type + " bias \"" + name + "\" with step number " +
|
||||||
|
cvm::to_str(state_file_step) + ".\n");
|
||||||
|
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::istream &colvarbias::read_state(std::istream &is)
|
||||||
|
{
|
||||||
|
return read_state_template_<std::istream>(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream &colvarbias::read_state(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
return read_state_template_<cvm::memory_stream>(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarbias::write_state_prefix(std::string const &prefix)
|
int colvarbias::write_state_prefix(std::string const &prefix)
|
||||||
{
|
{
|
||||||
std::string const filename =
|
std::string const filename =
|
||||||
@ -635,25 +703,51 @@ int colvarbias::read_state_string(char const *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::istream & colvarbias::read_state_data_key(std::istream &is, char const *key)
|
std::ostream &colvarbias::write_state_data_key(std::ostream &os, std::string const &key,
|
||||||
|
bool header)
|
||||||
{
|
{
|
||||||
std::streampos const start_pos = is.tellg();
|
os << (header ? "\n" : "") << key << (header ? "\n" : " ");
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream &colvarbias::write_state_data_key(cvm::memory_stream &os, std::string const &key,
|
||||||
|
bool /* header */)
|
||||||
|
{
|
||||||
|
os << std::string(key);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename IST>
|
||||||
|
IST &colvarbias::read_state_data_key_template_(IST &is, std::string const &key)
|
||||||
|
{
|
||||||
|
auto const start_pos = is.tellg();
|
||||||
std::string key_in;
|
std::string key_in;
|
||||||
if ( !(is >> key_in) ||
|
if (is >> key_in) {
|
||||||
!(to_lower_cppstr(key_in) == to_lower_cppstr(std::string(key))) ) {
|
if (key_in != key) {
|
||||||
cvm::error("Error: in reading restart configuration for "+
|
raise_error_rewind(is, start_pos, bias_type, name,
|
||||||
bias_type+" bias \""+this->name+"\" at position "+
|
" Expected keyword \"" + std::string(key) + "\", found \"" + key_in +
|
||||||
cvm::to_str(static_cast<size_t>(is.tellg()))+
|
"\".");
|
||||||
" in stream.\n", COLVARS_INPUT_ERROR);
|
}
|
||||||
is.clear();
|
} else {
|
||||||
is.seekg(start_pos, std::ios::beg);
|
raise_error_rewind(is, start_pos, bias_type, name);
|
||||||
is.setstate(std::ios::failbit);
|
|
||||||
return is;
|
|
||||||
}
|
}
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::istream & colvarbias::read_state_data_key(std::istream &is, std::string const &key)
|
||||||
|
{
|
||||||
|
return read_state_data_key_template_<std::istream>(is, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream & colvarbias::read_state_data_key(cvm::memory_stream &is, std::string const &key)
|
||||||
|
{
|
||||||
|
return read_state_data_key_template_<cvm::memory_stream>(is, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::ostream & colvarbias::write_traj_label(std::ostream &os)
|
std::ostream & colvarbias::write_traj_label(std::ostream &os)
|
||||||
{
|
{
|
||||||
@ -686,28 +780,11 @@ colvarbias_ti::colvarbias_ti(char const *key)
|
|||||||
// Samples at step zero can not be collected
|
// Samples at step zero can not be collected
|
||||||
feature_states[f_cvb_step_zero_data].available = false;
|
feature_states[f_cvb_step_zero_data].available = false;
|
||||||
}
|
}
|
||||||
ti_avg_forces = NULL;
|
|
||||||
ti_count = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvarbias_ti::~colvarbias_ti()
|
colvarbias_ti::~colvarbias_ti()
|
||||||
{
|
{
|
||||||
colvarbias_ti::clear_state_data();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int colvarbias_ti::clear_state_data()
|
|
||||||
{
|
|
||||||
if (ti_avg_forces != NULL) {
|
|
||||||
delete ti_avg_forces;
|
|
||||||
ti_avg_forces = NULL;
|
|
||||||
}
|
|
||||||
if (ti_count != NULL) {
|
|
||||||
delete ti_count;
|
|
||||||
ti_count = NULL;
|
|
||||||
}
|
|
||||||
return COLVARS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -765,7 +842,7 @@ int colvarbias_ti::init(std::string const &conf)
|
|||||||
int colvarbias_ti::init_grids()
|
int colvarbias_ti::init_grids()
|
||||||
{
|
{
|
||||||
if (is_enabled(f_cvb_calc_ti_samples)) {
|
if (is_enabled(f_cvb_calc_ti_samples)) {
|
||||||
if (ti_avg_forces == NULL) {
|
if (!ti_avg_forces) {
|
||||||
ti_bin.resize(num_variables());
|
ti_bin.resize(num_variables());
|
||||||
ti_system_forces.resize(num_variables());
|
ti_system_forces.resize(num_variables());
|
||||||
for (size_t icv = 0; icv < num_variables(); icv++) {
|
for (size_t icv = 0; icv < num_variables(); icv++) {
|
||||||
@ -773,8 +850,8 @@ int colvarbias_ti::init_grids()
|
|||||||
ti_system_forces[icv].is_derivative();
|
ti_system_forces[icv].is_derivative();
|
||||||
ti_system_forces[icv].reset();
|
ti_system_forces[icv].reset();
|
||||||
}
|
}
|
||||||
ti_avg_forces = new colvar_grid_gradient(colvars);
|
ti_avg_forces.reset(new colvar_grid_gradient(colvars));
|
||||||
ti_count = new colvar_grid_count(colvars);
|
ti_count.reset(new colvar_grid_count(colvars));
|
||||||
ti_avg_forces->samples = ti_count;
|
ti_avg_forces->samples = ti_count;
|
||||||
ti_count->has_parent_data = true;
|
ti_count->has_parent_data = true;
|
||||||
}
|
}
|
||||||
@ -860,9 +937,22 @@ std::ostream & colvarbias_ti::write_state_data(std::ostream &os)
|
|||||||
if (! is_enabled(f_cvb_calc_ti_samples)) {
|
if (! is_enabled(f_cvb_calc_ti_samples)) {
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
os << "\nhistogram\n";
|
write_state_data_key(os, "histogram");
|
||||||
ti_count->write_raw(os);
|
ti_count->write_raw(os);
|
||||||
os << "\nsystem_forces\n";
|
write_state_data_key(os, "system_forces");
|
||||||
|
ti_avg_forces->write_raw(os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream & colvarbias_ti::write_state_data(cvm::memory_stream &os)
|
||||||
|
{
|
||||||
|
if (! is_enabled(f_cvb_calc_ti_samples)) {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
write_state_data_key(os, "histogram");
|
||||||
|
ti_count->write_raw(os);
|
||||||
|
write_state_data_key(os, "system_forces");
|
||||||
ti_avg_forces->write_raw(os);
|
ti_avg_forces->write_raw(os);
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
@ -895,6 +985,33 @@ std::istream & colvarbias_ti::read_state_data(std::istream &is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream & colvarbias_ti::read_state_data(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
if (! is_enabled(f_cvb_calc_ti_samples)) {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
if (cvm::debug()) {
|
||||||
|
cvm::log("Reading state data for the TI estimator.\n");
|
||||||
|
}
|
||||||
|
if (! read_state_data_key(is, "histogram")) {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
if (! ti_count->read_raw(is)) {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
if (! read_state_data_key(is, "system_forces")) {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
if (! ti_avg_forces->read_raw(is)) {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
if (cvm::debug()) {
|
||||||
|
cvm::log("Done reading state data for the TI estimator.\n");
|
||||||
|
}
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarbias_ti::write_output_files()
|
int colvarbias_ti::write_output_files()
|
||||||
{
|
{
|
||||||
int error_code = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
#ifndef COLVARBIAS_H
|
#ifndef COLVARBIAS_H
|
||||||
#define COLVARBIAS_H
|
#define COLVARBIAS_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvarparse.h"
|
#include "colvarparse.h"
|
||||||
#include "colvardeps.h"
|
#include "colvardeps.h"
|
||||||
@ -91,11 +93,16 @@ public:
|
|||||||
// FIXME this is currently 1D only
|
// FIXME this is currently 1D only
|
||||||
virtual int current_bin();
|
virtual int current_bin();
|
||||||
//// Give the count at a given bin index.
|
//// Give the count at a given bin index.
|
||||||
// FIXME this is currently 1D only
|
|
||||||
virtual int bin_count(int bin_index);
|
virtual int bin_count(int bin_index);
|
||||||
|
/// Return the average number of samples in a given "radius" around current bin
|
||||||
|
virtual int local_sample_count(int radius);
|
||||||
|
|
||||||
//// Share information between replicas, whatever it may be.
|
//// Share information between replicas, whatever it may be.
|
||||||
virtual int replica_share();
|
virtual int replica_share();
|
||||||
|
|
||||||
|
/// Report the frequency at which this bias needs to communicate with replicas
|
||||||
|
virtual size_t replica_share_freq() const;
|
||||||
|
|
||||||
/// Perform analysis tasks
|
/// Perform analysis tasks
|
||||||
virtual void analyze() {}
|
virtual void analyze() {}
|
||||||
|
|
||||||
@ -133,32 +140,87 @@ public:
|
|||||||
/// Write the values of specific mutable properties to a string
|
/// Write the values of specific mutable properties to a string
|
||||||
virtual std::string const get_state_params() const;
|
virtual std::string const get_state_params() const;
|
||||||
|
|
||||||
|
/// Check the name of the bias vs. the given string, set the matching_state flag accordingly
|
||||||
|
int check_matching_state(std::string const &conf);
|
||||||
|
|
||||||
/// Read the values of specific mutable properties from a string
|
/// Read the values of specific mutable properties from a string
|
||||||
virtual int set_state_params(std::string const &state_conf);
|
virtual int set_state_params(std::string const &state_conf);
|
||||||
|
|
||||||
/// Write all mutable data not already written by get_state_params()
|
/// Write all mutable data not already written by get_state_params() to a formatted stream
|
||||||
virtual std::ostream & write_state_data(std::ostream &os)
|
virtual std::ostream & write_state_data(std::ostream &os)
|
||||||
{
|
{
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read all mutable data not already set by set_state_params()
|
/// Write all mutable data not already written by get_state_params() to an unformatted stream
|
||||||
|
virtual cvm::memory_stream & write_state_data(cvm::memory_stream &os)
|
||||||
|
{
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read all mutable data not already set by set_state_params() from a formatted stream
|
||||||
virtual std::istream & read_state_data(std::istream &is)
|
virtual std::istream & read_state_data(std::istream &is)
|
||||||
{
|
{
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a keyword from the state data (typically a header)
|
/// Read all mutable data not already set by set_state_params() from an unformatted stream
|
||||||
/// \param Input stream
|
virtual cvm::memory_stream & read_state_data(cvm::memory_stream &is)
|
||||||
/// \param Keyword labeling the header block
|
{
|
||||||
std::istream & read_state_data_key(std::istream &is, char const *key);
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
/// Write the bias configuration to a state file or other stream
|
/// Write a keyword header for a data sequence to a formatted stream
|
||||||
std::ostream & write_state(std::ostream &os);
|
/// \param[in,out] os Output stream
|
||||||
|
/// \param[in] key Keyword labeling the header block
|
||||||
|
/// \param[in] header Whether this is the header of a multi-line segment vs a single line
|
||||||
|
std::ostream &write_state_data_key(std::ostream &os, std::string const &key, bool header = true);
|
||||||
|
|
||||||
/// Read the bias configuration from a restart file or other stream
|
/// Write a keyword header for a data sequence to an unformatted stream
|
||||||
|
/// \param[in,out] os Output stream
|
||||||
|
/// \param[in] key Keyword labeling the header block
|
||||||
|
/// \param[in] header Ignored
|
||||||
|
cvm::memory_stream &write_state_data_key(cvm::memory_stream &os, std::string const &key,
|
||||||
|
bool header = true);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// Read a keyword header for a data sequence from a stream
|
||||||
|
/// \param[in,out] Input stream
|
||||||
|
/// \param[in] Keyword labeling the header block; an error will be raised if not matching
|
||||||
|
template <typename IST> IST &read_state_data_key_template_(IST &is, std::string const &key);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Read a keyword header for a data sequence from a formatted stream
|
||||||
|
/// \param[in,out] Input stream
|
||||||
|
/// \param[in] Keyword labeling the header block; an error will be raised if not matching
|
||||||
|
std::istream & read_state_data_key(std::istream &is, std::string const &key);
|
||||||
|
|
||||||
|
/// Read a keyword header for a data sequence from an unformatted stream
|
||||||
|
/// \param[in,out] Input stream
|
||||||
|
/// \param[in] Keyword labeling the header block; an error will be raised if not matching
|
||||||
|
cvm::memory_stream & read_state_data_key(cvm::memory_stream &is, std::string const &key);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// Generic stream reading function (formatted and not)
|
||||||
|
template <typename IST> IST & read_state_template_(IST &is);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Write the bias configuration to a formatted stream
|
||||||
|
std::ostream &write_state(std::ostream &os);
|
||||||
|
|
||||||
|
/// Write the bias configuration to an unformatted stream
|
||||||
|
cvm::memory_stream & write_state(cvm::memory_stream &os);
|
||||||
|
|
||||||
|
/// Read the bias configuration from a formatted stream
|
||||||
std::istream & read_state(std::istream &is);
|
std::istream & read_state(std::istream &is);
|
||||||
|
|
||||||
|
/// Read the bias configuration from an unformatted stream
|
||||||
|
cvm::memory_stream & read_state(cvm::memory_stream &is);
|
||||||
|
|
||||||
/// Write the bias state to a file with the given prefix
|
/// Write the bias state to a file with the given prefix
|
||||||
int write_state_prefix(std::string const &prefix);
|
int write_state_prefix(std::string const &prefix);
|
||||||
|
|
||||||
@ -274,8 +336,6 @@ public:
|
|||||||
colvarbias_ti(char const *key);
|
colvarbias_ti(char const *key);
|
||||||
virtual ~colvarbias_ti();
|
virtual ~colvarbias_ti();
|
||||||
|
|
||||||
virtual int clear_state_data();
|
|
||||||
|
|
||||||
virtual int init(std::string const &conf);
|
virtual int init(std::string const &conf);
|
||||||
virtual int init_grids();
|
virtual int init_grids();
|
||||||
virtual int update();
|
virtual int update();
|
||||||
@ -288,7 +348,9 @@ public:
|
|||||||
virtual std::string const get_state_params() const;
|
virtual std::string const get_state_params() const;
|
||||||
virtual int set_state_params(std::string const &state_conf);
|
virtual int set_state_params(std::string const &state_conf);
|
||||||
virtual std::ostream & write_state_data(std::ostream &os);
|
virtual std::ostream & write_state_data(std::ostream &os);
|
||||||
|
virtual cvm::memory_stream & write_state_data(cvm::memory_stream &os);
|
||||||
virtual std::istream & read_state_data(std::istream &is);
|
virtual std::istream & read_state_data(std::istream &is);
|
||||||
|
virtual cvm::memory_stream & read_state_data(cvm::memory_stream &is);
|
||||||
virtual int write_output_files();
|
virtual int write_output_files();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -297,10 +359,10 @@ protected:
|
|||||||
std::vector<colvarvalue> ti_system_forces;
|
std::vector<colvarvalue> ti_system_forces;
|
||||||
|
|
||||||
/// Averaged system forces
|
/// Averaged system forces
|
||||||
colvar_grid_gradient *ti_avg_forces;
|
std::shared_ptr<colvar_grid_gradient> ti_avg_forces;
|
||||||
|
|
||||||
/// Histogram of sampled data
|
/// Histogram of sampled data
|
||||||
colvar_grid_count *ti_count;
|
std::shared_ptr<colvar_grid_count> ti_count;
|
||||||
|
|
||||||
/// Because total forces may be from the last simulation step,
|
/// Because total forces may be from the last simulation step,
|
||||||
/// store the index of the variables then
|
/// store the index of the variables then
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -14,13 +14,14 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
#include "colvarbias.h"
|
#include "colvarbias.h"
|
||||||
#include "colvargrid.h"
|
#include "colvargrid.h"
|
||||||
#include "colvar_UIestimator.h"
|
#include "colvar_UIestimator.h"
|
||||||
|
|
||||||
typedef cvm::real* gradient_t;
|
typedef cvm::real *gradient_t;
|
||||||
|
|
||||||
|
|
||||||
/// ABF bias
|
/// ABF bias
|
||||||
@ -31,17 +32,14 @@ public:
|
|||||||
/// Constructor for ABF bias
|
/// Constructor for ABF bias
|
||||||
colvarbias_abf(char const *key);
|
colvarbias_abf(char const *key);
|
||||||
/// Initializer for ABF bias
|
/// Initializer for ABF bias
|
||||||
virtual int init(std::string const &conf);
|
int init(std::string const &conf) override;
|
||||||
/// Default destructor for ABF bias
|
/// Default destructor for ABF bias
|
||||||
virtual ~colvarbias_abf();
|
~colvarbias_abf() override;
|
||||||
/// Per-timestep update of ABF bias
|
/// Per-timestep update of ABF bias
|
||||||
virtual int update();
|
int update() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// Filename prefix for human-readable gradient/sample count output
|
|
||||||
std::string output_prefix;
|
|
||||||
|
|
||||||
/// Base filename(s) for reading previous gradient data (replaces data from restart file)
|
/// Base filename(s) for reading previous gradient data (replaces data from restart file)
|
||||||
std::vector<std::string> input_prefix;
|
std::vector<std::string> input_prefix;
|
||||||
|
|
||||||
@ -57,8 +55,8 @@ 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;
|
||||||
/// Write combined files with a history of all output data?
|
/// Latest absolute time step at which history files were written
|
||||||
bool b_history_files;
|
cvm::step_number history_last_step;
|
||||||
/// Write CZAR output file for stratified eABF (.zgrad)
|
/// Write CZAR output file for stratified eABF (.zgrad)
|
||||||
bool b_czar_window_file;
|
bool b_czar_window_file;
|
||||||
/// Number of timesteps between recording data in history files (if non-zero)
|
/// Number of timesteps between recording data in history files (if non-zero)
|
||||||
@ -99,75 +97,104 @@ private:
|
|||||||
gradient_t system_force;
|
gradient_t system_force;
|
||||||
|
|
||||||
/// n-dim grid of free energy gradients
|
/// n-dim grid of free energy gradients
|
||||||
colvar_grid_gradient *gradients;
|
std::shared_ptr<colvar_grid_gradient> gradients;
|
||||||
/// n-dim grid of number of samples
|
/// n-dim grid of number of samples
|
||||||
colvar_grid_count *samples;
|
std::shared_ptr<colvar_grid_count> samples;
|
||||||
/// n-dim grid of pmf (dimension 1 to 3)
|
/// n-dim grid of pmf (dimension 1 to 3)
|
||||||
integrate_potential *pmf;
|
std::shared_ptr<integrate_potential> pmf;
|
||||||
/// n-dim grid: average force on "real" coordinate for eABF z-based estimator
|
/// n-dim grid: average force on "real" coordinate for eABF z-based estimator
|
||||||
colvar_grid_gradient *z_gradients;
|
std::shared_ptr<colvar_grid_gradient> z_gradients;
|
||||||
/// n-dim grid of number of samples on "real" coordinate for eABF z-based estimator
|
/// n-dim grid of number of samples on "real" coordinate for eABF z-based estimator
|
||||||
colvar_grid_count *z_samples;
|
std::shared_ptr<colvar_grid_count> z_samples;
|
||||||
/// n-dim grid containing CZAR estimator of "real" free energy gradients
|
/// n-dim grid containing CZAR estimatr of "real" free energy gradients
|
||||||
colvar_grid_gradient *czar_gradients;
|
std::shared_ptr<colvar_grid_gradient> czar_gradients;
|
||||||
/// n-dim grid of CZAR pmf (dimension 1 to 3)
|
/// n-dim grid of CZAR pmf (dimension 1 to 3)
|
||||||
integrate_potential *czar_pmf;
|
std::shared_ptr<integrate_potential> czar_pmf;
|
||||||
|
|
||||||
inline int update_system_force(size_t i)
|
/// Calculate system force for all colvars
|
||||||
{
|
int update_system_force();
|
||||||
if (colvars[i]->is_enabled(f_cv_subtract_applied_force)) {
|
|
||||||
// this colvar is already subtracting the ABF force
|
/// Calulate the biasing force for the current bin
|
||||||
system_force[i] = colvars[i]->total_force().real_value;
|
int calc_biasing_force(std::vector<cvm::real> &force);
|
||||||
} else {
|
|
||||||
system_force[i] = colvars[i]->total_force().real_value
|
/// Calulate the smoothing factor to apply to biasing forces for given local count
|
||||||
- colvar_forces[i].real_value;
|
cvm::real smoothing_factor(cvm::real weight);
|
||||||
// If hideJacobian is active then total_force has an extra term of -fj
|
|
||||||
// which is the Jacobian-compensating force at the colvar level
|
|
||||||
}
|
|
||||||
if (cvm::debug())
|
|
||||||
cvm::log("ABF System force calc: cv " + cvm::to_str(i) +
|
|
||||||
" fs " + cvm::to_str(system_force[i]) +
|
|
||||||
" = ft " + cvm::to_str(colvars[i]->total_force().real_value) +
|
|
||||||
" - fa " + cvm::to_str(colvar_forces[i].real_value));
|
|
||||||
return COLVARS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// shared ABF
|
// shared ABF
|
||||||
bool shared_on;
|
bool shared_on;
|
||||||
size_t shared_freq;
|
size_t shared_freq;
|
||||||
cvm::step_number shared_last_step;
|
cvm::step_number shared_last_step;
|
||||||
// Share between replicas -- may be called independently of update
|
|
||||||
virtual int replica_share();
|
|
||||||
|
|
||||||
// Store the last set for shared ABF
|
// Share between replicas -- may be called independently of update
|
||||||
colvar_grid_gradient *last_gradients;
|
int replica_share() override;
|
||||||
colvar_grid_count *last_samples;
|
|
||||||
|
// Share data needed for CZAR between replicas - called before output only
|
||||||
|
int replica_share_CZAR();
|
||||||
|
|
||||||
|
/// Report the frequency at which this bias needs to communicate with replicas
|
||||||
|
size_t replica_share_freq() const override;
|
||||||
|
|
||||||
|
// Data just after the last share (start of cycle) in shared ABF
|
||||||
|
std::unique_ptr<colvar_grid_gradient> last_gradients;
|
||||||
|
std::shared_ptr<colvar_grid_count> last_samples;
|
||||||
|
// eABF/CZAR local data last shared
|
||||||
|
std::unique_ptr<colvar_grid_gradient> z_gradients_in;
|
||||||
|
std::shared_ptr<colvar_grid_count> z_samples_in;
|
||||||
|
// ABF data from local replica only in shared ABF
|
||||||
|
std::shared_ptr<colvar_grid_gradient> local_gradients;
|
||||||
|
std::shared_ptr<colvar_grid_count> local_samples;
|
||||||
|
std::unique_ptr<integrate_potential> local_pmf;
|
||||||
|
// eABF/CZAR data collected from all replicas in shared eABF on replica 0
|
||||||
|
// if non-shared, aliases of regular CZAR grids, for output purposes
|
||||||
|
std::shared_ptr<colvar_grid_gradient> global_z_gradients;
|
||||||
|
std::shared_ptr<colvar_grid_count> global_z_samples;
|
||||||
|
std::shared_ptr<colvar_grid_gradient> global_czar_gradients;
|
||||||
|
std::shared_ptr<integrate_potential> global_czar_pmf;
|
||||||
|
|
||||||
|
|
||||||
// For Tcl implementation of selection rules.
|
// For Tcl implementation of selection rules.
|
||||||
/// Give the total number of bins for a given bias.
|
/// Give the total number of bins for a given bias.
|
||||||
virtual int bin_num();
|
int bin_num() override;
|
||||||
/// Calculate the bin index for a given bias.
|
/// Calculate the bin index for a given bias.
|
||||||
virtual int current_bin();
|
int current_bin() override;
|
||||||
//// Give the count at a given bin index.
|
//// Give the count at a given bin index.
|
||||||
virtual int bin_count(int bin_index);
|
int bin_count(int bin_index) override;
|
||||||
|
/// Return the average number of samples in a given "radius" around current bin
|
||||||
|
int local_sample_count(int radius) override;
|
||||||
|
|
||||||
/// 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 close = true);
|
/// \param local write grids contining replica-local data in shared ABF
|
||||||
|
void write_gradients_samples(const std::string &prefix, bool close = true, bool local = false);
|
||||||
|
|
||||||
/// Read human-readable FE gradients and sample count (if not using restart)
|
/// Read human-readable FE gradients and sample count (if not using restart)
|
||||||
int read_gradients_samples();
|
int read_gradients_samples();
|
||||||
|
|
||||||
/// Template used in write_gradient_samples()
|
/// Shorthand template used in write_gradient_samples()
|
||||||
template <class T> int write_grid_to_file(T const *grid,
|
template <class T> int write_grid_to_file(T const *grid,
|
||||||
std::string const &name,
|
std::string const &name,
|
||||||
bool close);
|
bool close);
|
||||||
|
|
||||||
virtual std::istream& read_state_data(std::istream&);
|
private:
|
||||||
virtual std::ostream& write_state_data(std::ostream&);
|
|
||||||
virtual int write_output_files();
|
/// Generic stream writing function (formatted and not)
|
||||||
|
template <typename OST> OST &write_state_data_template_(OST &os);
|
||||||
|
|
||||||
|
/// Generic stream readingx function (formatted and not)
|
||||||
|
template <typename IST> IST &read_state_data_template_(IST &is);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
std::ostream &write_state_data(std::ostream &os) override;
|
||||||
|
|
||||||
|
cvm::memory_stream &write_state_data(cvm::memory_stream &os) override;
|
||||||
|
|
||||||
|
std::istream &read_state_data(std::istream &is) override;
|
||||||
|
|
||||||
|
cvm::memory_stream &read_state_data(cvm::memory_stream &is) override;
|
||||||
|
|
||||||
|
int write_output_files() override;
|
||||||
|
|
||||||
/// Calculate the bias energy for 1D ABF
|
/// Calculate the bias energy for 1D ABF
|
||||||
virtual int calc_energy(std::vector<colvarvalue> const *values);
|
int calc_energy(std::vector<colvarvalue> const *values) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
136
lib/colvars/colvarbias_abmd.cpp
Normal file
136
lib/colvars/colvarbias_abmd.cpp
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
// -*- 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 "colvarbias_abmd.h"
|
||||||
|
#include "colvarproxy.h"
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
|
||||||
|
colvarbias_abmd::colvarbias_abmd(char const *key)
|
||||||
|
: colvarbias(key),
|
||||||
|
colvarbias_ti(key)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarbias_abmd::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
cvm::main()->cite_feature("ABMD bias");
|
||||||
|
|
||||||
|
int err = colvarbias::init(conf);
|
||||||
|
err |= colvarbias_ti::init(conf);
|
||||||
|
if (err != COLVARS_OK) return err;
|
||||||
|
|
||||||
|
enable(f_cvb_apply_force);
|
||||||
|
|
||||||
|
if (num_variables() != 1) {
|
||||||
|
return cvm::error("ABMD requires exactly one collective variable.\n", COLVARS_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! (variables(0))->is_enabled(f_cv_scalar) ) {
|
||||||
|
return cvm::error("ABMD colvar must be scalar.\n", COLVARS_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_keyval(conf, "forceConstant", k);
|
||||||
|
get_keyval(conf, "decreasing", decreasing, decreasing);
|
||||||
|
get_keyval(conf, "stoppingValue", stopping_val);
|
||||||
|
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarbias_abmd::update()
|
||||||
|
{
|
||||||
|
if (!cvm::main()->proxy->simulation_running()) {
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
colvar const *cv = variables(0);
|
||||||
|
cvm::real const val = cv->value().real_value;
|
||||||
|
|
||||||
|
if (!ref_initialized) {
|
||||||
|
ref_val = val;
|
||||||
|
ref_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute sign factor to unify increasing and decreasing cases below
|
||||||
|
// less conditionals, more arithmetic
|
||||||
|
cvm::real const sign = decreasing ? -1. : 1.;
|
||||||
|
cvm::real const diff = (val - ref_val) * sign;
|
||||||
|
|
||||||
|
if ( diff > 0. ) {
|
||||||
|
colvar_forces[0] = 0.;
|
||||||
|
bias_energy = 0.;
|
||||||
|
if ( (ref_val-stopping_val) * sign <= 0. ) ref_val = val;
|
||||||
|
} else {
|
||||||
|
colvar_forces[0] = - sign * k * diff;
|
||||||
|
bias_energy = 0.5 * k * diff * diff;;
|
||||||
|
}
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string const colvarbias_abmd::get_state_params() const
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
os.setf(std::ios::scientific, std::ios::floatfield);
|
||||||
|
|
||||||
|
os << " refValue "
|
||||||
|
<< std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width)
|
||||||
|
<< ref_val << "\n";
|
||||||
|
os << " stoppingValue " << stopping_val << "\n";
|
||||||
|
os << " forceConstant " << k << "\n";
|
||||||
|
os << " decreasing " << (decreasing ? "on" : "off") << "\n";
|
||||||
|
|
||||||
|
return (colvarbias::get_state_params() + os.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarbias_abmd::set_state_params(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = colvarbias::set_state_params(conf);
|
||||||
|
|
||||||
|
if (error_code != COLVARS_OK) {
|
||||||
|
return error_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_keyval(conf, "refValue", ref_val, ref_val,
|
||||||
|
colvarparse::parse_restart | colvarparse::parse_required);
|
||||||
|
ref_initialized = true;
|
||||||
|
|
||||||
|
get_keyval(conf, "forceConstant", k, k,
|
||||||
|
colvarparse::parse_restart | colvarparse::parse_required);
|
||||||
|
get_keyval(conf, "decreasing", decreasing, decreasing,
|
||||||
|
colvarparse::parse_restart | colvarparse::parse_required);
|
||||||
|
get_keyval(conf, "stoppingValue", stopping_val, stopping_val,
|
||||||
|
colvarparse::parse_restart | colvarparse::parse_required);
|
||||||
|
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream & colvarbias_abmd::write_traj_label(std::ostream &os)
|
||||||
|
{
|
||||||
|
size_t const this_cv_width = (variables(0)->value()).output_width(cvm::cv_width);
|
||||||
|
os << " ref_"
|
||||||
|
<< cvm::wrap_string(variables(0)->name, this_cv_width-4);
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream & colvarbias_abmd::write_traj(std::ostream &os)
|
||||||
|
{
|
||||||
|
os << " "
|
||||||
|
<< std::setprecision(cvm::en_prec) << std::setw(cvm::en_width)
|
||||||
|
<< ref_val;
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
49
lib/colvars/colvarbias_abmd.h
Normal file
49
lib/colvars/colvarbias_abmd.h
Normal 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.
|
||||||
|
|
||||||
|
#ifndef COLVARBIAS_ABMD_H
|
||||||
|
#define COLVARBIAS_ABMD_H
|
||||||
|
|
||||||
|
#include "colvarbias_restraint.h"
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Adiabatic Bias MD
|
||||||
|
class colvarbias_abmd
|
||||||
|
: public colvarbias_ti
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
colvarbias_abmd(char const *key);
|
||||||
|
virtual int init(std::string const &conf);
|
||||||
|
virtual int update();
|
||||||
|
virtual std::string const get_state_params() const;
|
||||||
|
virtual int set_state_params(std::string const &conf);
|
||||||
|
virtual std::ostream & write_traj_label(std::ostream &os);
|
||||||
|
virtual std::ostream & write_traj(std::ostream &os);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// \brief Location of the moving wall
|
||||||
|
cvm::real ref_val = 0.;
|
||||||
|
|
||||||
|
/// \brief Has ref_val already been set?
|
||||||
|
bool ref_initialized = false;
|
||||||
|
|
||||||
|
/// \brief Value of the reference where it stops moving
|
||||||
|
cvm::real stopping_val = 0.;
|
||||||
|
|
||||||
|
/// \brief Is the target moving down?
|
||||||
|
bool decreasing = false;
|
||||||
|
|
||||||
|
/// \brief Restraint force constant
|
||||||
|
cvm::real k = 0.;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
@ -40,7 +39,10 @@ colvarbias_alb::colvarbias_alb(char const *key)
|
|||||||
int colvarbias_alb::init(std::string const &conf)
|
int colvarbias_alb::init(std::string const &conf)
|
||||||
{
|
{
|
||||||
colvarproxy *proxy = cvm::main()->proxy;
|
colvarproxy *proxy = cvm::main()->proxy;
|
||||||
colvarbias::init(conf);
|
int err = colvarbias::init(conf);
|
||||||
|
if (err != COLVARS_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
cvm::main()->cite_feature("ALB colvar bias implementation");
|
cvm::main()->cite_feature("ALB colvar bias implementation");
|
||||||
|
|
||||||
enable(f_cvb_scalar_variables);
|
enable(f_cvb_scalar_variables);
|
||||||
|
|||||||
@ -7,10 +7,13 @@
|
|||||||
// 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 <iostream>
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvarbias_histogram.h"
|
#include "colvarbias_histogram.h"
|
||||||
|
#include "colvars_memstream.h"
|
||||||
|
|
||||||
|
|
||||||
colvarbias_histogram::colvarbias_histogram(char const *key)
|
colvarbias_histogram::colvarbias_histogram(char const *key)
|
||||||
@ -23,7 +26,10 @@ colvarbias_histogram::colvarbias_histogram(char const *key)
|
|||||||
|
|
||||||
int colvarbias_histogram::init(std::string const &conf)
|
int colvarbias_histogram::init(std::string const &conf)
|
||||||
{
|
{
|
||||||
colvarbias::init(conf);
|
int err = colvarbias::init(conf);
|
||||||
|
if (err != COLVARS_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
cvm::main()->cite_feature("Histogram colvar bias implementation");
|
cvm::main()->cite_feature("Histogram colvar bias implementation");
|
||||||
|
|
||||||
enable(f_cvb_scalar_variables);
|
enable(f_cvb_scalar_variables);
|
||||||
@ -125,22 +131,6 @@ int colvarbias_histogram::update()
|
|||||||
// assign a valid bin size
|
// assign a valid bin size
|
||||||
bin.assign(num_variables(), 0);
|
bin.assign(num_variables(), 0);
|
||||||
|
|
||||||
if (out_name.size() == 0) {
|
|
||||||
// At the first timestep, we need to assign out_name since
|
|
||||||
// output_prefix is unset during the constructor
|
|
||||||
if (cvm::step_relative() == 0) {
|
|
||||||
out_name = cvm::output_prefix() + "." + this->name + ".dat";
|
|
||||||
cvm::log("Histogram " + this->name + " will be written to file \"" + out_name + "\"\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out_name_dx.size() == 0) {
|
|
||||||
if (cvm::step_relative() == 0) {
|
|
||||||
out_name_dx = cvm::output_prefix() + "." + this->name + ".dx";
|
|
||||||
cvm::log("Histogram " + this->name + " will be written to file \"" + out_name_dx + "\"\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colvar_array_size == 0) {
|
if (colvar_array_size == 0) {
|
||||||
// update indices for scalar values
|
// update indices for scalar values
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -181,6 +171,16 @@ int colvarbias_histogram::write_output_files()
|
|||||||
|
|
||||||
int error_code = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
|
|
||||||
|
// Set default filenames, if none have been provided
|
||||||
|
if (!cvm::output_prefix().empty()) {
|
||||||
|
if (out_name.empty()) {
|
||||||
|
out_name = cvm::output_prefix() + "." + this->name + ".dat";
|
||||||
|
}
|
||||||
|
if (out_name_dx.empty()) {
|
||||||
|
out_name_dx = cvm::output_prefix() + "." + this->name + ".dx";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (out_name.size() && out_name != "none") {
|
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");
|
||||||
error_code |= grid->write_multicol(out_name, "histogram output file");
|
error_code |= grid->write_multicol(out_name, "histogram output file");
|
||||||
@ -197,13 +197,18 @@ int colvarbias_histogram::write_output_files()
|
|||||||
|
|
||||||
std::istream & colvarbias_histogram::read_state_data(std::istream& is)
|
std::istream & colvarbias_histogram::read_state_data(std::istream& is)
|
||||||
{
|
{
|
||||||
if (! read_state_data_key(is, "grid")) {
|
if (read_state_data_key(is, "grid")) {
|
||||||
return is;
|
grid->read_raw(is);
|
||||||
}
|
|
||||||
if (! grid->read_raw(is)) {
|
|
||||||
return is;
|
|
||||||
}
|
}
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream & colvarbias_histogram::read_state_data(cvm::memory_stream& is)
|
||||||
|
{
|
||||||
|
if (read_state_data_key(is, "grid")) {
|
||||||
|
grid->read_raw(is);
|
||||||
|
}
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,8 +217,16 @@ std::ostream & colvarbias_histogram::write_state_data(std::ostream& os)
|
|||||||
{
|
{
|
||||||
std::ios::fmtflags flags(os.flags());
|
std::ios::fmtflags flags(os.flags());
|
||||||
os.setf(std::ios::fmtflags(0), std::ios::floatfield);
|
os.setf(std::ios::fmtflags(0), std::ios::floatfield);
|
||||||
os << "grid\n";
|
write_state_data_key(os, "grid");
|
||||||
grid->write_raw(os, 8);
|
grid->write_raw(os, 8);
|
||||||
os.flags(flags);
|
os.flags(flags);
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream & colvarbias_histogram::write_state_data(cvm::memory_stream& os)
|
||||||
|
{
|
||||||
|
write_state_data_key(os, "grid");
|
||||||
|
grid->write_raw(os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|||||||
@ -24,11 +24,16 @@ class colvarbias_histogram : public colvarbias {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
colvarbias_histogram(char const *key);
|
colvarbias_histogram(char const *key);
|
||||||
~colvarbias_histogram();
|
virtual ~colvarbias_histogram();
|
||||||
virtual int init(std::string const &conf);
|
virtual int init(std::string const &conf);
|
||||||
virtual int update();
|
virtual int update();
|
||||||
virtual int write_output_files();
|
virtual int write_output_files();
|
||||||
|
|
||||||
|
virtual std::ostream & write_state_data(std::ostream &os);
|
||||||
|
virtual cvm::memory_stream & write_state_data(cvm::memory_stream &os);
|
||||||
|
virtual std::istream & read_state_data(std::istream &is);
|
||||||
|
virtual cvm::memory_stream & read_state_data(cvm::memory_stream &is);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// n-dim histogram
|
/// n-dim histogram
|
||||||
@ -40,9 +45,6 @@ protected:
|
|||||||
size_t colvar_array_size;
|
size_t colvar_array_size;
|
||||||
/// If colvar_array_size is larger than 1, weigh each one by this number before accumulating the histogram
|
/// If colvar_array_size is larger than 1, weigh each one by this number before accumulating the histogram
|
||||||
std::vector<cvm::real> weights;
|
std::vector<cvm::real> weights;
|
||||||
|
|
||||||
virtual std::istream & read_state_data(std::istream &is);
|
|
||||||
virtual std::ostream & write_state_data(std::ostream &os);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "colvarbias_histogram_reweight_amd.h"
|
#include "colvarbias_histogram_reweight_amd.h"
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
|
#include "colvars_memstream.h"
|
||||||
|
|
||||||
colvarbias_reweightaMD::colvarbias_reweightaMD(char const *key)
|
colvarbias_reweightaMD::colvarbias_reweightaMD(char const *key)
|
||||||
: colvarbias_histogram(key), grid_count(NULL), grid_dV(NULL),
|
: colvarbias_histogram(key), grid_count(NULL), grid_dV(NULL),
|
||||||
@ -343,23 +344,37 @@ void colvarbias_reweightaMD::compute_cumulant_expansion_factor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream & colvarbias_reweightaMD::write_state_data(std::ostream& os)
|
|
||||||
|
template <typename OST> OST & colvarbias_reweightaMD::write_state_data_template_(OST& os)
|
||||||
{
|
{
|
||||||
std::ios::fmtflags flags(os.flags());
|
std::ios::fmtflags flags(os.flags());
|
||||||
os.setf(std::ios::fmtflags(0), std::ios::floatfield);
|
os.setf(std::ios::fmtflags(0), std::ios::floatfield);
|
||||||
os << "grid\n";
|
write_state_data_key(os, "grid");
|
||||||
grid->write_raw(os, 8);
|
grid->write_raw(os, 8);
|
||||||
os << "grid_count\n";
|
write_state_data_key(os, "grid_count");
|
||||||
grid_count->write_raw(os, 8);
|
grid_count->write_raw(os, 8);
|
||||||
os << "grid_dV\n";
|
write_state_data_key(os, "grid_dV");
|
||||||
grid_dV->write_raw(os, 8);
|
grid_dV->write_raw(os, 8);
|
||||||
os << "grid_dV_square\n";
|
write_state_data_key(os, "grid_dV_square");
|
||||||
grid_dV_square->write_raw(os, 8);
|
grid_dV_square->write_raw(os, 8);
|
||||||
os.flags(flags);
|
os.flags(flags);
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream & colvarbias_reweightaMD::read_state_data(std::istream& is)
|
|
||||||
|
std::ostream & colvarbias_reweightaMD::write_state_data(std::ostream& os)
|
||||||
|
{
|
||||||
|
return write_state_data_template_<std::ostream>(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream & colvarbias_reweightaMD::write_state_data(cvm::memory_stream& os)
|
||||||
|
{
|
||||||
|
return write_state_data_template_<cvm::memory_stream>(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename IST> IST & colvarbias_reweightaMD::read_state_data_template_(IST& is)
|
||||||
{
|
{
|
||||||
if (! read_state_data_key(is, "grid")) {
|
if (! read_state_data_key(is, "grid")) {
|
||||||
return is;
|
return is;
|
||||||
@ -387,3 +402,15 @@ std::istream & colvarbias_reweightaMD::read_state_data(std::istream& is)
|
|||||||
}
|
}
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::istream & colvarbias_reweightaMD::read_state_data(std::istream& is)
|
||||||
|
{
|
||||||
|
return read_state_data_template_<std::istream>(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream & colvarbias_reweightaMD::read_state_data(cvm::memory_stream& is)
|
||||||
|
{
|
||||||
|
return read_state_data_template_<cvm::memory_stream>(is);
|
||||||
|
}
|
||||||
|
|||||||
@ -18,15 +18,9 @@ class colvarbias_reweightaMD : public colvarbias_histogram {
|
|||||||
public:
|
public:
|
||||||
colvarbias_reweightaMD(char const *key);
|
colvarbias_reweightaMD(char const *key);
|
||||||
virtual ~colvarbias_reweightaMD();
|
virtual ~colvarbias_reweightaMD();
|
||||||
#if (__cplusplus >= 201103L)
|
|
||||||
virtual int init(std::string const &conf) override;
|
virtual int init(std::string const &conf) override;
|
||||||
virtual int update() override;
|
virtual int update() override;
|
||||||
virtual int write_output_files() override;
|
virtual int write_output_files() override;
|
||||||
#else
|
|
||||||
virtual int init(std::string const &conf);
|
|
||||||
virtual int update();
|
|
||||||
virtual int write_output_files();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// @brief convert histogram to PMF by taking logarithm and multiplying
|
/// @brief convert histogram to PMF by taking logarithm and multiplying
|
||||||
/// it with -1/beta
|
/// it with -1/beta
|
||||||
@ -85,14 +79,15 @@ protected:
|
|||||||
/// Write gradients of the PMF?
|
/// Write gradients of the PMF?
|
||||||
bool b_write_gradients;
|
bool b_write_gradients;
|
||||||
|
|
||||||
|
template <typename OST> OST & write_state_data_template_(OST& os);
|
||||||
|
template <typename IST> IST & read_state_data_template_(IST& is);
|
||||||
|
|
||||||
/// save and restore
|
/// save and restore
|
||||||
#if (__cplusplus >= 201103L)
|
|
||||||
virtual std::istream & read_state_data(std::istream &is) override;
|
virtual std::istream & read_state_data(std::istream &is) override;
|
||||||
|
virtual cvm::memory_stream & read_state_data(cvm::memory_stream &is) override;
|
||||||
virtual std::ostream & write_state_data(std::ostream &os) override;
|
virtual std::ostream & write_state_data(std::ostream &os) override;
|
||||||
#else
|
virtual cvm::memory_stream & write_state_data(cvm::memory_stream &os) override;
|
||||||
virtual std::istream & read_state_data(std::istream &is);
|
|
||||||
virtual std::ostream & write_state_data(std::ostream &os);
|
|
||||||
#endif
|
|
||||||
private:
|
private:
|
||||||
/// temporary grids for evaluating PMFs
|
/// temporary grids for evaluating PMFs
|
||||||
colvar_grid_scalar *pmf_grid_exp_avg;
|
colvar_grid_scalar *pmf_grid_exp_avg;
|
||||||
|
|||||||
@ -7,29 +7,33 @@
|
|||||||
// 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 <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
// used to set the absolute path of a replica file
|
// Define function to get the absolute path of a replica file
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#define CHDIR ::_chdir
|
#define GETCWD(BUF, SIZE) ::_getcwd(BUF, SIZE)
|
||||||
#define GETCWD ::_getcwd
|
|
||||||
#define PATHSEP "\\"
|
#define PATHSEP "\\"
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#define CHDIR ::chdir
|
#define GETCWD(BUF, SIZE) ::getcwd(BUF, SIZE)
|
||||||
#define GETCWD ::getcwd
|
|
||||||
#define PATHSEP "/"
|
#define PATHSEP "/"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cpp_lib_filesystem
|
||||||
|
// When std::filesystem is available, use it
|
||||||
|
#include <filesystem>
|
||||||
|
#undef GETCWD
|
||||||
|
#define GETCWD(BUF, SIZE) (std::filesystem::current_path().string().c_str())
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvarbias_meta.h"
|
#include "colvarbias_meta.h"
|
||||||
|
#include "colvars_memstream.h"
|
||||||
|
|
||||||
|
|
||||||
colvarbias_meta::colvarbias_meta(char const *key)
|
colvarbias_meta::colvarbias_meta(char const *key)
|
||||||
@ -58,7 +62,6 @@ colvarbias_meta::colvarbias_meta(char const *key)
|
|||||||
|
|
||||||
ebmeta_equil_steps = 0L;
|
ebmeta_equil_steps = 0L;
|
||||||
|
|
||||||
replica_update_freq = 0;
|
|
||||||
replica_id.clear();
|
replica_id.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,11 +395,8 @@ colvarbias_meta::add_hill(colvarbias_meta::hill const &h)
|
|||||||
|
|
||||||
// output to trajectory (if specified)
|
// output to trajectory (if specified)
|
||||||
if (b_hills_traj) {
|
if (b_hills_traj) {
|
||||||
// Open trajectory file or access the one already open
|
// Save the current hill to a buffer for further traj output
|
||||||
std::ostream &hills_traj_os =
|
hills_traj_os_buf << (hills.back()).output_traj();
|
||||||
cvm::proxy->output_stream(hills_traj_file_name());
|
|
||||||
hills_traj_os << (hills.back()).output_traj();
|
|
||||||
cvm::proxy->flush_output_stream(hills_traj_file_name());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
has_data = true;
|
has_data = true;
|
||||||
@ -427,13 +427,10 @@ colvarbias_meta::delete_hill(hill_iter &h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (b_hills_traj) {
|
if (b_hills_traj) {
|
||||||
// output to the trajectory
|
// Save the current hill to a buffer for further traj output
|
||||||
std::ostream &hills_traj_os =
|
hills_traj_os_buf << "# DELETED this hill: "
|
||||||
cvm::proxy->output_stream(hills_traj_file_name());
|
<< (hills.back()).output_traj()
|
||||||
hills_traj_os << "# DELETED this hill: "
|
<< "\n";
|
||||||
<< (hills.back()).output_traj()
|
|
||||||
<< "\n";
|
|
||||||
cvm::proxy->flush_output_stream(hills_traj_file_name());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hills.erase(h);
|
return hills.erase(h);
|
||||||
@ -624,9 +621,9 @@ int colvarbias_meta::update_bias()
|
|||||||
add_hill(hill(cvm::step_absolute(), hill_weight*hills_scale,
|
add_hill(hill(cvm::step_absolute(), hill_weight*hills_scale,
|
||||||
colvar_values, colvar_sigmas, replica_id));
|
colvar_values, colvar_sigmas, replica_id));
|
||||||
std::ostream &replica_hills_os =
|
std::ostream &replica_hills_os =
|
||||||
cvm::proxy->output_stream(replica_hills_file);
|
cvm::proxy->output_stream(replica_hills_file, "replica hills file");
|
||||||
if (replica_hills_os) {
|
if (replica_hills_os) {
|
||||||
replica_hills_os << hills.back();
|
write_hill(replica_hills_os, hills.back());
|
||||||
} else {
|
} else {
|
||||||
return cvm::error("Error: in metadynamics bias \""+this->name+"\""+
|
return cvm::error("Error: in metadynamics bias \""+this->name+"\""+
|
||||||
((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
|
((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
|
||||||
@ -985,9 +982,9 @@ void colvarbias_meta::recount_hills_off_grid(colvarbias_meta::hill_iter h_first
|
|||||||
int colvarbias_meta::replica_share()
|
int colvarbias_meta::replica_share()
|
||||||
{
|
{
|
||||||
int error_code = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
colvarproxy *proxy = cvm::proxy;
|
|
||||||
// sync with the other replicas (if needed)
|
// sync with the other replicas (if needed)
|
||||||
if (comm == multiple_replicas) {
|
if (comm == multiple_replicas) {
|
||||||
|
colvarproxy *proxy = cvm::main()->proxy;
|
||||||
// reread the replicas registry
|
// reread the replicas registry
|
||||||
error_code |= update_replicas_registry();
|
error_code |= update_replicas_registry();
|
||||||
// empty the output buffer
|
// empty the output buffer
|
||||||
@ -998,6 +995,12 @@ int colvarbias_meta::replica_share()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t colvarbias_meta::replica_share_freq() const
|
||||||
|
{
|
||||||
|
return replica_update_freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarbias_meta::update_replicas_registry()
|
int colvarbias_meta::update_replicas_registry()
|
||||||
{
|
{
|
||||||
int error_code = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
@ -1299,21 +1302,40 @@ int colvarbias_meta::set_state_params(std::string const &state_conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::istream & colvarbias_meta::read_state_data(std::istream& is)
|
template <typename IST, typename GT>
|
||||||
|
IST & colvarbias_meta::read_grid_data_template_(IST& is, std::string const &key,
|
||||||
|
GT *grid, GT *backup_grid)
|
||||||
|
{
|
||||||
|
auto const start_pos = is.tellg();
|
||||||
|
std::string key_in;
|
||||||
|
if (is >> key_in) {
|
||||||
|
if ((key != key_in) || !(grid->read_restart(is))) {
|
||||||
|
is.clear();
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
if (!rebin_grids) {
|
||||||
|
if ((backup_grid == nullptr) || (comm == single_replica)) {
|
||||||
|
cvm::error("Error: couldn't read grid data for metadynamics bias \""+
|
||||||
|
this->name+"\""+
|
||||||
|
((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
|
||||||
|
"; if useGrids was off when the state file was written, "
|
||||||
|
"try enabling rebinGrids now to regenerate the grids.\n", COLVARS_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
is.clear();
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
}
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename IST> IST &colvarbias_meta::read_state_data_template_(IST &is)
|
||||||
{
|
{
|
||||||
if (use_grids) {
|
if (use_grids) {
|
||||||
|
|
||||||
if (expand_grids) {
|
|
||||||
// the boundaries of the colvars may have been changed; TODO:
|
|
||||||
// this reallocation is only for backward-compatibility, and may
|
|
||||||
// be deleted when grid_parameters (i.e. colvargrid's own
|
|
||||||
// internal reallocation) has kicked in
|
|
||||||
delete hills_energy;
|
|
||||||
delete hills_energy_gradients;
|
|
||||||
hills_energy = new colvar_grid_scalar(colvars);
|
|
||||||
hills_energy_gradients = new colvar_grid_gradient(colvars);
|
|
||||||
}
|
|
||||||
|
|
||||||
colvar_grid_scalar *hills_energy_backup = NULL;
|
colvar_grid_scalar *hills_energy_backup = NULL;
|
||||||
colvar_grid_gradient *hills_energy_gradients_backup = NULL;
|
colvar_grid_gradient *hills_energy_gradients_backup = NULL;
|
||||||
|
|
||||||
@ -1328,95 +1350,26 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::streampos const hills_energy_pos = is.tellg();
|
read_grid_data_template_<IST, colvar_grid_scalar>(is, "hills_energy", hills_energy,
|
||||||
std::string key;
|
hills_energy_backup);
|
||||||
if (!(is >> key)) {
|
|
||||||
if (hills_energy_backup != NULL) {
|
read_grid_data_template_<IST, colvar_grid_gradient>(
|
||||||
delete hills_energy;
|
is, "hills_energy_gradients", hills_energy_gradients, hills_energy_gradients_backup);
|
||||||
delete hills_energy_gradients;
|
|
||||||
hills_energy = hills_energy_backup;
|
if (is) {
|
||||||
hills_energy_gradients = hills_energy_gradients_backup;
|
cvm::log(" successfully read the biasing potential and its gradients from grids.\n");
|
||||||
|
if (hills_energy_backup != nullptr) {
|
||||||
|
// Now that we have successfully updated the grids, delete the backup copies
|
||||||
|
delete hills_energy_backup;
|
||||||
|
delete hills_energy_gradients_backup;
|
||||||
}
|
}
|
||||||
is.clear();
|
} else {
|
||||||
is.seekg(hills_energy_pos, std::ios::beg);
|
|
||||||
is.setstate(std::ios::failbit);
|
|
||||||
return is;
|
return is;
|
||||||
} else if (!(key == std::string("hills_energy")) ||
|
|
||||||
!(hills_energy->read_restart(is))) {
|
|
||||||
is.clear();
|
|
||||||
is.seekg(hills_energy_pos, std::ios::beg);
|
|
||||||
if (!rebin_grids) {
|
|
||||||
if ((hills_energy_backup == NULL) || (comm == single_replica)) {
|
|
||||||
cvm::error("Error: couldn't read the energy grid for metadynamics bias \""+
|
|
||||||
this->name+"\""+
|
|
||||||
((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
|
|
||||||
"; if useGrids was off when the state file was written, "
|
|
||||||
"enable rebinGrids now to regenerate the grids.\n");
|
|
||||||
} else {
|
|
||||||
delete hills_energy;
|
|
||||||
delete hills_energy_gradients;
|
|
||||||
hills_energy = hills_energy_backup;
|
|
||||||
hills_energy_gradients = hills_energy_gradients_backup;
|
|
||||||
is.setstate(std::ios::failbit);
|
|
||||||
return is;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::streampos const hills_energy_gradients_pos = is.tellg();
|
|
||||||
if (!(is >> key)) {
|
|
||||||
if (hills_energy_backup != NULL) {
|
|
||||||
delete hills_energy;
|
|
||||||
delete hills_energy_gradients;
|
|
||||||
hills_energy = hills_energy_backup;
|
|
||||||
hills_energy_gradients = hills_energy_gradients_backup;
|
|
||||||
}
|
|
||||||
is.clear();
|
|
||||||
is.seekg(hills_energy_gradients_pos, std::ios::beg);
|
|
||||||
is.setstate(std::ios::failbit);
|
|
||||||
return is;
|
|
||||||
} else if (!(key == std::string("hills_energy_gradients")) ||
|
|
||||||
!(hills_energy_gradients->read_restart(is))) {
|
|
||||||
is.clear();
|
|
||||||
is.seekg(hills_energy_gradients_pos, std::ios::beg);
|
|
||||||
if (!rebin_grids) {
|
|
||||||
if ((hills_energy_backup == NULL) || (comm == single_replica)) {
|
|
||||||
cvm::error("Error: couldn't read the gradients grid for metadynamics bias \""+
|
|
||||||
this->name+"\""+
|
|
||||||
((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
|
|
||||||
"; if useGrids was off when the state file was written, "
|
|
||||||
"enable rebinGrids now to regenerate the grids.\n");
|
|
||||||
} else {
|
|
||||||
delete hills_energy;
|
|
||||||
delete hills_energy_gradients;
|
|
||||||
hills_energy = hills_energy_backup;
|
|
||||||
hills_energy_gradients = hills_energy_gradients_backup;
|
|
||||||
is.setstate(std::ios::failbit);
|
|
||||||
return is;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cvm::debug())
|
|
||||||
cvm::log("Successfully read new grids for bias \""+
|
|
||||||
this->name+"\""+
|
|
||||||
((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+"\n");
|
|
||||||
|
|
||||||
cvm::log(" read biasing energy and forces from grids.\n");
|
|
||||||
|
|
||||||
if (hills_energy_backup != NULL) {
|
|
||||||
// now that we have successfully updated the grids, delete the
|
|
||||||
// backup copies
|
|
||||||
if (cvm::debug())
|
|
||||||
cvm::log("Deallocating the older grids.\n");
|
|
||||||
|
|
||||||
delete hills_energy_backup;
|
|
||||||
delete hills_energy_gradients_backup;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save references to the end of the list of existing hills, so that it can
|
// Save references to the end of the list of existing hills, so that they can
|
||||||
// be cleared if hills are read successfully state
|
// be cleared if hills are read successfully from the stream
|
||||||
bool const existing_hills = !hills.empty();
|
bool const existing_hills = !hills.empty();
|
||||||
size_t const old_hills_size = hills.size();
|
size_t const old_hills_size = hills.size();
|
||||||
hill_iter old_hills_end = hills.end();
|
hill_iter old_hills_end = hills.end();
|
||||||
@ -1430,17 +1383,20 @@ std::istream & colvarbias_meta::read_state_data(std::istream& is)
|
|||||||
while (read_hill(is)) {
|
while (read_hill(is)) {
|
||||||
if (cvm::debug()) {
|
if (cvm::debug()) {
|
||||||
cvm::log("Read a previously saved hill under the "
|
cvm::log("Read a previously saved hill under the "
|
||||||
"metadynamics bias \""+
|
"metadynamics bias \"" +
|
||||||
this->name+"\", created at step "+
|
this->name + "\", created at step " + cvm::to_str((hills.back()).it) +
|
||||||
cvm::to_str((hills.back()).it)+".\n");
|
"; position in stream is " + cvm::to_str(is.tellg()) + ".\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is.clear();
|
is.clear();
|
||||||
|
|
||||||
new_hills_begin = hills.end();
|
new_hills_begin = hills.end();
|
||||||
cvm::log(" read "+cvm::to_str(hills.size() - old_hills_size)+
|
cvm::log(" successfully read "+cvm::to_str(hills.size() - old_hills_size)+
|
||||||
" additional explicit hills.\n");
|
" explicit hills from state.\n");
|
||||||
|
|
||||||
if (existing_hills) {
|
if (existing_hills) {
|
||||||
|
// Prune any hills that pre-existed those just read
|
||||||
hills.erase(hills.begin(), old_hills_end);
|
hills.erase(hills.begin(), old_hills_end);
|
||||||
hills_off_grid.erase(hills_off_grid.begin(), old_hills_off_grid_end);
|
hills_off_grid.erase(hills_off_grid.begin(), old_hills_off_grid_end);
|
||||||
if (cvm::debug()) {
|
if (cvm::debug()) {
|
||||||
@ -1449,6 +1405,46 @@ std::istream & colvarbias_meta::read_state_data(std::istream& is)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If rebinGrids is set, rebin the grids based on the current information
|
||||||
|
rebin_grids_after_restart();
|
||||||
|
|
||||||
|
if (use_grids) {
|
||||||
|
if (!hills_off_grid.empty()) {
|
||||||
|
cvm::log(cvm::to_str(hills_off_grid.size())+" hills are near the "
|
||||||
|
"grid boundaries: they will be computed analytically "
|
||||||
|
"and saved to the state files.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
colvarbias_ti::read_state_data(is);
|
||||||
|
|
||||||
|
if (cvm::debug())
|
||||||
|
cvm::log("colvarbias_meta::read_restart() done\n");
|
||||||
|
|
||||||
|
has_data = true;
|
||||||
|
|
||||||
|
if (comm == multiple_replicas) {
|
||||||
|
read_replica_files();
|
||||||
|
}
|
||||||
|
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::istream & colvarbias_meta::read_state_data(std::istream& is)
|
||||||
|
{
|
||||||
|
return read_state_data_template_<std::istream>(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream &colvarbias_meta::read_state_data(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
return read_state_data_template_<cvm::memory_stream>(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void colvarbias_meta::rebin_grids_after_restart()
|
||||||
|
{
|
||||||
if (rebin_grids) {
|
if (rebin_grids) {
|
||||||
|
|
||||||
// allocate new grids (based on the new boundaries and widths just
|
// allocate new grids (based on the new boundaries and widths just
|
||||||
@ -1463,9 +1459,9 @@ std::istream & colvarbias_meta::read_state_data(std::istream& is)
|
|||||||
if (cvm::debug()) {
|
if (cvm::debug()) {
|
||||||
std::ostringstream tmp_os;
|
std::ostringstream tmp_os;
|
||||||
tmp_os << "hills_energy parameters:\n";
|
tmp_os << "hills_energy parameters:\n";
|
||||||
hills_energy->write_params(tmp_os);
|
tmp_os << hills_energy->get_state_params();
|
||||||
tmp_os << "new_hills_energy parameters:\n";
|
tmp_os << "new_hills_energy parameters:\n";
|
||||||
new_hills_energy->write_params(tmp_os);
|
tmp_os << new_hills_energy->get_state_params();
|
||||||
cvm::log(tmp_os.str());
|
cvm::log(tmp_os.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1495,114 +1491,182 @@ std::istream & colvarbias_meta::read_state_data(std::istream& is)
|
|||||||
if (!hills.empty())
|
if (!hills.empty())
|
||||||
recount_hills_off_grid(hills.begin(), hills.end(), hills_energy);
|
recount_hills_off_grid(hills.begin(), hills.end(), hills_energy);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (use_grids) {
|
|
||||||
if (!hills_off_grid.empty()) {
|
template <typename OST>
|
||||||
cvm::log(cvm::to_str(hills_off_grid.size())+" hills are near the "
|
OST &colvarbias_meta::write_hill_template_(OST &os, colvarbias_meta::hill const &h)
|
||||||
"grid boundaries: they will be computed analytically "
|
{
|
||||||
"and saved to the state files.\n");
|
bool const formatted = !std::is_same<OST, cvm::memory_stream>::value;
|
||||||
|
|
||||||
|
if (formatted) {
|
||||||
|
os.setf(std::ios::scientific, std::ios::floatfield);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_state_data_key(os, "hill", false);
|
||||||
|
|
||||||
|
if (formatted)
|
||||||
|
os << "{\n";
|
||||||
|
|
||||||
|
write_state_data_key(os, "step", false);
|
||||||
|
if (formatted)
|
||||||
|
os << std::setw(cvm::it_width);
|
||||||
|
os << h.it;
|
||||||
|
if (formatted)
|
||||||
|
os << "\n";
|
||||||
|
|
||||||
|
write_state_data_key(os, "weight", false);
|
||||||
|
if (formatted)
|
||||||
|
os << std::setprecision(cvm::en_prec) << std::setw(cvm::en_width);
|
||||||
|
os << h.W;
|
||||||
|
if (formatted)
|
||||||
|
os << "\n";
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
write_state_data_key(os, "centers", false);
|
||||||
|
for (i = 0; i < (h.centers).size(); i++) {
|
||||||
|
if (formatted)
|
||||||
|
os << " " << std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width);
|
||||||
|
os << h.centers[i];
|
||||||
|
}
|
||||||
|
if (formatted)
|
||||||
|
os << "\n";
|
||||||
|
|
||||||
|
// For backward compatibility, write the widths instead of the sigmas
|
||||||
|
write_state_data_key(os, "widths", false);
|
||||||
|
for (i = 0; i < (h.sigmas).size(); i++) {
|
||||||
|
if (formatted)
|
||||||
|
os << " " << std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width);
|
||||||
|
os << 2.0 * h.sigmas[i];
|
||||||
|
}
|
||||||
|
if (formatted)
|
||||||
|
os << "\n";
|
||||||
|
|
||||||
|
if (h.replica.size()) {
|
||||||
|
write_state_data_key(os, "replicaID", false);
|
||||||
|
os << h.replica;
|
||||||
|
if (formatted)
|
||||||
|
os << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formatted)
|
||||||
|
os << "}\n";
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream &colvarbias_meta::write_hill(std::ostream &os, colvarbias_meta::hill const &h)
|
||||||
|
{
|
||||||
|
return write_hill_template_<std::ostream>(os, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream &colvarbias_meta::write_hill(cvm::memory_stream &os,
|
||||||
|
colvarbias_meta::hill const &h)
|
||||||
|
{
|
||||||
|
return write_hill_template_<cvm::memory_stream>(os, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename IST> IST &hill_stream_error(IST &is, size_t start_pos, std::string const &key)
|
||||||
|
{
|
||||||
|
is.clear();
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
cvm::error("Error: in reading data for keyword \"" + key + "\" from stream.\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename IST> IST &colvarbias_meta::read_hill_template_(IST &is)
|
||||||
|
{
|
||||||
|
if (!is)
|
||||||
|
return is; // do nothing if failbit is set
|
||||||
|
|
||||||
|
bool const formatted = !std::is_same<IST, cvm::memory_stream>::value;
|
||||||
|
|
||||||
|
auto const start_pos = is.tellg();
|
||||||
|
|
||||||
|
std::string key;
|
||||||
|
if (!(is >> key) || (key != "hill")) {
|
||||||
|
is.clear();
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formatted) {
|
||||||
|
std::string brace;
|
||||||
|
if (!(is >> brace) || (brace != "{")) {
|
||||||
|
return hill_stream_error<IST>(is, start_pos, "hill");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
colvarbias_ti::read_state_data(is);
|
|
||||||
|
|
||||||
if (cvm::debug())
|
|
||||||
cvm::log("colvarbias_meta::read_restart() done\n");
|
|
||||||
|
|
||||||
has_data = true;
|
|
||||||
|
|
||||||
if (comm != single_replica) {
|
|
||||||
read_replica_files();
|
|
||||||
}
|
|
||||||
|
|
||||||
return is;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::istream & reset_istream(std::istream &is, size_t start_pos)
|
|
||||||
{
|
|
||||||
is.clear();
|
|
||||||
is.seekg(start_pos, std::ios::beg);
|
|
||||||
is.setstate(std::ios::failbit);
|
|
||||||
return is;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::istream & colvarbias_meta::read_hill(std::istream &is)
|
|
||||||
{
|
|
||||||
if (!is) return is; // do nothing if failbit is set
|
|
||||||
|
|
||||||
std::streampos const start_pos = is.tellg();
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
std::string data;
|
|
||||||
if ( !(is >> read_block("hill", &data)) ) {
|
|
||||||
return reset_istream(is, start_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::istringstream data_is(data);
|
|
||||||
|
|
||||||
cvm::step_number h_it = 0L;
|
cvm::step_number h_it = 0L;
|
||||||
cvm::real h_weight;
|
cvm::real h_weight = 0.0;
|
||||||
std::vector<colvarvalue> h_centers(num_variables());
|
std::vector<colvarvalue> h_centers(num_variables());
|
||||||
for (i = 0; i < num_variables(); i++) {
|
for (size_t i = 0; i < num_variables(); i++) {
|
||||||
h_centers[i].type(variables(i)->value());
|
h_centers[i].type(variables(i)->value());
|
||||||
}
|
}
|
||||||
std::vector<cvm::real> h_sigmas(num_variables());
|
std::vector<cvm::real> h_sigmas(num_variables());
|
||||||
std::string h_replica;
|
std::string h_replica;
|
||||||
|
|
||||||
std::string keyword;
|
if (!read_state_data_key(is, "step") || !(is >> h_it)) {
|
||||||
while (data_is >> keyword) {
|
return hill_stream_error<IST>(is, start_pos, "step");
|
||||||
|
}
|
||||||
|
|
||||||
if (keyword == "step") {
|
if (read_state_data_key(is, "weight")) {
|
||||||
if ( !(data_is >> h_it)) {
|
if (!(is >> h_weight)) {
|
||||||
return reset_istream(is, start_pos);
|
return hill_stream_error<IST>(is, start_pos, "weight");
|
||||||
}
|
}
|
||||||
if ((h_it <= state_file_step) && !restart_keep_hills) {
|
}
|
||||||
if (cvm::debug())
|
|
||||||
cvm::log("Skipping a hill older than the state file for metadynamics bias \""+
|
if (read_state_data_key(is, "centers")) {
|
||||||
this->name+"\""+
|
for (size_t i = 0; i < num_variables(); i++) {
|
||||||
((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+"\n");
|
if (!(is >> h_centers[i])) {
|
||||||
return is;
|
return hill_stream_error<IST>(is, start_pos, "centers");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (keyword == "weight") {
|
if (read_state_data_key(is, "widths")) {
|
||||||
if ( !(data_is >> h_weight)) {
|
for (size_t i = 0; i < num_variables(); i++) {
|
||||||
return reset_istream(is, start_pos);
|
if (!(is >> h_sigmas[i])) {
|
||||||
|
return hill_stream_error<IST>(is, start_pos, "widths");
|
||||||
|
}
|
||||||
|
// For backward compatibility, read the widths instead of the sigmas
|
||||||
|
h_sigmas[i] /= 2.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comm != single_replica) {
|
||||||
|
if (read_state_data_key(is, "replicaID")) {
|
||||||
|
if (!(is >> h_replica)) {
|
||||||
|
return hill_stream_error<IST>(is, start_pos, "replicaID");
|
||||||
|
}
|
||||||
|
if (h_replica != replica_id) {
|
||||||
|
cvm::error("Error: trying to read a hill created by replica \"" + h_replica +
|
||||||
|
"\" for replica \"" + replica_id + "\"; did you swap output files?\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
return hill_stream_error<IST>(is, start_pos, "replicaID");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (keyword == "centers") {
|
if (formatted) {
|
||||||
for (i = 0; i < num_variables(); i++) {
|
std::string brace;
|
||||||
if ( !(data_is >> h_centers[i])) {
|
if (!(is >> brace) || (brace != "}")) {
|
||||||
return reset_istream(is, start_pos);
|
return hill_stream_error<IST>(is, start_pos, "hill");
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (keyword == "widths") {
|
if ((h_it <= state_file_step) && !restart_keep_hills) {
|
||||||
for (i = 0; i < num_variables(); i++) {
|
if (cvm::debug())
|
||||||
if ( !(data_is >> h_sigmas[i])) {
|
cvm::log("Skipping a hill older than the state file for metadynamics bias \"" + this->name +
|
||||||
return reset_istream(is, start_pos);
|
"\"" + ((comm != single_replica) ? ", replica \"" + replica_id + "\"" : "") + "\n");
|
||||||
}
|
return is;
|
||||||
// For backward compatibility, read the widths instead of the sigmas
|
|
||||||
h_sigmas[i] /= 2.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (comm != single_replica) {
|
|
||||||
if (keyword == "replicaID") {
|
|
||||||
if ( !(data_is >> h_replica)) {
|
|
||||||
return reset_istream(is, start_pos);
|
|
||||||
}
|
|
||||||
if (h_replica != replica_id) {
|
|
||||||
cvm::error("Error: trying to read a hill created by replica \""+
|
|
||||||
h_replica+"\" for replica \""+replica_id+
|
|
||||||
"\"; did you swap output files?\n", COLVARS_INPUT_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hill_iter const hills_end = hills.end();
|
hill_iter const hills_end = hills.end();
|
||||||
@ -1617,7 +1681,7 @@ std::istream & colvarbias_meta::read_hill(std::istream &is)
|
|||||||
// add this also to the list of hills that are off-grid, which will
|
// add this also to the list of hills that are off-grid, which will
|
||||||
// be computed analytically
|
// be computed analytically
|
||||||
cvm::real const min_dist =
|
cvm::real const min_dist =
|
||||||
hills_energy->bin_distance_from_boundaries((hills.back()).centers, true);
|
hills_energy->bin_distance_from_boundaries((hills.back()).centers, true);
|
||||||
if (min_dist < (3.0 * cvm::floor(hill_width)) + 1.0) {
|
if (min_dist < (3.0 * cvm::floor(hill_width)) + 1.0) {
|
||||||
hills_off_grid.push_back(hills.back());
|
hills_off_grid.push_back(hills.back());
|
||||||
}
|
}
|
||||||
@ -1628,6 +1692,18 @@ std::istream & colvarbias_meta::read_hill(std::istream &is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::istream &colvarbias_meta::read_hill(std::istream &is)
|
||||||
|
{
|
||||||
|
return read_hill_template_<std::istream>(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream &colvarbias_meta::read_hill(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
return read_hill_template_<cvm::memory_stream>(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarbias_meta::setup_output()
|
int colvarbias_meta::setup_output()
|
||||||
{
|
{
|
||||||
int error_code = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
@ -1644,7 +1720,10 @@ int colvarbias_meta::setup_output()
|
|||||||
|
|
||||||
// TODO: one may want to specify the path manually for intricated filesystems?
|
// TODO: one may want to specify the path manually for intricated filesystems?
|
||||||
char *pwd = new char[3001];
|
char *pwd = new char[3001];
|
||||||
if (GETCWD(pwd, 3000) == NULL) {
|
if (GETCWD(pwd, 3000) == nullptr) {
|
||||||
|
if (pwd != nullptr) { //
|
||||||
|
delete[] pwd;
|
||||||
|
}
|
||||||
return cvm::error("Error: cannot get the path of the current working directory.\n",
|
return cvm::error("Error: cannot get the path of the current working directory.\n",
|
||||||
COLVARS_BUG_ERROR);
|
COLVARS_BUG_ERROR);
|
||||||
}
|
}
|
||||||
@ -1701,7 +1780,7 @@ int colvarbias_meta::setup_output()
|
|||||||
|
|
||||||
// if we're running without grids, use a growing list of "hills" files
|
// if we're running without grids, use a growing list of "hills" files
|
||||||
// otherwise, just one state file and one "hills" file as buffer
|
// otherwise, just one state file and one "hills" file as buffer
|
||||||
std::ostream &list_os = cvm::proxy->output_stream(replica_list_file);
|
std::ostream &list_os = cvm::proxy->output_stream(replica_list_file, "replica list file");
|
||||||
if (list_os) {
|
if (list_os) {
|
||||||
list_os << "stateFile " << replica_state_file << "\n";
|
list_os << "stateFile " << replica_state_file << "\n";
|
||||||
list_os << "hillsFile " << replica_hills_file << "\n";
|
list_os << "hillsFile " << replica_hills_file << "\n";
|
||||||
@ -1723,7 +1802,7 @@ int colvarbias_meta::setup_output()
|
|||||||
|
|
||||||
if (b_hills_traj) {
|
if (b_hills_traj) {
|
||||||
std::ostream &hills_traj_os =
|
std::ostream &hills_traj_os =
|
||||||
cvm::proxy->output_stream(hills_traj_file_name());
|
cvm::proxy->output_stream(hills_traj_file_name(), "hills trajectory file");
|
||||||
if (!hills_traj_os) {
|
if (!hills_traj_os) {
|
||||||
error_code |= COLVARS_FILE_ERROR;
|
error_code |= COLVARS_FILE_ERROR;
|
||||||
}
|
}
|
||||||
@ -1757,36 +1836,32 @@ std::string const colvarbias_meta::get_state_params() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::ostream & colvarbias_meta::write_state_data(std::ostream& os)
|
template <typename OST> OST &colvarbias_meta::write_state_data_template_(OST &os)
|
||||||
{
|
{
|
||||||
if (use_grids) {
|
if (use_grids) {
|
||||||
|
|
||||||
// this is a very good time to project hills, if you haven't done
|
// this is a very good time to project hills, if you haven't done
|
||||||
// it already!
|
// it already!
|
||||||
project_hills(new_hills_begin, hills.end(),
|
project_hills(new_hills_begin, hills.end(), hills_energy, hills_energy_gradients);
|
||||||
hills_energy, hills_energy_gradients);
|
|
||||||
new_hills_begin = hills.end();
|
new_hills_begin = hills.end();
|
||||||
|
|
||||||
// write down the grids to the restart file
|
// write down the grids to the restart file
|
||||||
os << " hills_energy\n";
|
write_state_data_key(os, "hills_energy");
|
||||||
hills_energy->write_restart(os);
|
hills_energy->write_restart(os);
|
||||||
os << " hills_energy_gradients\n";
|
write_state_data_key(os, "hills_energy_gradients");
|
||||||
hills_energy_gradients->write_restart(os);
|
hills_energy_gradients->write_restart(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (!use_grids) || keep_hills ) {
|
if ((!use_grids) || keep_hills) {
|
||||||
// write all hills currently in memory
|
// write all hills currently in memory
|
||||||
for (std::list<hill>::const_iterator h = this->hills.begin();
|
for (std::list<hill>::const_iterator h = this->hills.begin(); h != this->hills.end(); h++) {
|
||||||
h != this->hills.end();
|
write_hill(os, *h);
|
||||||
h++) {
|
|
||||||
os << *h;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// write just those that are near the grid boundaries
|
// write just those that are near the grid boundaries
|
||||||
for (std::list<hill>::const_iterator h = this->hills_off_grid.begin();
|
for (std::list<hill>::const_iterator h = this->hills_off_grid.begin();
|
||||||
h != this->hills_off_grid.end();
|
h != this->hills_off_grid.end(); h++) {
|
||||||
h++) {
|
write_hill(os, *h);
|
||||||
os << *h;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1795,6 +1870,18 @@ std::ostream & colvarbias_meta::write_state_data(std::ostream& os)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream & colvarbias_meta::write_state_data(std::ostream& os)
|
||||||
|
{
|
||||||
|
return write_state_data_template_<std::ostream>(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream &colvarbias_meta::write_state_data(cvm::memory_stream &os)
|
||||||
|
{
|
||||||
|
return write_state_data_template_<cvm::memory_stream>(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarbias_meta::write_state_to_replicas()
|
int colvarbias_meta::write_state_to_replicas()
|
||||||
{
|
{
|
||||||
int error_code = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
@ -1816,6 +1903,15 @@ int colvarbias_meta::write_output_files()
|
|||||||
if (dump_fes) {
|
if (dump_fes) {
|
||||||
write_pmf();
|
write_pmf();
|
||||||
}
|
}
|
||||||
|
if (b_hills_traj) {
|
||||||
|
std::ostream &hills_traj_os =
|
||||||
|
cvm::proxy->output_stream(hills_traj_file_name(), "hills trajectory file");
|
||||||
|
hills_traj_os << hills_traj_os_buf.str();
|
||||||
|
cvm::proxy->flush_output_stream(hills_traj_file_name());
|
||||||
|
// clear the buffer
|
||||||
|
hills_traj_os_buf.str("");
|
||||||
|
hills_traj_os_buf.clear();
|
||||||
|
}
|
||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1915,7 +2011,7 @@ int colvarbias_meta::write_replica_state_file()
|
|||||||
// Write to temporary state file
|
// Write to temporary state file
|
||||||
std::string const tmp_state_file(replica_state_file+".tmp");
|
std::string const tmp_state_file(replica_state_file+".tmp");
|
||||||
error_code |= proxy->remove_file(tmp_state_file);
|
error_code |= proxy->remove_file(tmp_state_file);
|
||||||
std::ostream &rep_state_os = cvm::proxy->output_stream(tmp_state_file);
|
std::ostream &rep_state_os = cvm::proxy->output_stream(tmp_state_file, "temporary state file");
|
||||||
if (rep_state_os) {
|
if (rep_state_os) {
|
||||||
if (!write_state(rep_state_os)) {
|
if (!write_state(rep_state_os)) {
|
||||||
error_code |= cvm::error("Error: in writing to temporary file \""+
|
error_code |= cvm::error("Error: in writing to temporary file \""+
|
||||||
@ -1934,11 +2030,11 @@ int colvarbias_meta::reopen_replica_buffer_file()
|
|||||||
{
|
{
|
||||||
int error_code = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
colvarproxy *proxy = cvm::proxy;
|
colvarproxy *proxy = cvm::proxy;
|
||||||
if (proxy->output_stream(replica_hills_file)) {
|
if (proxy->output_stream(replica_hills_file, "replica hills file")) {
|
||||||
error_code |= proxy->close_output_stream(replica_hills_file);
|
error_code |= proxy->close_output_stream(replica_hills_file);
|
||||||
}
|
}
|
||||||
error_code |= proxy->remove_file(replica_hills_file);
|
error_code |= proxy->remove_file(replica_hills_file);
|
||||||
std::ostream &replica_hills_os = proxy->output_stream(replica_hills_file);
|
std::ostream &replica_hills_os = proxy->output_stream(replica_hills_file, "replica hills file");
|
||||||
if (replica_hills_os) {
|
if (replica_hills_os) {
|
||||||
replica_hills_os.setf(std::ios::scientific, std::ios::floatfield);
|
replica_hills_os.setf(std::ios::scientific, std::ios::floatfield);
|
||||||
} else {
|
} else {
|
||||||
@ -2037,43 +2133,3 @@ colvarbias_meta::hill::operator = (colvarbias_meta::hill const &h)
|
|||||||
|
|
||||||
colvarbias_meta::hill::~hill()
|
colvarbias_meta::hill::~hill()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream &os, colvarbias_meta::hill const &h)
|
|
||||||
{
|
|
||||||
os.setf(std::ios::scientific, std::ios::floatfield);
|
|
||||||
|
|
||||||
os << "hill {\n";
|
|
||||||
os << " step " << std::setw(cvm::it_width) << h.it << "\n";
|
|
||||||
os << " weight "
|
|
||||||
<< std::setprecision(cvm::en_prec)
|
|
||||||
<< std::setw(cvm::en_width)
|
|
||||||
<< h.W << "\n";
|
|
||||||
|
|
||||||
if (h.replica.size())
|
|
||||||
os << " replicaID " << h.replica << "\n";
|
|
||||||
|
|
||||||
size_t i;
|
|
||||||
os << " centers ";
|
|
||||||
for (i = 0; i < (h.centers).size(); i++) {
|
|
||||||
os << " "
|
|
||||||
<< std::setprecision(cvm::cv_prec)
|
|
||||||
<< std::setw(cvm::cv_width)
|
|
||||||
<< h.centers[i];
|
|
||||||
}
|
|
||||||
os << "\n";
|
|
||||||
|
|
||||||
// For backward compatibility, write the widths instead of the sigmas
|
|
||||||
os << " widths ";
|
|
||||||
for (i = 0; i < (h.sigmas).size(); i++) {
|
|
||||||
os << " "
|
|
||||||
<< std::setprecision(cvm::cv_prec)
|
|
||||||
<< std::setw(cvm::cv_width)
|
|
||||||
<< 2.0 * h.sigmas[i];
|
|
||||||
}
|
|
||||||
os << "\n";
|
|
||||||
|
|
||||||
os << "}\n";
|
|
||||||
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
#include "colvarbias.h"
|
#include "colvarbias.h"
|
||||||
#include "colvargrid.h"
|
#include "colvargrid.h"
|
||||||
|
|
||||||
|
|
||||||
/// Metadynamics bias (implementation of \link colvarbias \endlink)
|
/// Metadynamics bias (implementation of \link colvarbias \endlink)
|
||||||
class colvarbias_meta
|
class colvarbias_meta
|
||||||
: public virtual colvarbias,
|
: public virtual colvarbias,
|
||||||
@ -51,14 +52,32 @@ public:
|
|||||||
virtual int update_bias();
|
virtual int update_bias();
|
||||||
virtual int update_grid_data();
|
virtual int update_grid_data();
|
||||||
virtual int replica_share();
|
virtual int replica_share();
|
||||||
|
virtual size_t replica_share_freq() const;
|
||||||
|
|
||||||
virtual int calc_energy(std::vector<colvarvalue> const *values);
|
virtual int calc_energy(std::vector<colvarvalue> const *values);
|
||||||
virtual int calc_forces(std::vector<colvarvalue> const *values);
|
virtual int calc_forces(std::vector<colvarvalue> const *values);
|
||||||
|
|
||||||
virtual std::string const get_state_params() const;
|
virtual std::string const get_state_params() const;
|
||||||
virtual int set_state_params(std::string const &state_conf);
|
virtual int set_state_params(std::string const &state_conf);
|
||||||
virtual std::ostream & write_state_data(std::ostream &os);
|
|
||||||
virtual std::istream & read_state_data(std::istream &os);
|
virtual std::ostream &write_state_data(std::ostream &os);
|
||||||
|
virtual cvm::memory_stream &write_state_data(cvm::memory_stream &os);
|
||||||
|
virtual std::istream &read_state_data(std::istream &is);
|
||||||
|
virtual cvm::memory_stream &read_state_data(cvm::memory_stream &is);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
template <typename IST, typename GT>
|
||||||
|
IST &read_grid_data_template_(IST &is, std::string const &key, GT *grid, GT *backup_grid);
|
||||||
|
|
||||||
|
template <typename IST> IST &read_state_data_template_(IST &is);
|
||||||
|
|
||||||
|
template <typename OST> OST &write_state_data_template_(OST &os);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Function called by read_state_data() to execute rebinning (if requested)
|
||||||
|
void rebin_grids_after_restart();
|
||||||
|
|
||||||
virtual int setup_output();
|
virtual int setup_output();
|
||||||
virtual int write_output_files();
|
virtual int write_output_files();
|
||||||
@ -105,11 +124,24 @@ protected:
|
|||||||
|
|
||||||
/// Regenerate the hills_off_grid list
|
/// Regenerate the hills_off_grid list
|
||||||
void recount_hills_off_grid(hill_iter h_first, hill_iter h_last,
|
void recount_hills_off_grid(hill_iter h_first, hill_iter h_last,
|
||||||
colvar_grid_scalar *ge);
|
colvar_grid_scalar *ge);
|
||||||
|
|
||||||
/// Read a hill from a file
|
template <typename OST> OST &write_hill_template_(OST &os, colvarbias_meta::hill const &h);
|
||||||
|
|
||||||
|
/// Write a hill to a formatted stream
|
||||||
|
std::ostream &write_hill(std::ostream &os, hill const &h);
|
||||||
|
|
||||||
|
/// Write a hill to an unformatted stream
|
||||||
|
cvm::memory_stream &write_hill(cvm::memory_stream &os, hill const &h);
|
||||||
|
|
||||||
|
template <typename IST> IST &read_hill_template_(IST &is);
|
||||||
|
|
||||||
|
/// Read a new hill from a formatted stream
|
||||||
std::istream & read_hill(std::istream &is);
|
std::istream & read_hill(std::istream &is);
|
||||||
|
|
||||||
|
/// Read a new hill from an unformatted stream
|
||||||
|
cvm::memory_stream & read_hill(cvm::memory_stream &is);
|
||||||
|
|
||||||
/// \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
|
||||||
@ -230,7 +262,7 @@ protected:
|
|||||||
std::vector<colvarbias_meta *> replicas;
|
std::vector<colvarbias_meta *> replicas;
|
||||||
|
|
||||||
/// \brief Frequency at which data the "mirror" biases are updated
|
/// \brief Frequency at which data the "mirror" biases are updated
|
||||||
size_t replica_update_freq;
|
size_t replica_update_freq = 0;
|
||||||
|
|
||||||
/// List of replicas (and their output list files): contents are
|
/// List of replicas (and their output list files): contents are
|
||||||
/// copied into replicas_registry for convenience
|
/// copied into replicas_registry for convenience
|
||||||
@ -258,6 +290,8 @@ protected:
|
|||||||
/// Position within replica_hills_file (when reading it)
|
/// Position within replica_hills_file (when reading it)
|
||||||
std::streampos replica_hills_file_pos;
|
std::streampos replica_hills_file_pos;
|
||||||
|
|
||||||
|
/// Cache of the hills trajectory
|
||||||
|
std::ostringstream hills_traj_os_buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -399,9 +433,6 @@ public:
|
|||||||
/// Represent the hill ina string suitable for a trajectory file
|
/// Represent the hill ina string suitable for a trajectory file
|
||||||
std::string output_traj();
|
std::string output_traj();
|
||||||
|
|
||||||
/// Write the hill to an output stream
|
|
||||||
friend std::ostream & operator << (std::ostream &os, hill const &h);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,10 @@ colvarbias_restraint::colvarbias_restraint(char const *key)
|
|||||||
|
|
||||||
int colvarbias_restraint::init(std::string const &conf)
|
int colvarbias_restraint::init(std::string const &conf)
|
||||||
{
|
{
|
||||||
colvarbias::init(conf);
|
int err = colvarbias::init(conf);
|
||||||
|
if (err != COLVARS_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
enable(f_cvb_apply_force);
|
enable(f_cvb_apply_force);
|
||||||
|
|
||||||
colvarbias_ti::init(conf);
|
colvarbias_ti::init(conf);
|
||||||
@ -202,6 +205,8 @@ int colvarbias_restraint_moving::init(std::string const &conf)
|
|||||||
|
|
||||||
first_step = cvm::step_absolute();
|
first_step = cvm::step_absolute();
|
||||||
|
|
||||||
|
cvm::log("Initial step for restraint change: " + cvm::to_str(first_step) + "\n");
|
||||||
|
|
||||||
get_keyval(conf, "targetNumSteps", target_nsteps, target_nsteps);
|
get_keyval(conf, "targetNumSteps", target_nsteps, target_nsteps);
|
||||||
if (!target_nsteps) {
|
if (!target_nsteps) {
|
||||||
cvm::error("Error: targetNumSteps must be non-zero.\n", COLVARS_INPUT_ERROR);
|
cvm::error("Error: targetNumSteps must be non-zero.\n", COLVARS_INPUT_ERROR);
|
||||||
@ -232,10 +237,9 @@ std::string const colvarbias_restraint_moving::get_state_params() const
|
|||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os.setf(std::ios::scientific, std::ios::floatfield);
|
os.setf(std::ios::scientific, std::ios::floatfield);
|
||||||
if (b_chg_centers || b_chg_force_k) {
|
if (b_chg_centers || b_chg_force_k) {
|
||||||
// TODO move this
|
os << "firstStep " << std::setw(cvm::it_width) << first_step << "\n";
|
||||||
if (target_nstages) {
|
if (target_nstages) {
|
||||||
os << "stage " << std::setw(cvm::it_width)
|
os << "stage " << std::setw(cvm::it_width) << stage << "\n";
|
||||||
<< stage << "\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return os.str();
|
return os.str();
|
||||||
@ -245,6 +249,12 @@ std::string const colvarbias_restraint_moving::get_state_params() const
|
|||||||
int colvarbias_restraint_moving::set_state_params(std::string const &conf)
|
int colvarbias_restraint_moving::set_state_params(std::string const &conf)
|
||||||
{
|
{
|
||||||
if (b_chg_centers || b_chg_force_k) {
|
if (b_chg_centers || b_chg_force_k) {
|
||||||
|
auto first_step_flags = colvarparse::parse_restart;
|
||||||
|
if (cvm::main()->restart_version_number() > 20230906) {
|
||||||
|
// Only require the first step when the code could produce it
|
||||||
|
first_step_flags = colvarparse::parse_restart | colvarparse::parse_required;
|
||||||
|
}
|
||||||
|
get_keyval(conf, "firstStep", first_step, first_step, first_step_flags);
|
||||||
if (target_nstages) {
|
if (target_nstages) {
|
||||||
get_keyval(conf, "stage", stage, stage,
|
get_keyval(conf, "stage", stage, stage,
|
||||||
colvarparse::parse_restart | colvarparse::parse_required);
|
colvarparse::parse_restart | colvarparse::parse_required);
|
||||||
@ -837,18 +847,6 @@ int colvarbias_restraint_harmonic::set_state_params(std::string const &conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::ostream & colvarbias_restraint_harmonic::write_state_data(std::ostream &os)
|
|
||||||
{
|
|
||||||
return colvarbias_ti::write_state_data(os);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::istream & colvarbias_restraint_harmonic::read_state_data(std::istream &is)
|
|
||||||
{
|
|
||||||
return colvarbias_ti::read_state_data(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::ostream & colvarbias_restraint_harmonic::write_traj_label(std::ostream &os)
|
std::ostream & colvarbias_restraint_harmonic::write_traj_label(std::ostream &os)
|
||||||
{
|
{
|
||||||
colvarbias_restraint::write_traj_label(os);
|
colvarbias_restraint::write_traj_label(os);
|
||||||
@ -1136,18 +1134,6 @@ int colvarbias_restraint_harmonic_walls::set_state_params(std::string const &con
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::ostream & colvarbias_restraint_harmonic_walls::write_state_data(std::ostream &os)
|
|
||||||
{
|
|
||||||
return colvarbias_ti::write_state_data(os);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::istream & colvarbias_restraint_harmonic_walls::read_state_data(std::istream &is)
|
|
||||||
{
|
|
||||||
return colvarbias_ti::read_state_data(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::ostream & colvarbias_restraint_harmonic_walls::write_traj_label(std::ostream &os)
|
std::ostream & colvarbias_restraint_harmonic_walls::write_traj_label(std::ostream &os)
|
||||||
{
|
{
|
||||||
colvarbias_restraint::write_traj_label(os);
|
colvarbias_restraint::write_traj_label(os);
|
||||||
@ -1293,18 +1279,6 @@ int colvarbias_restraint_linear::set_state_params(std::string const &conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::ostream & colvarbias_restraint_linear::write_state_data(std::ostream &os)
|
|
||||||
{
|
|
||||||
return colvarbias_ti::write_state_data(os);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::istream & colvarbias_restraint_linear::read_state_data(std::istream &is)
|
|
||||||
{
|
|
||||||
return colvarbias_ti::read_state_data(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::ostream & colvarbias_restraint_linear::write_traj_label(std::ostream &os)
|
std::ostream & colvarbias_restraint_linear::write_traj_label(std::ostream &os)
|
||||||
{
|
{
|
||||||
colvarbias_restraint::write_traj_label(os);
|
colvarbias_restraint::write_traj_label(os);
|
||||||
@ -1338,7 +1312,10 @@ int colvarbias_restraint_histogram::init(std::string const &conf)
|
|||||||
{
|
{
|
||||||
int error_code = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
|
|
||||||
colvarbias::init(conf);
|
int err = colvarbias::init(conf);
|
||||||
|
if (err != COLVARS_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
enable(f_cvb_apply_force);
|
enable(f_cvb_apply_force);
|
||||||
|
|
||||||
cvm::main()->cite_feature("histogramRestraint colvar bias implementation");
|
cvm::main()->cite_feature("histogramRestraint colvar bias implementation");
|
||||||
|
|||||||
@ -38,9 +38,6 @@ public:
|
|||||||
|
|
||||||
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::istream & read_state_data(std::istream &os);
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@ -242,8 +239,6 @@ public:
|
|||||||
virtual int update();
|
virtual int update();
|
||||||
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::istream & read_state_data(std::istream &os);
|
|
||||||
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);
|
||||||
virtual int change_configuration(std::string const &conf);
|
virtual int change_configuration(std::string const &conf);
|
||||||
@ -269,8 +264,6 @@ public:
|
|||||||
virtual int update();
|
virtual int update();
|
||||||
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::istream & read_state_data(std::istream &os);
|
|
||||||
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);
|
||||||
|
|
||||||
@ -311,8 +304,6 @@ public:
|
|||||||
|
|
||||||
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::istream & read_state_data(std::istream &os);
|
|
||||||
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);
|
||||||
|
|
||||||
|
|||||||
@ -19,45 +19,40 @@
|
|||||||
colvar::cvc::cvc()
|
colvar::cvc::cvc()
|
||||||
{
|
{
|
||||||
description = "uninitialized colvar component";
|
description = "uninitialized colvar component";
|
||||||
b_try_scalable = true;
|
|
||||||
sup_coeff = 1.0;
|
|
||||||
sup_np = 1;
|
|
||||||
period = 0.0;
|
|
||||||
wrap_center = 0.0;
|
|
||||||
width = 0.0;
|
|
||||||
cvc::init_dependencies();
|
cvc::init_dependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar::cvc::cvc(std::string const &conf)
|
int colvar::cvc::update_description()
|
||||||
{
|
{
|
||||||
description = "uninitialized colvar component";
|
if (name.size() > 0) {
|
||||||
b_try_scalable = true;
|
description = "cvc \"" + name + "\"";
|
||||||
sup_coeff = 1.0;
|
} else {
|
||||||
sup_np = 1;
|
description = "unnamed cvc";
|
||||||
period = 0.0;
|
}
|
||||||
wrap_center = 0.0;
|
description += " of type \"" + function_type() + "\"";
|
||||||
width = 0.0;
|
return COLVARS_OK;
|
||||||
init_dependencies();
|
}
|
||||||
colvar::cvc::init(conf);
|
|
||||||
|
|
||||||
|
std::string colvar::cvc::function_type() const
|
||||||
|
{
|
||||||
|
if (function_types.empty()) {
|
||||||
|
return "unset";
|
||||||
|
}
|
||||||
|
return function_types.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvar::cvc::set_function_type(std::string const &type)
|
int colvar::cvc::set_function_type(std::string const &type)
|
||||||
{
|
{
|
||||||
function_type = type;
|
function_types.push_back(type);
|
||||||
if (function_types.size() == 0) {
|
update_description();
|
||||||
function_types.push_back(function_type);
|
cvm::main()->cite_feature(function_types[0]+" colvar component");
|
||||||
} else {
|
|
||||||
if (function_types.back() != function_type) {
|
|
||||||
function_types.push_back(function_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (size_t i = function_types.size()-1; i > 0; i--) {
|
for (size_t i = function_types.size()-1; i > 0; i--) {
|
||||||
cvm::main()->cite_feature(function_types[i]+" colvar component"+
|
cvm::main()->cite_feature(function_types[i]+" colvar component"+
|
||||||
" (derived from "+function_types[i-1]+")");
|
" (derived from "+function_types[i-1]+")");
|
||||||
}
|
}
|
||||||
cvm::main()->cite_feature(function_types[0]+" colvar component");
|
|
||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +62,8 @@ int colvar::cvc::init(std::string const &conf)
|
|||||||
if (cvm::debug())
|
if (cvm::debug())
|
||||||
cvm::log("Initializing cvc base object.\n");
|
cvm::log("Initializing cvc base object.\n");
|
||||||
|
|
||||||
|
int error_code = COLVARS_OK;
|
||||||
|
|
||||||
std::string const old_name(name);
|
std::string const old_name(name);
|
||||||
|
|
||||||
if (name.size() > 0) {
|
if (name.size() > 0) {
|
||||||
@ -74,18 +71,14 @@ int colvar::cvc::init(std::string const &conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (get_keyval(conf, "name", name, name)) {
|
if (get_keyval(conf, "name", name, name)) {
|
||||||
if (name.size() > 0) {
|
|
||||||
description = "cvc \"" + name + "\" of type " + function_type;
|
|
||||||
} else {
|
|
||||||
description = "unnamed cvc";
|
|
||||||
}
|
|
||||||
if ((name != old_name) && (old_name.size() > 0)) {
|
if ((name != old_name) && (old_name.size() > 0)) {
|
||||||
cvm::error("Error: cannot rename component \""+old_name+
|
error_code |= cvm::error("Error: cannot rename component \"" + old_name +
|
||||||
"\" after initialization (new name = \""+name+"\")",
|
"\" after initialization (new name = \"" + name + "\")",
|
||||||
COLVARS_INPUT_ERROR);
|
COLVARS_INPUT_ERROR);
|
||||||
name = old_name;
|
name = old_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
update_description();
|
||||||
|
|
||||||
get_keyval(conf, "componentCoeff", sup_coeff, sup_coeff);
|
get_keyval(conf, "componentCoeff", sup_coeff, sup_coeff);
|
||||||
get_keyval(conf, "componentExp", sup_np, sup_np);
|
get_keyval(conf, "componentExp", sup_np, sup_np);
|
||||||
@ -102,6 +95,24 @@ int colvar::cvc::init(std::string const &conf)
|
|||||||
register_param("period", reinterpret_cast<void *>(&period));
|
register_param("period", reinterpret_cast<void *>(&period));
|
||||||
register_param("wrapAround", reinterpret_cast<void *>(&wrap_center));
|
register_param("wrapAround", reinterpret_cast<void *>(&wrap_center));
|
||||||
|
|
||||||
|
if (period != 0.0) {
|
||||||
|
if (!is_available(f_cvc_periodic)) {
|
||||||
|
error_code |=
|
||||||
|
cvm::error("Error: invalid use of period and/or "
|
||||||
|
"wrapAround in a \"" +
|
||||||
|
function_type() + "\" component.\n" + "Period: " + cvm::to_str(period) +
|
||||||
|
" wrapAround: " + cvm::to_str(wrap_center),
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
} else {
|
||||||
|
enable(f_cvc_periodic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((wrap_center != 0.0) && !is_enabled(f_cvc_periodic)) {
|
||||||
|
error_code |= cvm::error("Error: wrapAround was defined for a non-periodic component.\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
get_keyval_feature(this, conf, "debugGradients",
|
get_keyval_feature(this, conf, "debugGradients",
|
||||||
f_cvc_debug_gradient, false, parse_silent);
|
f_cvc_debug_gradient, false, parse_silent);
|
||||||
|
|
||||||
@ -119,7 +130,7 @@ int colvar::cvc::init(std::string const &conf)
|
|||||||
if (cvm::debug())
|
if (cvm::debug())
|
||||||
cvm::log("Done initializing cvc base object.\n");
|
cvm::log("Done initializing cvc base object.\n");
|
||||||
|
|
||||||
return cvm::get_error();
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -157,10 +168,13 @@ cvm::atom_group *colvar::cvc::parse_group(std::string const &conf,
|
|||||||
char const *group_key,
|
char const *group_key,
|
||||||
bool optional)
|
bool optional)
|
||||||
{
|
{
|
||||||
cvm::atom_group *group = NULL;
|
int error_code = COLVARS_OK;
|
||||||
|
|
||||||
|
cvm::atom_group *group = nullptr;
|
||||||
std::string group_conf;
|
std::string group_conf;
|
||||||
|
|
||||||
if (key_lookup(conf, group_key, &group_conf)) {
|
if (key_lookup(conf, group_key, &group_conf)) {
|
||||||
|
|
||||||
group = new cvm::atom_group(group_key);
|
group = new cvm::atom_group(group_key);
|
||||||
|
|
||||||
if (b_try_scalable) {
|
if (b_try_scalable) {
|
||||||
@ -177,31 +191,42 @@ cvm::atom_group *colvar::cvc::parse_group(std::string const &conf,
|
|||||||
// TODO check for other types of parallelism here
|
// TODO check for other types of parallelism here
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group_conf.size() == 0) {
|
if (group_conf.empty()) {
|
||||||
cvm::error("Error: atom group \""+group->key+
|
error_code |= cvm::error("Error: atom group \"" + group->key + "\" has no definition.\n",
|
||||||
"\" is set, but has no definition.\n",
|
COLVARS_INPUT_ERROR);
|
||||||
COLVARS_INPUT_ERROR);
|
delete group;
|
||||||
|
group = nullptr;
|
||||||
|
// Silence unused variable warning; TODO stop returning a pointer
|
||||||
|
(void) error_code;
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
cvm::increase_depth();
|
cvm::increase_depth();
|
||||||
if (group->parse(group_conf) == COLVARS_OK) {
|
error_code |= group->parse(group_conf);
|
||||||
|
if (error_code != COLVARS_OK) {
|
||||||
|
error_code |=
|
||||||
|
cvm::error("Error: in definition of atom group \"" + std::string(group_key) + "\".",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
delete group;
|
||||||
|
group = nullptr;
|
||||||
|
} else {
|
||||||
register_atom_group(group);
|
register_atom_group(group);
|
||||||
}
|
error_code |= group->check_keywords(group_conf, group_key);
|
||||||
group->check_keywords(group_conf, group_key);
|
|
||||||
if (cvm::get_error()) {
|
|
||||||
cvm::error("Error parsing definition for atom group \""+
|
|
||||||
std::string(group_key)+"\".", COLVARS_INPUT_ERROR);
|
|
||||||
}
|
}
|
||||||
cvm::decrease_depth();
|
cvm::decrease_depth();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (! optional) {
|
|
||||||
cvm::error("Error: definition for atom group \""+
|
if (!optional) {
|
||||||
std::string(group_key)+"\" not found.\n");
|
error_code |=
|
||||||
|
cvm::error("Error: atom group \"" + std::string(group_key) + "\" is required.\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Silence unused variable warning; TODO stop returning a pointer
|
||||||
|
(void) error_code;
|
||||||
|
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,6 +253,8 @@ int colvar::cvc::init_dependencies() {
|
|||||||
|
|
||||||
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_explicit_atom_groups, "explicit_atom_groups", 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);
|
||||||
@ -264,6 +291,7 @@ int colvar::cvc::init_dependencies() {
|
|||||||
|
|
||||||
init_feature(f_cvc_collect_atom_ids, "collect_atom_ids", f_type_dynamic);
|
init_feature(f_cvc_collect_atom_ids, "collect_atom_ids", f_type_dynamic);
|
||||||
require_feature_children(f_cvc_collect_atom_ids, f_ag_collect_atom_ids);
|
require_feature_children(f_cvc_collect_atom_ids, f_ag_collect_atom_ids);
|
||||||
|
require_feature_self(f_cvc_collect_atom_ids, f_cvc_explicit_atom_groups);
|
||||||
|
|
||||||
// TODO only enable this when f_ag_scalable can be turned on for a pre-initialized group
|
// TODO only enable this when f_ag_scalable can be turned on for a pre-initialized group
|
||||||
// require_feature_children(f_cvc_scalable, f_ag_scalable);
|
// require_feature_children(f_cvc_scalable, f_ag_scalable);
|
||||||
@ -281,7 +309,7 @@ int colvar::cvc::init_dependencies() {
|
|||||||
// default as available, not enabled
|
// default as available, not enabled
|
||||||
// except dynamic features which default as unavailable
|
// except dynamic features which default as unavailable
|
||||||
feature_states.reserve(f_cvc_ntot);
|
feature_states.reserve(f_cvc_ntot);
|
||||||
for (i = 0; i < colvardeps::f_cvc_ntot; i++) {
|
for (i = feature_states.size(); i < colvardeps::f_cvc_ntot; i++) {
|
||||||
bool avail = is_dynamic(i) ? false : true;
|
bool avail = is_dynamic(i) ? false : true;
|
||||||
feature_states.push_back(feature_state(avail, false));
|
feature_states.push_back(feature_state(avail, false));
|
||||||
}
|
}
|
||||||
@ -292,6 +320,8 @@ int colvar::cvc::init_dependencies() {
|
|||||||
feature_states[f_cvc_gradient].available = true;
|
feature_states[f_cvc_gradient].available = true;
|
||||||
feature_states[f_cvc_collect_atom_ids].available = true;
|
feature_states[f_cvc_collect_atom_ids].available = true;
|
||||||
|
|
||||||
|
feature_states[f_cvc_periodic].available = false;
|
||||||
|
|
||||||
// CVCs are enabled from the start - get disabled based on flags
|
// CVCs are enabled from the start - get disabled based on flags
|
||||||
enable(f_cvc_active);
|
enable(f_cvc_active);
|
||||||
|
|
||||||
@ -314,7 +344,7 @@ int colvar::cvc::init_dependencies() {
|
|||||||
|
|
||||||
int colvar::cvc::setup()
|
int colvar::cvc::setup()
|
||||||
{
|
{
|
||||||
description = "cvc " + name;
|
update_description();
|
||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,6 +379,7 @@ void colvar::cvc::init_as_angle()
|
|||||||
void colvar::cvc::init_as_periodic_angle()
|
void colvar::cvc::init_as_periodic_angle()
|
||||||
{
|
{
|
||||||
x.type(colvarvalue::type_scalar);
|
x.type(colvarvalue::type_scalar);
|
||||||
|
provide(f_cvc_periodic);
|
||||||
enable(f_cvc_periodic);
|
enable(f_cvc_periodic);
|
||||||
period = 360.0;
|
period = 360.0;
|
||||||
init_scalar_boundaries(-180.0, 180.0);
|
init_scalar_boundaries(-180.0, 180.0);
|
||||||
@ -372,6 +403,7 @@ void colvar::cvc::register_atom_group(cvm::atom_group *ag)
|
|||||||
{
|
{
|
||||||
atom_groups.push_back(ag);
|
atom_groups.push_back(ag);
|
||||||
add_child(ag);
|
add_child(ag);
|
||||||
|
enable(f_cvc_explicit_atom_groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -411,29 +443,21 @@ int colvar::cvc::set_param(std::string const ¶m_name,
|
|||||||
|
|
||||||
void colvar::cvc::read_data()
|
void colvar::cvc::read_data()
|
||||||
{
|
{
|
||||||
size_t ig;
|
if (is_enabled(f_cvc_explicit_atom_groups)) {
|
||||||
for (ig = 0; ig < atom_groups.size(); ig++) {
|
for (auto agi = atom_groups.begin(); agi != atom_groups.end(); agi++) {
|
||||||
cvm::atom_group &atoms = *(atom_groups[ig]);
|
cvm::atom_group &atoms = *(*agi);
|
||||||
atoms.reset_atoms_data();
|
atoms.reset_atoms_data();
|
||||||
atoms.read_positions();
|
atoms.read_positions();
|
||||||
atoms.calc_required_properties();
|
atoms.calc_required_properties();
|
||||||
// each atom group will take care of its own fitting_group, if defined
|
// each atom group will take care of its own fitting_group, if defined
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Don't try to get atom velocities, as no back-end currently implements it
|
|
||||||
// if (tasks[task_output_velocity] && !tasks[task_fdiff_velocity]) {
|
|
||||||
// for (i = 0; i < cvcs.size(); i++) {
|
|
||||||
// for (ig = 0; ig < cvcs[i]->atom_groups.size(); ig++) {
|
|
||||||
// cvcs[i]->atom_groups[ig]->read_velocities();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::vector<int> > colvar::cvc::get_atom_lists()
|
std::vector<std::vector<int>> colvar::cvc::get_atom_lists()
|
||||||
{
|
{
|
||||||
std::vector<std::vector<int> > lists;
|
std::vector<std::vector<int>> lists;
|
||||||
|
|
||||||
std::vector<cvm::atom_group *>::iterator agi = atom_groups.begin();
|
std::vector<cvm::atom_group *>::iterator agi = atom_groups.begin();
|
||||||
for ( ; agi != atom_groups.end(); ++agi) {
|
for ( ; agi != atom_groups.end(); ++agi) {
|
||||||
@ -462,12 +486,12 @@ void colvar::cvc::collect_gradients(std::vector<int> const &atom_ids, std::vecto
|
|||||||
// If necessary, apply inverse rotation to get atomic
|
// If necessary, apply inverse rotation to get atomic
|
||||||
// gradient in the laboratory frame
|
// gradient in the laboratory frame
|
||||||
if (ag.is_enabled(f_ag_rotate)) {
|
if (ag.is_enabled(f_ag_rotate)) {
|
||||||
cvm::rotation const rot_inv = ag.rot.inverse();
|
const auto rot_inv = ag.rot.inverse().matrix();
|
||||||
|
|
||||||
for (size_t k = 0; k < ag.size(); k++) {
|
for (size_t k = 0; k < ag.size(); k++) {
|
||||||
size_t a = std::lower_bound(atom_ids.begin(), atom_ids.end(),
|
size_t a = std::lower_bound(atom_ids.begin(), atom_ids.end(),
|
||||||
ag[k].id) - atom_ids.begin();
|
ag[k].id) - atom_ids.begin();
|
||||||
atomic_gradients[a] += coeff * rot_inv.rotate(ag[k].grad);
|
atomic_gradients[a] += coeff * (rot_inv * ag[k].grad);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -494,7 +518,7 @@ void colvar::cvc::collect_gradients(std::vector<int> const &atom_ids, std::vecto
|
|||||||
void colvar::cvc::calc_force_invgrads()
|
void colvar::cvc::calc_force_invgrads()
|
||||||
{
|
{
|
||||||
cvm::error("Error: calculation of inverse gradients is not implemented "
|
cvm::error("Error: calculation of inverse gradients is not implemented "
|
||||||
"for colvar components of type \""+function_type+"\".\n",
|
"for colvar components of type \""+function_type()+"\".\n",
|
||||||
COLVARS_NOT_IMPLEMENTED);
|
COLVARS_NOT_IMPLEMENTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,7 +526,7 @@ void colvar::cvc::calc_force_invgrads()
|
|||||||
void colvar::cvc::calc_Jacobian_derivative()
|
void colvar::cvc::calc_Jacobian_derivative()
|
||||||
{
|
{
|
||||||
cvm::error("Error: calculation of inverse gradients is not implemented "
|
cvm::error("Error: calculation of inverse gradients is not implemented "
|
||||||
"for colvar components of type \""+function_type+"\".\n",
|
"for colvar components of type \""+function_type()+"\".\n",
|
||||||
COLVARS_NOT_IMPLEMENTED);
|
COLVARS_NOT_IMPLEMENTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,6 +539,18 @@ void colvar::cvc::calc_fit_gradients()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void colvar::cvc::apply_force(colvarvalue const &cvforce)
|
||||||
|
{
|
||||||
|
if (is_enabled(f_cvc_explicit_atom_groups)) {
|
||||||
|
for (auto agi = atom_groups.begin(); agi != atom_groups.end(); agi++) {
|
||||||
|
if (!(*agi)->noforce) {
|
||||||
|
(*agi)->apply_colvar_force(cvforce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::cvc::debug_gradients()
|
void colvar::cvc::debug_gradients()
|
||||||
{
|
{
|
||||||
// this function should work for any scalar cvc:
|
// this function should work for any scalar cvc:
|
||||||
@ -528,8 +564,8 @@ void colvar::cvc::debug_gradients()
|
|||||||
cvm::atom_group *group = atom_groups[ig];
|
cvm::atom_group *group = atom_groups[ig];
|
||||||
if (group->b_dummy) continue;
|
if (group->b_dummy) continue;
|
||||||
|
|
||||||
cvm::rotation const rot_0 = group->rot;
|
const auto rot_0 = group->rot.matrix();
|
||||||
cvm::rotation const rot_inv = group->rot.inverse();
|
const auto rot_inv = group->rot.inverse().matrix();
|
||||||
|
|
||||||
cvm::real x_0 = x.real_value;
|
cvm::real x_0 = x.real_value;
|
||||||
if ((x.type() == colvarvalue::type_vector) && (x.size() == 1)) x_0 = x[0];
|
if ((x.type() == colvarvalue::type_vector) && (x.size() == 1)) x_0 = x[0];
|
||||||
@ -550,7 +586,7 @@ void colvar::cvc::debug_gradients()
|
|||||||
cvm::log((group->fitting_group ? std::string("refPosGroup") : group->key) +
|
cvm::log((group->fitting_group ? std::string("refPosGroup") : group->key) +
|
||||||
"[" + cvm::to_str(j) + "] = " +
|
"[" + cvm::to_str(j) + "] = " +
|
||||||
(group->is_enabled(f_ag_rotate) ?
|
(group->is_enabled(f_ag_rotate) ?
|
||||||
cvm::to_str(rot_0.rotate(group_for_fit->fit_gradients[j])) :
|
cvm::to_str(rot_0 * (group_for_fit->fit_gradients[j])) :
|
||||||
cvm::to_str(group_for_fit->fit_gradients[j])));
|
cvm::to_str(group_for_fit->fit_gradients[j])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -561,7 +597,7 @@ void colvar::cvc::debug_gradients()
|
|||||||
|
|
||||||
// tests are best conducted in the unrotated (simulation) frame
|
// tests are best conducted in the unrotated (simulation) frame
|
||||||
cvm::rvector const atom_grad = (group->is_enabled(f_ag_rotate) ?
|
cvm::rvector const atom_grad = (group->is_enabled(f_ag_rotate) ?
|
||||||
rot_inv.rotate((*group)[ia].grad) :
|
rot_inv * ((*group)[ia].grad) :
|
||||||
(*group)[ia].grad);
|
(*group)[ia].grad);
|
||||||
gradient_sum += atom_grad;
|
gradient_sum += atom_grad;
|
||||||
|
|
||||||
@ -634,34 +670,43 @@ void colvar::cvc::debug_gradients()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cvm::real colvar::cvc::dist2(colvarvalue const &x1,
|
cvm::real colvar::cvc::dist2(colvarvalue const &x1, colvarvalue const &x2) const
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
{
|
||||||
return x1.dist2(x2);
|
cvm::real diff = x1.real_value - x2.real_value;
|
||||||
|
if (is_enabled(f_cvc_periodic)) {
|
||||||
|
cvm::real const shift = cvm::floor(diff / period + 0.5);
|
||||||
|
diff -= shift * period;
|
||||||
|
}
|
||||||
|
return diff * diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::cvc::dist2_lgrad(colvarvalue const &x1,
|
colvarvalue colvar::cvc::dist2_lgrad(colvarvalue const &x1, colvarvalue const &x2) const
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
{
|
||||||
return x1.dist2_grad(x2);
|
cvm::real diff = x1.real_value - x2.real_value;
|
||||||
|
if (is_enabled(f_cvc_periodic)) {
|
||||||
|
cvm::real const shift = cvm::floor(diff / period + 0.5);
|
||||||
|
diff -= shift * period;
|
||||||
|
}
|
||||||
|
return 2.0 * diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::cvc::dist2_rgrad(colvarvalue const &x1,
|
colvarvalue colvar::cvc::dist2_rgrad(colvarvalue const &x1, colvarvalue const &x2) const
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
{
|
||||||
return x2.dist2_grad(x1);
|
return cvc::dist2_lgrad(x1, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::cvc::wrap(colvarvalue & /* x_unwrapped */) const
|
void colvar::cvc::wrap(colvarvalue &x_unwrapped) const
|
||||||
{
|
{
|
||||||
return;
|
if (is_enabled(f_cvc_periodic)) {
|
||||||
|
cvm::real const shift = cvm::floor((x_unwrapped.real_value - wrap_center) / period + 0.5);
|
||||||
|
x_unwrapped.real_value -= shift * period;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Static members
|
// Static members
|
||||||
|
|
||||||
std::vector<colvardeps::feature *> colvar::cvc::cvc_features;
|
std::vector<colvardeps::feature *> colvar::cvc::cvc_features;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -12,13 +12,11 @@
|
|||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvarparse.h"
|
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvarcomp.h"
|
#include "colvarcomp.h"
|
||||||
|
|
||||||
|
|
||||||
colvar::alch_lambda::alch_lambda(std::string const &conf)
|
colvar::alch_lambda::alch_lambda()
|
||||||
: cvc(conf)
|
|
||||||
{
|
{
|
||||||
set_function_type("alchLambda");
|
set_function_type("alchLambda");
|
||||||
|
|
||||||
@ -56,12 +54,9 @@ void colvar::alch_lambda::apply_force(colvarvalue const & /* force */)
|
|||||||
cvm::proxy->set_alch_lambda(x.real_value);
|
cvm::proxy->set_alch_lambda(x.real_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
simple_scalar_dist_functions(alch_lambda)
|
|
||||||
|
|
||||||
|
|
||||||
|
colvar::alch_Flambda::alch_Flambda()
|
||||||
colvar::alch_Flambda::alch_Flambda(std::string const &conf)
|
|
||||||
: cvc(conf)
|
|
||||||
{
|
{
|
||||||
set_function_type("alch_Flambda");
|
set_function_type("alch_Flambda");
|
||||||
|
|
||||||
@ -103,4 +98,3 @@ void colvar::alch_Flambda::apply_force(colvarvalue const &force)
|
|||||||
cvm::proxy->indirect_lambda_biasing_force += d2E_dlambda2 * f;
|
cvm::proxy->indirect_lambda_biasing_force += d2E_dlambda2 * f;
|
||||||
}
|
}
|
||||||
|
|
||||||
simple_scalar_dist_functions(alch_Flambda)
|
|
||||||
|
|||||||
@ -12,8 +12,7 @@
|
|||||||
#include "colvarcomp.h"
|
#include "colvarcomp.h"
|
||||||
|
|
||||||
|
|
||||||
colvar::angle::angle(std::string const &conf)
|
colvar::angle::angle()
|
||||||
: cvc(conf)
|
|
||||||
{
|
{
|
||||||
set_function_type("angle");
|
set_function_type("angle");
|
||||||
init_as_angle();
|
init_as_angle();
|
||||||
@ -21,26 +20,25 @@ colvar::angle::angle(std::string const &conf)
|
|||||||
provide(f_cvc_inv_gradient);
|
provide(f_cvc_inv_gradient);
|
||||||
provide(f_cvc_Jacobian);
|
provide(f_cvc_Jacobian);
|
||||||
enable(f_cvc_com_based);
|
enable(f_cvc_com_based);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::angle::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
|
||||||
group1 = parse_group(conf, "group1");
|
group1 = parse_group(conf, "group1");
|
||||||
group2 = parse_group(conf, "group2");
|
group2 = parse_group(conf, "group2");
|
||||||
group3 = parse_group(conf, "group3");
|
group3 = parse_group(conf, "group3");
|
||||||
|
|
||||||
init_total_force_params(conf);
|
error_code |= init_total_force_params(conf);
|
||||||
|
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar::angle::angle(cvm::atom const &a1,
|
colvar::angle::angle(cvm::atom const &a1, cvm::atom const &a2, cvm::atom const &a3) : angle()
|
||||||
cvm::atom const &a2,
|
|
||||||
cvm::atom const &a3)
|
|
||||||
{
|
{
|
||||||
set_function_type("angle");
|
|
||||||
init_as_angle();
|
|
||||||
|
|
||||||
provide(f_cvc_inv_gradient);
|
|
||||||
provide(f_cvc_Jacobian);
|
|
||||||
enable(f_cvc_com_based);
|
|
||||||
|
|
||||||
group1 = new cvm::atom_group(std::vector<cvm::atom>(1, a1));
|
group1 = new cvm::atom_group(std::vector<cvm::atom>(1, a1));
|
||||||
group2 = new cvm::atom_group(std::vector<cvm::atom>(1, a2));
|
group2 = new cvm::atom_group(std::vector<cvm::atom>(1, a2));
|
||||||
group3 = new cvm::atom_group(std::vector<cvm::atom>(1, a3));
|
group3 = new cvm::atom_group(std::vector<cvm::atom>(1, a3));
|
||||||
@ -120,52 +118,6 @@ void colvar::angle::calc_Jacobian_derivative()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::angle::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
if (!group1->noforce)
|
|
||||||
group1->apply_colvar_force(force.real_value);
|
|
||||||
|
|
||||||
if (!group2->noforce)
|
|
||||||
group2->apply_colvar_force(force.real_value);
|
|
||||||
|
|
||||||
if (!group3->noforce)
|
|
||||||
group3->apply_colvar_force(force.real_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
simple_scalar_dist_functions(angle)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
colvar::dipole_angle::dipole_angle(std::string const &conf)
|
|
||||||
: cvc(conf)
|
|
||||||
{
|
|
||||||
set_function_type("dipoleAngle");
|
|
||||||
init_as_angle();
|
|
||||||
|
|
||||||
group1 = parse_group(conf, "group1");
|
|
||||||
group2 = parse_group(conf, "group2");
|
|
||||||
group3 = parse_group(conf, "group3");
|
|
||||||
|
|
||||||
init_total_force_params(conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvar::dipole_angle::dipole_angle(cvm::atom const &a1,
|
|
||||||
cvm::atom const &a2,
|
|
||||||
cvm::atom const &a3)
|
|
||||||
{
|
|
||||||
set_function_type("dipoleAngle");
|
|
||||||
init_as_angle();
|
|
||||||
|
|
||||||
group1 = new cvm::atom_group(std::vector<cvm::atom>(1, a1));
|
|
||||||
group2 = new cvm::atom_group(std::vector<cvm::atom>(1, a2));
|
|
||||||
group3 = new cvm::atom_group(std::vector<cvm::atom>(1, a3));
|
|
||||||
register_atom_group(group1);
|
|
||||||
register_atom_group(group2);
|
|
||||||
register_atom_group(group3);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvar::dipole_angle::dipole_angle()
|
colvar::dipole_angle::dipole_angle()
|
||||||
{
|
{
|
||||||
@ -174,6 +126,19 @@ colvar::dipole_angle::dipole_angle()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::dipole_angle::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
|
||||||
|
group1 = parse_group(conf, "group1");
|
||||||
|
group2 = parse_group(conf, "group2");
|
||||||
|
group3 = parse_group(conf, "group3");
|
||||||
|
|
||||||
|
error_code |= init_total_force_params(conf);
|
||||||
|
return error_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::dipole_angle::calc_value()
|
void colvar::dipole_angle::calc_value()
|
||||||
{
|
{
|
||||||
cvm::atom_pos const g1_pos = group1->center_of_mass();
|
cvm::atom_pos const g1_pos = group1->center_of_mass();
|
||||||
@ -229,52 +194,35 @@ void colvar::dipole_angle::calc_gradients()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::dipole_angle::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
if (!group1->noforce)
|
|
||||||
group1->apply_colvar_force(force.real_value);
|
|
||||||
|
|
||||||
if (!group2->noforce)
|
colvar::dihedral::dihedral()
|
||||||
group2->apply_colvar_force(force.real_value);
|
|
||||||
|
|
||||||
if (!group3->noforce)
|
|
||||||
group3->apply_colvar_force(force.real_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
simple_scalar_dist_functions(dipole_angle)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
colvar::dihedral::dihedral(std::string const &conf)
|
|
||||||
: cvc(conf)
|
|
||||||
{
|
{
|
||||||
set_function_type("dihedral");
|
set_function_type("dihedral");
|
||||||
init_as_periodic_angle();
|
init_as_periodic_angle();
|
||||||
provide(f_cvc_inv_gradient);
|
provide(f_cvc_inv_gradient);
|
||||||
provide(f_cvc_Jacobian);
|
provide(f_cvc_Jacobian);
|
||||||
enable(f_cvc_com_based);
|
enable(f_cvc_com_based);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::dihedral::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
|
||||||
group1 = parse_group(conf, "group1");
|
group1 = parse_group(conf, "group1");
|
||||||
group2 = parse_group(conf, "group2");
|
group2 = parse_group(conf, "group2");
|
||||||
group3 = parse_group(conf, "group3");
|
group3 = parse_group(conf, "group3");
|
||||||
group4 = parse_group(conf, "group4");
|
group4 = parse_group(conf, "group4");
|
||||||
|
|
||||||
init_total_force_params(conf);
|
error_code |= init_total_force_params(conf);
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar::dihedral::dihedral(cvm::atom const &a1,
|
colvar::dihedral::dihedral(cvm::atom const &a1, cvm::atom const &a2, cvm::atom const &a3,
|
||||||
cvm::atom const &a2,
|
|
||||||
cvm::atom const &a3,
|
|
||||||
cvm::atom const &a4)
|
cvm::atom const &a4)
|
||||||
|
: dihedral()
|
||||||
{
|
{
|
||||||
set_function_type("dihedral");
|
|
||||||
init_as_periodic_angle();
|
|
||||||
provide(f_cvc_inv_gradient);
|
|
||||||
provide(f_cvc_Jacobian);
|
|
||||||
enable(f_cvc_com_based);
|
|
||||||
|
|
||||||
b_1site_force = false;
|
b_1site_force = false;
|
||||||
|
|
||||||
group1 = new cvm::atom_group(std::vector<cvm::atom>(1, a1));
|
group1 = new cvm::atom_group(std::vector<cvm::atom>(1, a1));
|
||||||
@ -288,16 +236,6 @@ colvar::dihedral::dihedral(cvm::atom const &a1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar::dihedral::dihedral()
|
|
||||||
{
|
|
||||||
set_function_type("dihedral");
|
|
||||||
init_as_periodic_angle();
|
|
||||||
enable(f_cvc_periodic);
|
|
||||||
provide(f_cvc_inv_gradient);
|
|
||||||
provide(f_cvc_Jacobian);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void colvar::dihedral::calc_value()
|
void colvar::dihedral::calc_value()
|
||||||
{
|
{
|
||||||
cvm::atom_pos const g1_pos = group1->center_of_mass();
|
cvm::atom_pos const g1_pos = group1->center_of_mass();
|
||||||
@ -323,7 +261,7 @@ void colvar::dihedral::calc_value()
|
|||||||
cvm::real const sin_phi = n1 * r34 * r23.norm();
|
cvm::real const sin_phi = n1 * r34 * r23.norm();
|
||||||
|
|
||||||
x.real_value = (180.0/PI) * cvm::atan2(sin_phi, cos_phi);
|
x.real_value = (180.0/PI) * cvm::atan2(sin_phi, cos_phi);
|
||||||
this->wrap(x);
|
wrap(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -349,7 +287,7 @@ void colvar::dihedral::calc_gradients()
|
|||||||
A *= rA;
|
A *= rA;
|
||||||
cvm::rvector const dcosdA = rA*(cos_phi*A-B);
|
cvm::rvector const dcosdA = rA*(cos_phi*A-B);
|
||||||
cvm::rvector const dcosdB = rB*(cos_phi*B-A);
|
cvm::rvector const dcosdB = rB*(cos_phi*B-A);
|
||||||
rA = 1.0;
|
// rA = 1.0;
|
||||||
|
|
||||||
cvm::real const K = (1.0/sin_phi) * (180.0/PI);
|
cvm::real const K = (1.0/sin_phi) * (180.0/PI);
|
||||||
|
|
||||||
@ -363,7 +301,7 @@ void colvar::dihedral::calc_gradients()
|
|||||||
C *= rC;
|
C *= rC;
|
||||||
cvm::rvector const dsindC = rC*(sin_phi*C-B);
|
cvm::rvector const dsindC = rC*(sin_phi*C-B);
|
||||||
cvm::rvector const dsindB = rB*(sin_phi*B-C);
|
cvm::rvector const dsindB = rB*(sin_phi*B-C);
|
||||||
rC = 1.0;
|
// rC = 1.0;
|
||||||
|
|
||||||
cvm::real const K = (-1.0/cos_phi) * (180.0/PI);
|
cvm::real const K = (-1.0/cos_phi) * (180.0/PI);
|
||||||
|
|
||||||
@ -439,81 +377,22 @@ void colvar::dihedral::calc_Jacobian_derivative()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::dihedral::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
if (!group1->noforce)
|
|
||||||
group1->apply_colvar_force(force.real_value);
|
|
||||||
|
|
||||||
if (!group2->noforce)
|
|
||||||
group2->apply_colvar_force(force.real_value);
|
|
||||||
|
|
||||||
if (!group3->noforce)
|
|
||||||
group3->apply_colvar_force(force.real_value);
|
|
||||||
|
|
||||||
if (!group4->noforce)
|
|
||||||
group4->apply_colvar_force(force.real_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// metrics functions for cvc implementations with a periodicity
|
|
||||||
|
|
||||||
cvm::real colvar::dihedral::dist2(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return diff * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::dihedral::dist2_lgrad(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return 2.0 * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::dihedral::dist2_rgrad(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return (-2.0) * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void colvar::dihedral::wrap(colvarvalue &x_unwrapped) const
|
|
||||||
{
|
|
||||||
if ((x_unwrapped.real_value - wrap_center) >= 180.0) {
|
|
||||||
x_unwrapped.real_value -= 360.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((x_unwrapped.real_value - wrap_center) < -180.0) {
|
|
||||||
x_unwrapped.real_value += 360.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvar::polar_theta::polar_theta(std::string const &conf)
|
|
||||||
: cvc(conf)
|
|
||||||
{
|
|
||||||
set_function_type("polarTheta");
|
|
||||||
enable(f_cvc_com_based);
|
|
||||||
|
|
||||||
atoms = parse_group(conf, "atoms");
|
|
||||||
init_total_force_params(conf);
|
|
||||||
x.type(colvarvalue::type_scalar);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvar::polar_theta::polar_theta()
|
colvar::polar_theta::polar_theta()
|
||||||
{
|
{
|
||||||
|
r = theta = phi = 0.0;
|
||||||
set_function_type("polarTheta");
|
set_function_type("polarTheta");
|
||||||
x.type(colvarvalue::type_scalar);
|
enable(f_cvc_com_based);
|
||||||
|
init_as_angle();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::polar_theta::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
atoms = parse_group(conf, "atoms");
|
||||||
|
error_code |= init_total_force_params(conf);
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -540,35 +419,25 @@ void colvar::polar_theta::calc_gradients()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::polar_theta::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
if (!atoms->noforce)
|
|
||||||
atoms->apply_colvar_force(force.real_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
simple_scalar_dist_functions(polar_theta)
|
|
||||||
|
|
||||||
|
|
||||||
colvar::polar_phi::polar_phi(std::string const &conf)
|
|
||||||
: cvc(conf)
|
|
||||||
{
|
|
||||||
set_function_type("polarPhi");
|
|
||||||
init_as_periodic_angle();
|
|
||||||
enable(f_cvc_com_based);
|
|
||||||
|
|
||||||
atoms = parse_group(conf, "atoms");
|
|
||||||
init_total_force_params(conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvar::polar_phi::polar_phi()
|
colvar::polar_phi::polar_phi()
|
||||||
{
|
{
|
||||||
|
r = theta = phi = 0.0;
|
||||||
set_function_type("polarPhi");
|
set_function_type("polarPhi");
|
||||||
|
enable(f_cvc_com_based);
|
||||||
init_as_periodic_angle();
|
init_as_periodic_angle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::polar_phi::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
atoms = parse_group(conf, "atoms");
|
||||||
|
error_code |= init_total_force_params(conf);
|
||||||
|
return error_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::polar_phi::calc_value()
|
void colvar::polar_phi::calc_value()
|
||||||
{
|
{
|
||||||
cvm::rvector pos = atoms->center_of_mass();
|
cvm::rvector pos = atoms->center_of_mass();
|
||||||
@ -587,55 +456,3 @@ void colvar::polar_phi::calc_gradients()
|
|||||||
(180.0/PI) * cvm::cos(phi) / (r*cvm::sin(theta)),
|
(180.0/PI) * cvm::cos(phi) / (r*cvm::sin(theta)),
|
||||||
0.));
|
0.));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::polar_phi::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
if (!atoms->noforce)
|
|
||||||
atoms->apply_colvar_force(force.real_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Same as dihedral, for polar_phi
|
|
||||||
|
|
||||||
cvm::real colvar::polar_phi::dist2(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return diff * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::polar_phi::dist2_lgrad(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return 2.0 * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::polar_phi::dist2_rgrad(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return (-2.0) * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void colvar::polar_phi::wrap(colvarvalue &x_unwrapped) const
|
|
||||||
{
|
|
||||||
if ((x_unwrapped.real_value - wrap_center) >= 180.0) {
|
|
||||||
x_unwrapped.real_value -= 360.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((x_unwrapped.real_value - wrap_center) < -180.0) {
|
|
||||||
x_unwrapped.real_value += 360.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,78 +1,312 @@
|
|||||||
#if (__cplusplus >= 201103L)
|
// -*- 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 <numeric>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvarparse.h"
|
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvarcomp.h"
|
#include "colvarcomp.h"
|
||||||
|
#include "colvar_arithmeticpath.h"
|
||||||
|
|
||||||
colvar::aspathCV::aspathCV(std::string const &conf): CVBasedPath(conf) {
|
|
||||||
|
struct ArithmeticPathImpl: public ArithmeticPathCV::ArithmeticPathBase<cvm::real> {
|
||||||
|
std::vector<std::vector<colvarvalue>> frame_element_distances;
|
||||||
|
std::vector<std::vector<colvarvalue>> dsdx;
|
||||||
|
std::vector<std::vector<colvarvalue>> dzdx;
|
||||||
|
template <typename T>
|
||||||
|
void updateCartesianDistanceToReferenceFrames(T* obj) {
|
||||||
|
for (size_t i_frame = 0; i_frame < obj->reference_frames.size(); ++i_frame) {
|
||||||
|
for (size_t i_atom = 0; i_atom < obj->atoms->size(); ++i_atom) {
|
||||||
|
frame_element_distances[i_frame][i_atom] = (*(obj->comp_atoms[i_frame]))[i_atom].pos - obj->reference_frames[i_frame][i_atom];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
void updateCVDistanceToReferenceFrames(T* obj) {
|
||||||
|
for (size_t i_cv = 0; i_cv < obj->cv.size(); ++i_cv) {
|
||||||
|
obj->cv[i_cv]->calc_value();
|
||||||
|
}
|
||||||
|
for (size_t i_frame = 0; i_frame < obj->ref_cv.size(); ++i_frame) {
|
||||||
|
for (size_t i_cv = 0; i_cv < obj->cv.size(); ++i_cv) {
|
||||||
|
colvarvalue ref_cv_value(obj->ref_cv[i_frame][i_cv]);
|
||||||
|
colvarvalue current_cv_value(obj->cv[i_cv]->value());
|
||||||
|
if (current_cv_value.type() == colvarvalue::type_scalar) {
|
||||||
|
frame_element_distances[i_frame][i_cv] = 0.5 * obj->cv[i_cv]->dist2_lgrad(obj->cv[i_cv]->sup_coeff * (cvm::pow(current_cv_value.real_value, obj->cv[i_cv]->sup_np)), ref_cv_value.real_value);
|
||||||
|
} else {
|
||||||
|
frame_element_distances[i_frame][i_cv] = 0.5 * obj->cv[i_cv]->dist2_lgrad(obj->cv[i_cv]->sup_coeff * current_cv_value, ref_cv_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ArithmeticPathImpl(size_t p_num_elements, size_t p_total_frames, cvm::real p_lambda, const std::vector<cvm::real>& p_weights) {
|
||||||
|
ArithmeticPathCV::ArithmeticPathBase<cvm::real>::initialize(p_num_elements, p_total_frames, p_lambda, p_weights);
|
||||||
|
frame_element_distances.resize(p_total_frames, std::vector<colvarvalue>(p_num_elements, colvarvalue(colvarvalue::Type::type_notset)));
|
||||||
|
dsdx.resize(p_total_frames, std::vector<colvarvalue>(p_num_elements, colvarvalue(colvarvalue::Type::type_notset)));
|
||||||
|
dzdx.resize(p_total_frames, std::vector<colvarvalue>(p_num_elements, colvarvalue(colvarvalue::Type::type_notset)));
|
||||||
|
}
|
||||||
|
cvm::real get_lambda() const {return lambda;}
|
||||||
|
cvm::real compute_s() {
|
||||||
|
cvm::real s;
|
||||||
|
computeValue(frame_element_distances, &s, nullptr);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
cvm::real compute_z() {
|
||||||
|
cvm::real z;
|
||||||
|
computeValue(frame_element_distances, nullptr, &z);
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
void compute_s_derivatives() {
|
||||||
|
computeDerivatives<colvarvalue>(frame_element_distances, &dsdx, nullptr);
|
||||||
|
}
|
||||||
|
void compute_z_derivatives() {
|
||||||
|
computeDerivatives<colvarvalue>(frame_element_distances, nullptr, &dzdx);
|
||||||
|
}
|
||||||
|
// for debug gradients of implicit sub CVs
|
||||||
|
template <typename T>
|
||||||
|
colvarvalue compute_s_analytical_derivative_ij(size_t i, size_t j, cvm::real eps, T* obj) const {
|
||||||
|
ArithmeticPathImpl tmp_left(*this), tmp_right(*this);
|
||||||
|
const size_t value_size = frame_element_distances[i][j].size();
|
||||||
|
colvarvalue result(frame_element_distances[i][j].type());
|
||||||
|
colvarvalue ref_cv_value(obj->ref_cv[i][j]);
|
||||||
|
for (size_t k = 0; k < value_size; ++k) {
|
||||||
|
// get the current CV value
|
||||||
|
colvarvalue current_cv_value(obj->cv[j]->value());
|
||||||
|
// save the old values in frame element distance matrices
|
||||||
|
const auto saved_left = tmp_left.frame_element_distances[i][j][k];
|
||||||
|
const auto saved_right = tmp_right.frame_element_distances[i][j][k];
|
||||||
|
// update frame element distance matrices
|
||||||
|
if (current_cv_value.type() == colvarvalue::type_scalar) {
|
||||||
|
tmp_left.frame_element_distances[i][j] = 0.5 * obj->cv[j]->dist2_lgrad(obj->cv[j]->sup_coeff * (cvm::pow(current_cv_value.real_value - eps, obj->cv[j]->sup_np)), ref_cv_value.real_value);
|
||||||
|
tmp_right.frame_element_distances[i][j] = 0.5 * obj->cv[j]->dist2_lgrad(obj->cv[j]->sup_coeff * (cvm::pow(current_cv_value.real_value + eps, obj->cv[j]->sup_np)), ref_cv_value.real_value);
|
||||||
|
} else {
|
||||||
|
current_cv_value[k] -= eps;
|
||||||
|
tmp_left.frame_element_distances[i][j] = 0.5 * obj->cv[j]->dist2_lgrad(obj->cv[j]->sup_coeff * current_cv_value, ref_cv_value);
|
||||||
|
current_cv_value[k] += eps + eps;
|
||||||
|
tmp_right.frame_element_distances[i][j] = 0.5 * obj->cv[j]->dist2_lgrad(obj->cv[j]->sup_coeff * current_cv_value, ref_cv_value);
|
||||||
|
}
|
||||||
|
const cvm::real s_left = tmp_left.compute_s();
|
||||||
|
const cvm::real s_right = tmp_right.compute_s();
|
||||||
|
result[k] = (s_right - s_left) / (2.0 * eps);
|
||||||
|
tmp_left.frame_element_distances[i][j][k] = saved_left;
|
||||||
|
tmp_right.frame_element_distances[i][j][k] = saved_right;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
colvarvalue compute_z_analytical_derivative_ij(size_t i, size_t j, cvm::real eps, T* obj) const {
|
||||||
|
ArithmeticPathImpl tmp_left(*this), tmp_right(*this);
|
||||||
|
const size_t value_size = frame_element_distances[i][j].size();
|
||||||
|
colvarvalue result(frame_element_distances[i][j].type());
|
||||||
|
colvarvalue ref_cv_value(obj->ref_cv[i][j]);
|
||||||
|
for (size_t k = 0; k < value_size; ++k) {
|
||||||
|
// get the current CV value
|
||||||
|
colvarvalue current_cv_value(obj->cv[j]->value());
|
||||||
|
// save the old values in frame element distance matrices
|
||||||
|
const auto saved_left = tmp_left.frame_element_distances[i][j][k];
|
||||||
|
const auto saved_right = tmp_right.frame_element_distances[i][j][k];
|
||||||
|
// update frame element distance matrices
|
||||||
|
if (current_cv_value.type() == colvarvalue::type_scalar) {
|
||||||
|
tmp_left.frame_element_distances[i][j] = 0.5 * obj->cv[j]->dist2_lgrad(obj->cv[j]->sup_coeff * (cvm::pow(current_cv_value.real_value - eps, obj->cv[j]->sup_np)), ref_cv_value.real_value);
|
||||||
|
tmp_right.frame_element_distances[i][j] = 0.5 * obj->cv[j]->dist2_lgrad(obj->cv[j]->sup_coeff * (cvm::pow(current_cv_value.real_value + eps, obj->cv[j]->sup_np)), ref_cv_value.real_value);
|
||||||
|
} else {
|
||||||
|
current_cv_value[k] -= eps;
|
||||||
|
tmp_left.frame_element_distances[i][j] = 0.5 * obj->cv[j]->dist2_lgrad(obj->cv[j]->sup_coeff * current_cv_value, ref_cv_value);
|
||||||
|
current_cv_value[k] += eps + eps;
|
||||||
|
tmp_right.frame_element_distances[i][j] = 0.5 * obj->cv[j]->dist2_lgrad(obj->cv[j]->sup_coeff * current_cv_value, ref_cv_value);
|
||||||
|
}
|
||||||
|
const cvm::real z_left = tmp_left.compute_z();
|
||||||
|
const cvm::real z_right = tmp_right.compute_z();
|
||||||
|
result[k] = (z_right - z_left) / (2.0 * eps);
|
||||||
|
tmp_left.frame_element_distances[i][j][k] = saved_left;
|
||||||
|
tmp_right.frame_element_distances[i][j][k] = saved_right;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
colvar::aspath::aspath()
|
||||||
|
{
|
||||||
|
set_function_type("aspath");
|
||||||
|
x.type(colvarvalue::type_scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::aspath::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = CartesianBasedPath::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n"));
|
||||||
|
cvm::real p_lambda;
|
||||||
|
get_keyval(conf, "lambda", p_lambda, -1.0);
|
||||||
|
const size_t num_atoms = atoms->size();
|
||||||
|
std::vector<cvm::real> p_weights(num_atoms, std::sqrt(1.0 / num_atoms));
|
||||||
|
// ArithmeticPathCV::ArithmeticPathBase<cvm::atom_pos, cvm::real, ArithmeticPathCV::path_sz::S>::initialize(num_atoms, total_reference_frames, p_lambda, reference_frames[0], p_weights);
|
||||||
|
if (impl_) impl_.reset();
|
||||||
|
impl_ = std::unique_ptr<ArithmeticPathImpl>(new ArithmeticPathImpl(num_atoms, total_reference_frames, p_lambda, p_weights));
|
||||||
|
cvm::log(std::string("Lambda is ") + cvm::to_str(impl_->get_lambda()) + std::string("\n"));
|
||||||
|
return error_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
colvar::aspath::~aspath() {}
|
||||||
|
|
||||||
|
void colvar::aspath::calc_value() {
|
||||||
|
if (impl_->get_lambda() < 0) {
|
||||||
|
// this implies that the user may not set a valid lambda value
|
||||||
|
// so recompute it by the suggested value in Parrinello's paper
|
||||||
|
cvm::log("A non-positive value of lambda is detected, which implies that it may not set in the configuration.\n");
|
||||||
|
cvm::log("This component (aspath) will recompute a value for lambda following the suggestion in the origin paper.\n");
|
||||||
|
std::vector<cvm::real> rmsd_between_refs(total_reference_frames - 1, 0.0);
|
||||||
|
computeDistanceBetweenReferenceFrames(rmsd_between_refs);
|
||||||
|
impl_->reComputeLambda(rmsd_between_refs);
|
||||||
|
cvm::log("Ok, the value of lambda is updated to " + cvm::to_str(impl_->get_lambda()));
|
||||||
|
}
|
||||||
|
impl_->updateCartesianDistanceToReferenceFrames(this);
|
||||||
|
x = impl_->compute_s();
|
||||||
|
}
|
||||||
|
|
||||||
|
void colvar::aspath::calc_gradients() {
|
||||||
|
impl_->compute_s_derivatives();
|
||||||
|
for (size_t i_frame = 0; i_frame < reference_frames.size(); ++i_frame) {
|
||||||
|
for (size_t i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
||||||
|
(*(comp_atoms[i_frame]))[i_atom].grad += impl_->dsdx[i_frame][i_atom];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void colvar::aspath::apply_force(colvarvalue const &force) {
|
||||||
|
cvm::real const &F = force.real_value;
|
||||||
|
for (size_t i_frame = 0; i_frame < reference_frames.size(); ++i_frame) {
|
||||||
|
(*(comp_atoms[i_frame])).apply_colvar_force(F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
colvar::azpath::azpath()
|
||||||
|
{
|
||||||
|
set_function_type("azpath");
|
||||||
|
x.type(colvarvalue::type_scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
int colvar::azpath::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = CartesianBasedPath::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n"));
|
||||||
|
x.type(colvarvalue::type_scalar);
|
||||||
|
cvm::real p_lambda;
|
||||||
|
get_keyval(conf, "lambda", p_lambda, -1.0);
|
||||||
|
const size_t num_atoms = atoms->size();
|
||||||
|
std::vector<cvm::real> p_weights(num_atoms, std::sqrt(1.0 / num_atoms));
|
||||||
|
if (impl_) impl_.reset();
|
||||||
|
impl_ = std::unique_ptr<ArithmeticPathImpl>(new ArithmeticPathImpl(num_atoms, total_reference_frames, p_lambda, p_weights));
|
||||||
|
cvm::log(std::string("Lambda is ") + cvm::to_str(impl_->get_lambda()) + std::string("\n"));
|
||||||
|
return error_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
colvar::azpath::~azpath() {}
|
||||||
|
|
||||||
|
void colvar::azpath::calc_value() {
|
||||||
|
if (impl_->get_lambda() < 0) {
|
||||||
|
// this implies that the user may not set a valid lambda value
|
||||||
|
// so recompute it by the suggested value in Parrinello's paper
|
||||||
|
cvm::log("A non-positive value of lambda is detected, which implies that it may not set in the configuration.\n");
|
||||||
|
cvm::log("This component (azpath) will recompute a value for lambda following the suggestion in the origin paper.\n");
|
||||||
|
std::vector<cvm::real> rmsd_between_refs(total_reference_frames - 1, 0.0);
|
||||||
|
computeDistanceBetweenReferenceFrames(rmsd_between_refs);
|
||||||
|
impl_->reComputeLambda(rmsd_between_refs);
|
||||||
|
cvm::log("Ok, the value of lambda is updated to " + cvm::to_str(impl_->get_lambda()));
|
||||||
|
}
|
||||||
|
impl_->updateCartesianDistanceToReferenceFrames(this);
|
||||||
|
x = impl_->compute_z();
|
||||||
|
}
|
||||||
|
|
||||||
|
void colvar::azpath::calc_gradients() {
|
||||||
|
impl_->compute_z_derivatives();
|
||||||
|
for (size_t i_frame = 0; i_frame < reference_frames.size(); ++i_frame) {
|
||||||
|
for (size_t i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
||||||
|
(*(comp_atoms[i_frame]))[i_atom].grad += impl_->dzdx[i_frame][i_atom];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void colvar::azpath::apply_force(colvarvalue const &force) {
|
||||||
|
cvm::real const &F = force.real_value;
|
||||||
|
for (size_t i_frame = 0; i_frame < reference_frames.size(); ++i_frame) {
|
||||||
|
(*(comp_atoms[i_frame])).apply_colvar_force(F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
colvar::aspathCV::aspathCV()
|
||||||
|
{
|
||||||
set_function_type("aspathCV");
|
set_function_type("aspathCV");
|
||||||
|
x.type(colvarvalue::type_scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
int colvar::aspathCV::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = CVBasedPath::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n"));
|
cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n"));
|
||||||
std::vector<cvm::real> p_weights(cv.size(), 1.0);
|
std::vector<cvm::real> p_weights(cv.size(), 1.0);
|
||||||
get_keyval(conf, "weights", p_weights, std::vector<cvm::real>(cv.size(), 1.0));
|
get_keyval(conf, "weights", p_weights, std::vector<cvm::real>(cv.size(), 1.0));
|
||||||
x.type(colvarvalue::type_scalar);
|
|
||||||
use_explicit_gradients = true;
|
use_explicit_gradients = true;
|
||||||
cvm::real p_lambda;
|
cvm::real p_lambda;
|
||||||
get_keyval(conf, "lambda", p_lambda, -1.0);
|
get_keyval(conf, "lambda", p_lambda, -1.0);
|
||||||
ArithmeticPathCV::ArithmeticPathBase<colvarvalue, cvm::real, ArithmeticPathCV::path_sz::S>::initialize(cv.size(), total_reference_frames, p_lambda, ref_cv[0], p_weights);
|
if (impl_) impl_.reset();
|
||||||
cvm::log(std::string("Lambda is ") + cvm::to_str(lambda) + std::string("\n"));
|
impl_ = std::unique_ptr<ArithmeticPathImpl>(new ArithmeticPathImpl(cv.size(), total_reference_frames, p_lambda, p_weights));
|
||||||
|
cvm::log(std::string("Lambda is ") + cvm::to_str(impl_->get_lambda()) + std::string("\n"));
|
||||||
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
||||||
if (!cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
|
if (!cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
|
||||||
use_explicit_gradients = false;
|
use_explicit_gradients = false;
|
||||||
}
|
}
|
||||||
cvm::log(std::string("The weight of CV ") + cvm::to_str(i_cv) + std::string(" is ") + cvm::to_str(weights[i_cv]) + std::string("\n"));
|
cvm::log(std::string("The weight of CV ") + cvm::to_str(i_cv) + std::string(" is ") + cvm::to_str(p_weights[i_cv]) + std::string("\n"));
|
||||||
}
|
}
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void colvar::aspathCV::updateDistanceToReferenceFrames() {
|
colvar::aspathCV::~aspathCV() {}
|
||||||
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
|
||||||
cv[i_cv]->calc_value();
|
|
||||||
}
|
|
||||||
for (size_t i_frame = 0; i_frame < ref_cv.size(); ++i_frame) {
|
|
||||||
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
|
||||||
colvarvalue ref_cv_value(ref_cv[i_frame][i_cv]);
|
|
||||||
colvarvalue current_cv_value(cv[i_cv]->value());
|
|
||||||
if (current_cv_value.type() == colvarvalue::type_scalar) {
|
|
||||||
frame_element_distances[i_frame][i_cv] = 0.5 * cv[i_cv]->dist2_lgrad(cv[i_cv]->sup_coeff * (cvm::pow(current_cv_value.real_value, cv[i_cv]->sup_np)), ref_cv_value.real_value);
|
|
||||||
} else {
|
|
||||||
frame_element_distances[i_frame][i_cv] = 0.5 * cv[i_cv]->dist2_lgrad(cv[i_cv]->sup_coeff * current_cv_value, ref_cv_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void colvar::aspathCV::calc_value() {
|
void colvar::aspathCV::calc_value() {
|
||||||
if (lambda < 0) {
|
if (impl_->get_lambda() < 0) {
|
||||||
// this implies that the user may not set a valid lambda value
|
// this implies that the user may not set a valid lambda value
|
||||||
// so recompute it by the suggested value in Parrinello's paper
|
// so recompute it by the suggested value in Parrinello's paper
|
||||||
cvm::log("A non-positive value of lambda is detected, which implies that it may not set in the configuration.\n");
|
cvm::log("A non-positive value of lambda is detected, which implies that it may not set in the configuration.\n");
|
||||||
cvm::log("This component (aspathCV) will recompute a value for lambda following the suggestion in the origin paper.\n");
|
cvm::log("This component (aspathCV) will recompute a value for lambda following the suggestion in the origin paper.\n");
|
||||||
std::vector<cvm::real> rmsd_between_refs(total_reference_frames - 1, 0.0);
|
std::vector<cvm::real> rmsd_between_refs(total_reference_frames - 1, 0.0);
|
||||||
computeDistanceBetweenReferenceFrames(rmsd_between_refs);
|
computeDistanceBetweenReferenceFrames(rmsd_between_refs);
|
||||||
reComputeLambda(rmsd_between_refs);
|
impl_->reComputeLambda(rmsd_between_refs);
|
||||||
cvm::log("Ok, the value of lambda is updated to " + cvm::to_str(lambda));
|
cvm::log("Ok, the value of lambda is updated to " + cvm::to_str(impl_->get_lambda()));
|
||||||
}
|
}
|
||||||
computeValue();
|
impl_->updateCVDistanceToReferenceFrames(this);
|
||||||
x = s;
|
x = impl_->compute_s();
|
||||||
}
|
}
|
||||||
|
|
||||||
void colvar::aspathCV::calc_gradients() {
|
void colvar::aspathCV::calc_gradients() {
|
||||||
computeDerivatives();
|
impl_->compute_s_derivatives();
|
||||||
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
||||||
cv[i_cv]->calc_gradients();
|
cv[i_cv]->calc_gradients();
|
||||||
if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
|
if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
|
||||||
cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
|
cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
|
||||||
|
// compute the gradient (grad) with respect to the i-th CV
|
||||||
|
colvarvalue grad(cv[i_cv]->value().type());
|
||||||
|
// sum up derivatives with respect to all frames
|
||||||
|
for (size_t m_frame = 0; m_frame < impl_->dsdx.size(); ++m_frame) {
|
||||||
|
// dsdx is the derivative of s with respect to the m-th frame
|
||||||
|
grad += impl_->dsdx[m_frame][i_cv];
|
||||||
|
}
|
||||||
for (size_t j_elem = 0; j_elem < cv[i_cv]->value().size(); ++j_elem) {
|
for (size_t j_elem = 0; j_elem < cv[i_cv]->value().size(); ++j_elem) {
|
||||||
for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) {
|
for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) {
|
||||||
for (size_t l_atom = 0; l_atom < (cv[i_cv]->atom_groups)[k_ag]->size(); ++l_atom) {
|
for (size_t l_atom = 0; l_atom < (cv[i_cv]->atom_groups)[k_ag]->size(); ++l_atom) {
|
||||||
(*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad = dsdx[i_cv][j_elem] * factor_polynomial * (*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad;
|
(*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad = grad[j_elem] * factor_polynomial * (*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,97 +322,137 @@ void colvar::aspathCV::apply_force(colvarvalue const &force) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
|
cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
|
||||||
colvarvalue cv_force = dsdx[i_cv] * force.real_value * factor_polynomial;
|
// compute the gradient (grad) with respect to the i-th CV
|
||||||
cv[i_cv]->apply_force(cv_force);
|
colvarvalue grad(cv[i_cv]->value().type());
|
||||||
}
|
for (size_t m_frame = 0; m_frame < impl_->dsdx.size(); ++m_frame) {
|
||||||
}
|
// dsdx is the derivative of s with respect to the m-th frame
|
||||||
}
|
grad += impl_->dsdx[m_frame][i_cv];
|
||||||
|
}
|
||||||
colvar::aspathCV::~aspathCV() {}
|
grad *= factor_polynomial;
|
||||||
|
cv[i_cv]->apply_force(force.real_value * grad);
|
||||||
colvar::azpathCV::azpathCV(std::string const &conf): CVBasedPath(conf) {
|
// try my best to debug gradients even if the sub-CVs do not have explicit gradients
|
||||||
set_function_type("azpathCV");
|
if (is_enabled(f_cvc_debug_gradient)) {
|
||||||
cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n"));
|
cvm::log("Debugging gradients for " + description +
|
||||||
std::vector<cvm::real> p_weights(cv.size(), 1.0);
|
" with respect to sub-CV " + cv[i_cv]->description +
|
||||||
get_keyval(conf, "weights", p_weights, std::vector<cvm::real>(cv.size(), 1.0));
|
", which has no explicit gradient with respect to its own input(s)");
|
||||||
x.type(colvarvalue::type_scalar);
|
colvarvalue analytical_grad(cv[i_cv]->value().type());
|
||||||
use_explicit_gradients = true;
|
for (size_t m_frame = 0; m_frame < impl_->dsdx.size(); ++m_frame) {
|
||||||
cvm::real p_lambda;
|
analytical_grad += impl_->compute_s_analytical_derivative_ij(
|
||||||
get_keyval(conf, "lambda", p_lambda, -1.0);
|
m_frame, i_cv, cvm::debug_gradients_step_size, this);
|
||||||
ArithmeticPathCV::ArithmeticPathBase<colvarvalue, cvm::real, ArithmeticPathCV::path_sz::Z>::initialize(cv.size(), total_reference_frames, p_lambda, ref_cv[0], p_weights);
|
}
|
||||||
cvm::log(std::string("Lambda is ") + cvm::to_str(lambda) + std::string("\n"));
|
cvm::log("dx(actual) = "+cvm::to_str(analytical_grad, 21, 14)+"\n");
|
||||||
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
cvm::log("dx(interp) = "+cvm::to_str(grad, 21, 14)+"\n");
|
||||||
if (!cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
|
cvm::log("|dx(actual) - dx(interp)|/|dx(actual)| = "+
|
||||||
use_explicit_gradients = false;
|
cvm::to_str((analytical_grad - grad).norm() /
|
||||||
}
|
(analytical_grad).norm(), 12, 5)+"\n");
|
||||||
cvm::log(std::string("The weight of CV ") + cvm::to_str(i_cv) + std::string(" is ") + cvm::to_str(weights[i_cv]) + std::string("\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void colvar::azpathCV::updateDistanceToReferenceFrames() {
|
|
||||||
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
|
||||||
cv[i_cv]->calc_value();
|
|
||||||
}
|
|
||||||
for (size_t i_frame = 0; i_frame < ref_cv.size(); ++i_frame) {
|
|
||||||
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
|
||||||
colvarvalue ref_cv_value(ref_cv[i_frame][i_cv]);
|
|
||||||
colvarvalue current_cv_value(cv[i_cv]->value());
|
|
||||||
if (current_cv_value.type() == colvarvalue::type_scalar) {
|
|
||||||
frame_element_distances[i_frame][i_cv] = 0.5 * cv[i_cv]->dist2_lgrad(cv[i_cv]->sup_coeff * (cvm::pow(current_cv_value.real_value, cv[i_cv]->sup_np)), ref_cv_value.real_value);
|
|
||||||
} else {
|
|
||||||
frame_element_distances[i_frame][i_cv] = 0.5 * cv[i_cv]->dist2_lgrad(cv[i_cv]->sup_coeff * current_cv_value, ref_cv_value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
colvar::azpathCV::azpathCV()
|
||||||
|
{
|
||||||
|
set_function_type("azpathCV");
|
||||||
|
x.type(colvarvalue::type_scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
int colvar::azpathCV::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = CVBasedPath::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n"));
|
||||||
|
std::vector<cvm::real> p_weights(cv.size(), 1.0);
|
||||||
|
get_keyval(conf, "weights", p_weights, std::vector<cvm::real>(cv.size(), 1.0));
|
||||||
|
use_explicit_gradients = true;
|
||||||
|
cvm::real p_lambda;
|
||||||
|
get_keyval(conf, "lambda", p_lambda, -1.0);
|
||||||
|
if (impl_) impl_.reset();
|
||||||
|
impl_ = std::unique_ptr<ArithmeticPathImpl>(new ArithmeticPathImpl(cv.size(), total_reference_frames, p_lambda, p_weights));
|
||||||
|
cvm::log(std::string("Lambda is ") + cvm::to_str(impl_->get_lambda()) + std::string("\n"));
|
||||||
|
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
||||||
|
if (!cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
|
||||||
|
use_explicit_gradients = false;
|
||||||
|
}
|
||||||
|
cvm::log(std::string("The weight of CV ") + cvm::to_str(i_cv) + std::string(" is ") + cvm::to_str(p_weights[i_cv]) + std::string("\n"));
|
||||||
|
}
|
||||||
|
return error_code;
|
||||||
|
}
|
||||||
|
|
||||||
void colvar::azpathCV::calc_value() {
|
void colvar::azpathCV::calc_value() {
|
||||||
if (lambda < 0) {
|
if (impl_->get_lambda() < 0) {
|
||||||
// this implies that the user may not set a valid lambda value
|
// this implies that the user may not set a valid lambda value
|
||||||
// so recompute it by the suggested value in Parrinello's paper
|
// so recompute it by the suggested value in Parrinello's paper
|
||||||
cvm::log("A non-positive value of lambda is detected, which implies that it may not set in the configuration.\n");
|
cvm::log("A non-positive value of lambda is detected, which implies that it may not set in the configuration.\n");
|
||||||
cvm::log("This component (azpathCV) will recompute a value for lambda following the suggestion in the origin paper.\n");
|
cvm::log("This component (azpathCV) will recompute a value for lambda following the suggestion in the origin paper.\n");
|
||||||
std::vector<cvm::real> rmsd_between_refs(total_reference_frames - 1, 0.0);
|
std::vector<cvm::real> rmsd_between_refs(total_reference_frames - 1, 0.0);
|
||||||
computeDistanceBetweenReferenceFrames(rmsd_between_refs);
|
computeDistanceBetweenReferenceFrames(rmsd_between_refs);
|
||||||
reComputeLambda(rmsd_between_refs);
|
impl_->reComputeLambda(rmsd_between_refs);
|
||||||
cvm::log("Ok, the value of lambda is updated to " + cvm::to_str(lambda));
|
cvm::log("Ok, the value of lambda is updated to " + cvm::to_str(impl_->get_lambda()));
|
||||||
}
|
}
|
||||||
computeValue();
|
impl_->updateCVDistanceToReferenceFrames(this);
|
||||||
x = z;
|
x = impl_->compute_z();
|
||||||
}
|
}
|
||||||
|
|
||||||
void colvar::azpathCV::calc_gradients() {
|
void colvar::azpathCV::calc_gradients() {
|
||||||
computeDerivatives();
|
impl_->compute_z_derivatives();
|
||||||
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
||||||
cv[i_cv]->calc_gradients();
|
cv[i_cv]->calc_gradients();
|
||||||
if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
|
if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
|
||||||
cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
|
cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
|
||||||
|
// compute the gradient (grad) with respect to the i-th CV
|
||||||
|
colvarvalue grad(cv[i_cv]->value().type());
|
||||||
|
// sum up derivatives with respect to all frames
|
||||||
|
for (size_t m_frame = 0; m_frame < impl_->dzdx.size(); ++m_frame) {
|
||||||
|
// dzdx is the derivative of z with respect to the m-th frame
|
||||||
|
grad += impl_->dzdx[m_frame][i_cv];
|
||||||
|
}
|
||||||
for (size_t j_elem = 0; j_elem < cv[i_cv]->value().size(); ++j_elem) {
|
for (size_t j_elem = 0; j_elem < cv[i_cv]->value().size(); ++j_elem) {
|
||||||
for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) {
|
for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) {
|
||||||
for (size_t l_atom = 0; l_atom < (cv[i_cv]->atom_groups)[k_ag]->size(); ++l_atom) {
|
for (size_t l_atom = 0; l_atom < (cv[i_cv]->atom_groups)[k_ag]->size(); ++l_atom) {
|
||||||
(*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad = dzdx[i_cv][j_elem] * factor_polynomial * (*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad;
|
(*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad = grad[j_elem] * factor_polynomial * (*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void colvar::azpathCV::apply_force(colvarvalue const &force) {
|
void colvar::azpathCV::apply_force(colvarvalue const &force) {
|
||||||
|
// the PCV component itself is a scalar, so force should be scalar
|
||||||
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
||||||
if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
|
if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
|
||||||
for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) {
|
for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) {
|
||||||
(cv[i_cv]->atom_groups)[k_ag]->apply_colvar_force(force.real_value);
|
(cv[i_cv]->atom_groups)[k_ag]->apply_colvar_force(force.real_value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
|
const cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
|
||||||
const colvarvalue cv_force = dzdx[i_cv] * force.real_value * factor_polynomial;
|
// compute the gradient (grad) with respect to the i-th CV
|
||||||
cv[i_cv]->apply_force(cv_force);
|
colvarvalue grad(cv[i_cv]->value().type());
|
||||||
|
for (size_t m_frame = 0; m_frame < impl_->dzdx.size(); ++m_frame) {
|
||||||
|
// dzdx is the derivative of z with respect to the m-th frame
|
||||||
|
grad += impl_->dzdx[m_frame][i_cv];
|
||||||
|
}
|
||||||
|
grad *= factor_polynomial;
|
||||||
|
cv[i_cv]->apply_force(force.real_value * grad);
|
||||||
|
// try my best to debug gradients even if the sub-CVs do not have explicit gradients
|
||||||
|
if (is_enabled(f_cvc_debug_gradient)) {
|
||||||
|
cvm::log("Debugging gradients for " + description +
|
||||||
|
" with respect to sub-CV " + cv[i_cv]->description +
|
||||||
|
", which has no explicit gradient with respect to its own input(s)");
|
||||||
|
colvarvalue analytical_grad(cv[i_cv]->value().type());
|
||||||
|
for (size_t m_frame = 0; m_frame < impl_->dzdx.size(); ++m_frame) {
|
||||||
|
analytical_grad += impl_->compute_z_analytical_derivative_ij(
|
||||||
|
m_frame, i_cv, cvm::debug_gradients_step_size, this);
|
||||||
|
}
|
||||||
|
cvm::log("dx(actual) = "+cvm::to_str(analytical_grad, 21, 14)+"\n");
|
||||||
|
cvm::log("dx(interp) = "+cvm::to_str(grad, 21, 14)+"\n");
|
||||||
|
cvm::log("|dx(actual) - dx(interp)|/|dx(actual)| = "+
|
||||||
|
cvm::to_str((analytical_grad - grad).norm() /
|
||||||
|
(analytical_grad).norm(), 12, 5)+"\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
colvar::azpathCV::~azpathCV() {}
|
colvar::azpathCV::~azpathCV() {}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#if (__cplusplus >= 201103L)
|
// -*- c++ -*-
|
||||||
|
|
||||||
// This file is part of the Collective Variables module (Colvars).
|
// This file is part of the Collective Variables module (Colvars).
|
||||||
// The original version of Colvars and its updates are located at:
|
// The original version of Colvars and its updates are located at:
|
||||||
@ -9,14 +9,26 @@
|
|||||||
|
|
||||||
#include "colvarcomp.h"
|
#include "colvarcomp.h"
|
||||||
|
|
||||||
colvar::linearCombination::linearCombination(std::string const &conf): cvc(conf) {
|
|
||||||
|
colvar::linearCombination::linearCombination()
|
||||||
|
{
|
||||||
|
set_function_type("linearCombination");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::linearCombination::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
|
||||||
// Lookup all available sub-cvcs
|
// Lookup all available sub-cvcs
|
||||||
for (auto it_cv_map = colvar::get_global_cvc_map().begin(); it_cv_map != colvar::get_global_cvc_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);
|
||||||
for (auto it_sub_cvc_conf = sub_cvc_confs.begin(); it_sub_cvc_conf != sub_cvc_confs.end(); ++it_sub_cvc_conf) {
|
for (auto it_sub_cvc_conf = sub_cvc_confs.begin(); it_sub_cvc_conf != sub_cvc_confs.end(); ++it_sub_cvc_conf) {
|
||||||
cv.push_back((it_cv_map->second)(*(it_sub_cvc_conf)));
|
cv.push_back((it_cv_map->second)());
|
||||||
|
cv.back()->init(*(it_sub_cvc_conf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,26 +41,11 @@ colvar::linearCombination::linearCombination(std::string const &conf): cvc(conf)
|
|||||||
}
|
}
|
||||||
// Show useful error messages and prevent crashes if no sub CVC is found
|
// Show useful error messages and prevent crashes if no sub CVC is found
|
||||||
if (cv.size() == 0) {
|
if (cv.size() == 0) {
|
||||||
cvm::error("Error: the CV " + name +
|
return cvm::error("Error: the CV " + name + " expects one or more nesting components.\n",
|
||||||
" expects one or more nesting components.\n");
|
COLVARS_INPUT_ERROR);
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: Maybe we can add an option to allow mixing scalar and vector types,
|
|
||||||
// but that's a bit complicated so we just require a consistent type
|
|
||||||
// of nesting CVs.
|
|
||||||
x.type(cv[0]->value());
|
x.type(cv[0]->value());
|
||||||
x.reset();
|
x.reset();
|
||||||
for (size_t i_cv = 1; i_cv < cv.size(); ++i_cv) {
|
|
||||||
const auto type_i = cv[i_cv]->value().type();
|
|
||||||
if (type_i != x.type()) {
|
|
||||||
cvm::error("Error: the type of sub-CVC " + cv[i_cv]->name +
|
|
||||||
" is " + colvarvalue::type_desc(type_i) + ", which is "
|
|
||||||
"different to the type of the first sub-CVC. Currently "
|
|
||||||
"only sub-CVCs of the same type are supported to be "
|
|
||||||
"nested.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
use_explicit_gradients = true;
|
use_explicit_gradients = true;
|
||||||
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
||||||
@ -59,6 +56,7 @@ colvar::linearCombination::linearCombination(std::string const &conf): cvc(conf)
|
|||||||
if (!use_explicit_gradients) {
|
if (!use_explicit_gradients) {
|
||||||
disable(f_cvc_explicit_gradient);
|
disable(f_cvc_explicit_gradient);
|
||||||
}
|
}
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
cvm::real colvar::linearCombination::getPolynomialFactorOfCVGradient(size_t i_cv) const {
|
cvm::real colvar::linearCombination::getPolynomialFactorOfCVGradient(size_t i_cv) const {
|
||||||
@ -138,8 +136,42 @@ void colvar::linearCombination::apply_force(colvarvalue const &force) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
colvar::customColvar::customColvar(std::string const &conf): linearCombination(conf) {
|
|
||||||
use_custom_function = false;
|
cvm::real colvar::linearCombination::dist2(colvarvalue const &x1, colvarvalue const &x2) const
|
||||||
|
{
|
||||||
|
return x1.dist2(x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
colvarvalue colvar::linearCombination::dist2_lgrad(colvarvalue const &x1,
|
||||||
|
colvarvalue const &x2) const
|
||||||
|
{
|
||||||
|
return x1.dist2_grad(x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
colvarvalue colvar::linearCombination::dist2_rgrad(colvarvalue const &x1,
|
||||||
|
colvarvalue const &x2) const
|
||||||
|
{
|
||||||
|
return x2.dist2_grad(x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void colvar::linearCombination::wrap(colvarvalue & /* x_unwrapped */) const {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
colvar::customColvar::customColvar()
|
||||||
|
{
|
||||||
|
set_function_type("customColvar");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::customColvar::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = linearCombination::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
|
||||||
// code swipe from colvar::init_custom_function
|
// code swipe from colvar::init_custom_function
|
||||||
std::string expr_in, expr;
|
std::string expr_in, expr;
|
||||||
size_t pos = 0; // current position in config string
|
size_t pos = 0; // current position in config string
|
||||||
@ -160,7 +192,7 @@ colvar::customColvar::customColvar(std::string const &conf): linearCombination(c
|
|||||||
pexpr = Lepton::Parser::parse(expr);
|
pexpr = Lepton::Parser::parse(expr);
|
||||||
pexprs.push_back(pexpr);
|
pexprs.push_back(pexpr);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
cvm::error("Error parsing expression \"" + expr + "\".\n", COLVARS_INPUT_ERROR);
|
return cvm::error("Error parsing expression \"" + expr + "\".\n", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
value_evaluators.push_back(new Lepton::CompiledExpression(pexpr.createCompiledExpression()));
|
value_evaluators.push_back(new Lepton::CompiledExpression(pexpr.createCompiledExpression()));
|
||||||
@ -178,7 +210,7 @@ colvar::customColvar::customColvar(std::string const &conf): linearCombination(c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
cvm::error("Error compiling expression \"" + expr + "\".\n", COLVARS_INPUT_ERROR);
|
return cvm::error("Error compiling expression \"" + expr + "\".\n", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
} while (key_lookup(conf, "customFunction", &expr_in, &pos));
|
} while (key_lookup(conf, "customFunction", &expr_in, &pos));
|
||||||
// Now define derivative with respect to each scalar sub-component
|
// Now define derivative with respect to each scalar sub-component
|
||||||
@ -203,7 +235,7 @@ colvar::customColvar::customColvar(std::string const &conf): linearCombination(c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value_evaluators.size() == 0) {
|
if (value_evaluators.size() == 0) {
|
||||||
cvm::error("Error: no custom function defined.\n", COLVARS_INPUT_ERROR);
|
return cvm::error("Error: no custom function defined.\n", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
if (value_evaluators.size() != 1) {
|
if (value_evaluators.size() != 1) {
|
||||||
x.type(colvarvalue::type_vector);
|
x.type(colvarvalue::type_vector);
|
||||||
@ -211,14 +243,17 @@ colvar::customColvar::customColvar(std::string const &conf): linearCombination(c
|
|||||||
x.type(colvarvalue::type_scalar);
|
x.type(colvarvalue::type_scalar);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
cvm::error("customFunction requires the Lepton library, but it is not enabled during compilation.\n"
|
return cvm::error(
|
||||||
"Please refer to the Compilation Notes section of the Colvars manual for more information.\n",
|
"customFunction requires the Lepton library, but it is not enabled during compilation.\n"
|
||||||
COLVARS_INPUT_ERROR);
|
"Please refer to the Compilation Notes section of the Colvars manual for more "
|
||||||
|
"information.\n",
|
||||||
|
COLVARS_NOT_IMPLEMENTED);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
cvm::log("Warning: no customFunction specified.\n");
|
cvm::log("Warning: no customFunction specified.\n");
|
||||||
cvm::log("Warning: use linear combination instead.\n");
|
cvm::log("Warning: use linear combination instead.\n");
|
||||||
}
|
}
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
colvar::customColvar::~customColvar() {
|
colvar::customColvar::~customColvar() {
|
||||||
@ -317,7 +352,8 @@ void colvar::customColvar::apply_force(colvarvalue const &force) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const colvarvalue& current_cv_value = cv[i_cv]->value();
|
const colvarvalue& current_cv_value = cv[i_cv]->value();
|
||||||
colvarvalue cv_force(current_cv_value.type());
|
colvarvalue cv_force(current_cv_value);
|
||||||
|
cv_force.reset();
|
||||||
const cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
|
const cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
|
||||||
for (size_t j_elem = 0; j_elem < current_cv_value.size(); ++j_elem) {
|
for (size_t j_elem = 0; j_elem < current_cv_value.size(); ++j_elem) {
|
||||||
for (size_t c = 0; c < x.size(); ++c) {
|
for (size_t c = 0; c < x.size(); ++c) {
|
||||||
@ -340,5 +376,3 @@ void colvar::customColvar::apply_force(colvarvalue const &force) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus >= 201103L
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
// Colvars repository at GitHub.
|
// Colvars repository at GitHub.
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarparse.h"
|
|
||||||
#include "colvaratoms.h"
|
#include "colvaratoms.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
@ -90,48 +89,47 @@ cvm::real colvar::coordnum::switching_function(cvm::real const &r0,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar::coordnum::coordnum(std::string const &conf)
|
colvar::coordnum::coordnum()
|
||||||
: cvc(conf), b_anisotropic(false), pairlist(NULL)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
set_function_type("coordNum");
|
set_function_type("coordNum");
|
||||||
x.type(colvarvalue::type_scalar);
|
x.type(colvarvalue::type_scalar);
|
||||||
|
|
||||||
colvarproxy *proxy = cvm::main()->proxy;
|
colvarproxy *proxy = cvm::main()->proxy;
|
||||||
|
r0 = proxy->angstrom_to_internal(4.0);
|
||||||
|
r0_vec = cvm::rvector(proxy->angstrom_to_internal(4.0),
|
||||||
|
proxy->angstrom_to_internal(4.0),
|
||||||
|
proxy->angstrom_to_internal(4.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::coordnum::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
|
||||||
group1 = parse_group(conf, "group1");
|
group1 = parse_group(conf, "group1");
|
||||||
group2 = parse_group(conf, "group2");
|
group2 = parse_group(conf, "group2");
|
||||||
|
|
||||||
if (group1 == NULL || group2 == NULL) {
|
if (!group1 || !group2) {
|
||||||
cvm::error("Error: failed to initialize atom groups.\n",
|
return error_code | COLVARS_INPUT_ERROR;
|
||||||
COLVARS_INPUT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (int atom_number = cvm::atom_group::overlap(*group1, *group2)) {
|
if (int atom_number = cvm::atom_group::overlap(*group1, *group2)) {
|
||||||
cvm::error("Error: group1 and group2 share a common atom (number: " +
|
error_code |= cvm::error(
|
||||||
cvm::to_str(atom_number) + ")\n", COLVARS_INPUT_ERROR);
|
"Error: group1 and group2 share a common atom (number: " + cvm::to_str(atom_number) + ")\n",
|
||||||
return;
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group1->b_dummy) {
|
if (group1->b_dummy) {
|
||||||
cvm::error("Error: only group2 is allowed to be a dummy atom\n",
|
error_code |=
|
||||||
COLVARS_INPUT_ERROR);
|
cvm::error("Error: only group2 is allowed to be a dummy atom\n", COLVARS_INPUT_ERROR);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool const b_isotropic = get_keyval(conf, "cutoff", r0,
|
bool const b_isotropic = get_keyval(conf, "cutoff", r0, r0);
|
||||||
cvm::real(proxy->angstrom_to_internal(4.0)));
|
|
||||||
|
|
||||||
if (get_keyval(conf, "cutoff3", r0_vec,
|
if (get_keyval(conf, "cutoff3", r0_vec, r0_vec)) {
|
||||||
cvm::rvector(proxy->angstrom_to_internal(4.0),
|
|
||||||
proxy->angstrom_to_internal(4.0),
|
|
||||||
proxy->angstrom_to_internal(4.0)))) {
|
|
||||||
if (b_isotropic) {
|
if (b_isotropic) {
|
||||||
cvm::error("Error: cannot specify \"cutoff\" and \"cutoff3\" "
|
error_code |= cvm::error("Error: cannot specify \"cutoff\" and \"cutoff3\" "
|
||||||
"at the same time.\n",
|
"at the same time.\n",
|
||||||
COLVARS_INPUT_ERROR);
|
COLVARS_INPUT_ERROR);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b_anisotropic = true;
|
b_anisotropic = true;
|
||||||
@ -141,17 +139,17 @@ colvar::coordnum::coordnum(std::string const &conf)
|
|||||||
if (r0_vec.z < 0.0) r0_vec.z *= -1.0;
|
if (r0_vec.z < 0.0) r0_vec.z *= -1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_keyval(conf, "expNumer", en, 6);
|
get_keyval(conf, "expNumer", en, en);
|
||||||
get_keyval(conf, "expDenom", ed, 12);
|
get_keyval(conf, "expDenom", ed, ed);
|
||||||
|
|
||||||
if ( (en%2) || (ed%2) ) {
|
if ( (en%2) || (ed%2) ) {
|
||||||
cvm::error("Error: odd exponent(s) provided, can only use even ones.\n",
|
error_code |= cvm::error("Error: odd exponent(s) provided, can only use even ones.\n",
|
||||||
COLVARS_INPUT_ERROR);
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (en <= 0) || (ed <= 0) ) {
|
if ( (en <= 0) || (ed <= 0) ) {
|
||||||
cvm::error("Error: negative exponent(s) provided.\n",
|
error_code |= cvm::error("Error: negative exponent(s) provided.\n",
|
||||||
COLVARS_INPUT_ERROR);
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_enabled(f_cvc_pbc_minimum_image)) {
|
if (!is_enabled(f_cvc_pbc_minimum_image)) {
|
||||||
@ -160,14 +158,14 @@ colvar::coordnum::coordnum(std::string const &conf)
|
|||||||
|
|
||||||
get_keyval(conf, "group2CenterOnly", b_group2_center_only, group2->b_dummy);
|
get_keyval(conf, "group2CenterOnly", b_group2_center_only, group2->b_dummy);
|
||||||
|
|
||||||
get_keyval(conf, "tolerance", tolerance, 0.0);
|
get_keyval(conf, "tolerance", tolerance, tolerance);
|
||||||
if (tolerance > 0) {
|
if (tolerance > 0) {
|
||||||
cvm::main()->cite_feature("coordNum pairlist");
|
cvm::main()->cite_feature("coordNum pairlist");
|
||||||
get_keyval(conf, "pairListFrequency", pairlist_freq, 100);
|
get_keyval(conf, "pairListFrequency", pairlist_freq, pairlist_freq);
|
||||||
if ( ! (pairlist_freq > 0) ) {
|
if ( ! (pairlist_freq > 0) ) {
|
||||||
cvm::error("Error: non-positive pairlistfrequency provided.\n",
|
return cvm::error("Error: non-positive pairlistfrequency provided.\n",
|
||||||
COLVARS_INPUT_ERROR);
|
COLVARS_INPUT_ERROR);
|
||||||
return; // and do not allocate the pairlists below
|
// return and do not allocate the pairlists below
|
||||||
}
|
}
|
||||||
if (b_group2_center_only) {
|
if (b_group2_center_only) {
|
||||||
pairlist = new bool[group1->size()];
|
pairlist = new bool[group1->size()];
|
||||||
@ -181,12 +179,14 @@ colvar::coordnum::coordnum(std::string const &conf)
|
|||||||
static_cast<cvm::real>(group1->size()) :
|
static_cast<cvm::real>(group1->size()) :
|
||||||
static_cast<cvm::real>(group1->size() *
|
static_cast<cvm::real>(group1->size() *
|
||||||
group2->size()));
|
group2->size()));
|
||||||
|
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar::coordnum::~coordnum()
|
colvar::coordnum::~coordnum()
|
||||||
{
|
{
|
||||||
if (pairlist != NULL) {
|
if (pairlist) {
|
||||||
delete [] pairlist;
|
delete [] pairlist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,25 +285,23 @@ void colvar::coordnum::calc_gradients()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::coordnum::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
if (!group1->noforce)
|
|
||||||
group1->apply_colvar_force(force.real_value);
|
|
||||||
|
|
||||||
if (!group2->noforce)
|
|
||||||
group2->apply_colvar_force(force.real_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
simple_scalar_dist_functions(coordnum)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// h_bond member functions
|
// h_bond member functions
|
||||||
|
|
||||||
colvar::h_bond::h_bond(std::string const &conf)
|
colvar::h_bond::h_bond()
|
||||||
: cvc(conf)
|
|
||||||
{
|
{
|
||||||
|
colvarproxy *proxy = cvm::main()->proxy;
|
||||||
|
r0 = proxy->angstrom_to_internal(3.3);
|
||||||
|
set_function_type("hBond");
|
||||||
|
x.type(colvarvalue::type_scalar);
|
||||||
|
init_scalar_boundaries(0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::h_bond::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
|
||||||
if (cvm::debug())
|
if (cvm::debug())
|
||||||
cvm::log("Initializing h_bond object.\n");
|
cvm::log("Initializing h_bond object.\n");
|
||||||
|
|
||||||
@ -311,15 +309,12 @@ colvar::h_bond::h_bond(std::string const &conf)
|
|||||||
x.type(colvarvalue::type_scalar);
|
x.type(colvarvalue::type_scalar);
|
||||||
init_scalar_boundaries(0.0, 1.0);
|
init_scalar_boundaries(0.0, 1.0);
|
||||||
|
|
||||||
colvarproxy *proxy = cvm::main()->proxy;
|
|
||||||
|
|
||||||
int a_num = -1, d_num = -1;
|
int a_num = -1, d_num = -1;
|
||||||
get_keyval(conf, "acceptor", a_num, a_num);
|
get_keyval(conf, "acceptor", a_num, a_num);
|
||||||
get_keyval(conf, "donor", d_num, a_num);
|
get_keyval(conf, "donor", d_num, a_num);
|
||||||
|
|
||||||
if ( (a_num == -1) || (d_num == -1) ) {
|
if ( (a_num == -1) || (d_num == -1) ) {
|
||||||
cvm::error("Error: either acceptor or donor undefined.\n");
|
error_code |= cvm::error("Error: either acceptor or donor undefined.\n", COLVARS_INPUT_ERROR);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cvm::atom acceptor = cvm::atom(a_num);
|
cvm::atom acceptor = cvm::atom(a_num);
|
||||||
@ -328,34 +323,34 @@ colvar::h_bond::h_bond(std::string const &conf)
|
|||||||
atom_groups[0]->add_atom(acceptor);
|
atom_groups[0]->add_atom(acceptor);
|
||||||
atom_groups[0]->add_atom(donor);
|
atom_groups[0]->add_atom(donor);
|
||||||
|
|
||||||
get_keyval(conf, "cutoff", r0, proxy->angstrom_to_internal(3.3));
|
get_keyval(conf, "cutoff", r0, r0);
|
||||||
get_keyval(conf, "expNumer", en, 6);
|
get_keyval(conf, "expNumer", en, en);
|
||||||
get_keyval(conf, "expDenom", ed, 8);
|
get_keyval(conf, "expDenom", ed, ed);
|
||||||
|
|
||||||
if ( (en%2) || (ed%2) ) {
|
if ((en % 2) || (ed % 2)) {
|
||||||
cvm::error("Error: odd exponent(s) provided, can only use even ones.\n",
|
error_code |= cvm::error("Error: odd exponent(s) provided, can only use even ones.\n",
|
||||||
COLVARS_INPUT_ERROR);
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (en <= 0) || (ed <= 0) ) {
|
if ((en <= 0) || (ed <= 0)) {
|
||||||
cvm::error("Error: negative exponent(s) provided.\n",
|
error_code |= cvm::error("Error: negative exponent(s) provided.\n", COLVARS_INPUT_ERROR);
|
||||||
COLVARS_INPUT_ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cvm::debug())
|
if (cvm::debug())
|
||||||
cvm::log("Done initializing h_bond object.\n");
|
cvm::log("Done initializing h_bond object.\n");
|
||||||
|
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar::h_bond::h_bond(cvm::atom const &acceptor,
|
colvar::h_bond::h_bond(cvm::atom const &acceptor,
|
||||||
cvm::atom const &donor,
|
cvm::atom const &donor,
|
||||||
cvm::real r0_i, int en_i, int ed_i)
|
cvm::real r0_i, int en_i, int ed_i)
|
||||||
: r0(r0_i), en(en_i), ed(ed_i)
|
: h_bond()
|
||||||
{
|
{
|
||||||
set_function_type("hBond");
|
r0 = r0_i;
|
||||||
x.type(colvarvalue::type_scalar);
|
en = en_i;
|
||||||
init_scalar_boundaries(0.0, 1.0);
|
ed = ed_i;
|
||||||
|
|
||||||
register_atom_group(new cvm::atom_group);
|
register_atom_group(new cvm::atom_group);
|
||||||
atom_groups[0]->add_atom(acceptor);
|
atom_groups[0]->add_atom(acceptor);
|
||||||
atom_groups[0]->add_atom(donor);
|
atom_groups[0]->add_atom(donor);
|
||||||
@ -385,64 +380,63 @@ void colvar::h_bond::calc_gradients()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::h_bond::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
(atom_groups[0])->apply_colvar_force(force);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
colvar::selfcoordnum::selfcoordnum()
|
||||||
simple_scalar_dist_functions(h_bond)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
colvar::selfcoordnum::selfcoordnum(std::string const &conf)
|
|
||||||
: cvc(conf), pairlist(NULL)
|
|
||||||
{
|
{
|
||||||
set_function_type("selfCoordNum");
|
set_function_type("selfCoordNum");
|
||||||
x.type(colvarvalue::type_scalar);
|
x.type(colvarvalue::type_scalar);
|
||||||
|
r0 = cvm::main()->proxy->angstrom_to_internal(4.0);
|
||||||
|
}
|
||||||
|
|
||||||
colvarproxy *proxy = cvm::main()->proxy;
|
|
||||||
|
int colvar::selfcoordnum::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
|
||||||
group1 = parse_group(conf, "group1");
|
group1 = parse_group(conf, "group1");
|
||||||
|
|
||||||
get_keyval(conf, "cutoff", r0, cvm::real(proxy->angstrom_to_internal(4.0)));
|
if (!group1 || group1->size() == 0) {
|
||||||
get_keyval(conf, "expNumer", en, 6);
|
return error_code | COLVARS_INPUT_ERROR;
|
||||||
get_keyval(conf, "expDenom", ed, 12);
|
|
||||||
|
|
||||||
|
|
||||||
if ( (en%2) || (ed%2) ) {
|
|
||||||
cvm::error("Error: odd exponent(s) provided, can only use even ones.\n",
|
|
||||||
COLVARS_INPUT_ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (en <= 0) || (ed <= 0) ) {
|
get_keyval(conf, "cutoff", r0, r0);
|
||||||
cvm::error("Error: negative exponent(s) provided.\n",
|
get_keyval(conf, "expNumer", en, en);
|
||||||
COLVARS_INPUT_ERROR);
|
get_keyval(conf, "expDenom", ed, ed);
|
||||||
|
|
||||||
|
|
||||||
|
if ((en % 2) || (ed % 2)) {
|
||||||
|
error_code |= cvm::error("Error: odd exponent(s) provided, can only use even ones.\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((en <= 0) || (ed <= 0)) {
|
||||||
|
error_code |= cvm::error("Error: negative exponent(s) provided.\n", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_enabled(f_cvc_pbc_minimum_image)) {
|
if (!is_enabled(f_cvc_pbc_minimum_image)) {
|
||||||
cvm::log("Warning: only minimum-image distances are used by this variable.\n");
|
cvm::log("Warning: only minimum-image distances are used by this variable.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
get_keyval(conf, "tolerance", tolerance, 0.0);
|
get_keyval(conf, "tolerance", tolerance, tolerance);
|
||||||
if (tolerance > 0) {
|
if (tolerance > 0) {
|
||||||
get_keyval(conf, "pairListFrequency", pairlist_freq, 100);
|
get_keyval(conf, "pairListFrequency", pairlist_freq, pairlist_freq);
|
||||||
if ( ! (pairlist_freq > 0) ) {
|
if ( ! (pairlist_freq > 0) ) {
|
||||||
cvm::error("Error: non-positive pairlistfrequency provided.\n",
|
error_code |= cvm::error("Error: non-positive pairlistfrequency provided.\n",
|
||||||
COLVARS_INPUT_ERROR);
|
COLVARS_INPUT_ERROR);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
pairlist = new bool[(group1->size()-1) * (group1->size()-1)];
|
pairlist = new bool[(group1->size()-1) * (group1->size()-1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
init_scalar_boundaries(0.0, static_cast<cvm::real>((group1->size()-1) *
|
init_scalar_boundaries(0.0, static_cast<cvm::real>((group1->size()-1) *
|
||||||
(group1->size()-1)));
|
(group1->size()-1)));
|
||||||
|
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar::selfcoordnum::~selfcoordnum()
|
colvar::selfcoordnum::~selfcoordnum()
|
||||||
{
|
{
|
||||||
if (pairlist != NULL) {
|
if (pairlist) {
|
||||||
delete [] pairlist;
|
delete [] pairlist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -527,44 +521,36 @@ void colvar::selfcoordnum::calc_gradients()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::selfcoordnum::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
if (!group1->noforce) {
|
|
||||||
group1->apply_colvar_force(force.real_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
colvar::groupcoordnum::groupcoordnum()
|
||||||
simple_scalar_dist_functions(selfcoordnum)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// groupcoordnum member functions
|
|
||||||
colvar::groupcoordnum::groupcoordnum(std::string const &conf)
|
|
||||||
: distance(conf), b_anisotropic(false)
|
|
||||||
{
|
{
|
||||||
set_function_type("groupCoord");
|
set_function_type("groupCoord");
|
||||||
x.type(colvarvalue::type_scalar);
|
x.type(colvarvalue::type_scalar);
|
||||||
init_scalar_boundaries(0.0, 1.0);
|
init_scalar_boundaries(0.0, 1.0);
|
||||||
|
|
||||||
colvarproxy *proxy = cvm::main()->proxy;
|
colvarproxy *proxy = cvm::main()->proxy;
|
||||||
|
r0 = proxy->angstrom_to_internal(4.0);
|
||||||
|
r0_vec = cvm::rvector(proxy->angstrom_to_internal(4.0),
|
||||||
|
proxy->angstrom_to_internal(4.0),
|
||||||
|
proxy->angstrom_to_internal(4.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::groupcoordnum::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = distance::init(conf);
|
||||||
|
|
||||||
// group1 and group2 are already initialized by distance()
|
// group1 and group2 are already initialized by distance()
|
||||||
if (group1->b_dummy || group2->b_dummy) {
|
if (group1->b_dummy || group2->b_dummy) {
|
||||||
cvm::error("Error: neither group can be a dummy atom\n");
|
return cvm::error("Error: neither group can be a dummy atom\n", COLVARS_INPUT_ERROR);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool const b_scale = get_keyval(conf, "cutoff", r0,
|
bool const b_scale = get_keyval(conf, "cutoff", r0, r0);
|
||||||
cvm::real(proxy->angstrom_to_internal(4.0)));
|
|
||||||
|
|
||||||
if (get_keyval(conf, "cutoff3", r0_vec,
|
|
||||||
cvm::rvector(4.0, 4.0, 4.0), parse_silent)) {
|
|
||||||
|
|
||||||
|
if (get_keyval(conf, "cutoff3", r0_vec, r0_vec)) {
|
||||||
if (b_scale) {
|
if (b_scale) {
|
||||||
cvm::error("Error: cannot specify \"scale\" and "
|
error_code |=
|
||||||
"\"scale3\" at the same time.\n");
|
cvm::error("Error: cannot specify \"cutoff\" and \"cutoff3\" at the same time.\n",
|
||||||
return;
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
b_anisotropic = true;
|
b_anisotropic = true;
|
||||||
// remove meaningless negative signs
|
// remove meaningless negative signs
|
||||||
@ -573,23 +559,23 @@ colvar::groupcoordnum::groupcoordnum(std::string const &conf)
|
|||||||
if (r0_vec.z < 0.0) r0_vec.z *= -1.0;
|
if (r0_vec.z < 0.0) r0_vec.z *= -1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_keyval(conf, "expNumer", en, 6);
|
get_keyval(conf, "expNumer", en, en);
|
||||||
get_keyval(conf, "expDenom", ed, 12);
|
get_keyval(conf, "expDenom", ed, ed);
|
||||||
|
|
||||||
if ( (en%2) || (ed%2) ) {
|
if ((en % 2) || (ed % 2)) {
|
||||||
cvm::error("Error: odd exponent(s) provided, can only use even ones.\n",
|
error_code |= cvm::error("Error: odd exponent(s) provided, can only use even ones.\n",
|
||||||
COLVARS_INPUT_ERROR);
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (en <= 0) || (ed <= 0) ) {
|
if ((en <= 0) || (ed <= 0)) {
|
||||||
cvm::error("Error: negative exponent(s) provided.\n",
|
error_code |= cvm::error("Error: negative exponent(s) provided.\n", COLVARS_INPUT_ERROR);
|
||||||
COLVARS_INPUT_ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_enabled(f_cvc_pbc_minimum_image)) {
|
if (!is_enabled(f_cvc_pbc_minimum_image)) {
|
||||||
cvm::log("Warning: only minimum-image distances are used by this variable.\n");
|
cvm::log("Warning: only minimum-image distances are used by this variable.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -640,16 +626,3 @@ void colvar::groupcoordnum::calc_gradients()
|
|||||||
group1->set_weighted_gradient(group1_com_atom.grad);
|
group1->set_weighted_gradient(group1_com_atom.grad);
|
||||||
group2->set_weighted_gradient(group2_com_atom.grad);
|
group2->set_weighted_gradient(group2_com_atom.grad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::groupcoordnum::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
if (!group1->noforce)
|
|
||||||
group1->apply_colvar_force(force.real_value);
|
|
||||||
|
|
||||||
if (!group2->noforce)
|
|
||||||
group2->apply_colvar_force(force.real_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
simple_scalar_dist_functions(groupcoordnum)
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
#if (__cplusplus >= 201103L)
|
// -*- c++ -*-
|
||||||
|
|
||||||
// This file is part of the Collective Variables module (Colvars).
|
// This file is part of the Collective Variables module (Colvars).
|
||||||
// The original version of Colvars and its updates are located at:
|
// The original version of Colvars and its updates are located at:
|
||||||
@ -10,17 +10,29 @@
|
|||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvarparse.h"
|
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvarcomp.h"
|
#include "colvarcomp.h"
|
||||||
|
|
||||||
colvar::CartesianBasedPath::CartesianBasedPath(std::string const &conf): cvc(conf), atoms(nullptr), reference_frames(0) {
|
|
||||||
|
|
||||||
|
colvar::CartesianBasedPath::CartesianBasedPath()
|
||||||
|
{
|
||||||
|
x.type(colvarvalue::type_scalar);
|
||||||
|
// Don't use implicit gradient
|
||||||
|
enable(f_cvc_explicit_gradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::CartesianBasedPath::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
|
||||||
// Parse selected atoms
|
// Parse selected atoms
|
||||||
atoms = parse_group(conf, "atoms");
|
atoms = parse_group(conf, "atoms");
|
||||||
has_user_defined_fitting = false;
|
has_user_defined_fitting = false;
|
||||||
@ -31,13 +43,12 @@ colvar::CartesianBasedPath::CartesianBasedPath(std::string const &conf): cvc(con
|
|||||||
// Lookup reference column of PDB
|
// Lookup reference column of PDB
|
||||||
// Copied from the RMSD class
|
// Copied from the RMSD class
|
||||||
std::string reference_column;
|
std::string reference_column;
|
||||||
double reference_column_value;
|
double reference_column_value = 0.0;
|
||||||
if (get_keyval(conf, "refPositionsCol", reference_column, std::string(""))) {
|
if (get_keyval(conf, "refPositionsCol", reference_column, std::string(""))) {
|
||||||
bool found = get_keyval(conf, "refPositionsColValue", reference_column_value, 0.0);
|
bool found = get_keyval(conf, "refPositionsColValue", reference_column_value, reference_column_value);
|
||||||
if (found && reference_column_value == 0.0) {
|
if (found && reference_column_value == 0.0) {
|
||||||
cvm::error("Error: refPositionsColValue, "
|
return cvm::error("Error: refPositionsColValue, if provided, must be non-zero.\n",
|
||||||
"if provided, must be non-zero.\n");
|
COLVARS_INPUT_ERROR);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Lookup all reference frames
|
// Lookup all reference frames
|
||||||
@ -66,9 +77,6 @@ colvar::CartesianBasedPath::CartesianBasedPath(std::string const &conf): cvc(con
|
|||||||
tmp_atoms->ref_pos = reference_frames[i_frame];
|
tmp_atoms->ref_pos = reference_frames[i_frame];
|
||||||
tmp_atoms->center_ref_pos();
|
tmp_atoms->center_ref_pos();
|
||||||
tmp_atoms->enable(f_ag_fit_gradients);
|
tmp_atoms->enable(f_ag_fit_gradients);
|
||||||
tmp_atoms->rot.request_group1_gradients(tmp_atoms->size());
|
|
||||||
tmp_atoms->rot.request_group2_gradients(tmp_atoms->size());
|
|
||||||
comp_atoms.push_back(tmp_atoms);
|
|
||||||
} else {
|
} else {
|
||||||
// parse a group of atoms for fitting
|
// parse a group of atoms for fitting
|
||||||
std::string fitting_group_name = std::string("fittingAtoms") + cvm::to_str(i_frame);
|
std::string fitting_group_name = std::string("fittingAtoms") + cvm::to_str(i_frame);
|
||||||
@ -91,15 +99,13 @@ colvar::CartesianBasedPath::CartesianBasedPath(std::string const &conf): cvc(con
|
|||||||
tmp_atoms->enable(f_ag_fit_gradients);
|
tmp_atoms->enable(f_ag_fit_gradients);
|
||||||
tmp_atoms->enable(f_ag_fitting_group);
|
tmp_atoms->enable(f_ag_fitting_group);
|
||||||
tmp_atoms->fitting_group = tmp_fitting_atoms;
|
tmp_atoms->fitting_group = tmp_fitting_atoms;
|
||||||
tmp_atoms->rot.request_group1_gradients(tmp_fitting_atoms->size());
|
|
||||||
tmp_atoms->rot.request_group2_gradients(tmp_fitting_atoms->size());
|
|
||||||
reference_fitting_frames.push_back(reference_fitting_position);
|
reference_fitting_frames.push_back(reference_fitting_position);
|
||||||
comp_atoms.push_back(tmp_atoms);
|
|
||||||
}
|
}
|
||||||
|
tmp_atoms->setup_rotation_derivative();
|
||||||
|
comp_atoms.push_back(tmp_atoms);
|
||||||
}
|
}
|
||||||
x.type(colvarvalue::type_scalar);
|
|
||||||
// Don't use implicit gradient
|
return error_code;
|
||||||
enable(f_cvc_explicit_gradient);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
colvar::CartesianBasedPath::~CartesianBasedPath() {
|
colvar::CartesianBasedPath::~CartesianBasedPath() {
|
||||||
@ -125,8 +131,60 @@ void colvar::CartesianBasedPath::computeDistanceToReferenceFrames(std::vector<cv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
colvar::gspath::gspath(std::string const &conf): CartesianBasedPath(conf) {
|
// mainly used for determining the lambda value for arithmetic path
|
||||||
|
void colvar::CartesianBasedPath::computeDistanceBetweenReferenceFrames(std::vector<cvm::real>& result) {
|
||||||
|
for (size_t i_frame = 0; i_frame < reference_frames.size() - 1; ++i_frame) {
|
||||||
|
std::vector<cvm::atom_pos> this_frame_atom_pos(reference_frames[i_frame].size());
|
||||||
|
std::vector<cvm::atom_pos> next_frame_atom_pos(reference_frames[i_frame + 1].size());
|
||||||
|
cvm::real frame_rmsd = 0.0;
|
||||||
|
const size_t this_index = i_frame;
|
||||||
|
const size_t next_index = i_frame + 1;
|
||||||
|
// compute COM of two successive images, respectively
|
||||||
|
cvm::atom_pos reference_cog_this, reference_cog_next;
|
||||||
|
for (size_t i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
||||||
|
reference_cog_this += reference_frames[this_index][i_atom];
|
||||||
|
reference_cog_next += reference_frames[next_index][i_atom];
|
||||||
|
}
|
||||||
|
reference_cog_this /= reference_frames[this_index].size();
|
||||||
|
reference_cog_next /= reference_frames[next_index].size();
|
||||||
|
// move all atoms to COM
|
||||||
|
for (size_t i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
||||||
|
this_frame_atom_pos[i_atom] = reference_frames[this_index][i_atom] - reference_cog_this;
|
||||||
|
next_frame_atom_pos[i_atom] = reference_frames[next_index][i_atom] - reference_cog_next;
|
||||||
|
}
|
||||||
|
cvm::rotation rot_this_to_next;
|
||||||
|
// compute the optimal rotation
|
||||||
|
rot_this_to_next.calc_optimal_rotation(this_frame_atom_pos, next_frame_atom_pos);
|
||||||
|
// compute rmsd between reference frames
|
||||||
|
for (size_t i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
||||||
|
frame_rmsd += (rot_this_to_next.q.rotate(this_frame_atom_pos[i_atom]) - next_frame_atom_pos[i_atom]).norm2();
|
||||||
|
}
|
||||||
|
frame_rmsd /= cvm::real(atoms->size());
|
||||||
|
frame_rmsd = cvm::sqrt(frame_rmsd);
|
||||||
|
result[i_frame] = frame_rmsd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void colvar::CartesianBasedPath::apply_force(colvarvalue const &force)
|
||||||
|
{
|
||||||
|
cvm::error("Error: using apply_force() in a component of type CartesianBasedPath, which is abstract.\n",
|
||||||
|
COLVARS_BUG_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
colvar::gspath::gspath()
|
||||||
|
{
|
||||||
set_function_type("gspath");
|
set_function_type("gspath");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::gspath::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = CartesianBasedPath::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
|
||||||
get_keyval(conf, "useSecondClosestFrame", use_second_closest_frame, true);
|
get_keyval(conf, "useSecondClosestFrame", use_second_closest_frame, true);
|
||||||
if (use_second_closest_frame == true) {
|
if (use_second_closest_frame == true) {
|
||||||
cvm::log(std::string("Geometric path s(σ) will use the second closest frame to compute s_(m-1)\n"));
|
cvm::log(std::string("Geometric path s(σ) will use the second closest frame to compute s_(m-1)\n"));
|
||||||
@ -140,12 +198,14 @@ colvar::gspath::gspath(std::string const &conf): CartesianBasedPath(conf) {
|
|||||||
cvm::log(std::string("Geometric path s(σ) will use the neighbouring frame to compute s_(m+1)\n"));
|
cvm::log(std::string("Geometric path s(σ) will use the neighbouring frame to compute s_(m+1)\n"));
|
||||||
}
|
}
|
||||||
if (total_reference_frames < 2) {
|
if (total_reference_frames < 2) {
|
||||||
cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + " reference frames, but gspath requires at least 2 frames.\n");
|
return cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) +
|
||||||
return;
|
" reference frames, but gspath requires at least 2 frames.\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
GeometricPathCV::GeometricPathBase<cvm::atom_pos, cvm::real, GeometricPathCV::path_sz::S>::initialize(atoms->size(), cvm::atom_pos(), total_reference_frames, use_second_closest_frame, use_third_closest_frame);
|
GeometricPathCV::GeometricPathBase<cvm::atom_pos, cvm::real, GeometricPathCV::path_sz::S>::initialize(atoms->size(), cvm::atom_pos(), total_reference_frames, use_second_closest_frame, use_third_closest_frame);
|
||||||
cvm::log(std::string("Geometric pathCV(s) is initialized.\n"));
|
cvm::log(std::string("Geometric pathCV(s) is initialized.\n"));
|
||||||
cvm::log(std::string("Geometric pathCV(s) loaded ") + cvm::to_str(reference_frames.size()) + std::string(" frames.\n"));
|
cvm::log(std::string("Geometric pathCV(s) loaded ") + cvm::to_str(reference_frames.size()) + std::string(" frames.\n"));
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void colvar::gspath::updateDistanceToReferenceFrames() {
|
void colvar::gspath::updateDistanceToReferenceFrames() {
|
||||||
@ -192,8 +252,9 @@ void colvar::gspath::prepareVectors() {
|
|||||||
} else {
|
} else {
|
||||||
rot_v3.calc_optimal_rotation(tmp_reference_frame_1, tmp_reference_frame_2);
|
rot_v3.calc_optimal_rotation(tmp_reference_frame_1, tmp_reference_frame_2);
|
||||||
}
|
}
|
||||||
|
const auto rot_mat_v3 = rot_v3.matrix();
|
||||||
for (i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
for (i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
||||||
v3[i_atom] = rot_v3.q.rotate(tmp_reference_frame_1[i_atom]) - tmp_reference_frame_2[i_atom];
|
v3[i_atom] = rot_mat_v3 * tmp_reference_frame_1[i_atom] - tmp_reference_frame_2[i_atom];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cvm::atom_pos reference_cog_1, reference_cog_3;
|
cvm::atom_pos reference_cog_1, reference_cog_3;
|
||||||
@ -227,9 +288,10 @@ void colvar::gspath::prepareVectors() {
|
|||||||
} else {
|
} else {
|
||||||
rot_v3.calc_optimal_rotation(tmp_reference_frame_1, tmp_reference_frame_3);
|
rot_v3.calc_optimal_rotation(tmp_reference_frame_1, tmp_reference_frame_3);
|
||||||
}
|
}
|
||||||
|
const auto rot_mat_v3 = rot_v3.matrix();
|
||||||
for (i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
for (i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
||||||
// v3 = s_(m+1) - s_m
|
// v3 = s_(m+1) - s_m
|
||||||
v3[i_atom] = tmp_reference_frame_3[i_atom] - rot_v3.q.rotate(tmp_reference_frame_1[i_atom]);
|
v3[i_atom] = tmp_reference_frame_3[i_atom] - rot_mat_v3 * tmp_reference_frame_1[i_atom];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,8 +329,17 @@ void colvar::gspath::apply_force(colvarvalue const &force) {
|
|||||||
(*(comp_atoms[min_frame_index_2])).apply_colvar_force(F);
|
(*(comp_atoms[min_frame_index_2])).apply_colvar_force(F);
|
||||||
}
|
}
|
||||||
|
|
||||||
colvar::gzpath::gzpath(std::string const &conf): CartesianBasedPath(conf) {
|
|
||||||
|
colvar::gzpath::gzpath()
|
||||||
|
{
|
||||||
set_function_type("gzpath");
|
set_function_type("gzpath");
|
||||||
|
}
|
||||||
|
|
||||||
|
int colvar::gzpath::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = CartesianBasedPath::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
|
||||||
get_keyval(conf, "useSecondClosestFrame", use_second_closest_frame, true);
|
get_keyval(conf, "useSecondClosestFrame", use_second_closest_frame, true);
|
||||||
if (use_second_closest_frame == true) {
|
if (use_second_closest_frame == true) {
|
||||||
cvm::log(std::string("Geometric path z(σ) will use the second closest frame to compute s_(m-1)\n"));
|
cvm::log(std::string("Geometric path z(σ) will use the second closest frame to compute s_(m-1)\n"));
|
||||||
@ -287,13 +358,15 @@ colvar::gzpath::gzpath(std::string const &conf): CartesianBasedPath(conf) {
|
|||||||
cvm::log(std::string("Geometric path z(σ) will use the square of distance from current frame to path compute z\n"));
|
cvm::log(std::string("Geometric path z(σ) will use the square of distance from current frame to path compute z\n"));
|
||||||
}
|
}
|
||||||
if (total_reference_frames < 2) {
|
if (total_reference_frames < 2) {
|
||||||
cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + " reference frames, but gzpath requires at least 2 frames.\n");
|
return cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) +
|
||||||
return;
|
" reference frames, but gzpath requires at least 2 frames.\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
GeometricPathCV::GeometricPathBase<cvm::atom_pos, cvm::real, GeometricPathCV::path_sz::Z>::initialize(atoms->size(), cvm::atom_pos(), total_reference_frames, use_second_closest_frame, use_third_closest_frame, b_use_z_square);
|
GeometricPathCV::GeometricPathBase<cvm::atom_pos, cvm::real, GeometricPathCV::path_sz::Z>::initialize(atoms->size(), cvm::atom_pos(), total_reference_frames, use_second_closest_frame, use_third_closest_frame, b_use_z_square);
|
||||||
// Logging
|
// Logging
|
||||||
cvm::log(std::string("Geometric pathCV(z) is initialized.\n"));
|
cvm::log(std::string("Geometric pathCV(z) is initialized.\n"));
|
||||||
cvm::log(std::string("Geometric pathCV(z) loaded ") + cvm::to_str(reference_frames.size()) + std::string(" frames.\n"));
|
cvm::log(std::string("Geometric pathCV(z) loaded ") + cvm::to_str(reference_frames.size()) + std::string(" frames.\n"));
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void colvar::gzpath::updateDistanceToReferenceFrames() {
|
void colvar::gzpath::updateDistanceToReferenceFrames() {
|
||||||
@ -335,12 +408,13 @@ void colvar::gzpath::prepareVectors() {
|
|||||||
} else {
|
} else {
|
||||||
rot_v4.calc_optimal_rotation(tmp_reference_frame_1, tmp_reference_frame_2);
|
rot_v4.calc_optimal_rotation(tmp_reference_frame_1, tmp_reference_frame_2);
|
||||||
}
|
}
|
||||||
|
const auto rot_mat_v4 = rot_v4.matrix();
|
||||||
for (i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
for (i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
||||||
v1[i_atom] = reference_frames[min_frame_index_1][i_atom] - (*(comp_atoms[min_frame_index_1]))[i_atom].pos;
|
v1[i_atom] = reference_frames[min_frame_index_1][i_atom] - (*(comp_atoms[min_frame_index_1]))[i_atom].pos;
|
||||||
v2[i_atom] = (*(comp_atoms[min_frame_index_2]))[i_atom].pos - reference_frames[min_frame_index_2][i_atom];
|
v2[i_atom] = (*(comp_atoms[min_frame_index_2]))[i_atom].pos - reference_frames[min_frame_index_2][i_atom];
|
||||||
// v4 only computes in gzpath
|
// v4 only computes in gzpath
|
||||||
// v4 = s_m - s_(m-1)
|
// v4 = s_m - s_(m-1)
|
||||||
v4[i_atom] = rot_v4.q.rotate(tmp_reference_frame_1[i_atom]) - tmp_reference_frame_2[i_atom];
|
v4[i_atom] = rot_mat_v4 * tmp_reference_frame_1[i_atom] - tmp_reference_frame_2[i_atom];
|
||||||
}
|
}
|
||||||
if (min_frame_index_3 < 0 || min_frame_index_3 > M) {
|
if (min_frame_index_3 < 0 || min_frame_index_3 > M) {
|
||||||
v3 = v4;
|
v3 = v4;
|
||||||
@ -368,9 +442,10 @@ void colvar::gzpath::prepareVectors() {
|
|||||||
} else {
|
} else {
|
||||||
rot_v3.calc_optimal_rotation(tmp_reference_frame_1, tmp_reference_frame_3);
|
rot_v3.calc_optimal_rotation(tmp_reference_frame_1, tmp_reference_frame_3);
|
||||||
}
|
}
|
||||||
|
const auto rot_mat_v3 = rot_v3.matrix();
|
||||||
for (i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
for (i_atom = 0; i_atom < atoms->size(); ++i_atom) {
|
||||||
// v3 = s_(m+1) - s_m
|
// v3 = s_(m+1) - s_m
|
||||||
v3[i_atom] = tmp_reference_frame_3[i_atom] - rot_v3.q.rotate(tmp_reference_frame_1[i_atom]);
|
v3[i_atom] = tmp_reference_frame_3[i_atom] - rot_mat_v3 * tmp_reference_frame_1[i_atom];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -399,14 +474,26 @@ void colvar::gzpath::apply_force(colvarvalue const &force) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) {
|
colvar::CVBasedPath::CVBasedPath()
|
||||||
|
{
|
||||||
|
set_function_type("gspathCV");
|
||||||
|
x.type(colvarvalue::type_scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::CVBasedPath::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
|
||||||
// Lookup all available sub-cvcs
|
// Lookup all available sub-cvcs
|
||||||
for (auto it_cv_map = colvar::get_global_cvc_map().begin(); it_cv_map != colvar::get_global_cvc_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);
|
||||||
for (auto it_sub_cvc_conf = sub_cvc_confs.begin(); it_sub_cvc_conf != sub_cvc_confs.end(); ++it_sub_cvc_conf) {
|
for (auto it_sub_cvc_conf = sub_cvc_confs.begin(); it_sub_cvc_conf != sub_cvc_confs.end(); ++it_sub_cvc_conf) {
|
||||||
cv.push_back((it_cv_map->second)(*(it_sub_cvc_conf)));
|
cv.push_back((it_cv_map->second)());
|
||||||
|
cv.back()->init(*(it_sub_cvc_conf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -429,7 +516,7 @@ colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) {
|
|||||||
cvm::log(std::string("Reading path file: ") + path_filename + std::string("\n"));
|
cvm::log(std::string("Reading path file: ") + path_filename + std::string("\n"));
|
||||||
auto &ifs_path = cvm::main()->proxy->input_stream(path_filename);
|
auto &ifs_path = cvm::main()->proxy->input_stream(path_filename);
|
||||||
if (!ifs_path) {
|
if (!ifs_path) {
|
||||||
return;
|
return COLVARS_INPUT_ERROR;
|
||||||
}
|
}
|
||||||
std::string line;
|
std::string line;
|
||||||
const std::string token(" ");
|
const std::string token(" ");
|
||||||
@ -450,8 +537,8 @@ colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) {
|
|||||||
cvm::log(cvm::to_str(tmp_cv[i_cv][i - start_index]));
|
cvm::log(cvm::to_str(tmp_cv[i_cv][i - start_index]));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cvm::error("Error: incorrect format of path file.\n");
|
error_code = cvm::error("Error: incorrect format of path file.\n", COLVARS_INPUT_ERROR);
|
||||||
return;
|
return error_code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!fields.empty()) {
|
if (!fields.empty()) {
|
||||||
@ -461,15 +548,18 @@ colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) {
|
|||||||
}
|
}
|
||||||
cvm::main()->proxy->close_input_stream(path_filename);
|
cvm::main()->proxy->close_input_stream(path_filename);
|
||||||
if (total_reference_frames <= 1) {
|
if (total_reference_frames <= 1) {
|
||||||
cvm::error("Error: there is only 1 or 0 reference frame, which doesn't constitute a path.\n");
|
error_code = cvm::error(
|
||||||
return;
|
"Error: there is only 1 or 0 reference frame, which doesn't constitute a path.\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
if (cv.size() == 0) {
|
if (cv.size() == 0) {
|
||||||
cvm::error("Error: the CV " + name +
|
error_code =
|
||||||
" expects one or more nesting components.\n");
|
cvm::error("Error: the CV " + name + " expects one or more nesting components.\n",
|
||||||
return;
|
COLVARS_INPUT_ERROR);
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
x.type(colvarvalue::type_scalar);
|
|
||||||
use_explicit_gradients = true;
|
use_explicit_gradients = true;
|
||||||
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
|
||||||
if (!cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
|
if (!cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
|
||||||
@ -479,6 +569,8 @@ colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) {
|
|||||||
if (!use_explicit_gradients) {
|
if (!use_explicit_gradients) {
|
||||||
disable(f_cvc_explicit_gradient);
|
disable(f_cvc_explicit_gradient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void colvar::CVBasedPath::computeDistanceToReferenceFrames(std::vector<cvm::real>& result) {
|
void colvar::CVBasedPath::computeDistanceToReferenceFrames(std::vector<cvm::real>& result) {
|
||||||
@ -548,8 +640,47 @@ colvar::CVBasedPath::~CVBasedPath() {
|
|||||||
atom_groups.clear();
|
atom_groups.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
colvar::gspathCV::gspathCV(std::string const &conf): CVBasedPath(conf) {
|
|
||||||
|
void colvar::CVBasedPath::apply_force(colvarvalue const &force)
|
||||||
|
{
|
||||||
|
cvm::error("Error: using apply_force() in a component of type CVBasedPath, which is abstract.\n",
|
||||||
|
COLVARS_BUG_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::real colvar::CVBasedPath::dist2(colvarvalue const &x1, colvarvalue const &x2) const
|
||||||
|
{
|
||||||
|
return x1.dist2(x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
colvarvalue colvar::CVBasedPath::dist2_lgrad(colvarvalue const &x1, colvarvalue const &x2) const
|
||||||
|
{
|
||||||
|
return x1.dist2_grad(x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
colvarvalue colvar::CVBasedPath::dist2_rgrad(colvarvalue const &x1, colvarvalue const &x2) const
|
||||||
|
{
|
||||||
|
return x2.dist2_grad(x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void colvar::CVBasedPath::wrap(colvarvalue & /* x_unwrapped */) const {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
colvar::gspathCV::gspathCV()
|
||||||
|
{
|
||||||
set_function_type("gspathCV");
|
set_function_type("gspathCV");
|
||||||
|
x.type(colvarvalue::type_scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
int colvar::gspathCV::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = CVBasedPath::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
|
||||||
cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n"));
|
cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n"));
|
||||||
// Initialize variables for future calculation
|
// Initialize variables for future calculation
|
||||||
get_keyval(conf, "useSecondClosestFrame", use_second_closest_frame, true);
|
get_keyval(conf, "useSecondClosestFrame", use_second_closest_frame, true);
|
||||||
@ -565,11 +696,10 @@ colvar::gspathCV::gspathCV(std::string const &conf): CVBasedPath(conf) {
|
|||||||
cvm::log(std::string("Geometric path s(σ) will use the neighbouring frame to compute s_(m+1)\n"));
|
cvm::log(std::string("Geometric path s(σ) will use the neighbouring frame to compute s_(m+1)\n"));
|
||||||
}
|
}
|
||||||
if (total_reference_frames < 2) {
|
if (total_reference_frames < 2) {
|
||||||
cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + " reference frames, but gspathCV requires at least 2 frames.\n");
|
return cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + " reference frames, but gspathCV requires at least 2 frames.\n", COLVARS_INPUT_ERROR);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
GeometricPathCV::GeometricPathBase<colvarvalue, cvm::real, GeometricPathCV::path_sz::S>::initialize(cv.size(), ref_cv[0], total_reference_frames, use_second_closest_frame, use_third_closest_frame);
|
GeometricPathCV::GeometricPathBase<colvarvalue, cvm::real, GeometricPathCV::path_sz::S>::initialize(cv.size(), ref_cv[0], total_reference_frames, use_second_closest_frame, use_third_closest_frame);
|
||||||
x.type(colvarvalue::type_scalar);
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
colvar::gspathCV::~gspathCV() {}
|
colvar::gspathCV::~gspathCV() {}
|
||||||
@ -671,8 +801,16 @@ void colvar::gspathCV::apply_force(colvarvalue const &force) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
colvar::gzpathCV::gzpathCV(std::string const &conf): CVBasedPath(conf) {
|
colvar::gzpathCV::gzpathCV()
|
||||||
|
{
|
||||||
set_function_type("gzpathCV");
|
set_function_type("gzpathCV");
|
||||||
|
}
|
||||||
|
|
||||||
|
int colvar::gzpathCV::init(std::string const &conf) {
|
||||||
|
|
||||||
|
int error_code = CVBasedPath::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
|
||||||
cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n"));
|
cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n"));
|
||||||
// Initialize variables for future calculation
|
// Initialize variables for future calculation
|
||||||
M = cvm::real(total_reference_frames - 1);
|
M = cvm::real(total_reference_frames - 1);
|
||||||
@ -695,11 +833,13 @@ colvar::gzpathCV::gzpathCV(std::string const &conf): CVBasedPath(conf) {
|
|||||||
cvm::log(std::string("Geometric path z(σ) will use the square of distance from current frame to path compute z\n"));
|
cvm::log(std::string("Geometric path z(σ) will use the square of distance from current frame to path compute z\n"));
|
||||||
}
|
}
|
||||||
if (total_reference_frames < 2) {
|
if (total_reference_frames < 2) {
|
||||||
cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + " reference frames, but gzpathCV requires at least 2 frames.\n");
|
return cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) +
|
||||||
return;
|
" reference frames, but gzpathCV requires at least 2 frames.\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
GeometricPathCV::GeometricPathBase<colvarvalue, cvm::real, GeometricPathCV::path_sz::Z>::initialize(cv.size(), ref_cv[0], total_reference_frames, use_second_closest_frame, use_third_closest_frame, b_use_z_square);
|
GeometricPathCV::GeometricPathBase<colvarvalue, cvm::real, GeometricPathCV::path_sz::Z>::initialize(cv.size(), ref_cv[0], total_reference_frames, use_second_closest_frame, use_third_closest_frame, b_use_z_square);
|
||||||
x.type(colvarvalue::type_scalar);
|
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
colvar::gzpathCV::~gzpathCV() {
|
colvar::gzpathCV::~gzpathCV() {
|
||||||
@ -794,5 +934,3 @@ void colvar::gzpathCV::apply_force(colvarvalue const &force) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@ -1,16 +1,31 @@
|
|||||||
#if (__cplusplus >= 201103L)
|
// -*- 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 "colvarmodule.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvarparse.h"
|
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvarcomp.h"
|
#include "colvarcomp.h"
|
||||||
#include "colvar_neuralnetworkcompute.h"
|
#include "colvar_neuralnetworkcompute.h"
|
||||||
|
|
||||||
using namespace neuralnetworkCV;
|
using namespace neuralnetworkCV;
|
||||||
|
|
||||||
colvar::neuralNetwork::neuralNetwork(std::string const &conf): linearCombination(conf) {
|
|
||||||
|
colvar::neuralNetwork::neuralNetwork()
|
||||||
|
{
|
||||||
set_function_type("neuralNetwork");
|
set_function_type("neuralNetwork");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::neuralNetwork::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = linearCombination::init(conf);
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
// the output of neural network consists of multiple values
|
// the output of neural network consists of multiple values
|
||||||
// read "output_component" key to determine it
|
// read "output_component" key to determine it
|
||||||
get_keyval(conf, "output_component", m_output_index);
|
get_keyval(conf, "output_component", m_output_index);
|
||||||
@ -59,8 +74,8 @@ colvar::neuralNetwork::neuralNetwork(std::string const &conf): linearCombination
|
|||||||
std::string function_name;
|
std::string function_name;
|
||||||
get_keyval(conf, lookup_key.c_str(), function_name, std::string(""));
|
get_keyval(conf, lookup_key.c_str(), function_name, std::string(""));
|
||||||
if (activation_function_map.find(function_name) == activation_function_map.end()) {
|
if (activation_function_map.find(function_name) == activation_function_map.end()) {
|
||||||
cvm::error("Unknown activation function name: \"" + function_name + "\".\n");
|
return cvm::error("Unknown activation function name: \"" + function_name + "\".\n",
|
||||||
return;
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
activation_functions.push_back(std::make_pair(false, function_name));
|
activation_functions.push_back(std::make_pair(false, function_name));
|
||||||
cvm::log(std::string{"The activation function for layer["} + cvm::to_str(num_activation_functions + 1) + std::string{"] is "} + function_name + '\n');
|
cvm::log(std::string{"The activation function for layer["} + cvm::to_str(num_activation_functions + 1) + std::string{"] is "} + function_name + '\n');
|
||||||
@ -79,11 +94,13 @@ colvar::neuralNetwork::neuralNetwork(std::string const &conf): linearCombination
|
|||||||
}
|
}
|
||||||
// expect the three numbers are equal
|
// expect the three numbers are equal
|
||||||
if ((num_layers_weight != num_layers_bias) || (num_layers_bias != num_activation_functions)) {
|
if ((num_layers_weight != num_layers_bias) || (num_layers_bias != num_activation_functions)) {
|
||||||
cvm::error("Error: the numbers of weights, biases and activation functions do not match.\n");
|
return cvm::error(
|
||||||
return;
|
"Error: the numbers of weights, biases and activation functions do not match.\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
// nn = std::make_unique<neuralnetworkCV::neuralNetworkCompute>();
|
// nn = std::make_unique<neuralnetworkCV::neuralNetworkCompute>();
|
||||||
// std::make_unique is only available in C++14
|
// std::make_unique is only available in C++14
|
||||||
|
if (nn) nn.reset();
|
||||||
nn = std::unique_ptr<neuralnetworkCV::neuralNetworkCompute>(new neuralnetworkCV::neuralNetworkCompute());
|
nn = std::unique_ptr<neuralnetworkCV::neuralNetworkCompute>(new neuralnetworkCV::neuralNetworkCompute());
|
||||||
for (size_t i_layer = 0; i_layer < num_layers_weight; ++i_layer) {
|
for (size_t i_layer = 0; i_layer < num_layers_weight; ++i_layer) {
|
||||||
denseLayer d;
|
denseLayer d;
|
||||||
@ -93,8 +110,9 @@ colvar::neuralNetwork::neuralNetwork(std::string const &conf): linearCombination
|
|||||||
try {
|
try {
|
||||||
d = denseLayer(weight_files[i_layer], bias_files[i_layer], activation_functions[i_layer].second);
|
d = denseLayer(weight_files[i_layer], bias_files[i_layer], activation_functions[i_layer].second);
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
cvm::error("Error on initializing layer " + cvm::to_str(i_layer) + " (" + ex.what() + ")\n", COLVARS_INPUT_ERROR);
|
return cvm::error("Error on initializing layer " + cvm::to_str(i_layer) +
|
||||||
return;
|
" (" + ex.what() + ")\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
@ -104,8 +122,9 @@ colvar::neuralNetwork::neuralNetwork(std::string const &conf): linearCombination
|
|||||||
try {
|
try {
|
||||||
d = denseLayer(weight_files[i_layer], bias_files[i_layer], f, df);
|
d = denseLayer(weight_files[i_layer], bias_files[i_layer], f, df);
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
cvm::error("Error on initializing layer " + cvm::to_str(i_layer) + " (" + ex.what() + ")\n", COLVARS_INPUT_ERROR);
|
return cvm::error("Error on initializing layer " + cvm::to_str(i_layer) +
|
||||||
return;
|
" (" + ex.what() + ")\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
#ifdef LEPTON
|
#ifdef LEPTON
|
||||||
}
|
}
|
||||||
@ -123,11 +142,11 @@ colvar::neuralNetwork::neuralNetwork(std::string const &conf): linearCombination
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cvm::error("Error: error on adding a new dense layer.\n");
|
return cvm::error("Error: error on adding a new dense layer.\n", COLVARS_INPUT_ERROR);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nn->input().resize(cv.size());
|
nn->input().resize(cv.size());
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
colvar::neuralNetwork::~neuralNetwork() {
|
colvar::neuralNetwork::~neuralNetwork() {
|
||||||
@ -185,4 +204,24 @@ void colvar::neuralNetwork::apply_force(colvarvalue const &force) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
cvm::real colvar::neuralNetwork::dist2(colvarvalue const &x1, colvarvalue const &x2) const
|
||||||
|
{
|
||||||
|
return x1.dist2(x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
colvarvalue colvar::neuralNetwork::dist2_lgrad(colvarvalue const &x1, colvarvalue const &x2) const
|
||||||
|
{
|
||||||
|
return x1.dist2_grad(x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
colvarvalue colvar::neuralNetwork::dist2_rgrad(colvarvalue const &x1, colvarvalue const &x2) const
|
||||||
|
{
|
||||||
|
return x2.dist2_grad(x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void colvar::neuralNetwork::wrap(colvarvalue & /* x_unwrapped */) const {}
|
||||||
|
|||||||
@ -11,19 +11,23 @@
|
|||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvarparse.h"
|
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvarcomp.h"
|
#include "colvarcomp.h"
|
||||||
|
|
||||||
|
|
||||||
colvar::alpha_angles::alpha_angles(std::string const &conf)
|
colvar::alpha_angles::alpha_angles()
|
||||||
: cvc(conf)
|
|
||||||
{
|
{
|
||||||
set_function_type("alpha");
|
set_function_type("alpha");
|
||||||
enable(f_cvc_explicit_gradient);
|
enable(f_cvc_explicit_gradient);
|
||||||
x.type(colvarvalue::type_scalar);
|
x.type(colvarvalue::type_scalar);
|
||||||
|
|
||||||
colvarproxy *proxy = cvm::main()->proxy;
|
colvarproxy *proxy = cvm::main()->proxy;
|
||||||
|
r0 = proxy->angstrom_to_internal(3.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::alpha_angles::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
|
||||||
std::string segment_id;
|
std::string segment_id;
|
||||||
get_keyval(conf, "psfSegID", segment_id, std::string("MAIN"));
|
get_keyval(conf, "psfSegID", segment_id, std::string("MAIN"));
|
||||||
@ -44,29 +48,29 @@ colvar::alpha_angles::alpha_angles(std::string const &conf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cvm::error("Error: no residues defined in \"residueRange\".\n");
|
error_code |=
|
||||||
return;
|
cvm::error("Error: no residues defined in \"residueRange\".\n", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (residues.size() < 5) {
|
if (residues.size() < 5) {
|
||||||
cvm::error("Error: not enough residues defined in \"residueRange\".\n");
|
error_code |= cvm::error("Error: not enough residues defined in \"residueRange\".\n",
|
||||||
return;
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const &sid = segment_id;
|
std::string const &sid = segment_id;
|
||||||
std::vector<int> const &r = residues;
|
std::vector<int> const &r = residues;
|
||||||
|
|
||||||
|
|
||||||
get_keyval(conf, "hBondCoeff", hb_coeff, 0.5);
|
get_keyval(conf, "hBondCoeff", hb_coeff, hb_coeff);
|
||||||
if ( (hb_coeff < 0.0) || (hb_coeff > 1.0) ) {
|
if ((hb_coeff < 0.0) || (hb_coeff > 1.0)) {
|
||||||
cvm::error("Error: hBondCoeff must be defined between 0 and 1.\n");
|
error_code |=
|
||||||
return;
|
cvm::error("Error: hBondCoeff must be defined between 0 and 1.\n", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
get_keyval(conf, "angleRef", theta_ref, 88.0);
|
get_keyval(conf, "angleRef", theta_ref, theta_ref);
|
||||||
get_keyval(conf, "angleTol", theta_tol, 15.0);
|
get_keyval(conf, "angleTol", theta_tol, theta_tol);
|
||||||
|
|
||||||
if (hb_coeff < 1.0) {
|
if (hb_coeff < 1.0) {
|
||||||
|
|
||||||
@ -84,11 +88,9 @@ colvar::alpha_angles::alpha_angles(std::string const &conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
cvm::real r0;
|
get_keyval(conf, "hBondCutoff", r0, r0);
|
||||||
size_t en, ed;
|
get_keyval(conf, "hBondExpNumer", en, en);
|
||||||
get_keyval(conf, "hBondCutoff", r0, proxy->angstrom_to_internal(3.3));
|
get_keyval(conf, "hBondExpDenom", ed, ed);
|
||||||
get_keyval(conf, "hBondExpNumer", en, 6);
|
|
||||||
get_keyval(conf, "hBondExpDenom", ed, 8);
|
|
||||||
|
|
||||||
if (hb_coeff > 0.0) {
|
if (hb_coeff > 0.0) {
|
||||||
|
|
||||||
@ -103,15 +105,8 @@ colvar::alpha_angles::alpha_angles(std::string const &conf)
|
|||||||
cvm::log("The hBondCoeff specified will disable the hydrogen bond terms.\n");
|
cvm::log("The hBondCoeff specified will disable the hydrogen bond terms.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return error_code;
|
||||||
colvar::alpha_angles::alpha_angles()
|
|
||||||
: cvc()
|
|
||||||
{
|
|
||||||
set_function_type("alphaAngles");
|
|
||||||
enable(f_cvc_explicit_gradient);
|
|
||||||
x.type(colvarvalue::type_scalar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -273,24 +268,27 @@ void colvar::alpha_angles::apply_force(colvarvalue const &force)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
simple_scalar_dist_functions(alpha_angles)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// dihedral principal component
|
// dihedral principal component
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
colvar::dihedPC::dihedPC(std::string const &conf)
|
colvar::dihedPC::dihedPC()
|
||||||
: cvc(conf)
|
|
||||||
{
|
{
|
||||||
if (cvm::debug())
|
|
||||||
cvm::log("Initializing dihedral PC object.\n");
|
|
||||||
|
|
||||||
set_function_type("dihedPC");
|
set_function_type("dihedPC");
|
||||||
// Supported through references to atom groups of children cvcs
|
// Supported through references to atom groups of children cvcs
|
||||||
enable(f_cvc_explicit_gradient);
|
enable(f_cvc_explicit_gradient);
|
||||||
x.type(colvarvalue::type_scalar);
|
x.type(colvarvalue::type_scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvar::dihedPC::init(std::string const &conf)
|
||||||
|
{
|
||||||
|
int error_code = cvc::init(conf);
|
||||||
|
|
||||||
|
if (cvm::debug())
|
||||||
|
cvm::log("Initializing dihedral PC object.\n");
|
||||||
|
|
||||||
std::string segment_id;
|
std::string segment_id;
|
||||||
get_keyval(conf, "psfSegID", segment_id, std::string("MAIN"));
|
get_keyval(conf, "psfSegID", segment_id, std::string("MAIN"));
|
||||||
@ -311,14 +309,14 @@ colvar::dihedPC::dihedPC(std::string const &conf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cvm::error("Error: no residues defined in \"residueRange\".\n");
|
error_code |=
|
||||||
return;
|
cvm::error("Error: no residues defined in \"residueRange\".\n", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (residues.size() < 2) {
|
if (residues.size() < 2) {
|
||||||
cvm::error("Error: dihedralPC requires at least two residues.\n");
|
error_code |=
|
||||||
return;
|
cvm::error("Error: dihedralPC requires at least two residues.\n", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const &sid = segment_id;
|
std::string const &sid = segment_id;
|
||||||
@ -329,15 +327,15 @@ colvar::dihedPC::dihedPC(std::string const &conf)
|
|||||||
if (get_keyval(conf, "vectorFile", vecFileName, vecFileName)) {
|
if (get_keyval(conf, "vectorFile", vecFileName, vecFileName)) {
|
||||||
get_keyval(conf, "vectorNumber", vecNumber, 0);
|
get_keyval(conf, "vectorNumber", vecNumber, 0);
|
||||||
if (vecNumber < 1) {
|
if (vecNumber < 1) {
|
||||||
cvm::error("A positive value of vectorNumber is required.");
|
error_code |=
|
||||||
return;
|
cvm::error("A positive value of vectorNumber is required.", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream &vecFile =
|
std::istream &vecFile =
|
||||||
cvm::main()->proxy->input_stream(vecFileName,
|
cvm::main()->proxy->input_stream(vecFileName,
|
||||||
"dihedral PCA vector file");
|
"dihedral PCA vector file");
|
||||||
if (!vecFile) {
|
if (!vecFile) {
|
||||||
return;
|
return COLVARS_INPUT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: adapt to different formats by setting this flag
|
// TODO: adapt to different formats by setting this flag
|
||||||
@ -383,11 +381,10 @@ colvar::dihedPC::dihedPC(std::string const &conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( coeffs.size() != 4 * (residues.size() - 1)) {
|
if ( coeffs.size() != 4 * (residues.size() - 1)) {
|
||||||
cvm::error("Error: wrong number of coefficients: " +
|
error_code |= cvm::error("Error: wrong number of coefficients: " + cvm::to_str(coeffs.size()) +
|
||||||
cvm::to_str(coeffs.size()) + ". Expected " +
|
". Expected " + cvm::to_str(4 * (residues.size() - 1)) +
|
||||||
cvm::to_str(4 * (residues.size() - 1)) +
|
" (4 coeffs per residue, minus one residue).\n",
|
||||||
" (4 coeffs per residue, minus one residue).\n");
|
COLVARS_INPUT_ERROR);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < residues.size()-1; i++) {
|
for (size_t i = 0; i < residues.size()-1; i++) {
|
||||||
@ -413,16 +410,8 @@ colvar::dihedPC::dihedPC(std::string const &conf)
|
|||||||
|
|
||||||
if (cvm::debug())
|
if (cvm::debug())
|
||||||
cvm::log("Done initializing dihedPC object.\n");
|
cvm::log("Done initializing dihedPC object.\n");
|
||||||
}
|
|
||||||
|
|
||||||
|
return error_code;
|
||||||
colvar::dihedPC::dihedPC()
|
|
||||||
: cvc()
|
|
||||||
{
|
|
||||||
set_function_type("dihedPC");
|
|
||||||
// Supported through references to atom groups of children cvcs
|
|
||||||
enable(f_cvc_explicit_gradient);
|
|
||||||
x.type(colvarvalue::type_scalar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -491,6 +480,3 @@ void colvar::dihedPC::apply_force(colvarvalue const &force)
|
|||||||
coeffs[2*i+1] * dsindt) * force);
|
coeffs[2*i+1] * dsindt) * force);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
simple_scalar_dist_functions(dihedPC)
|
|
||||||
|
|||||||
@ -9,27 +9,39 @@
|
|||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvarparse.h"
|
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvarcomp.h"
|
#include "colvarcomp.h"
|
||||||
|
#include "colvar_rotation_derivative.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct colvar::orientation::rotation_derivative_impl_: public rotation_derivative<cvm::atom_pos, cvm::atom_pos> {
|
||||||
|
public:
|
||||||
|
rotation_derivative_impl_(colvar::orientation* orientation_cvc):
|
||||||
|
rotation_derivative<cvm::atom_pos, cvm::atom_pos>(
|
||||||
|
orientation_cvc->rot, orientation_cvc->ref_pos, orientation_cvc->shifted_pos) {}
|
||||||
|
};
|
||||||
|
|
||||||
colvar::orientation::orientation(std::string const &conf)
|
|
||||||
: cvc()
|
colvar::orientation::orientation()
|
||||||
{
|
{
|
||||||
set_function_type("orientation");
|
set_function_type("orientation");
|
||||||
|
rot_deriv_impl = std::unique_ptr<rotation_derivative_impl_>(new rotation_derivative_impl_(this));
|
||||||
disable(f_cvc_explicit_gradient);
|
disable(f_cvc_explicit_gradient);
|
||||||
x.type(colvarvalue::type_quaternion);
|
x.type(colvarvalue::type_quaternion);
|
||||||
colvar::orientation::init(conf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
colvar::orientation::~orientation() {}
|
||||||
|
|
||||||
|
|
||||||
int colvar::orientation::init(std::string const &conf)
|
int colvar::orientation::init(std::string const &conf)
|
||||||
{
|
{
|
||||||
int error_code = cvc::init(conf);
|
int error_code = cvc::init(conf);
|
||||||
|
|
||||||
atoms = parse_group(conf, "atoms");
|
atoms = parse_group(conf, "atoms");
|
||||||
|
if (!atoms || atoms->size() == 0) {
|
||||||
|
return error_code | COLVARS_INPUT_ERROR;
|
||||||
|
}
|
||||||
ref_pos.reserve(atoms->size());
|
ref_pos.reserve(atoms->size());
|
||||||
|
|
||||||
if (get_keyval(conf, "refPositions", ref_pos, ref_pos)) {
|
if (get_keyval(conf, "refPositions", ref_pos, ref_pos)) {
|
||||||
@ -56,17 +68,18 @@ int colvar::orientation::init(std::string const &conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ref_pos.resize(atoms->size());
|
ref_pos.resize(atoms->size());
|
||||||
cvm::load_coords(file_name.c_str(), &ref_pos, atoms,
|
error_code |= cvm::load_coords(file_name.c_str(), &ref_pos, atoms,
|
||||||
file_col, file_col_value);
|
file_col, file_col_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
|
||||||
if (!ref_pos.size()) {
|
if (!ref_pos.size()) {
|
||||||
return cvm::error("Error: must define a set of "
|
return cvm::error("Error: must define a set of "
|
||||||
"reference coordinates.\n", COLVARS_INPUT_ERROR);
|
"reference coordinates.\n", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cvm::rvector ref_cog(0.0, 0.0, 0.0);
|
cvm::rvector ref_cog(0.0, 0.0, 0.0);
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < ref_pos.size(); i++) {
|
for (i = 0; i < ref_pos.size(); i++) {
|
||||||
@ -84,30 +97,21 @@ int colvar::orientation::init(std::string const &conf)
|
|||||||
|
|
||||||
get_keyval(conf, "closestToQuaternion", ref_quat, cvm::quaternion(1.0, 0.0, 0.0, 0.0));
|
get_keyval(conf, "closestToQuaternion", ref_quat, cvm::quaternion(1.0, 0.0, 0.0, 0.0));
|
||||||
|
|
||||||
// initialize rot member data
|
// If the debug gradients feature is active, debug the rotation gradients
|
||||||
if (!atoms->noforce) {
|
// (note that this won't be active for the orientation CVC itself, because
|
||||||
rot.request_group2_gradients(atoms->size());
|
// colvardeps prevents the flag's activation)
|
||||||
}
|
rot.b_debug_gradients = is_enabled(f_cvc_debug_gradient);
|
||||||
|
|
||||||
return error_code;
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar::orientation::orientation()
|
|
||||||
: cvc()
|
|
||||||
{
|
|
||||||
set_function_type("orientation");
|
|
||||||
disable(f_cvc_explicit_gradient);
|
|
||||||
x.type(colvarvalue::type_quaternion);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void colvar::orientation::calc_value()
|
void colvar::orientation::calc_value()
|
||||||
{
|
{
|
||||||
rot.b_debug_gradients = is_enabled(f_cvc_debug_gradient);
|
|
||||||
atoms_cog = atoms->center_of_geometry();
|
atoms_cog = atoms->center_of_geometry();
|
||||||
|
|
||||||
rot.calc_optimal_rotation(ref_pos, atoms->positions_shifted(-1.0 * atoms_cog));
|
shifted_pos = atoms->positions_shifted(-1.0 * atoms_cog);
|
||||||
|
rot.calc_optimal_rotation(ref_pos, shifted_pos);
|
||||||
|
|
||||||
if ((rot.q).inner(ref_quat) >= 0.0) {
|
if ((rot.q).inner(ref_quat) >= 0.0) {
|
||||||
x.quaternion_value = rot.q;
|
x.quaternion_value = rot.q;
|
||||||
@ -131,9 +135,12 @@ void colvar::orientation::apply_force(colvarvalue const &force)
|
|||||||
cvm::quaternion const &FQ = force.quaternion_value;
|
cvm::quaternion const &FQ = force.quaternion_value;
|
||||||
|
|
||||||
if (!atoms->noforce) {
|
if (!atoms->noforce) {
|
||||||
|
rot_deriv_impl->prepare_derivative(rotation_derivative_dldq::use_dq);
|
||||||
|
cvm::vector1d<cvm::rvector> dq0_2;
|
||||||
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
||||||
|
rot_deriv_impl->calc_derivative_wrt_group2(ia, nullptr, &dq0_2);
|
||||||
for (size_t i = 0; i < 4; i++) {
|
for (size_t i = 0; i < 4; i++) {
|
||||||
(*atoms)[ia].apply_force(FQ[i] * rot.dQ0_2[ia][i]);
|
(*atoms)[ia].apply_force(FQ[i] * dq0_2[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,20 +168,15 @@ colvarvalue colvar::orientation::dist2_rgrad(colvarvalue const &x1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void colvar::orientation::wrap(colvarvalue & /* x_unwrapped */) const {}
|
||||||
|
|
||||||
colvar::orientation_angle::orientation_angle(std::string const &conf)
|
|
||||||
: orientation()
|
|
||||||
|
colvar::orientation_angle::orientation_angle()
|
||||||
{
|
{
|
||||||
set_function_type("orientationAngle");
|
set_function_type("orientationAngle");
|
||||||
init_as_angle();
|
init_as_angle();
|
||||||
enable(f_cvc_explicit_gradient);
|
enable(f_cvc_explicit_gradient);
|
||||||
orientation_angle::init(conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int colvar::orientation_angle::init(std::string const &conf)
|
|
||||||
{
|
|
||||||
return orientation::init(conf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -182,7 +184,8 @@ void colvar::orientation_angle::calc_value()
|
|||||||
{
|
{
|
||||||
atoms_cog = atoms->center_of_geometry();
|
atoms_cog = atoms->center_of_geometry();
|
||||||
|
|
||||||
rot.calc_optimal_rotation(ref_pos, atoms->positions_shifted(-1.0 * atoms_cog));
|
shifted_pos = atoms->positions_shifted(-1.0 * atoms_cog);
|
||||||
|
rot.calc_optimal_rotation(ref_pos, shifted_pos);
|
||||||
|
|
||||||
if ((rot.q).q0 >= 0.0) {
|
if ((rot.q).q0 >= 0.0) {
|
||||||
x.real_value = (180.0/PI) * 2.0 * cvm::acos((rot.q).q0);
|
x.real_value = (180.0/PI) * 2.0 * cvm::acos((rot.q).q0);
|
||||||
@ -199,46 +202,59 @@ void colvar::orientation_angle::calc_gradients()
|
|||||||
((180.0 / PI) * (-2.0) / cvm::sqrt(1.0 - ((rot.q).q0 * (rot.q).q0))) :
|
((180.0 / PI) * (-2.0) / cvm::sqrt(1.0 - ((rot.q).q0 * (rot.q).q0))) :
|
||||||
0.0 );
|
0.0 );
|
||||||
|
|
||||||
|
rot_deriv_impl->prepare_derivative(rotation_derivative_dldq::use_dq);
|
||||||
|
cvm::vector1d<cvm::rvector> dq0_2;
|
||||||
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
||||||
(*atoms)[ia].grad = (dxdq0 * (rot.dQ0_2[ia])[0]);
|
rot_deriv_impl->calc_derivative_wrt_group2(ia, nullptr, &dq0_2);
|
||||||
|
(*atoms)[ia].grad = (dxdq0 * dq0_2[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::orientation_angle::apply_force(colvarvalue const &force)
|
void colvar::orientation_angle::apply_force(colvarvalue const &force)
|
||||||
{
|
{
|
||||||
cvm::real const &fw = force.real_value;
|
cvc::apply_force(force);
|
||||||
if (!atoms->noforce) {
|
|
||||||
atoms->apply_colvar_force(fw);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
simple_scalar_dist_functions(orientation_angle)
|
cvm::real colvar::orientation_angle::dist2(colvarvalue const &x1, colvarvalue const &x2) const
|
||||||
|
{
|
||||||
|
return cvc::dist2(x1, x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
colvarvalue colvar::orientation_angle::dist2_lgrad(colvarvalue const &x1,
|
||||||
|
colvarvalue const &x2) const
|
||||||
|
{
|
||||||
|
return cvc::dist2_lgrad(x1, x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
colvarvalue colvar::orientation_angle::dist2_rgrad(colvarvalue const &x1,
|
||||||
|
colvarvalue const &x2) const
|
||||||
|
{
|
||||||
|
return cvc::dist2_rgrad(x1, x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void colvar::orientation_angle::wrap(colvarvalue & /* x_unwrapped */) const {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
colvar::orientation_proj::orientation_proj(std::string const &conf)
|
colvar::orientation_proj::orientation_proj()
|
||||||
: orientation()
|
|
||||||
{
|
{
|
||||||
set_function_type("orientationProj");
|
set_function_type("orientationProj");
|
||||||
enable(f_cvc_explicit_gradient);
|
enable(f_cvc_explicit_gradient);
|
||||||
x.type(colvarvalue::type_scalar);
|
x.type(colvarvalue::type_scalar);
|
||||||
init_scalar_boundaries(0.0, 1.0);
|
init_scalar_boundaries(0.0, 1.0);
|
||||||
orientation_proj::init(conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int colvar::orientation_proj::init(std::string const &conf)
|
|
||||||
{
|
|
||||||
return orientation::init(conf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::orientation_proj::calc_value()
|
void colvar::orientation_proj::calc_value()
|
||||||
{
|
{
|
||||||
atoms_cog = atoms->center_of_geometry();
|
atoms_cog = atoms->center_of_geometry();
|
||||||
rot.calc_optimal_rotation(ref_pos, atoms->positions_shifted(-1.0 * atoms_cog));
|
shifted_pos = atoms->positions_shifted(-1.0 * atoms_cog);
|
||||||
|
rot.calc_optimal_rotation(ref_pos, shifted_pos);
|
||||||
x.real_value = 2.0 * (rot.q).q0 * (rot.q).q0 - 1.0;
|
x.real_value = 2.0 * (rot.q).q0 * (rot.q).q0 - 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,42 +262,28 @@ void colvar::orientation_proj::calc_value()
|
|||||||
void colvar::orientation_proj::calc_gradients()
|
void colvar::orientation_proj::calc_gradients()
|
||||||
{
|
{
|
||||||
cvm::real const dxdq0 = 2.0 * 2.0 * (rot.q).q0;
|
cvm::real const dxdq0 = 2.0 * 2.0 * (rot.q).q0;
|
||||||
|
rot_deriv_impl->prepare_derivative(rotation_derivative_dldq::use_dq);
|
||||||
|
cvm::vector1d<cvm::rvector> dq0_2;
|
||||||
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
||||||
(*atoms)[ia].grad = (dxdq0 * (rot.dQ0_2[ia])[0]);
|
rot_deriv_impl->calc_derivative_wrt_group2(ia, nullptr, &dq0_2);
|
||||||
|
(*atoms)[ia].grad = (dxdq0 * dq0_2[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::orientation_proj::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
cvm::real const &fw = force.real_value;
|
|
||||||
|
|
||||||
if (!atoms->noforce) {
|
colvar::tilt::tilt()
|
||||||
atoms->apply_colvar_force(fw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
simple_scalar_dist_functions(orientation_proj)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
colvar::tilt::tilt(std::string const &conf)
|
|
||||||
: orientation()
|
|
||||||
{
|
{
|
||||||
set_function_type("tilt");
|
set_function_type("tilt");
|
||||||
x.type(colvarvalue::type_scalar);
|
x.type(colvarvalue::type_scalar);
|
||||||
enable(f_cvc_explicit_gradient);
|
enable(f_cvc_explicit_gradient);
|
||||||
init_scalar_boundaries(-1.0, 1.0);
|
init_scalar_boundaries(-1.0, 1.0);
|
||||||
tilt::init(conf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvar::tilt::init(std::string const &conf)
|
int colvar::tilt::init(std::string const &conf)
|
||||||
{
|
{
|
||||||
int error_code = COLVARS_OK;
|
int error_code = orientation_proj::init(conf);
|
||||||
|
|
||||||
error_code |= orientation::init(conf);
|
|
||||||
|
|
||||||
get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0));
|
get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0));
|
||||||
if (axis.norm2() != 1.0) {
|
if (axis.norm2() != 1.0) {
|
||||||
@ -297,7 +299,8 @@ void colvar::tilt::calc_value()
|
|||||||
{
|
{
|
||||||
atoms_cog = atoms->center_of_geometry();
|
atoms_cog = atoms->center_of_geometry();
|
||||||
|
|
||||||
rot.calc_optimal_rotation(ref_pos, atoms->positions_shifted(-1.0 * atoms_cog));
|
shifted_pos = atoms->positions_shifted(-1.0 * atoms_cog);
|
||||||
|
rot.calc_optimal_rotation(ref_pos, shifted_pos);
|
||||||
|
|
||||||
x.real_value = rot.cos_theta(axis);
|
x.real_value = rot.cos_theta(axis);
|
||||||
}
|
}
|
||||||
@ -307,64 +310,24 @@ void colvar::tilt::calc_gradients()
|
|||||||
{
|
{
|
||||||
cvm::quaternion const dxdq = rot.dcos_theta_dq(axis);
|
cvm::quaternion const dxdq = rot.dcos_theta_dq(axis);
|
||||||
|
|
||||||
|
rot_deriv_impl->prepare_derivative(rotation_derivative_dldq::use_dq);
|
||||||
|
cvm::vector1d<cvm::rvector> dq0_2;
|
||||||
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
||||||
(*atoms)[ia].grad = cvm::rvector(0.0, 0.0, 0.0);
|
(*atoms)[ia].grad = cvm::rvector(0.0, 0.0, 0.0);
|
||||||
|
rot_deriv_impl->calc_derivative_wrt_group2(ia, nullptr, &dq0_2);
|
||||||
for (size_t iq = 0; iq < 4; iq++) {
|
for (size_t iq = 0; iq < 4; iq++) {
|
||||||
(*atoms)[ia].grad += (dxdq[iq] * (rot.dQ0_2[ia])[iq]);
|
(*atoms)[ia].grad += (dxdq[iq] * dq0_2[iq]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::tilt::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
cvm::real const &fw = force.real_value;
|
|
||||||
|
|
||||||
if (!atoms->noforce) {
|
colvar::spin_angle::spin_angle()
|
||||||
atoms->apply_colvar_force(fw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
simple_scalar_dist_functions(tilt)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
colvar::spin_angle::spin_angle(std::string const &conf)
|
|
||||||
: orientation()
|
|
||||||
{
|
{
|
||||||
set_function_type("spinAngle");
|
set_function_type("spinAngle");
|
||||||
init_as_periodic_angle();
|
init_as_periodic_angle();
|
||||||
enable(f_cvc_periodic);
|
|
||||||
enable(f_cvc_explicit_gradient);
|
enable(f_cvc_explicit_gradient);
|
||||||
spin_angle::init(conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int colvar::spin_angle::init(std::string const &conf)
|
|
||||||
{
|
|
||||||
int error_code = COLVARS_OK;
|
|
||||||
|
|
||||||
error_code |= orientation::init(conf);
|
|
||||||
|
|
||||||
get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0));
|
|
||||||
if (axis.norm2() != 1.0) {
|
|
||||||
axis /= axis.norm();
|
|
||||||
cvm::log("Normalizing rotation axis to "+cvm::to_str(axis)+".\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return error_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvar::spin_angle::spin_angle()
|
|
||||||
: orientation()
|
|
||||||
{
|
|
||||||
set_function_type("spinAngle");
|
|
||||||
period = 360.0;
|
|
||||||
enable(f_cvc_periodic);
|
|
||||||
enable(f_cvc_explicit_gradient);
|
|
||||||
x.type(colvarvalue::type_scalar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -372,10 +335,11 @@ void colvar::spin_angle::calc_value()
|
|||||||
{
|
{
|
||||||
atoms_cog = atoms->center_of_geometry();
|
atoms_cog = atoms->center_of_geometry();
|
||||||
|
|
||||||
rot.calc_optimal_rotation(ref_pos, atoms->positions_shifted(-1.0 * atoms_cog));
|
shifted_pos = atoms->positions_shifted(-1.0 * atoms_cog);
|
||||||
|
rot.calc_optimal_rotation(ref_pos, shifted_pos);
|
||||||
|
|
||||||
x.real_value = rot.spin_angle(axis);
|
x.real_value = rot.spin_angle(axis);
|
||||||
this->wrap(x);
|
wrap(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -383,80 +347,20 @@ void colvar::spin_angle::calc_gradients()
|
|||||||
{
|
{
|
||||||
cvm::quaternion const dxdq = rot.dspin_angle_dq(axis);
|
cvm::quaternion const dxdq = rot.dspin_angle_dq(axis);
|
||||||
|
|
||||||
|
rot_deriv_impl->prepare_derivative(rotation_derivative_dldq::use_dq);
|
||||||
|
cvm::vector1d<cvm::rvector> dq0_2;
|
||||||
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
||||||
(*atoms)[ia].grad = cvm::rvector(0.0, 0.0, 0.0);
|
(*atoms)[ia].grad = cvm::rvector(0.0, 0.0, 0.0);
|
||||||
|
rot_deriv_impl->calc_derivative_wrt_group2(ia, nullptr, &dq0_2);
|
||||||
for (size_t iq = 0; iq < 4; iq++) {
|
for (size_t iq = 0; iq < 4; iq++) {
|
||||||
(*atoms)[ia].grad += (dxdq[iq] * (rot.dQ0_2[ia])[iq]);
|
(*atoms)[ia].grad += (dxdq[iq] * dq0_2[iq]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::spin_angle::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
cvm::real const &fw = force.real_value;
|
|
||||||
|
|
||||||
if (!atoms->noforce) {
|
|
||||||
atoms->apply_colvar_force(fw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cvm::real colvar::spin_angle::dist2(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return diff * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::spin_angle::dist2_lgrad(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return 2.0 * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::spin_angle::dist2_rgrad(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return (-2.0) * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void colvar::spin_angle::wrap(colvarvalue &x_unwrapped) const
|
|
||||||
{
|
|
||||||
if ((x_unwrapped.real_value - wrap_center) >= 180.0) {
|
|
||||||
x_unwrapped.real_value -= 360.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((x_unwrapped.real_value - wrap_center) < -180.0) {
|
|
||||||
x_unwrapped.real_value += 360.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvar::euler_phi::euler_phi(std::string const &conf)
|
|
||||||
: orientation()
|
|
||||||
{
|
|
||||||
set_function_type("eulerPhi");
|
|
||||||
init_as_periodic_angle();
|
|
||||||
enable(f_cvc_explicit_gradient);
|
|
||||||
euler_phi::init(conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvar::euler_phi::euler_phi()
|
colvar::euler_phi::euler_phi()
|
||||||
: orientation()
|
|
||||||
{
|
{
|
||||||
set_function_type("eulerPhi");
|
set_function_type("eulerPhi");
|
||||||
init_as_periodic_angle();
|
init_as_periodic_angle();
|
||||||
@ -464,19 +368,12 @@ colvar::euler_phi::euler_phi()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvar::euler_phi::init(std::string const &conf)
|
|
||||||
{
|
|
||||||
int error_code = COLVARS_OK;
|
|
||||||
error_code |= orientation::init(conf);
|
|
||||||
return error_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void colvar::euler_phi::calc_value()
|
void colvar::euler_phi::calc_value()
|
||||||
{
|
{
|
||||||
atoms_cog = atoms->center_of_geometry();
|
atoms_cog = atoms->center_of_geometry();
|
||||||
|
|
||||||
rot.calc_optimal_rotation(ref_pos, atoms->positions_shifted(-1.0 * atoms_cog));
|
shifted_pos = atoms->positions_shifted(-1.0 * atoms_cog);
|
||||||
|
rot.calc_optimal_rotation(ref_pos, shifted_pos);
|
||||||
|
|
||||||
const cvm::real& q0 = rot.q.q0;
|
const cvm::real& q0 = rot.q.q0;
|
||||||
const cvm::real& q1 = rot.q.q1;
|
const cvm::real& q1 = rot.q.q1;
|
||||||
@ -499,79 +396,20 @@ void colvar::euler_phi::calc_gradients()
|
|||||||
const cvm::real dxdq1 = (180.0/PI) * (2 * q0 * (-2 * q1 * q1 - 2 * q2 * q2 + 1) - 4 * q1 * (-2 * q0 * q1 - 2 * q2 * q3)) / denominator;
|
const cvm::real dxdq1 = (180.0/PI) * (2 * q0 * (-2 * q1 * q1 - 2 * q2 * q2 + 1) - 4 * q1 * (-2 * q0 * q1 - 2 * q2 * q3)) / denominator;
|
||||||
const cvm::real dxdq2 = (180.0/PI) * (-4 * q2 * (-2 * q0 * q1 - 2 * q2 * q3) + 2 * q3 * (-2 * q1 * q1 - 2 * q2 * q2 + 1)) / denominator;
|
const cvm::real dxdq2 = (180.0/PI) * (-4 * q2 * (-2 * q0 * q1 - 2 * q2 * q3) + 2 * q3 * (-2 * q1 * q1 - 2 * q2 * q2 + 1)) / denominator;
|
||||||
const cvm::real dxdq3 = (180.0/PI) * 2 * q2 * (-2 * q1 * q1 - 2 * q2 * q2 + 1) / denominator;
|
const cvm::real dxdq3 = (180.0/PI) * 2 * q2 * (-2 * q1 * q1 - 2 * q2 * q2 + 1) / denominator;
|
||||||
|
rot_deriv_impl->prepare_derivative(rotation_derivative_dldq::use_dq);
|
||||||
|
cvm::vector1d<cvm::rvector> dq0_2;
|
||||||
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
||||||
(*atoms)[ia].grad = (dxdq0 * (rot.dQ0_2[ia])[0]) +
|
rot_deriv_impl->calc_derivative_wrt_group2(ia, nullptr, &dq0_2);
|
||||||
(dxdq1 * (rot.dQ0_2[ia])[1]) +
|
(*atoms)[ia].grad = (dxdq0 * dq0_2[0]) +
|
||||||
(dxdq2 * (rot.dQ0_2[ia])[2]) +
|
(dxdq1 * dq0_2[1]) +
|
||||||
(dxdq3 * (rot.dQ0_2[ia])[3]);
|
(dxdq2 * dq0_2[2]) +
|
||||||
|
(dxdq3 * dq0_2[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::euler_phi::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
cvm::real const &fw = force.real_value;
|
|
||||||
if (!atoms->noforce) {
|
|
||||||
atoms->apply_colvar_force(fw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cvm::real colvar::euler_phi::dist2(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return diff * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::euler_phi::dist2_lgrad(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return 2.0 * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::euler_phi::dist2_rgrad(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return (-2.0) * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void colvar::euler_phi::wrap(colvarvalue &x_unwrapped) const
|
|
||||||
{
|
|
||||||
if ((x_unwrapped.real_value - wrap_center) >= 180.0) {
|
|
||||||
x_unwrapped.real_value -= 360.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((x_unwrapped.real_value - wrap_center) < -180.0) {
|
|
||||||
x_unwrapped.real_value += 360.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvar::euler_psi::euler_psi(std::string const &conf)
|
|
||||||
: orientation()
|
|
||||||
{
|
|
||||||
set_function_type("eulerPsi");
|
|
||||||
init_as_periodic_angle();
|
|
||||||
enable(f_cvc_explicit_gradient);
|
|
||||||
euler_psi::init(conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvar::euler_psi::euler_psi()
|
colvar::euler_psi::euler_psi()
|
||||||
: orientation()
|
|
||||||
{
|
{
|
||||||
set_function_type("eulerPsi");
|
set_function_type("eulerPsi");
|
||||||
init_as_periodic_angle();
|
init_as_periodic_angle();
|
||||||
@ -579,19 +417,12 @@ colvar::euler_psi::euler_psi()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvar::euler_psi::init(std::string const &conf)
|
|
||||||
{
|
|
||||||
int error_code = COLVARS_OK;
|
|
||||||
error_code |= orientation::init(conf);
|
|
||||||
return error_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void colvar::euler_psi::calc_value()
|
void colvar::euler_psi::calc_value()
|
||||||
{
|
{
|
||||||
atoms_cog = atoms->center_of_geometry();
|
atoms_cog = atoms->center_of_geometry();
|
||||||
|
|
||||||
rot.calc_optimal_rotation(ref_pos, atoms->positions_shifted(-1.0 * atoms_cog));
|
shifted_pos = atoms->positions_shifted(-1.0 * atoms_cog);
|
||||||
|
rot.calc_optimal_rotation(ref_pos, shifted_pos);
|
||||||
|
|
||||||
const cvm::real& q0 = rot.q.q0;
|
const cvm::real& q0 = rot.q.q0;
|
||||||
const cvm::real& q1 = rot.q.q1;
|
const cvm::real& q1 = rot.q.q1;
|
||||||
@ -614,79 +445,20 @@ void colvar::euler_psi::calc_gradients()
|
|||||||
const cvm::real dxdq1 = (180.0/PI) * 2 * q2 * (-2 * q2 * q2 - 2 * q3 * q3 + 1) / denominator;
|
const cvm::real dxdq1 = (180.0/PI) * 2 * q2 * (-2 * q2 * q2 - 2 * q3 * q3 + 1) / denominator;
|
||||||
const cvm::real dxdq2 = (180.0/PI) * (2 * q1 * (-2 * q2 * q2 - 2 * q3 * q3 + 1) - 4 * q2 * (-2 * q0 * q3 - 2 * q1 * q2)) / denominator;
|
const cvm::real dxdq2 = (180.0/PI) * (2 * q1 * (-2 * q2 * q2 - 2 * q3 * q3 + 1) - 4 * q2 * (-2 * q0 * q3 - 2 * q1 * q2)) / denominator;
|
||||||
const cvm::real dxdq3 = (180.0/PI) * (2 * q0 * (-2 * q2 * q2 - 2 * q3 * q3 + 1) - 4 * q3 * (-2 * q0 * q3 - 2 * q1 * q2)) / denominator;
|
const cvm::real dxdq3 = (180.0/PI) * (2 * q0 * (-2 * q2 * q2 - 2 * q3 * q3 + 1) - 4 * q3 * (-2 * q0 * q3 - 2 * q1 * q2)) / denominator;
|
||||||
|
rot_deriv_impl->prepare_derivative(rotation_derivative_dldq::use_dq);
|
||||||
|
cvm::vector1d<cvm::rvector> dq0_2;
|
||||||
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
||||||
(*atoms)[ia].grad = (dxdq0 * (rot.dQ0_2[ia])[0]) +
|
rot_deriv_impl->calc_derivative_wrt_group2(ia, nullptr, &dq0_2);
|
||||||
(dxdq1 * (rot.dQ0_2[ia])[1]) +
|
(*atoms)[ia].grad = (dxdq0 * dq0_2[0]) +
|
||||||
(dxdq2 * (rot.dQ0_2[ia])[2]) +
|
(dxdq1 * dq0_2[1]) +
|
||||||
(dxdq3 * (rot.dQ0_2[ia])[3]);
|
(dxdq2 * dq0_2[2]) +
|
||||||
|
(dxdq3 * dq0_2[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::euler_psi::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
cvm::real const &fw = force.real_value;
|
|
||||||
if (!atoms->noforce) {
|
|
||||||
atoms->apply_colvar_force(fw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cvm::real colvar::euler_psi::dist2(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return diff * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::euler_psi::dist2_lgrad(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return 2.0 * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::euler_psi::dist2_rgrad(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
cvm::real diff = x1.real_value - x2.real_value;
|
|
||||||
diff = (diff < -180.0 ? diff + 360.0 : (diff > 180.0 ? diff - 360.0 : diff));
|
|
||||||
return (-2.0) * diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void colvar::euler_psi::wrap(colvarvalue &x_unwrapped) const
|
|
||||||
{
|
|
||||||
if ((x_unwrapped.real_value - wrap_center) >= 180.0) {
|
|
||||||
x_unwrapped.real_value -= 360.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((x_unwrapped.real_value - wrap_center) < -180.0) {
|
|
||||||
x_unwrapped.real_value += 360.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvar::euler_theta::euler_theta(std::string const &conf)
|
|
||||||
: orientation()
|
|
||||||
{
|
|
||||||
set_function_type("eulerTheta");
|
|
||||||
init_as_angle();
|
|
||||||
enable(f_cvc_explicit_gradient);
|
|
||||||
euler_theta::init(conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvar::euler_theta::euler_theta()
|
colvar::euler_theta::euler_theta()
|
||||||
: orientation()
|
|
||||||
{
|
{
|
||||||
set_function_type("eulerTheta");
|
set_function_type("eulerTheta");
|
||||||
init_as_angle();
|
init_as_angle();
|
||||||
@ -694,19 +466,12 @@ colvar::euler_theta::euler_theta()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvar::euler_theta::init(std::string const &conf)
|
|
||||||
{
|
|
||||||
int error_code = COLVARS_OK;
|
|
||||||
error_code |= orientation::init(conf);
|
|
||||||
return error_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void colvar::euler_theta::calc_value()
|
void colvar::euler_theta::calc_value()
|
||||||
{
|
{
|
||||||
atoms_cog = atoms->center_of_geometry();
|
atoms_cog = atoms->center_of_geometry();
|
||||||
|
|
||||||
rot.calc_optimal_rotation(ref_pos, atoms->positions_shifted(-1.0 * atoms_cog));
|
shifted_pos = atoms->positions_shifted(-1.0 * atoms_cog);
|
||||||
|
rot.calc_optimal_rotation(ref_pos, shifted_pos);
|
||||||
|
|
||||||
const cvm::real& q0 = rot.q.q0;
|
const cvm::real& q0 = rot.q.q0;
|
||||||
const cvm::real& q1 = rot.q.q1;
|
const cvm::real& q1 = rot.q.q1;
|
||||||
@ -727,43 +492,13 @@ void colvar::euler_theta::calc_gradients()
|
|||||||
const cvm::real dxdq1 = (180.0/PI) * -2 * q3 / denominator;
|
const cvm::real dxdq1 = (180.0/PI) * -2 * q3 / denominator;
|
||||||
const cvm::real dxdq2 = (180.0/PI) * 2 * q0 / denominator;
|
const cvm::real dxdq2 = (180.0/PI) * 2 * q0 / denominator;
|
||||||
const cvm::real dxdq3 = (180.0/PI) * -2 * q1 / denominator;
|
const cvm::real dxdq3 = (180.0/PI) * -2 * q1 / denominator;
|
||||||
|
rot_deriv_impl->prepare_derivative(rotation_derivative_dldq::use_dq);
|
||||||
|
cvm::vector1d<cvm::rvector> dq0_2;
|
||||||
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
for (size_t ia = 0; ia < atoms->size(); ia++) {
|
||||||
(*atoms)[ia].grad = (dxdq0 * (rot.dQ0_2[ia])[0]) +
|
rot_deriv_impl->calc_derivative_wrt_group2(ia, nullptr, &dq0_2);
|
||||||
(dxdq1 * (rot.dQ0_2[ia])[1]) +
|
(*atoms)[ia].grad = (dxdq0 * dq0_2[0]) +
|
||||||
(dxdq2 * (rot.dQ0_2[ia])[2]) +
|
(dxdq1 * dq0_2[1]) +
|
||||||
(dxdq3 * (rot.dQ0_2[ia])[3]);
|
(dxdq2 * dq0_2[2]) +
|
||||||
|
(dxdq3 * dq0_2[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvar::euler_theta::apply_force(colvarvalue const &force)
|
|
||||||
{
|
|
||||||
cvm::real const &fw = force.real_value;
|
|
||||||
if (!atoms->noforce) {
|
|
||||||
atoms->apply_colvar_force(fw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cvm::real colvar::euler_theta::dist2(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
// theta angle is not periodic
|
|
||||||
return cvc::dist2(x1, x2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::euler_theta::dist2_lgrad(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
// theta angle is not periodic
|
|
||||||
return cvc::dist2_lgrad(x1, x2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
colvarvalue colvar::euler_theta::dist2_rgrad(colvarvalue const &x1,
|
|
||||||
colvarvalue const &x2) const
|
|
||||||
{
|
|
||||||
// theta angle is not periodic
|
|
||||||
return cvc::dist2_rgrad(x1, x2);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -9,35 +9,18 @@
|
|||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvarparse.h"
|
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvarcomp.h"
|
#include "colvarcomp.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
colvar::map_total::map_total()
|
colvar::map_total::map_total()
|
||||||
: cvc()
|
|
||||||
{
|
{
|
||||||
set_function_type("mapTotal");
|
set_function_type("mapTotal");
|
||||||
volmap_id = -1;
|
|
||||||
volmap_index = -1;
|
|
||||||
atoms = NULL;
|
|
||||||
x.type(colvarvalue::type_scalar);
|
x.type(colvarvalue::type_scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar::map_total::map_total(std::string const &conf)
|
|
||||||
: cvc() // init() will take care of this
|
|
||||||
{
|
|
||||||
set_function_type("mapTotal");
|
|
||||||
volmap_id = -1;
|
|
||||||
volmap_index = -1;
|
|
||||||
atoms = NULL;
|
|
||||||
x.type(colvarvalue::type_scalar);
|
|
||||||
map_total::init(conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int colvar::map_total::init(std::string const &conf)
|
int colvar::map_total::init(std::string const &conf)
|
||||||
{
|
{
|
||||||
int error_code = cvc::init(conf);
|
int error_code = cvc::init(conf);
|
||||||
@ -50,12 +33,12 @@ int colvar::map_total::init(std::string const &conf)
|
|||||||
|
|
||||||
if ((volmap_name.size() > 0) && (volmap_id >= 0)) {
|
if ((volmap_name.size() > 0) && (volmap_id >= 0)) {
|
||||||
error_code |=
|
error_code |=
|
||||||
cvm::error("Error: mapName and mapID are mutually exclusive.\n");
|
cvm::error("Error: mapName and mapID are mutually exclusive.\n", COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse optional group
|
// Parse optional group
|
||||||
atoms = parse_group(conf, "atoms", true);
|
atoms = parse_group(conf, "atoms", true);
|
||||||
if (atoms != NULL) {
|
if (atoms) {
|
||||||
|
|
||||||
// Using internal selection
|
// Using internal selection
|
||||||
if (volmap_name.size()) {
|
if (volmap_name.size()) {
|
||||||
@ -74,11 +57,11 @@ int colvar::map_total::init(std::string const &conf)
|
|||||||
if (volmap_id >= 0) {
|
if (volmap_id >= 0) {
|
||||||
volmap_index = proxy->init_volmap_by_id(volmap_id);
|
volmap_index = proxy->init_volmap_by_id(volmap_id);
|
||||||
}
|
}
|
||||||
error_code |= volmap_index > 0 ? COLVARS_OK : COLVARS_INPUT_ERROR;
|
error_code |= (volmap_index >= 0) ? COLVARS_OK : COLVARS_INPUT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_keyval(conf, "atomWeights", atom_weights, atom_weights)) {
|
if (get_keyval(conf, "atomWeights", atom_weights, atom_weights)) {
|
||||||
if (atoms == NULL) {
|
if (!atoms) {
|
||||||
error_code |= cvm::error("Error: weights can only be assigned when atoms "
|
error_code |= cvm::error("Error: weights can only be assigned when atoms "
|
||||||
"are selected explicitly in Colvars.\n",
|
"are selected explicitly in Colvars.\n",
|
||||||
COLVARS_INPUT_ERROR);
|
COLVARS_INPUT_ERROR);
|
||||||
@ -133,11 +116,10 @@ void colvar::map_total::calc_gradients()
|
|||||||
|
|
||||||
void colvar::map_total::apply_force(colvarvalue const &force)
|
void colvar::map_total::apply_force(colvarvalue const &force)
|
||||||
{
|
{
|
||||||
colvarproxy *proxy = cvm::main()->proxy;
|
|
||||||
if (atoms) {
|
if (atoms) {
|
||||||
if (!atoms->noforce)
|
cvc::apply_force(force);
|
||||||
atoms->apply_colvar_force(force.real_value);
|
|
||||||
} else {
|
} else {
|
||||||
|
colvarproxy *proxy = cvm::main()->proxy;
|
||||||
proxy->apply_volmap_force(volmap_index, force.real_value);
|
proxy->apply_volmap_force(volmap_index, force.real_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -129,6 +129,11 @@ int colvardeps::enable(int feature_id,
|
|||||||
int res;
|
int res;
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
bool ok;
|
bool ok;
|
||||||
|
|
||||||
|
if (feature_id < 0 || feature_id >= int(features().size())) {
|
||||||
|
cvm::error("Error: colvardeps::enable() called with invalid feature_id " + cvm::to_str(feature_id) + "\n");
|
||||||
|
return COLVARS_ERROR;
|
||||||
|
}
|
||||||
feature *f = features()[feature_id];
|
feature *f = features()[feature_id];
|
||||||
feature_state *fs = &feature_states[feature_id];
|
feature_state *fs = &feature_states[feature_id];
|
||||||
|
|
||||||
|
|||||||
@ -253,6 +253,8 @@ public:
|
|||||||
f_cvb_write_ti_pmf,
|
f_cvb_write_ti_pmf,
|
||||||
/// \brief whether this bias uses an external grid to scale the biasing forces
|
/// \brief whether this bias uses an external grid to scale the biasing forces
|
||||||
f_cvb_scale_biasing_force,
|
f_cvb_scale_biasing_force,
|
||||||
|
/// \brief whether this bias is applied to one or more ext-Lagrangian colvars
|
||||||
|
f_cvb_extended,
|
||||||
f_cvb_ntot
|
f_cvb_ntot
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -355,6 +357,8 @@ public:
|
|||||||
f_cvc_lower_boundary,
|
f_cvc_lower_boundary,
|
||||||
/// This CVC provides a default value for the colvar's upper boundary
|
/// This CVC provides a default value for the colvar's upper boundary
|
||||||
f_cvc_upper_boundary,
|
f_cvc_upper_boundary,
|
||||||
|
/// CVC accesses atom groups directly (as opposed to going throuh other objects)
|
||||||
|
f_cvc_explicit_atom_groups,
|
||||||
/// CVC calculates atom gradients
|
/// CVC calculates atom gradients
|
||||||
f_cvc_gradient,
|
f_cvc_gradient,
|
||||||
/// CVC calculates and stores explicit atom gradients on rank 0
|
/// CVC calculates and stores explicit atom gradients on rank 0
|
||||||
|
|||||||
@ -8,13 +8,11 @@
|
|||||||
// Colvars repository at GitHub.
|
// Colvars repository at GitHub.
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvarparse.h"
|
#include "colvarparse.h"
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvarcomp.h"
|
|
||||||
#include "colvargrid.h"
|
#include "colvargrid.h"
|
||||||
#include "colvargrid_def.h"
|
#include "colvargrid_def.h"
|
||||||
|
|
||||||
@ -37,6 +35,58 @@ colvar_grid_count::colvar_grid_count(std::vector<colvar *> &colvars,
|
|||||||
: colvar_grid<size_t>(colvars, def_count, 1, margin)
|
: colvar_grid<size_t>(colvars, def_count, 1, margin)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
std::string colvar_grid_count::get_state_params() const
|
||||||
|
{
|
||||||
|
return colvar_grid<size_t>::get_state_params();
|
||||||
|
}
|
||||||
|
|
||||||
|
int colvar_grid_count::parse_params(std::string const &conf,
|
||||||
|
colvarparse::Parse_Mode const parse_mode)
|
||||||
|
{
|
||||||
|
return colvar_grid<size_t>::parse_params(conf, parse_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream & colvar_grid_count::read_restart(std::istream &is)
|
||||||
|
{
|
||||||
|
return colvar_grid<size_t>::read_restart(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::memory_stream & colvar_grid_count::read_restart(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
return colvar_grid<size_t>::read_restart(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream & colvar_grid_count::write_restart(std::ostream &os)
|
||||||
|
{
|
||||||
|
return colvar_grid<size_t>::write_restart(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::memory_stream & colvar_grid_count::write_restart(cvm::memory_stream &os)
|
||||||
|
{
|
||||||
|
return colvar_grid<size_t>::write_restart(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream &colvar_grid_count::read_raw(std::istream &is)
|
||||||
|
{
|
||||||
|
return colvar_grid<size_t>::read_raw(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::memory_stream &colvar_grid_count::read_raw(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
return colvar_grid<size_t>::read_raw(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &colvar_grid_count::write_raw(std::ostream &os, size_t const buf_size) const
|
||||||
|
{
|
||||||
|
return colvar_grid<size_t>::write_raw(os, buf_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::memory_stream &colvar_grid_count::write_raw(cvm::memory_stream &os,
|
||||||
|
size_t const buf_size) const
|
||||||
|
{
|
||||||
|
return colvar_grid<size_t>::write_raw(os, buf_size);
|
||||||
|
}
|
||||||
|
|
||||||
std::istream & colvar_grid_count::read_multicol(std::istream &is, bool add)
|
std::istream & colvar_grid_count::read_multicol(std::istream &is, bool add)
|
||||||
{
|
{
|
||||||
return colvar_grid<size_t>::read_multicol(is, add);
|
return colvar_grid<size_t>::read_multicol(is, add);
|
||||||
@ -96,6 +146,58 @@ colvar_grid_scalar::~colvar_grid_scalar()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string colvar_grid_scalar::get_state_params() const
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::get_state_params();
|
||||||
|
}
|
||||||
|
|
||||||
|
int colvar_grid_scalar::parse_params(std::string const &conf,
|
||||||
|
colvarparse::Parse_Mode const parse_mode)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::parse_params(conf, parse_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream &colvar_grid_scalar::read_restart(std::istream &is)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::read_restart(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::memory_stream &colvar_grid_scalar::read_restart(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::read_restart(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &colvar_grid_scalar::write_restart(std::ostream &os)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::write_restart(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::memory_stream &colvar_grid_scalar::write_restart(cvm::memory_stream &os)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::write_restart(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream &colvar_grid_scalar::read_raw(std::istream &is)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::read_raw(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::memory_stream &colvar_grid_scalar::read_raw(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::read_raw(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &colvar_grid_scalar::write_raw(std::ostream &os, size_t const buf_size) const
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::write_raw(os, buf_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::memory_stream &colvar_grid_scalar::write_raw(cvm::memory_stream &os,
|
||||||
|
size_t const buf_size) const
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::write_raw(os, buf_size);
|
||||||
|
}
|
||||||
|
|
||||||
std::istream & colvar_grid_scalar::read_multicol(std::istream &is, bool add)
|
std::istream & colvar_grid_scalar::read_multicol(std::istream &is, bool add)
|
||||||
{
|
{
|
||||||
return colvar_grid<cvm::real>::read_multicol(is, add);
|
return colvar_grid<cvm::real>::read_multicol(is, add);
|
||||||
@ -195,30 +297,63 @@ cvm::real colvar_grid_scalar::entropy() const
|
|||||||
return bin_volume * sum;
|
return bin_volume * sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Return the RMSD between this grid's data and another one
|
||||||
|
/// Grids must have the same dimensions.
|
||||||
|
cvm::real colvar_grid_scalar::grid_rmsd(colvar_grid_scalar const &other_grid) const
|
||||||
|
{
|
||||||
|
if (other_grid.data.size() != this->data.size()) {
|
||||||
|
cvm::error("Error: trying to subtract two grids with "
|
||||||
|
"different size.\n");
|
||||||
|
return -1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::real sum2 = 0.0;
|
||||||
|
|
||||||
|
if (samples && other_grid.samples) {
|
||||||
|
for (size_t i = 0; i < data.size(); i++) {
|
||||||
|
size_t n = samples->get_value(i);
|
||||||
|
cvm::real us = n ? data[i] / n : 0.0;
|
||||||
|
n = other_grid.samples->get_value(i);
|
||||||
|
cvm::real them = n ? other_grid.data[i ] / n : 0.0;
|
||||||
|
cvm::real d = us - them;
|
||||||
|
sum2 += d*d;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < data.size(); i++) {
|
||||||
|
cvm::real d = other_grid.data[i] - data[i];
|
||||||
|
sum2 += d*d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sqrt(sum2/this->data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar_grid_gradient::colvar_grid_gradient()
|
colvar_grid_gradient::colvar_grid_gradient()
|
||||||
: colvar_grid<cvm::real>(),
|
: colvar_grid<cvm::real>(), samples(NULL), full_samples(0), min_samples(0)
|
||||||
samples(NULL),
|
|
||||||
weights(NULL)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
colvar_grid_gradient::colvar_grid_gradient(std::vector<int> const &nx_i)
|
colvar_grid_gradient::colvar_grid_gradient(std::vector<int> const &nx_i)
|
||||||
: colvar_grid<cvm::real>(nx_i, 0.0, nx_i.size()),
|
: colvar_grid<cvm::real>(nx_i, 0.0, nx_i.size()), samples(NULL), full_samples(0), min_samples(0)
|
||||||
samples(NULL),
|
|
||||||
weights(NULL)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
colvar_grid_gradient::colvar_grid_gradient(std::vector<colvar *> &colvars)
|
colvar_grid_gradient::colvar_grid_gradient(std::vector<colvar *> &colvars)
|
||||||
: colvar_grid<cvm::real>(colvars, 0.0, colvars.size()),
|
: colvar_grid<cvm::real>(colvars, 0.0, colvars.size()), samples(NULL), full_samples(0), min_samples(0)
|
||||||
samples(NULL),
|
|
||||||
weights(NULL)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
colvar_grid_gradient::colvar_grid_gradient(std::vector<colvar *> &colvars, std::shared_ptr<colvar_grid_count> samples_in)
|
||||||
|
: colvar_grid<cvm::real>(colvars, 0.0, colvars.size()), samples(samples_in), full_samples(0), min_samples(0)
|
||||||
|
{
|
||||||
|
samples_in->has_parent_data = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
colvar_grid_gradient::colvar_grid_gradient(std::string &filename)
|
colvar_grid_gradient::colvar_grid_gradient(std::string &filename)
|
||||||
: colvar_grid<cvm::real>(),
|
: colvar_grid<cvm::real>(),
|
||||||
samples(NULL),
|
samples(NULL)
|
||||||
weights(NULL)
|
|
||||||
{
|
{
|
||||||
std::istream &is = cvm::main()->proxy->input_stream(filename,
|
std::istream &is = cvm::main()->proxy->input_stream(filename,
|
||||||
"gradient file");
|
"gradient file");
|
||||||
@ -280,6 +415,57 @@ colvar_grid_gradient::colvar_grid_gradient(std::string &filename)
|
|||||||
cvm::main()->proxy->close_input_stream(filename);
|
cvm::main()->proxy->close_input_stream(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string colvar_grid_gradient::get_state_params() const
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::get_state_params();
|
||||||
|
}
|
||||||
|
|
||||||
|
int colvar_grid_gradient::parse_params(std::string const &conf,
|
||||||
|
colvarparse::Parse_Mode const parse_mode)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::parse_params(conf, parse_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream &colvar_grid_gradient::read_restart(std::istream &is)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::read_restart(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::memory_stream &colvar_grid_gradient::read_restart(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::read_restart(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &colvar_grid_gradient::write_restart(std::ostream &os)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::write_restart(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::memory_stream &colvar_grid_gradient::write_restart(cvm::memory_stream &os)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::write_restart(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream &colvar_grid_gradient::read_raw(std::istream &is)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::read_raw(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::memory_stream &colvar_grid_gradient::read_raw(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::read_raw(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &colvar_grid_gradient::write_raw(std::ostream &os, size_t const buf_size) const
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::write_raw(os, buf_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::memory_stream &colvar_grid_gradient::write_raw(cvm::memory_stream &os,
|
||||||
|
size_t const buf_size) const
|
||||||
|
{
|
||||||
|
return colvar_grid<cvm::real>::write_raw(os, buf_size);
|
||||||
|
}
|
||||||
|
|
||||||
std::istream & colvar_grid_gradient::read_multicol(std::istream &is, bool add)
|
std::istream & colvar_grid_gradient::read_multicol(std::istream &is, bool add)
|
||||||
{
|
{
|
||||||
@ -371,9 +557,38 @@ void colvar_grid_gradient::write_1D_integral(std::ostream &os)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Return the RMSD between this grid's data and another one
|
||||||
|
/// Grids must have the same dimensions.
|
||||||
|
cvm::real colvar_grid_gradient::grid_rmsd(colvar_grid_gradient const &other_grid) const
|
||||||
|
{
|
||||||
|
if (other_grid.multiplicity() != this->multiplicity()) {
|
||||||
|
cvm::error("Error: trying to subtract two grids with "
|
||||||
|
"different multiplicity.\n");
|
||||||
|
return -1.;
|
||||||
|
}
|
||||||
|
|
||||||
integrate_potential::integrate_potential(std::vector<colvar *> &colvars, colvar_grid_gradient * gradients)
|
if (other_grid.data.size() != this->data.size()) {
|
||||||
|
cvm::error("Error: trying to subtract two grids with "
|
||||||
|
"different size.\n");
|
||||||
|
return -1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::real sum2 = 0.0;
|
||||||
|
std::vector<int> ix;
|
||||||
|
size_t imult;
|
||||||
|
for (ix = new_index(); index_ok(ix); incr(ix)) {
|
||||||
|
for (imult = 0; imult < this->multiplicity(); imult++) {
|
||||||
|
cvm::real d = this->value_output(ix, imult) - other_grid.value_output(ix, imult);
|
||||||
|
sum2 += d*d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sqrt(sum2/this->data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
integrate_potential::integrate_potential(std::vector<colvar *> &colvars, std::shared_ptr<colvar_grid_gradient> gradients)
|
||||||
: colvar_grid_scalar(colvars, true),
|
: colvar_grid_scalar(colvars, true),
|
||||||
|
b_smoothed(false),
|
||||||
gradients(gradients)
|
gradients(gradients)
|
||||||
{
|
{
|
||||||
// parent class colvar_grid_scalar is constructed with margin option set to true
|
// parent class colvar_grid_scalar is constructed with margin option set to true
|
||||||
@ -402,8 +617,9 @@ integrate_potential::integrate_potential(std::vector<colvar *> &colvars, colvar_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
integrate_potential::integrate_potential(colvar_grid_gradient * gradients)
|
integrate_potential::integrate_potential(std::shared_ptr<colvar_grid_gradient> gradients)
|
||||||
: gradients(gradients)
|
: b_smoothed(false),
|
||||||
|
gradients(gradients)
|
||||||
{
|
{
|
||||||
nd = gradients->num_variables();
|
nd = gradients->num_variables();
|
||||||
nx = gradients->number_of_points_vec();
|
nx = gradients->number_of_points_vec();
|
||||||
@ -425,7 +641,7 @@ integrate_potential::integrate_potential(colvar_grid_gradient * gradients)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int integrate_potential::integrate(const int itmax, const cvm::real &tol, cvm::real & err)
|
int integrate_potential::integrate(const int itmax, const cvm::real &tol, cvm::real & err, bool verbose)
|
||||||
{
|
{
|
||||||
int iter = 0;
|
int iter = 0;
|
||||||
|
|
||||||
@ -438,22 +654,24 @@ int integrate_potential::integrate(const int itmax, const cvm::real &tol, cvm::r
|
|||||||
} else {
|
} else {
|
||||||
corr = 0.0;
|
corr = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> ix;
|
std::vector<int> ix;
|
||||||
// Iterate over valid indices in gradient grid
|
// Iterate over valid indices in gradient grid
|
||||||
for (ix = new_index(); gradients->index_ok(ix); incr(ix)) {
|
for (ix = new_index(); gradients->index_ok(ix); incr(ix)) {
|
||||||
set_value(ix, sum);
|
set_value(ix, sum);
|
||||||
sum += (gradients->value_output(ix) - corr) * widths[0];
|
cvm::real val = gradients->value_output_smoothed(ix, b_smoothed);
|
||||||
|
sum += (val - corr) * widths[0];
|
||||||
}
|
}
|
||||||
if (index_ok(ix)) {
|
if (index_ok(ix)) {
|
||||||
// This will happen if non-periodic: then PMF grid has one extra bin wrt gradient grid
|
// This will happen if non-periodic: then PMF grid has one extra bin wrt gradient grid
|
||||||
|
// If not, sum should be zero
|
||||||
set_value(ix, sum);
|
set_value(ix, sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (nd <= 3) {
|
} else if (nd <= 3) {
|
||||||
|
|
||||||
nr_linbcg_sym(divergence, data, tol, itmax, iter, err);
|
nr_linbcg_sym(divergence, data, tol, itmax, iter, err);
|
||||||
cvm::log("Integrated in " + cvm::to_str(iter) + " steps, error: " + cvm::to_str(err) + "\n");
|
if (verbose)
|
||||||
|
cvm::log("Integrated in " + cvm::to_str(iter) + " steps, error: " + cvm::to_str(err));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cvm::error("Cannot integrate PMF in dimension > 3\n");
|
cvm::error("Cannot integrate PMF in dimension > 3\n");
|
||||||
@ -477,7 +695,7 @@ void integrate_potential::update_div_neighbors(const std::vector<int> &ix0)
|
|||||||
std::vector<int> ix(ix0);
|
std::vector<int> ix(ix0);
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
|
|
||||||
// If not periodic, expanded grid ensures that neighbors of ix0 are valid grid points
|
// If not periodic, expanded grid ensures that upper neighbors of ix0 are valid grid points
|
||||||
if (nd == 1) {
|
if (nd == 1) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -509,30 +727,23 @@ void integrate_potential::update_div_neighbors(const std::vector<int> &ix0)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void integrate_potential::get_grad(cvm::real * g, std::vector<int> &ix)
|
void integrate_potential::get_grad(cvm::real * g, std::vector<int> &ix)
|
||||||
{
|
{
|
||||||
size_t count, i;
|
size_t i;
|
||||||
bool edge = gradients->wrap_edge(ix); // Detect edge if non-PBC
|
bool edge = gradients->wrap_detect_edge(ix); // Detect edge if non-PBC
|
||||||
|
|
||||||
if (gradients->samples) {
|
if (edge) {
|
||||||
count = gradients->samples->value(ix);
|
for ( i = 0; i<nd; i++ ) {
|
||||||
} else {
|
g[i] = 0.0;
|
||||||
count = 1;
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!edge && count) {
|
gradients->vector_value_smoothed(ix, g, b_smoothed);
|
||||||
cvm::real const *grad = &(gradients->value(ix));
|
|
||||||
cvm::real const fact = 1.0 / count;
|
|
||||||
for ( i = 0; i<nd; i++ ) {
|
|
||||||
g[i] = fact * grad[i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for ( i = 0; i<nd; i++ ) {
|
|
||||||
g[i] = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void integrate_potential::update_div_local(const std::vector<int> &ix0)
|
void integrate_potential::update_div_local(const std::vector<int> &ix0)
|
||||||
{
|
{
|
||||||
const size_t linear_index = address(ix0);
|
const size_t linear_index = address(ix0);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,233 @@
|
|||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvargrid.h"
|
#include "colvargrid.h"
|
||||||
|
#include "colvars_memstream.h"
|
||||||
|
|
||||||
|
|
||||||
|
template <class T, class IST> IST &read_restart_template_(colvar_grid<T> &g, IST &is)
|
||||||
|
{
|
||||||
|
auto const start_pos = is.tellg();
|
||||||
|
std::string conf;
|
||||||
|
if ((is >> colvarparse::read_block("grid_parameters", &conf)) &&
|
||||||
|
(g.parse_params(conf, colvarparse::parse_restart) == COLVARS_OK) && g.read_raw(is)) {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
auto const error_pos = is.tellg();
|
||||||
|
is.clear();
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
cvm::error("Error: in reading grid state from stream at position " + cvm::to_str(error_pos) +
|
||||||
|
"\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> std::istream &colvar_grid<T>::read_restart(std::istream &is)
|
||||||
|
{
|
||||||
|
return read_restart_template_<T, std::istream>(*this, is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> cvm::memory_stream &colvar_grid<T>::read_restart(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
return read_restart_template_<T, cvm::memory_stream>(*this, is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> std::ostream &colvar_grid<T>::write_restart(std::ostream &os)
|
||||||
|
{
|
||||||
|
os << "grid_parameters {\n" << get_state_params() << "}\n";
|
||||||
|
write_raw(os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> cvm::memory_stream &colvar_grid<T>::write_restart(cvm::memory_stream &os)
|
||||||
|
{
|
||||||
|
os << std::string("grid_parameters") << get_state_params();
|
||||||
|
write_raw(os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T, class IST> IST &read_raw_template_(colvar_grid<T> &g, IST &is)
|
||||||
|
{
|
||||||
|
auto const start_pos = is.tellg();
|
||||||
|
|
||||||
|
for (std::vector<int> ix = g.new_index(); g.index_ok(ix); g.incr(ix)) {
|
||||||
|
for (size_t imult = 0; imult < g.mult; imult++) {
|
||||||
|
T new_value;
|
||||||
|
if (is >> new_value) {
|
||||||
|
g.value_input(ix, new_value, imult);
|
||||||
|
} else {
|
||||||
|
is.clear();
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
cvm::error(
|
||||||
|
"Error: failed to read all of the grid points from file. Possible explanations: grid "
|
||||||
|
"parameters in the configuration (lowerBoundary, upperBoundary, width) are different "
|
||||||
|
"from those in the file, or the file is corrupt/incomplete.\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g.has_data = true;
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> std::istream &colvar_grid<T>::read_raw(std::istream &is)
|
||||||
|
{
|
||||||
|
return read_raw_template_<T, std::istream>(*this, is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> cvm::memory_stream &colvar_grid<T>::read_raw(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
return read_raw_template_<T, cvm::memory_stream>(*this, is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::ostream &colvar_grid<T>::write_raw(std::ostream &os, size_t const buf_size) const
|
||||||
|
{
|
||||||
|
auto const w = os.width();
|
||||||
|
auto const p = os.precision();
|
||||||
|
|
||||||
|
size_t count = 0;
|
||||||
|
for (auto ix = new_index(); index_ok(ix); incr(ix)) {
|
||||||
|
for (size_t imult = 0; imult < mult; imult++) {
|
||||||
|
os << " " << std::setw(w) << std::setprecision(p) << value_output(ix, imult);
|
||||||
|
if (((++count) % buf_size) == 0)
|
||||||
|
os << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// write a final newline only if buffer is not empty
|
||||||
|
if ((count % buf_size) != 0)
|
||||||
|
os << "\n";
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
cvm::memory_stream &colvar_grid<T>::write_raw(cvm::memory_stream &os, size_t const buf_size) const
|
||||||
|
{
|
||||||
|
for (auto ix = new_index(); index_ok(ix); incr(ix)) {
|
||||||
|
for (size_t imult = 0; imult < mult; imult++) {
|
||||||
|
os << value_output(ix, imult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> std::string colvar_grid<T>::get_state_params() const
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
size_t i;
|
||||||
|
os << " n_colvars " << nd << "\n";
|
||||||
|
|
||||||
|
os << " lower_boundaries ";
|
||||||
|
for (i = 0; i < nd; i++)
|
||||||
|
os << " " << lower_boundaries[i];
|
||||||
|
os << "\n";
|
||||||
|
|
||||||
|
os << " upper_boundaries ";
|
||||||
|
for (i = 0; i < nd; i++)
|
||||||
|
os << " " << upper_boundaries[i];
|
||||||
|
os << "\n";
|
||||||
|
|
||||||
|
os << " widths ";
|
||||||
|
for (i = 0; i < nd; i++)
|
||||||
|
os << " " << widths[i];
|
||||||
|
os << "\n";
|
||||||
|
|
||||||
|
os << " sizes ";
|
||||||
|
for (i = 0; i < nd; i++)
|
||||||
|
os << " " << nx[i];
|
||||||
|
os << "\n";
|
||||||
|
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> int colvar_grid<T>::parse_params(std::string const &conf,
|
||||||
|
colvarparse::Parse_Mode const parse_mode)
|
||||||
|
{
|
||||||
|
if (cvm::debug())
|
||||||
|
cvm::log("Reading grid configuration from string.\n");
|
||||||
|
|
||||||
|
std::vector<int> old_nx = nx;
|
||||||
|
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;
|
||||||
|
// this is only used in state files
|
||||||
|
colvarparse::get_keyval(conf, "n_colvars", nd_in, nd, colvarparse::parse_silent);
|
||||||
|
if (nd_in != nd) {
|
||||||
|
cvm::error("Error: trying to read data for a grid "
|
||||||
|
"that contains a different number of colvars ("+
|
||||||
|
cvm::to_str(nd_in)+") than the grid defined "
|
||||||
|
"in the configuration file("+cvm::to_str(nd)+
|
||||||
|
").\n");
|
||||||
|
return COLVARS_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// underscore keywords are used in state file
|
||||||
|
colvarparse::get_keyval(conf, "lower_boundaries",
|
||||||
|
lower_boundaries, lower_boundaries, colvarparse::parse_silent);
|
||||||
|
colvarparse::get_keyval(conf, "upper_boundaries",
|
||||||
|
upper_boundaries, upper_boundaries, colvarparse::parse_silent);
|
||||||
|
|
||||||
|
// camel case keywords are used in config file
|
||||||
|
colvarparse::get_keyval(conf, "lowerBoundaries",
|
||||||
|
lower_boundaries, lower_boundaries, parse_mode);
|
||||||
|
colvarparse::get_keyval(conf, "upperBoundaries",
|
||||||
|
upper_boundaries, upper_boundaries, parse_mode);
|
||||||
|
|
||||||
|
colvarparse::get_keyval(conf, "widths", widths, widths, parse_mode);
|
||||||
|
|
||||||
|
// only used in state file
|
||||||
|
colvarparse::get_keyval(conf, "sizes", nx, nx, colvarparse::parse_silent);
|
||||||
|
|
||||||
|
if (nd < lower_boundaries.size()) nd = lower_boundaries.size();
|
||||||
|
|
||||||
|
if (! use_actual_value.size()) use_actual_value.assign(nd, false);
|
||||||
|
if (! periodic.size()) periodic.assign(nd, false);
|
||||||
|
if (! widths.size()) widths.assign(nd, 1.0);
|
||||||
|
|
||||||
|
cvm::real eps = 1.e-10;
|
||||||
|
|
||||||
|
bool new_params = false;
|
||||||
|
if (old_nx.size()) {
|
||||||
|
for (size_t i = 0; i < nd; i++) {
|
||||||
|
if (old_nx[i] != nx[i] ||
|
||||||
|
cvm::sqrt(cv[i]->dist2(old_lb[i], lower_boundaries[i])) > eps ||
|
||||||
|
cvm::sqrt(cv[i]->dist2(old_ub[i], upper_boundaries[i])) > eps ||
|
||||||
|
cvm::fabs(old_w[i] - widths[i]) > eps) {
|
||||||
|
new_params = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
new_params = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reallocate the array in case the grid params have just changed
|
||||||
|
if (new_params) {
|
||||||
|
init_from_boundaries();
|
||||||
|
// data.clear(); // no longer needed: setup calls clear()
|
||||||
|
return this->setup(nx, T(), mult);
|
||||||
|
}
|
||||||
|
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -90,6 +317,9 @@ std::istream & colvar_grid<T>::read_multicol(std::istream &is, bool add)
|
|||||||
for (size_t i = 0; i < nd; i++ ) {
|
for (size_t i = 0; i < nd; i++ ) {
|
||||||
if ( !(is >> x) ) end_of_file = true;
|
if ( !(is >> x) ) end_of_file = true;
|
||||||
bin[i] = value_to_bin_scalar(x, i);
|
bin[i] = value_to_bin_scalar(x, i);
|
||||||
|
// if x is out of bounds and we are using PBC, wrap it
|
||||||
|
// Ignore out of bounds points in non-PBC
|
||||||
|
wrap_detect_edge(bin);
|
||||||
}
|
}
|
||||||
if (end_of_file) break;
|
if (end_of_file) break;
|
||||||
|
|
||||||
|
|||||||
@ -7,13 +7,10 @@
|
|||||||
// 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 <iostream>
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <memory>
|
||||||
#include <cstring>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarparse.h"
|
#include "colvarparse.h"
|
||||||
@ -21,6 +18,7 @@
|
|||||||
#include "colvar.h"
|
#include "colvar.h"
|
||||||
#include "colvarbias.h"
|
#include "colvarbias.h"
|
||||||
#include "colvarbias_abf.h"
|
#include "colvarbias_abf.h"
|
||||||
|
#include "colvarbias_abmd.h"
|
||||||
#include "colvarbias_alb.h"
|
#include "colvarbias_alb.h"
|
||||||
#include "colvarbias_histogram.h"
|
#include "colvarbias_histogram.h"
|
||||||
#include "colvarbias_histogram_reweight_amd.h"
|
#include "colvarbias_histogram_reweight_amd.h"
|
||||||
@ -29,7 +27,7 @@
|
|||||||
#include "colvarscript.h"
|
#include "colvarscript.h"
|
||||||
#include "colvaratoms.h"
|
#include "colvaratoms.h"
|
||||||
#include "colvarcomp.h"
|
#include "colvarcomp.h"
|
||||||
|
#include "colvars_memstream.h"
|
||||||
|
|
||||||
|
|
||||||
/// Track usage of Colvars features
|
/// Track usage of Colvars features
|
||||||
@ -69,6 +67,11 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr uint32_t colvars_magic_number = 2013813594;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
colvarmodule::colvarmodule(colvarproxy *proxy_in)
|
colvarmodule::colvarmodule(colvarproxy *proxy_in)
|
||||||
{
|
{
|
||||||
depth_s = 0;
|
depth_s = 0;
|
||||||
@ -98,16 +101,14 @@ colvarmodule::colvarmodule(colvarproxy *proxy_in)
|
|||||||
version_int = proxy->get_version_from_string(COLVARS_VERSION);
|
version_int = proxy->get_version_from_string(COLVARS_VERSION);
|
||||||
|
|
||||||
cvm::log(cvm::line_marker);
|
cvm::log(cvm::line_marker);
|
||||||
cvm::log("Initializing the collective variables module, version "+
|
cvm::log(
|
||||||
version()+".\n");
|
"Initializing the collective variables module, version " + version() +
|
||||||
|
(patch_version_number() ? (" (patch " + cvm::to_str(patch_version_number()) + ")") : "") +
|
||||||
|
".\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://doi.org/10.1080/00268976.2013.813594\n"
|
||||||
"as well as all other papers listed below for individual features used.\n");
|
"as well as all other papers listed below for individual features used.\n");
|
||||||
|
|
||||||
if (proxy->smp_enabled() == COLVARS_OK) {
|
|
||||||
cvm::log("SMP parallelism is enabled; if needed, use \"smp off\" to override this.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (__cplusplus >= 201103L)
|
#if (__cplusplus >= 201103L)
|
||||||
cvm::log("This version was built with the C++11 standard or higher.\n");
|
cvm::log("This version was built with the C++11 standard or higher.\n");
|
||||||
#else
|
#else
|
||||||
@ -116,8 +117,38 @@ colvarmodule::colvarmodule(colvarproxy *proxy_in)
|
|||||||
" https://colvars.github.io/README-c++11.html\n");
|
" https://colvars.github.io/README-c++11.html\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
cvm::log("Summary of compile-time features available in this build:\n");
|
||||||
|
|
||||||
|
if (proxy->check_smp_enabled() == COLVARS_NOT_IMPLEMENTED) {
|
||||||
|
cvm::log(" - SMP parallelism: not available\n");
|
||||||
|
} else {
|
||||||
|
if (proxy->check_smp_enabled() == COLVARS_OK) {
|
||||||
|
cvm::log(" - SMP parallelism: enabled (num. threads = " + to_str(proxy->smp_num_threads()) + ")\n");
|
||||||
|
} else {
|
||||||
|
cvm::log(" - SMP parallelism: available, but not enabled\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(LEPTON)
|
||||||
|
cvm::log(" - Lepton custom functions: available\n");
|
||||||
|
#else
|
||||||
|
cvm::log(" - Lepton custom functions: not available\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(COLVARS_TCL)
|
||||||
|
cvm::log(" - Tcl interpreter: available\n");
|
||||||
|
#else
|
||||||
|
cvm::log(" - Tcl interpreter: not available\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
// set initial default values
|
// set initial default values
|
||||||
|
|
||||||
|
binary_restart = false;
|
||||||
|
char const *env_var = getenv("COLVARS_BINARY_RESTART");
|
||||||
|
if (env_var && atoi(env_var)) {
|
||||||
|
binary_restart = true;
|
||||||
|
}
|
||||||
|
|
||||||
// "it_restart" will be set by the input state file, if any;
|
// "it_restart" will be set by the input state file, if any;
|
||||||
// "it" should be updated by the proxy
|
// "it" should be updated by the proxy
|
||||||
colvarmodule::it = colvarmodule::it_restart = 0;
|
colvarmodule::it = colvarmodule::it_restart = 0;
|
||||||
@ -182,6 +213,13 @@ size_t colvarmodule::size() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void colvarmodule::set_initial_step(step_number it_in)
|
||||||
|
{
|
||||||
|
cvm::log("Setting initial step number from MD engine: " + cvm::to_str(it_in) + "\n");
|
||||||
|
it = it_restart = it_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarmodule::read_config_file(char const *config_filename)
|
int colvarmodule::read_config_file(char const *config_filename)
|
||||||
{
|
{
|
||||||
cvm::log(cvm::line_marker);
|
cvm::log(cvm::line_marker);
|
||||||
@ -327,6 +365,7 @@ void colvarmodule::config_changed()
|
|||||||
|
|
||||||
int colvarmodule::parse_global_params(std::string const &conf)
|
int colvarmodule::parse_global_params(std::string const &conf)
|
||||||
{
|
{
|
||||||
|
int error_code = COLVARS_OK;
|
||||||
// TODO document and then echo this keyword
|
// TODO document and then echo this keyword
|
||||||
parse->get_keyval(conf, "logLevel", log_level_, log_level_,
|
parse->get_keyval(conf, "logLevel", log_level_, log_level_,
|
||||||
colvarparse::parse_silent);
|
colvarparse::parse_silent);
|
||||||
@ -334,10 +373,7 @@ int colvarmodule::parse_global_params(std::string const &conf)
|
|||||||
std::string units;
|
std::string units;
|
||||||
if (parse->get_keyval(conf, "units", units)) {
|
if (parse->get_keyval(conf, "units", units)) {
|
||||||
units = colvarparse::to_lower_cppstr(units);
|
units = colvarparse::to_lower_cppstr(units);
|
||||||
int error_code = proxy->set_unit_system(units, (colvars.size() != 0));
|
error_code |= proxy->set_unit_system(units, (colvars.size() != 0));
|
||||||
if (error_code != COLVARS_OK) {
|
|
||||||
return error_code;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,7 +382,7 @@ int colvarmodule::parse_global_params(std::string const &conf)
|
|||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
while (parse->key_lookup(conf, "indexFile", &index_file_name, &pos)) {
|
while (parse->key_lookup(conf, "indexFile", &index_file_name, &pos)) {
|
||||||
cvm::log("# indexFile = \""+index_file_name+"\"\n");
|
cvm::log("# indexFile = \""+index_file_name+"\"\n");
|
||||||
read_index_file(index_file_name.c_str());
|
error_code |= read_index_file(index_file_name.c_str());
|
||||||
index_file_name.clear();
|
index_file_name.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -358,9 +394,8 @@ int colvarmodule::parse_global_params(std::string const &conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool b_analysis = true;
|
bool b_analysis = true;
|
||||||
if (parse->get_keyval(conf, "analysis", b_analysis, true,
|
if (parse->get_keyval(conf, "analysis", b_analysis, true, colvarparse::parse_silent)) {
|
||||||
colvarparse::parse_silent)) {
|
cvm::log("Warning: keyword \"analysis\" is deprecated: it is now always set "
|
||||||
cvm::log("Warning: keyword \"analysis\" is deprecated: it is now set "
|
|
||||||
"to true; individual analyses are performed only if requested.");
|
"to true; individual analyses are performed only if requested.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,7 +426,12 @@ int colvarmodule::parse_global_params(std::string const &conf)
|
|||||||
parse->get_keyval(conf, "sourceTclFile", source_Tcl_script);
|
parse->get_keyval(conf, "sourceTclFile", source_Tcl_script);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return cvm::get_error();
|
if (proxy->engine_name() == "GROMACS" && proxy->version_number() >= 20231003) {
|
||||||
|
parse->get_keyval(conf, "defaultInputStateFile", default_input_state_file_,
|
||||||
|
default_input_state_file_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -522,6 +562,9 @@ int colvarmodule::parse_biases(std::string const &conf)
|
|||||||
/// initialize ABF instances
|
/// initialize ABF instances
|
||||||
parse_biases_type<colvarbias_abf>(conf, "abf");
|
parse_biases_type<colvarbias_abf>(conf, "abf");
|
||||||
|
|
||||||
|
/// initialize ABMD instances
|
||||||
|
parse_biases_type<colvarbias_abmd>(conf, "abmd");
|
||||||
|
|
||||||
/// initialize adaptive linear biases
|
/// initialize adaptive linear biases
|
||||||
parse_biases_type<colvarbias_alb>(conf, "ALB");
|
parse_biases_type<colvarbias_alb>(conf, "ALB");
|
||||||
|
|
||||||
@ -791,28 +834,26 @@ int colvarmodule::calc()
|
|||||||
|
|
||||||
// write restart files and similar data
|
// 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 if (output_prefix().size()) {
|
||||||
error_code |= write_restart_file(output_prefix()+".colvars.state");
|
error_code |= write_restart_file(output_prefix() + ".colvars.state");
|
||||||
}
|
}
|
||||||
|
|
||||||
cvm::increase_depth();
|
if (output_prefix().size()) {
|
||||||
for (std::vector<colvar *>::iterator cvi = colvars.begin();
|
cvm::increase_depth();
|
||||||
cvi != colvars.end();
|
for (std::vector<colvar *>::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) {
|
||||||
cvi++) {
|
// TODO remove this when corrFunc becomes a bias
|
||||||
// TODO remove this when corrFunc becomes a bias
|
error_code |= (*cvi)->write_output_files();
|
||||||
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();
|
||||||
}
|
}
|
||||||
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
|
// Write output files for biases, at the specified frequency for each
|
||||||
@ -881,7 +922,7 @@ int colvarmodule::calc_colvars()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if SMP support is available, split up the work
|
// if SMP support is available, split up the work
|
||||||
if (proxy->smp_enabled() == COLVARS_OK) {
|
if (proxy->check_smp_enabled() == COLVARS_OK) {
|
||||||
|
|
||||||
// first, calculate how much work (currently, how many active CVCs) each colvar has
|
// first, calculate how much work (currently, how many active CVCs) each colvar has
|
||||||
|
|
||||||
@ -963,8 +1004,16 @@ int colvarmodule::calc_biases()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if SMP support is available, split up the work
|
bool biases_need_main_thread = false;
|
||||||
if (proxy->smp_enabled() == COLVARS_OK) {
|
for (bi = biases_active()->begin(); bi != biases_active()->end(); bi++) {
|
||||||
|
if ((*bi)->replica_share_freq() > 0) {
|
||||||
|
// Biases that share data with replicas need read/write access to I/O or MPI
|
||||||
|
biases_need_main_thread = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If SMP support is available, split up the work (unless biases need to use main thread's memory)
|
||||||
|
if (proxy->check_smp_enabled() == COLVARS_OK && !biases_need_main_thread) {
|
||||||
|
|
||||||
if (use_scripted_forces && !scripting_after_biases) {
|
if (use_scripted_forces && !scripting_after_biases) {
|
||||||
// calculate biases and scripted forces in parallel
|
// calculate biases and scripted forces in parallel
|
||||||
@ -980,10 +1029,12 @@ int colvarmodule::calc_biases()
|
|||||||
error_code |= calc_scripted_forces();
|
error_code |= calc_scripted_forces();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Straight loop over biases on a single thread
|
||||||
cvm::increase_depth();
|
cvm::increase_depth();
|
||||||
for (bi = biases_active()->begin(); bi != biases_active()->end(); bi++) {
|
for (bi = biases_active()->begin(); bi != biases_active()->end(); bi++) {
|
||||||
error_code |= (*bi)->update();
|
error_code |= (*bi)->update();
|
||||||
if (cvm::get_error()) {
|
if (cvm::get_error()) {
|
||||||
|
cvm::decrease_depth();
|
||||||
return error_code;
|
return error_code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -994,7 +1045,7 @@ int colvarmodule::calc_biases()
|
|||||||
total_bias_energy += (*bi)->get_energy();
|
total_bias_energy += (*bi)->get_energy();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1082,9 +1133,22 @@ int colvarmodule::write_restart_file(std::string const &out_name)
|
|||||||
cvm::log("Saving collective variables state to \""+out_name+"\".\n");
|
cvm::log("Saving collective variables state to \""+out_name+"\".\n");
|
||||||
std::ostream &restart_out_os = proxy->output_stream(out_name, "state file");
|
std::ostream &restart_out_os = proxy->output_stream(out_name, "state file");
|
||||||
if (!restart_out_os) return COLVARS_FILE_ERROR;
|
if (!restart_out_os) return COLVARS_FILE_ERROR;
|
||||||
if (!write_restart(restart_out_os)) {
|
|
||||||
return cvm::error("Error: in writing restart file.\n", COLVARS_FILE_ERROR);
|
if (binary_restart) {
|
||||||
|
cvm::memory_stream mem_os;
|
||||||
|
if (!write_state(mem_os)) {
|
||||||
|
return cvm::error("Error: in writing binary state information to file.\n", COLVARS_ERROR);
|
||||||
|
}
|
||||||
|
if (!restart_out_os.write(reinterpret_cast<char *>(mem_os.output_buffer()),
|
||||||
|
mem_os.length())) {
|
||||||
|
return cvm::error("Error: in writing restart file.\n", COLVARS_FILE_ERROR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!write_state(restart_out_os)) {
|
||||||
|
return cvm::error("Error: in writing restart file.\n", COLVARS_FILE_ERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy->close_output_stream(out_name);
|
proxy->close_output_stream(out_name);
|
||||||
|
|
||||||
// Take the opportunity to flush colvars.traj
|
// Take the opportunity to flush colvars.traj
|
||||||
@ -1097,7 +1161,7 @@ int colvarmodule::write_restart_string(std::string &output)
|
|||||||
{
|
{
|
||||||
cvm::log("Saving state to output buffer.\n");
|
cvm::log("Saving state to output buffer.\n");
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
if (!write_restart(os)) {
|
if (!write_state(os)) {
|
||||||
return cvm::error("Error: in writing restart to buffer.\n", COLVARS_FILE_ERROR);
|
return cvm::error("Error: in writing restart to buffer.\n", COLVARS_FILE_ERROR);
|
||||||
}
|
}
|
||||||
output = os.str();
|
output = os.str();
|
||||||
@ -1207,9 +1271,17 @@ int colvarmodule::end_of_step()
|
|||||||
|
|
||||||
int colvarmodule::update_engine_parameters()
|
int colvarmodule::update_engine_parameters()
|
||||||
{
|
{
|
||||||
if (this->size() == 0) return cvm::get_error();
|
if (size() == 0) {
|
||||||
for (std::vector<colvar *>::iterator cvi = variables()->begin();
|
// No-op if no variables or biases are defined
|
||||||
cvi != variables()->end(); cvi++) {
|
return cvm::get_error();
|
||||||
|
}
|
||||||
|
if (proxy->simulation_running()) {
|
||||||
|
cvm::log("Current simulation parameters: initial step = " + cvm::to_str(it) +
|
||||||
|
", integration timestep = " + cvm::to_str(dt()) + "\n");
|
||||||
|
}
|
||||||
|
cvm::log("Updating atomic parameters (masses, charges, etc).\n");
|
||||||
|
for (std::vector<colvar *>::iterator cvi = variables()->begin(); cvi != variables()->end();
|
||||||
|
cvi++) {
|
||||||
(*cvi)->setup();
|
(*cvi)->setup();
|
||||||
}
|
}
|
||||||
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
|
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
|
||||||
@ -1250,10 +1322,10 @@ int colvarmodule::reset()
|
|||||||
parse->clear();
|
parse->clear();
|
||||||
|
|
||||||
// Iterate backwards because we are deleting the elements as we go
|
// Iterate backwards because we are deleting the elements as we go
|
||||||
for (std::vector<colvarbias *>::reverse_iterator bi = biases.rbegin();
|
while (!biases.empty()) {
|
||||||
bi != biases.rend();
|
colvarbias* tail = biases.back();
|
||||||
bi++) {
|
biases.pop_back();
|
||||||
delete *bi; // the bias destructor updates the biases array
|
delete tail; // the bias destructor updates the biases array
|
||||||
}
|
}
|
||||||
biases.clear();
|
biases.clear();
|
||||||
biases_active_.clear();
|
biases_active_.clear();
|
||||||
@ -1262,11 +1334,11 @@ int colvarmodule::reset()
|
|||||||
reinterpret_cast<std::map<std::string, int> *>(num_biases_types_used_)->clear();
|
reinterpret_cast<std::map<std::string, int> *>(num_biases_types_used_)->clear();
|
||||||
|
|
||||||
// Iterate backwards because we are deleting the elements as we go
|
// Iterate backwards because we are deleting the elements as we go
|
||||||
for (std::vector<colvar *>::reverse_iterator cvi = colvars.rbegin();
|
while (!colvars.empty()) {
|
||||||
cvi != colvars.rend();
|
colvar* cvi = colvars.back();
|
||||||
cvi++) {
|
colvars.pop_back();
|
||||||
delete *cvi; // the colvar destructor updates the colvars array
|
delete cvi; // the colvar destructor updates the colvars array
|
||||||
}
|
};
|
||||||
colvars.clear();
|
colvars.clear();
|
||||||
|
|
||||||
reset_index_groups();
|
reset_index_groups();
|
||||||
@ -1274,64 +1346,119 @@ int colvarmodule::reset()
|
|||||||
proxy->flush_output_streams();
|
proxy->flush_output_streams();
|
||||||
proxy->reset();
|
proxy->reset();
|
||||||
|
|
||||||
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
|
clear_error();
|
||||||
|
|
||||||
|
return COLVARS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarmodule::setup_input()
|
int colvarmodule::setup_input()
|
||||||
{
|
{
|
||||||
if (proxy->input_prefix().size()) {
|
if (proxy->input_prefix().empty() && (!proxy->input_stream_exists("input state string")) &&
|
||||||
// Read a state file
|
input_state_buffer_.empty()) {
|
||||||
std::string restart_in_name(proxy->input_prefix()+
|
// If no input sources have been defined up to this point, use defaultInputStateFile
|
||||||
std::string(".colvars.state"));
|
proxy->set_input_prefix(default_input_state_file_);
|
||||||
std::istream *input_is = &(proxy->input_stream(restart_in_name,
|
}
|
||||||
"restart file/channel",
|
|
||||||
false));
|
if (!proxy->input_prefix().empty()) {
|
||||||
|
|
||||||
|
// Read state from a file
|
||||||
|
|
||||||
|
std::string restart_in_name(proxy->input_prefix() + std::string(".colvars.state"));
|
||||||
|
std::istream *input_is = &(proxy->input_stream(restart_in_name, "restart file/channel", false));
|
||||||
if (!*input_is) {
|
if (!*input_is) {
|
||||||
// Try without the suffix ".colvars.state"
|
// Try without the suffix ".colvars.state"
|
||||||
restart_in_name = proxy->input_prefix();
|
restart_in_name = proxy->input_prefix();
|
||||||
input_is = &(proxy->input_stream(restart_in_name,
|
input_is = &(proxy->input_stream(restart_in_name, "restart file/channel"));
|
||||||
"restart file/channel"));
|
|
||||||
if (!*input_is) {
|
if (!*input_is) {
|
||||||
|
// Error message has already been printed, return now
|
||||||
return COLVARS_FILE_ERROR;
|
return COLVARS_FILE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that the file has been opened, clear this field so that this
|
// Now that the file has been opened, clear this field so that this block
|
||||||
// function will not be called twice
|
// will not be executed twice
|
||||||
proxy->input_prefix().clear();
|
proxy->set_input_prefix("");
|
||||||
|
|
||||||
cvm::log(cvm::line_marker);
|
|
||||||
cvm::log("Loading state from file \""+restart_in_name+"\".\n");
|
|
||||||
read_restart(*input_is);
|
|
||||||
cvm::log(cvm::line_marker);
|
cvm::log(cvm::line_marker);
|
||||||
|
|
||||||
proxy->close_input_stream(restart_in_name);
|
input_is->seekg(0, std::ios::end);
|
||||||
|
size_t const file_size = input_is->tellg();
|
||||||
|
input_is->seekg(0, std::ios::beg);
|
||||||
|
|
||||||
return cvm::get_error();
|
bool binary_state_file = false;
|
||||||
}
|
|
||||||
|
|
||||||
// TODO This could soon be redundant
|
uint32_t file_magic_number = 0;
|
||||||
if (proxy->input_buffer() != NULL) {
|
if (file_size > sizeof(uint32_t)) {
|
||||||
// Read a string buffer
|
if (input_is->read(reinterpret_cast<char *>(&file_magic_number), sizeof(uint32_t))) {
|
||||||
char const *buffer = proxy->input_buffer();
|
if (file_magic_number == colvars_magic_number) {
|
||||||
size_t const buffer_size = strlen(proxy->input_buffer());
|
binary_state_file = true;
|
||||||
// Clear proxy pointer for the next round
|
}
|
||||||
proxy->input_buffer() = NULL;
|
input_is->seekg(0, std::ios::beg);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (binary_state_file) {
|
||||||
|
cvm::log("Loading state from binary file \"" + restart_in_name + "\".\n");
|
||||||
|
// TODO integrate istream.read() into memory_stream to avoid copying
|
||||||
|
auto *buf = new unsigned char[file_size];
|
||||||
|
if (input_is->read(reinterpret_cast<char *>(buf), file_size)) {
|
||||||
|
cvm::memory_stream mem_is(file_size, buf);
|
||||||
|
if (!read_state(mem_is)) {
|
||||||
|
input_is->setstate(std::ios::failbit);
|
||||||
|
cvm::error("Error: cannot interpret contents of binary file \"" + restart_in_name +
|
||||||
|
"\".\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cvm::error("Error: cannot read from binary file \"" + restart_in_name + "\".\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
delete[] buf;
|
||||||
|
} else {
|
||||||
|
cvm::log("Loading state from text file \"" + restart_in_name + "\".\n");
|
||||||
|
read_state(*input_is);
|
||||||
|
}
|
||||||
|
cvm::log(cvm::line_marker);
|
||||||
|
|
||||||
|
// Now that an explicit state file was read, we shall ignore any other restart info
|
||||||
|
if (proxy->input_stream_exists("input state string")) {
|
||||||
|
proxy->delete_input_stream("input state string");
|
||||||
|
}
|
||||||
|
input_state_buffer_.clear();
|
||||||
|
|
||||||
|
proxy->delete_input_stream(restart_in_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return COLVARS_OK;
|
if (proxy->input_stream_exists("input state string")) {
|
||||||
|
|
||||||
|
if (!input_state_buffer_.empty()) {
|
||||||
|
return cvm::error("Error: formatted/text and unformatted/binary input state buffers are "
|
||||||
|
"defined at the same time.\n",
|
||||||
|
COLVARS_BUG_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
cvm::log(cvm::line_marker);
|
||||||
|
cvm::log("Loading state from formatted string.\n");
|
||||||
|
read_state(proxy->input_stream("input state string"));
|
||||||
|
cvm::log(cvm::line_marker);
|
||||||
|
|
||||||
|
proxy->delete_input_stream("input state string");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!input_state_buffer_.empty()) {
|
||||||
|
cvm::log(cvm::line_marker);
|
||||||
|
cvm::log("Loading state from unformatted memory.\n");
|
||||||
|
cvm::memory_stream ms(input_state_buffer_.size(), input_state_buffer_.data());
|
||||||
|
read_state(ms);
|
||||||
|
cvm::log(cvm::line_marker);
|
||||||
|
|
||||||
|
input_state_buffer_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
default_input_state_file_.clear();
|
||||||
|
|
||||||
|
return get_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1344,36 +1471,39 @@ int colvarmodule::setup_output()
|
|||||||
std::string(proxy->restart_output_prefix()+".colvars.state") :
|
std::string(proxy->restart_output_prefix()+".colvars.state") :
|
||||||
std::string("");
|
std::string("");
|
||||||
|
|
||||||
|
std::string const state_file_format(binary_restart ? " (binary format)" : "");
|
||||||
|
|
||||||
if (restart_out_name.size()) {
|
if (restart_out_name.size()) {
|
||||||
cvm::log("The restart output state file will be \""+
|
cvm::log("The restart output state file" + state_file_format + " will be \""+
|
||||||
restart_out_name+"\".\n");
|
restart_out_name+"\".\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
output_prefix() = proxy->output_prefix();
|
if (output_prefix() != proxy->output_prefix()) {
|
||||||
if (output_prefix().size()) {
|
output_prefix() = proxy->output_prefix();
|
||||||
cvm::log("The final output state file will be \""+
|
if (output_prefix().size()) {
|
||||||
(output_prefix().size() ?
|
cvm::log("The final output state file will be \"" +
|
||||||
std::string(output_prefix()+".colvars.state") :
|
(output_prefix().size() ? std::string(output_prefix() + ".colvars.state")
|
||||||
std::string("colvars.state"))+"\".\n");
|
: std::string("colvars.state")) +
|
||||||
// cvm::log (cvm::line_marker);
|
"\".\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proxy->output_stream_exists(cv_traj_name)) {
|
||||||
|
// Close old file
|
||||||
|
proxy->close_output_stream(cv_traj_name);
|
||||||
|
cv_traj_write_labels = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv_traj_name =
|
||||||
|
(output_prefix().size() ? std::string(output_prefix() + ".colvars.traj") : std::string(""));
|
||||||
|
|
||||||
|
for (std::vector<colvarbias *>::iterator bi = biases.begin();
|
||||||
|
bi != biases.end();
|
||||||
|
bi++) {
|
||||||
|
error_code |= (*bi)->setup_output();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cv_traj_name =
|
return error_code;
|
||||||
(output_prefix().size() ?
|
|
||||||
std::string(output_prefix()+".colvars.traj") :
|
|
||||||
std::string(""));
|
|
||||||
|
|
||||||
for (std::vector<colvarbias *>::iterator bi = biases.begin();
|
|
||||||
bi != biases.end();
|
|
||||||
bi++) {
|
|
||||||
error_code |= (*bi)->setup_output();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error_code != COLVARS_OK || cvm::get_error()) {
|
|
||||||
set_error_bits(COLVARS_FILE_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cvm::get_error();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1390,8 +1520,7 @@ std::string colvarmodule::state_file_prefix(char const *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename IST> IST & colvarmodule::read_state_template_(IST &is)
|
||||||
std::istream & colvarmodule::read_restart(std::istream &is)
|
|
||||||
{
|
{
|
||||||
bool warn_total_forces = false;
|
bool warn_total_forces = false;
|
||||||
|
|
||||||
@ -1417,8 +1546,11 @@ std::istream & colvarmodule::read_restart(std::istream &is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (restart_version() != version()) {
|
if (restart_version() != version()) {
|
||||||
cvm::log("This state file was generated with version "+
|
cvm::log("This state file was generated with version " + restart_version() + "\n");
|
||||||
restart_version()+"\n");
|
if (std::is_same<IST, cvm::memory_stream>::value) {
|
||||||
|
cvm::log("Warning: compatibility between differetn Colvars versions is not "
|
||||||
|
"guaranteed for unformatted (binary) state files.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (restart_version_number() < 20160810) {
|
if (restart_version_number() < 20160810) {
|
||||||
@ -1453,35 +1585,73 @@ std::istream & colvarmodule::read_restart(std::istream &is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::istream & colvarmodule::read_state(std::istream &is)
|
||||||
|
{
|
||||||
|
return read_state_template_<std::istream>(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream &colvarmodule::read_state(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
uint32_t file_magic_number = 0;
|
||||||
|
if (!(is >> file_magic_number)) {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
if (file_magic_number == colvars_magic_number) {
|
||||||
|
return read_state_template_<cvm::memory_stream>(is);
|
||||||
|
} else {
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
cvm::error("Error: magic number of binary file (" +
|
||||||
|
cvm::to_str(static_cast<size_t>(file_magic_number)) +
|
||||||
|
") does not match the expected magic number for a Colvars state file (" +
|
||||||
|
cvm::to_str(static_cast<size_t>(colvars_magic_number)) + ").\n",
|
||||||
|
COLVARS_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarmodule::set_input_state_buffer(size_t n, unsigned char *buf)
|
||||||
|
{
|
||||||
|
input_state_buffer_.clear();
|
||||||
|
std::copy(buf, buf + n, std::back_inserter(input_state_buffer_));
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarmodule::set_input_state_buffer(std::vector<unsigned char> &buf)
|
||||||
|
{
|
||||||
|
input_state_buffer_ = std::move(buf);
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::istream & colvarmodule::read_objects_state(std::istream &is)
|
std::istream & colvarmodule::read_objects_state(std::istream &is)
|
||||||
{
|
{
|
||||||
std::streampos pos = 0;
|
auto pos = is.tellg();
|
||||||
std::string word;
|
std::string word;
|
||||||
|
|
||||||
while (is.good()) {
|
while (is) {
|
||||||
pos = is.tellg();
|
pos = is.tellg();
|
||||||
word.clear();
|
|
||||||
is >> word;
|
|
||||||
|
|
||||||
if (word.size()) {
|
if (is >> word) {
|
||||||
|
|
||||||
is.seekg(pos, std::ios::beg);
|
is.seekg(pos);
|
||||||
|
|
||||||
if (word == "colvar") {
|
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++) {
|
||||||
cvi != colvars.end();
|
if (!((*cvi)->read_state(is))) {
|
||||||
cvi++) {
|
|
||||||
if ( !((*cvi)->read_state(is)) ) {
|
|
||||||
// Here an error signals that the variable is a match, but the
|
// Here an error signals that the variable is a match, but the
|
||||||
// state is corrupt; otherwise, the variable rewinds is silently
|
// state is corrupt; otherwise, the variable rewinds is silently
|
||||||
cvm::error("Error: in reading restart configuration for "
|
cvm::error("Error: in reading state for collective variable \"" +
|
||||||
"collective variable \""+(*cvi)->name+"\".\n",
|
(*cvi)->name + "\" at position " + cvm::to_str(is.tellg()) +
|
||||||
|
" in stream.\n",
|
||||||
COLVARS_INPUT_ERROR);
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
if (is.tellg() > pos) break; // found it
|
if (is.tellg() > pos)
|
||||||
|
break; // found it
|
||||||
}
|
}
|
||||||
cvm::decrease_depth();
|
cvm::decrease_depth();
|
||||||
|
|
||||||
@ -1498,11 +1668,12 @@ std::istream & colvarmodule::read_objects_state(std::istream &is)
|
|||||||
}
|
}
|
||||||
if (!((*bi)->read_state(is))) {
|
if (!((*bi)->read_state(is))) {
|
||||||
// Same as above, an error means a match but the state is incorrect
|
// 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 state for bias \"" + (*bi)->name + "\" at position " +
|
||||||
(*bi)->name+"\".\n",
|
cvm::to_str(is.tellg()) + " in stream.\n",
|
||||||
COLVARS_INPUT_ERROR);
|
COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
if (is.tellg() > pos) break; // found it
|
if (is.tellg() > pos)
|
||||||
|
break; // found it
|
||||||
}
|
}
|
||||||
cvm::decrease_depth();
|
cvm::decrease_depth();
|
||||||
}
|
}
|
||||||
@ -1521,6 +1692,25 @@ std::istream & colvarmodule::read_objects_state(std::istream &is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream &colvarmodule::read_objects_state(cvm::memory_stream &is)
|
||||||
|
{
|
||||||
|
// An unformatted stream must match the objects' exact configuration
|
||||||
|
cvm::increase_depth();
|
||||||
|
for (std::vector<colvar *>::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) {
|
||||||
|
if (!(*cvi)->read_state(is)) {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (std::vector<colvarbias *>::iterator bi = biases.begin(); bi != biases.end(); bi++) {
|
||||||
|
if (!(*bi)->read_state(is)) {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cvm::decrease_depth();
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarmodule::print_total_forces_errning(bool warn_total_forces)
|
int colvarmodule::print_total_forces_errning(bool warn_total_forces)
|
||||||
{
|
{
|
||||||
if (warn_total_forces) {
|
if (warn_total_forces) {
|
||||||
@ -1643,18 +1833,24 @@ int colvarmodule::read_traj(char const *traj_filename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::ostream & colvarmodule::write_restart(std::ostream &os)
|
template <typename OST> OST &colvarmodule::write_state_template_(OST &os)
|
||||||
{
|
{
|
||||||
os.setf(std::ios::scientific, std::ios::floatfield);
|
bool const formatted = !std::is_same<OST, cvm::memory_stream>::value;
|
||||||
os << "configuration {\n"
|
|
||||||
<< " step " << std::setw(it_width)
|
std::ostringstream oss;
|
||||||
<< it << "\n"
|
oss.setf(std::ios::scientific, std::ios::floatfield);
|
||||||
<< " dt " << dt() << "\n"
|
oss << " step " << std::setw(it_width)
|
||||||
<< " version " << std::string(COLVARS_VERSION) << "\n";
|
<< it << "\n"
|
||||||
|
<< " dt " << dt() << "\n"
|
||||||
|
<< " version " << std::string(COLVARS_VERSION) << "\n";
|
||||||
if (proxy->units.size() > 0) {
|
if (proxy->units.size() > 0) {
|
||||||
os << " units " << proxy->units << "\n";
|
oss << " units " << proxy->units << "\n";
|
||||||
}
|
}
|
||||||
os << "}\n\n";
|
|
||||||
|
os << std::string("configuration");
|
||||||
|
if (formatted) os << " {\n";
|
||||||
|
os << oss.str();
|
||||||
|
if (formatted) os << "}\n\n";
|
||||||
|
|
||||||
int error_code = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
|
|
||||||
@ -1681,7 +1877,32 @@ std::ostream & colvarmodule::write_restart(std::ostream &os)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::ostream & colvarmodule::write_traj_label(std::ostream &os)
|
std::ostream &colvarmodule::write_state(std::ostream &os)
|
||||||
|
{
|
||||||
|
return write_state_template_<std::ostream>(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream &colvarmodule::write_state(cvm::memory_stream &os)
|
||||||
|
{
|
||||||
|
if (os << colvars_magic_number) {
|
||||||
|
write_state_template_<cvm::memory_stream>(os);
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarmodule::write_state_buffer(std::vector<unsigned char> &buffer)
|
||||||
|
{
|
||||||
|
cvm::memory_stream os(buffer);
|
||||||
|
if (os << colvars_magic_number) {
|
||||||
|
write_state_template_<cvm::memory_stream>(os);
|
||||||
|
}
|
||||||
|
return os ? COLVARS_OK : COLVARS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream &colvarmodule::write_traj_label(std::ostream &os)
|
||||||
{
|
{
|
||||||
os.setf(std::ios::scientific, std::ios::floatfield);
|
os.setf(std::ios::scientific, std::ios::floatfield);
|
||||||
|
|
||||||
@ -1765,7 +1986,7 @@ 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();
|
||||||
if (proxy->smp_enabled() == COLVARS_OK) {
|
if (proxy->check_smp_enabled() == COLVARS_OK) {
|
||||||
int const nt = proxy->smp_num_threads();
|
int const nt = proxy->smp_num_threads();
|
||||||
if (int(cv->depth_v.size()) != nt) {
|
if (int(cv->depth_v.size()) != nt) {
|
||||||
proxy->smp_lock();
|
proxy->smp_lock();
|
||||||
@ -1810,7 +2031,7 @@ void colvarmodule::clear_error()
|
|||||||
|
|
||||||
int colvarmodule::error(std::string const &message, int code)
|
int colvarmodule::error(std::string const &message, int code)
|
||||||
{
|
{
|
||||||
set_error_bits(code);
|
set_error_bits(code >= 0 ? code : COLVARS_ERROR);
|
||||||
|
|
||||||
std::string const trailing_newline = (message.size() > 0) ?
|
std::string const trailing_newline = (message.size() > 0) ?
|
||||||
(message[message.size()-1] == '\n' ? "" : "\n") : "";
|
(message[message.size()-1] == '\n' ? "" : "\n") : "";
|
||||||
@ -1930,15 +2151,6 @@ int colvarmodule::reset_index_groups()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int cvm::load_atoms(char const *file_name,
|
|
||||||
cvm::atom_group &atoms,
|
|
||||||
std::string const &pdb_field,
|
|
||||||
double pdb_field_value)
|
|
||||||
{
|
|
||||||
return proxy->load_atoms(file_name, atoms, pdb_field, pdb_field_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int cvm::load_coords(char const *file_name,
|
int cvm::load_coords(char const *file_name,
|
||||||
std::vector<cvm::rvector> *pos,
|
std::vector<cvm::rvector> *pos,
|
||||||
cvm::atom_group *atoms,
|
cvm::atom_group *atoms,
|
||||||
@ -1953,7 +2165,7 @@ int cvm::load_coords(char const *file_name,
|
|||||||
|
|
||||||
atoms->create_sorted_ids();
|
atoms->create_sorted_ids();
|
||||||
|
|
||||||
std::vector<cvm::rvector> sorted_pos(atoms->size(), cvm::rvector(0.0));
|
std::vector<cvm::atom_pos> sorted_pos(atoms->size(), cvm::rvector(0.0));
|
||||||
|
|
||||||
// Differentiate between PDB and XYZ files
|
// Differentiate between PDB and XYZ files
|
||||||
if (colvarparse::to_lower_cppstr(ext) == std::string(".xyz")) {
|
if (colvarparse::to_lower_cppstr(ext) == std::string(".xyz")) {
|
||||||
@ -1965,11 +2177,12 @@ int cvm::load_coords(char const *file_name,
|
|||||||
error_code |= cvm::main()->load_coords_xyz(file_name, &sorted_pos, atoms);
|
error_code |= cvm::main()->load_coords_xyz(file_name, &sorted_pos, atoms);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, call proxy function for PDB
|
// Otherwise, call proxy function for PDB
|
||||||
error_code |= proxy->load_coords(file_name,
|
error_code |= proxy->load_coords_pdb(file_name, sorted_pos, atoms->sorted_ids(), pdb_field,
|
||||||
sorted_pos, atoms->sorted_ids(),
|
pdb_field_value);
|
||||||
pdb_field, pdb_field_value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error_code != COLVARS_OK) return error_code;
|
||||||
|
|
||||||
std::vector<int> const &map = atoms->sorted_ids_map();
|
std::vector<int> const &map = atoms->sorted_ids_map();
|
||||||
for (size_t i = 0; i < atoms->size(); i++) {
|
for (size_t i = 0; i < atoms->size(); i++) {
|
||||||
(*pos)[map[i]] = sorted_pos[i];
|
(*pos)[map[i]] = sorted_pos[i];
|
||||||
@ -1985,7 +2198,7 @@ int cvm::load_coords_xyz(char const *filename,
|
|||||||
bool keep_open)
|
bool keep_open)
|
||||||
{
|
{
|
||||||
std::istream &xyz_is = proxy->input_stream(filename, "XYZ file");
|
std::istream &xyz_is = proxy->input_stream(filename, "XYZ file");
|
||||||
unsigned int natoms;
|
size_t natoms;
|
||||||
char symbol[256];
|
char symbol[256];
|
||||||
std::string line;
|
std::string line;
|
||||||
cvm::real x = 0.0, y = 0.0, z = 0.0;
|
cvm::real x = 0.0, y = 0.0, z = 0.0;
|
||||||
@ -2009,12 +2222,19 @@ int cvm::load_coords_xyz(char const *filename,
|
|||||||
cvm::getline(xyz_is, line);
|
cvm::getline(xyz_is, line);
|
||||||
xyz_is.width(255);
|
xyz_is.width(255);
|
||||||
} else {
|
} else {
|
||||||
|
proxy->close_input_stream(filename);
|
||||||
return cvm::error(error_msg, COLVARS_INPUT_ERROR);
|
return cvm::error(error_msg, COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pos->size() > natoms) {
|
||||||
|
proxy->close_input_stream(filename);
|
||||||
|
return cvm::error("File \"" + std::string(filename) + "\" contains fewer atoms (" + cvm::to_str(natoms)
|
||||||
|
+ ") than expected (" + cvm::to_str(pos->size()) + ").", COLVARS_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<atom_pos>::iterator pos_i = pos->begin();
|
std::vector<atom_pos>::iterator pos_i = pos->begin();
|
||||||
size_t xyz_natoms = 0;
|
size_t xyz_natoms = 0;
|
||||||
if (pos->size() != natoms) { // Use specified indices
|
if (pos->size() < natoms) { // Use specified indices
|
||||||
int next = 0; // indices are zero-based
|
int next = 0; // indices are zero-based
|
||||||
if (!atoms) {
|
if (!atoms) {
|
||||||
// In the other branch of this test, reading all positions from the file,
|
// In the other branch of this test, reading all positions from the file,
|
||||||
@ -2022,6 +2242,13 @@ int cvm::load_coords_xyz(char const *filename,
|
|||||||
return cvm::error("Trying to read partial positions with invalid atom group pointer",
|
return cvm::error("Trying to read partial positions with invalid atom group pointer",
|
||||||
COLVARS_BUG_ERROR);
|
COLVARS_BUG_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (static_cast<unsigned int>(atoms->sorted_ids().back()) > natoms) {
|
||||||
|
proxy->close_input_stream(filename);
|
||||||
|
return cvm::error("File \"" + std::string(filename) + "\" contains fewer atoms (" + cvm::to_str(natoms)
|
||||||
|
+ ") than expected (" + cvm::to_str(atoms->sorted_ids().back()) + ").", COLVARS_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<int>::const_iterator index = atoms->sorted_ids().begin();
|
std::vector<int>::const_iterator index = atoms->sorted_ids().begin();
|
||||||
|
|
||||||
for ( ; pos_i != pos->end() ; pos_i++, index++) {
|
for ( ; pos_i != pos->end() ; pos_i++, index++) {
|
||||||
@ -2038,6 +2265,7 @@ int cvm::load_coords_xyz(char const *filename,
|
|||||||
(*pos_i)[2] = proxy->angstrom_to_internal(z);
|
(*pos_i)[2] = proxy->angstrom_to_internal(z);
|
||||||
xyz_natoms++;
|
xyz_natoms++;
|
||||||
} else {
|
} else {
|
||||||
|
proxy->close_input_stream(filename);
|
||||||
return cvm::error(error_msg, COLVARS_INPUT_ERROR);
|
return cvm::error(error_msg, COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2053,12 +2281,14 @@ int cvm::load_coords_xyz(char const *filename,
|
|||||||
(*pos_i)[2] = proxy->angstrom_to_internal(z);
|
(*pos_i)[2] = proxy->angstrom_to_internal(z);
|
||||||
xyz_natoms++;
|
xyz_natoms++;
|
||||||
} else {
|
} else {
|
||||||
|
proxy->close_input_stream(filename);
|
||||||
return cvm::error(error_msg, COLVARS_INPUT_ERROR);
|
return cvm::error(error_msg, COLVARS_INPUT_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xyz_natoms != pos->size()) {
|
if (xyz_natoms != pos->size()) {
|
||||||
|
proxy->close_input_stream(filename);
|
||||||
return cvm::error("Error: The number of positions read from file \""+
|
return cvm::error("Error: The number of positions read from file \""+
|
||||||
std::string(filename)+"\" does not match the number of "+
|
std::string(filename)+"\" does not match the number of "+
|
||||||
"positions required: "+cvm::to_str(xyz_natoms)+" vs. "+
|
"positions required: "+cvm::to_str(xyz_natoms)+" vs. "+
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
#ifndef COLVARMODULE_H
|
#ifndef COLVARMODULE_H
|
||||||
#define COLVARMODULE_H
|
#define COLVARMODULE_H
|
||||||
|
|
||||||
#include <cmath>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "colvars_version.h"
|
#include "colvars_version.h"
|
||||||
|
|
||||||
@ -19,9 +19,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! \mainpage Main page
|
/*! \mainpage Main page
|
||||||
This is the Developer's documentation for the Collective Variables Module.
|
This is the Developer's documentation for the Collective Variables module (Colvars).
|
||||||
|
|
||||||
You can browse the class hierarchy or the list of source files.
|
You can browse the class hierarchy or the list of source files.
|
||||||
|
|
||||||
|
Please note that this documentation is only supported for the master branch, and its features may differ from those in a given release of a simulation package.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// \file colvarmodule.h
|
/// \file colvarmodule.h
|
||||||
@ -33,26 +35,15 @@ You can browse the class hierarchy or the list of source files.
|
|||||||
/// shared between all object instances) to be accessed from other
|
/// shared between all object instances) to be accessed from other
|
||||||
/// objects.
|
/// objects.
|
||||||
|
|
||||||
#define COLVARS_OK 0
|
#include <cmath>
|
||||||
#define COLVARS_ERROR 1
|
#include <iosfwd>
|
||||||
#define COLVARS_NOT_IMPLEMENTED (1<<1)
|
|
||||||
#define COLVARS_INPUT_ERROR (1<<2) // out of bounds or inconsistent input
|
|
||||||
#define COLVARS_BUG_ERROR (1<<3) // Inconsistent state indicating bug
|
|
||||||
#define COLVARS_FILE_ERROR (1<<4)
|
|
||||||
#define COLVARS_MEMORY_ERROR (1<<5)
|
|
||||||
#define COLVARS_NO_SUCH_FRAME (1<<6) // Cannot load the requested frame
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
|
||||||
#include <iosfwd>
|
|
||||||
|
|
||||||
class colvarparse;
|
class colvarparse;
|
||||||
class colvar;
|
class colvar;
|
||||||
class colvarbias;
|
class colvarbias;
|
||||||
class colvarproxy;
|
class colvarproxy;
|
||||||
class colvarscript;
|
|
||||||
class colvarvalue;
|
class colvarvalue;
|
||||||
|
|
||||||
|
|
||||||
@ -67,14 +58,6 @@ class colvarvalue;
|
|||||||
/// child objects
|
/// child objects
|
||||||
class colvarmodule {
|
class colvarmodule {
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/// Impossible to initialize the main object without arguments
|
|
||||||
colvarmodule();
|
|
||||||
|
|
||||||
/// Integer representing the version string (allows comparisons)
|
|
||||||
int version_int;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Get the version string (YYYY-MM-DD format)
|
/// Get the version string (YYYY-MM-DD format)
|
||||||
@ -89,9 +72,21 @@ public:
|
|||||||
return version_int;
|
return version_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class colvarproxy;
|
/// Get the patch version number (non-zero in patch releases of other packages)
|
||||||
// TODO colvarscript should be unaware of colvarmodule's internals
|
int patch_version_number() const
|
||||||
friend class colvarscript;
|
{
|
||||||
|
return patch_version_int;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// Integer representing the version string (allows comparisons)
|
||||||
|
int version_int = 0;
|
||||||
|
|
||||||
|
/// Patch version number (non-zero in patch releases of other packages)
|
||||||
|
int patch_version_int = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
/// Use a 64-bit integer to store the step number
|
/// Use a 64-bit integer to store the step number
|
||||||
typedef long long step_number;
|
typedef long long step_number;
|
||||||
@ -190,7 +185,9 @@ public:
|
|||||||
template <class T> class matrix2d;
|
template <class T> class matrix2d;
|
||||||
class quaternion;
|
class quaternion;
|
||||||
class rotation;
|
class rotation;
|
||||||
|
|
||||||
class usage;
|
class usage;
|
||||||
|
class memory_stream;
|
||||||
|
|
||||||
/// Residue identifier
|
/// Residue identifier
|
||||||
typedef int residue_id;
|
typedef int residue_id;
|
||||||
@ -205,8 +202,6 @@ public:
|
|||||||
// allow these classes to access protected data
|
// allow these classes to access protected data
|
||||||
class atom;
|
class atom;
|
||||||
class atom_group;
|
class atom_group;
|
||||||
friend class atom;
|
|
||||||
friend class atom_group;
|
|
||||||
typedef std::vector<atom>::iterator atom_iter;
|
typedef std::vector<atom>::iterator atom_iter;
|
||||||
typedef std::vector<atom>::const_iterator atom_const_iter;
|
typedef std::vector<atom>::const_iterator atom_const_iter;
|
||||||
|
|
||||||
@ -247,6 +242,8 @@ public:
|
|||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool binary_restart;
|
||||||
|
|
||||||
/// \brief Finite difference step size (if there is no dynamics, or
|
/// \brief Finite difference step size (if there is no dynamics, or
|
||||||
/// if gradients need to be tested independently from the size of
|
/// if gradients need to be tested independently from the size of
|
||||||
/// dt)
|
/// dt)
|
||||||
@ -342,9 +339,19 @@ public:
|
|||||||
/// \param Pointer to instance of the proxy class (communicate with engine)
|
/// \param Pointer to instance of the proxy class (communicate with engine)
|
||||||
colvarmodule(colvarproxy *proxy);
|
colvarmodule(colvarproxy *proxy);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// Cannot initialize the main object without a proxy
|
||||||
|
colvarmodule();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~colvarmodule();
|
~colvarmodule();
|
||||||
|
|
||||||
|
/// Set the initial step number (it is 0 otherwise); may be overridden when reading a state
|
||||||
|
void set_initial_step(step_number it);
|
||||||
|
|
||||||
/// Actual function called by the destructor
|
/// Actual function called by the destructor
|
||||||
int reset();
|
int reset();
|
||||||
|
|
||||||
@ -449,17 +456,52 @@ 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 a restart file
|
private:
|
||||||
std::istream & read_restart(std::istream &is);
|
|
||||||
|
template <typename IST> IST & read_state_template_(IST &is);
|
||||||
|
|
||||||
|
/// Default input state file; if given, it is read unless the MD engine provides it
|
||||||
|
std::string default_input_state_file_;
|
||||||
|
|
||||||
|
/// Internal state buffer, to be read as an unformatted stream
|
||||||
|
std::vector<unsigned char> input_state_buffer_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Read all objects' state fron a formatted (text) stream
|
||||||
|
std::istream & read_state(std::istream &is);
|
||||||
|
|
||||||
|
/// Read all objects' state fron an unformatted (binary) stream
|
||||||
|
memory_stream & read_state(memory_stream &is);
|
||||||
|
|
||||||
|
/// Set an internal state buffer, to be read later as an unformatted stream when ready
|
||||||
|
int set_input_state_buffer(size_t n, unsigned char *buf);
|
||||||
|
|
||||||
|
/// Same as set_input_state_buffer() for C array, but uses std::move
|
||||||
|
int set_input_state_buffer(std::vector<unsigned char> &buf);
|
||||||
|
|
||||||
/// Read the states of individual objects; allows for changes
|
/// Read the states of individual objects; allows for changes
|
||||||
std::istream & read_objects_state(std::istream &is);
|
std::istream & read_objects_state(std::istream &is);
|
||||||
|
|
||||||
|
/// Read the states of individual objects; allows for changes
|
||||||
|
memory_stream & read_objects_state(memory_stream &is);
|
||||||
|
|
||||||
/// If needed (old restart file), print the warning that cannot be ignored
|
/// If needed (old restart file), print the warning that cannot be ignored
|
||||||
int print_total_forces_errning(bool warn_total_forces);
|
int print_total_forces_errning(bool warn_total_forces);
|
||||||
|
|
||||||
/// Write the output restart file
|
private:
|
||||||
std::ostream & write_restart(std::ostream &os);
|
template <typename OST> OST &write_state_template_(OST &os);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Write the state of the module to a formatted (text) file
|
||||||
|
std::ostream & write_state(std::ostream &os);
|
||||||
|
|
||||||
|
/// Write the state of the module to an unformatted (binary) file
|
||||||
|
memory_stream & write_state(memory_stream &os);
|
||||||
|
|
||||||
|
/// Write the state of the module to an array of bytes (wrapped as a memory_stream object)
|
||||||
|
int write_state_buffer(std::vector<unsigned char> &buffer);
|
||||||
|
|
||||||
/// Strips .colvars.state from filename and checks that it is not empty
|
/// Strips .colvars.state from filename and checks that it is not empty
|
||||||
static std::string state_file_prefix(char const *filename);
|
static std::string state_file_prefix(char const *filename);
|
||||||
@ -650,7 +692,7 @@ public:
|
|||||||
static void log(std::string const &message, int min_log_level = 10);
|
static void log(std::string const &message, int min_log_level = 10);
|
||||||
|
|
||||||
/// Print a message to the main log and set global error code
|
/// Print a message to the main log and set global error code
|
||||||
static int error(std::string const &message, int code = COLVARS_ERROR);
|
static int error(std::string const &message, int code = -1);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -715,17 +757,6 @@ public:
|
|||||||
/// Clear the index groups loaded so far
|
/// Clear the index groups loaded so far
|
||||||
int reset_index_groups();
|
int reset_index_groups();
|
||||||
|
|
||||||
/// \brief Select atom IDs from a file (usually PDB) \param filename name of
|
|
||||||
/// the file \param atoms array into which atoms read from "filename" will be
|
|
||||||
/// appended \param pdb_field (optional) if the file is a PDB and this
|
|
||||||
/// string is non-empty, select atoms for which this field is non-zero
|
|
||||||
/// \param pdb_field_value (optional) if non-zero, select only atoms whose
|
|
||||||
/// pdb_field equals this
|
|
||||||
static int load_atoms(char const *filename,
|
|
||||||
atom_group &atoms,
|
|
||||||
std::string const &pdb_field,
|
|
||||||
double pdb_field_value = 0.0);
|
|
||||||
|
|
||||||
/// \brief Load coordinates for a group of atoms from a file (PDB or XYZ);
|
/// \brief Load coordinates for a group of atoms from a file (PDB or XYZ);
|
||||||
/// if "pos" is already allocated, the number of its elements must match the
|
/// if "pos" is already allocated, the number of its elements must match the
|
||||||
/// number of entries in "filename" \param filename name of the file \param
|
/// number of entries in "filename" \param filename name of the file \param
|
||||||
@ -755,7 +786,7 @@ public:
|
|||||||
std::string restart_out_name;
|
std::string restart_out_name;
|
||||||
|
|
||||||
/// Pseudo-random number with Gaussian distribution
|
/// Pseudo-random number with Gaussian distribution
|
||||||
static real rand_gaussian(void);
|
static real rand_gaussian();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -838,9 +869,20 @@ public:
|
|||||||
typedef colvarmodule cvm;
|
typedef colvarmodule cvm;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream &os, cvm::rvector const &v);
|
std::ostream & operator << (std::ostream &os, cvm::rvector const &v);
|
||||||
std::istream & operator >> (std::istream &is, cvm::rvector &v);
|
std::istream & operator >> (std::istream &is, cvm::rvector &v);
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr int32_t COLVARS_OK = 0;
|
||||||
|
constexpr int32_t COLVARS_ERROR = 1;
|
||||||
|
constexpr int32_t COLVARS_NOT_IMPLEMENTED = (1<<1);
|
||||||
|
constexpr int32_t COLVARS_INPUT_ERROR = (1<<2); // out of bounds or inconsistent input
|
||||||
|
constexpr int32_t COLVARS_BUG_ERROR = (1<<3); // Inconsistent state indicating bug
|
||||||
|
constexpr int32_t COLVARS_FILE_ERROR = (1<<4);
|
||||||
|
constexpr int32_t COLVARS_MEMORY_ERROR = (1<<5);
|
||||||
|
constexpr int32_t COLVARS_NO_SUCH_FRAME = (1<<6); // Cannot load the requested frame
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -14,6 +14,22 @@
|
|||||||
" url = {https://doi.org/10.1016/j.softx.2015.06.001}\n"
|
" url = {https://doi.org/10.1016/j.softx.2015.06.001}\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
paper_count_[std::string("BouRabee2010")] = 0;
|
||||||
|
paper_url_[std::string("BouRabee2010")] = "https://doi.org/10.1137/090758842";
|
||||||
|
paper_bibtex_[std::string("BouRabee2010")] =
|
||||||
|
"\n"
|
||||||
|
"@article{BouRabee2010,\n"
|
||||||
|
" doi = {10.1137/090758842},\n"
|
||||||
|
" url = {https://doi.org/10.1137/090758842},\n"
|
||||||
|
" year = {2010},\n"
|
||||||
|
" volume = {48},\n"
|
||||||
|
" number = {1},\n"
|
||||||
|
" pages = {278--297},\n"
|
||||||
|
" author = {Nawaf Bou-Rabee and Houman Owhadi},\n"
|
||||||
|
" title = {Long-Run Accuracy of Variational Integrators in the Stochastic Context},\n"
|
||||||
|
" journal = {{SIAM} Journal on Numerical Analysis}\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
paper_count_[std::string("Chen2021")] = 0;
|
paper_count_[std::string("Chen2021")] = 0;
|
||||||
paper_url_[std::string("Chen2021")] = "https://doi.org/10.1021/acs.jctc.1c00103";
|
paper_url_[std::string("Chen2021")] = "https://doi.org/10.1021/acs.jctc.1c00103";
|
||||||
paper_bibtex_[std::string("Chen2021")] =
|
paper_bibtex_[std::string("Chen2021")] =
|
||||||
@ -182,6 +198,19 @@
|
|||||||
" url = {https://doi.org/10.1021/ct9004432}\n"
|
" url = {https://doi.org/10.1021/ct9004432}\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
paper_count_[std::string("Henin2021")] = 0;
|
||||||
|
paper_url_[std::string("Henin2021")] = "https://doi.org/10.1021/acs.jctc.1c00593";
|
||||||
|
paper_bibtex_[std::string("Henin2021")] =
|
||||||
|
"\n"
|
||||||
|
"@Article{Henin2021,\n"
|
||||||
|
" author = {H\\'enin, J.},\n"
|
||||||
|
" journal = {J. Chem. Theory Comput.},\n"
|
||||||
|
" title = {Fast and accurate multidimensional free energy integration},\n"
|
||||||
|
" year = {2021},\n"
|
||||||
|
" doi = {10.1021/acs.jctc.1c00593},\n"
|
||||||
|
" url = {https://doi.org/10.1021/acs.jctc.1c00593},\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
paper_count_[std::string("Humphrey1996")] = 0;
|
paper_count_[std::string("Humphrey1996")] = 0;
|
||||||
paper_url_[std::string("Humphrey1996")] = "https://doi.org/10.1016/0263-7855(96)00018-5";
|
paper_url_[std::string("Humphrey1996")] = "https://doi.org/10.1016/0263-7855(96)00018-5";
|
||||||
paper_bibtex_[std::string("Humphrey1996")] =
|
paper_bibtex_[std::string("Humphrey1996")] =
|
||||||
@ -215,19 +244,6 @@
|
|||||||
" url = {https://doi.org/10.1021/acs.jpcb.6b10055}\n"
|
" url = {https://doi.org/10.1021/acs.jpcb.6b10055}\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
paper_count_[std::string("Henin2021")] = 0;
|
|
||||||
paper_url_[std::string("Henin2021")] = "https://doi.org/10.1021/acs.jctc.1c00593";
|
|
||||||
paper_bibtex_[std::string("Henin2021")] =
|
|
||||||
"\n"
|
|
||||||
"@Article{Henin2021,\n"
|
|
||||||
" author = {H\\'enin, J.},\n"
|
|
||||||
" journal = {J. Chem. Theory Comput.},\n"
|
|
||||||
" title = {Fast and accurate multidimensional free energy integration},\n"
|
|
||||||
" year = {2021},\n"
|
|
||||||
" doi = {10.1021/acs.jctc.1c00593},\n"
|
|
||||||
" url = {https://doi.org/10.1021/acs.jctc.1c00593},\n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
paper_count_[std::string("Marinelli2015")] = 0;
|
paper_count_[std::string("Marinelli2015")] = 0;
|
||||||
paper_url_[std::string("Marinelli2015")] = "https://doi.org/10.1016/j.bpj.2015.05.024";
|
paper_url_[std::string("Marinelli2015")] = "https://doi.org/10.1016/j.bpj.2015.05.024";
|
||||||
paper_bibtex_[std::string("Marinelli2015")] =
|
paper_bibtex_[std::string("Marinelli2015")] =
|
||||||
@ -335,6 +351,9 @@
|
|||||||
feature_count_[std::string("GROMACS engine")] = 0;
|
feature_count_[std::string("GROMACS engine")] = 0;
|
||||||
feature_paper_map_[std::string("GROMACS engine")] = "Abraham2015";
|
feature_paper_map_[std::string("GROMACS engine")] = "Abraham2015";
|
||||||
|
|
||||||
|
feature_count_[std::string("BAOA integrator")] = 0;
|
||||||
|
feature_paper_map_[std::string("BAOA integrator")] = "BouRabee2010";
|
||||||
|
|
||||||
feature_count_[std::string("reweightaMD colvar bias implementation (NAMD)")] = 0;
|
feature_count_[std::string("reweightaMD colvar bias implementation (NAMD)")] = 0;
|
||||||
feature_paper_map_[std::string("reweightaMD colvar bias implementation (NAMD)")] = "Chen2021";
|
feature_paper_map_[std::string("reweightaMD colvar bias implementation (NAMD)")] = "Chen2021";
|
||||||
|
|
||||||
@ -422,14 +441,14 @@
|
|||||||
feature_count_[std::string("orientationAngle colvar component (derived from orientation)")] = 0;
|
feature_count_[std::string("orientationAngle colvar component (derived from orientation)")] = 0;
|
||||||
feature_paper_map_[std::string("orientationAngle colvar component (derived from orientation)")] = "Fiorin2013";
|
feature_paper_map_[std::string("orientationAngle colvar component (derived from orientation)")] = "Fiorin2013";
|
||||||
|
|
||||||
feature_count_[std::string("orientationProj colvar component (derived from orientation)")] = 0;
|
feature_count_[std::string("orientationProj colvar component (derived from orientationAngle)")] = 0;
|
||||||
feature_paper_map_[std::string("orientationProj colvar component (derived from orientation)")] = "Fiorin2013";
|
feature_paper_map_[std::string("orientationProj colvar component (derived from orientationAngle)")] = "Fiorin2013";
|
||||||
|
|
||||||
feature_count_[std::string("spinAngle colvar component (derived from orientation)")] = 0;
|
feature_count_[std::string("spinAngle colvar component (derived from tilt)")] = 0;
|
||||||
feature_paper_map_[std::string("spinAngle colvar component (derived from orientation)")] = "Fiorin2013";
|
feature_paper_map_[std::string("spinAngle colvar component (derived from tilt)")] = "Fiorin2013";
|
||||||
|
|
||||||
feature_count_[std::string("tilt colvar component (derived from orientation)")] = 0;
|
feature_count_[std::string("tilt colvar component (derived from orientationProj)")] = 0;
|
||||||
feature_paper_map_[std::string("tilt colvar component (derived from orientation)")] = "Fiorin2013";
|
feature_paper_map_[std::string("tilt colvar component (derived from orientationProj)")] = "Fiorin2013";
|
||||||
|
|
||||||
feature_count_[std::string("alpha colvar component")] = 0;
|
feature_count_[std::string("alpha colvar component")] = 0;
|
||||||
feature_paper_map_[std::string("alpha colvar component")] = "Fiorin2013";
|
feature_paper_map_[std::string("alpha colvar component")] = "Fiorin2013";
|
||||||
@ -479,14 +498,14 @@
|
|||||||
feature_count_[std::string("polarPhi colvar component")] = 0;
|
feature_count_[std::string("polarPhi colvar component")] = 0;
|
||||||
feature_paper_map_[std::string("polarPhi colvar component")] = "Fu2017";
|
feature_paper_map_[std::string("polarPhi colvar component")] = "Fu2017";
|
||||||
|
|
||||||
feature_count_[std::string("eulerPhi colvar component (derived from orientation)")] = 0;
|
feature_count_[std::string("eulerPhi colvar component (derived from orientation_angle)")] = 0;
|
||||||
feature_paper_map_[std::string("eulerPhi colvar component (derived from orientation)")] = "Fu2017";
|
feature_paper_map_[std::string("eulerPhi colvar component (derived from orientation_angle)")] = "Fu2017";
|
||||||
|
|
||||||
feature_count_[std::string("eulerTheta colvar component (derived from orientation)")] = 0;
|
feature_count_[std::string("eulerTheta colvar component (derived from orientation_angle)")] = 0;
|
||||||
feature_paper_map_[std::string("eulerTheta colvar component (derived from orientation)")] = "Fu2017";
|
feature_paper_map_[std::string("eulerTheta colvar component (derived from orientation_angle)")] = "Fu2017";
|
||||||
|
|
||||||
feature_count_[std::string("eulerPsi colvar component (derived from orientation)")] = 0;
|
feature_count_[std::string("eulerPsi colvar component (derived from orientation_angle)")] = 0;
|
||||||
feature_paper_map_[std::string("eulerPsi colvar component (derived from orientation)")] = "Fu2017";
|
feature_paper_map_[std::string("eulerPsi colvar component (derived from orientation_angle)")] = "Fu2017";
|
||||||
|
|
||||||
feature_count_[std::string("dipoleAngle colvar component")] = 0;
|
feature_count_[std::string("dipoleAngle colvar component")] = 0;
|
||||||
feature_paper_map_[std::string("dipoleAngle colvar component")] = "Garate2019";
|
feature_paper_map_[std::string("dipoleAngle colvar component")] = "Garate2019";
|
||||||
@ -500,6 +519,9 @@
|
|||||||
feature_count_[std::string("Internal-forces free energy estimator")] = 0;
|
feature_count_[std::string("Internal-forces free energy estimator")] = 0;
|
||||||
feature_paper_map_[std::string("Internal-forces free energy estimator")] = "Henin2010";
|
feature_paper_map_[std::string("Internal-forces free energy estimator")] = "Henin2010";
|
||||||
|
|
||||||
|
feature_count_[std::string("Poisson integration of 2D/3D free energy surfaces")] = 0;
|
||||||
|
feature_paper_map_[std::string("Poisson integration of 2D/3D free energy surfaces")] = "Henin2021";
|
||||||
|
|
||||||
feature_count_[std::string("VMD engine")] = 0;
|
feature_count_[std::string("VMD engine")] = 0;
|
||||||
feature_paper_map_[std::string("VMD engine")] = "Humphrey1996";
|
feature_paper_map_[std::string("VMD engine")] = "Humphrey1996";
|
||||||
|
|
||||||
@ -509,9 +531,6 @@
|
|||||||
feature_count_[std::string("CZAR eABF estimator")] = 0;
|
feature_count_[std::string("CZAR eABF estimator")] = 0;
|
||||||
feature_paper_map_[std::string("CZAR eABF estimator")] = "Lesage2017";
|
feature_paper_map_[std::string("CZAR eABF estimator")] = "Lesage2017";
|
||||||
|
|
||||||
feature_count_[std::string("Poisson integration of 2D/3D free energy surfaces")] = 0;
|
|
||||||
feature_paper_map_[std::string("Poisson integration of 2D/3D free energy surfaces")] = "Henin2021";
|
|
||||||
|
|
||||||
feature_count_[std::string("Ensemble-biased metadynamics (ebMetaD)")] = 0;
|
feature_count_[std::string("Ensemble-biased metadynamics (ebMetaD)")] = 0;
|
||||||
feature_paper_map_[std::string("Ensemble-biased metadynamics (ebMetaD)")] = "Marinelli2015";
|
feature_paper_map_[std::string("Ensemble-biased metadynamics (ebMetaD)")] = "Marinelli2015";
|
||||||
|
|
||||||
@ -539,9 +558,6 @@
|
|||||||
feature_count_[std::string("Colvars-GROMACS interface")] = 0;
|
feature_count_[std::string("Colvars-GROMACS interface")] = 0;
|
||||||
feature_paper_map_[std::string("Colvars-GROMACS interface")] = "n/a";
|
feature_paper_map_[std::string("Colvars-GROMACS interface")] = "n/a";
|
||||||
|
|
||||||
feature_count_[std::string("Colvars Dashboard (Colvars-VMD graphical user interface)")] = 0;
|
|
||||||
feature_paper_map_[std::string("Colvars Dashboard (Colvars-VMD graphical user interface)")] = "n/a";
|
|
||||||
|
|
||||||
feature_count_[std::string("gspath colvar component")] = 0;
|
feature_count_[std::string("gspath colvar component")] = 0;
|
||||||
feature_paper_map_[std::string("gspath colvar component")] = "n/a";
|
feature_paper_map_[std::string("gspath colvar component")] = "n/a";
|
||||||
|
|
||||||
@ -571,3 +587,6 @@
|
|||||||
|
|
||||||
feature_count_[std::string("Scripted functions (Tcl)")] = 0;
|
feature_count_[std::string("Scripted functions (Tcl)")] = 0;
|
||||||
feature_paper_map_[std::string("Scripted functions (Tcl)")] = "n/a";
|
feature_paper_map_[std::string("Scripted functions (Tcl)")] = "n/a";
|
||||||
|
|
||||||
|
feature_count_[std::string("ABMD bias")] = 0;
|
||||||
|
feature_paper_map_[std::string("ABMD bias")] = "n/a";
|
||||||
|
|||||||
@ -8,12 +8,12 @@
|
|||||||
// Colvars repository at GitHub.
|
// Colvars repository at GitHub.
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvarparse.h"
|
#include "colvarparse.h"
|
||||||
|
#include "colvars_memstream.h"
|
||||||
|
|
||||||
|
|
||||||
// space & tab
|
// space & tab
|
||||||
@ -100,7 +100,7 @@ bool colvarparse::get_key_string_multi_value(std::string const &conf,
|
|||||||
char const *key, std::vector<std::string>& data)
|
char const *key, std::vector<std::string>& data)
|
||||||
{
|
{
|
||||||
bool b_found = false, b_found_any = false;
|
bool b_found = false, b_found_any = false;
|
||||||
size_t save_pos = 0, found_count = 0;
|
size_t save_pos = 0;
|
||||||
|
|
||||||
data.clear();
|
data.clear();
|
||||||
|
|
||||||
@ -110,7 +110,6 @@ bool colvarparse::get_key_string_multi_value(std::string const &conf,
|
|||||||
if (b_found) {
|
if (b_found) {
|
||||||
if (!b_found_any)
|
if (!b_found_any)
|
||||||
b_found_any = true;
|
b_found_any = true;
|
||||||
found_count++;
|
|
||||||
data.push_back(data_this);
|
data.push_back(data_this);
|
||||||
}
|
}
|
||||||
} while (b_found);
|
} while (b_found);
|
||||||
@ -786,14 +785,12 @@ bool colvarparse::key_lookup(std::string const &conf,
|
|||||||
if (line[brace] == '{') brace_count++;
|
if (line[brace] == '{') brace_count++;
|
||||||
if (line[brace] == '}') brace_count--;
|
if (line[brace] == '}') brace_count--;
|
||||||
if (brace_count == 0) {
|
if (brace_count == 0) {
|
||||||
data_end = brace+1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
brace = line.find_first_of("{}", brace+1);
|
brace = line.find_first_of("{}", brace+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (brace_count == 0) {
|
if (brace_count == 0) {
|
||||||
data_end = brace+1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -869,55 +866,107 @@ 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)
|
||||||
{
|
{
|
||||||
std::streampos start_pos = is.tellg();
|
auto start_pos = is.tellg();
|
||||||
std::string read_key, next;
|
|
||||||
|
|
||||||
if ( !(is >> read_key) || !(read_key == rb.key) ||
|
std::string read_key;
|
||||||
!(is >> next) ) {
|
if ( !(is >> read_key) || !(read_key == rb.key) ) {
|
||||||
// the requested keyword has not been found, or it is not possible
|
// the requested keyword has not been found
|
||||||
// to read data after it
|
|
||||||
is.clear();
|
is.clear();
|
||||||
is.seekg(start_pos, std::ios::beg);
|
is.seekg(start_pos);
|
||||||
is.setstate(std::ios::failbit);
|
is.setstate(std::ios::failbit);
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next != "{") {
|
std::string next;
|
||||||
if (rb.data) {
|
if (is >> next) {
|
||||||
*(rb.data) = next;
|
if (next == "{") {
|
||||||
|
// Parse a formatted brace-delimited block
|
||||||
|
rb.read_block_contents(is);
|
||||||
|
} else {
|
||||||
|
if (rb.data) {
|
||||||
|
*(rb.data) = next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return is;
|
} else {
|
||||||
|
is.clear();
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(std::ios::badbit);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t brace_count = 1;
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::istream &colvarparse::read_block::read_block_contents(std::istream &is,
|
||||||
|
bool block_only) const
|
||||||
|
{
|
||||||
|
int brace_count = block_only ? 0 : 1;
|
||||||
|
auto const start_pos = is.tellg();
|
||||||
std::string line;
|
std::string line;
|
||||||
while (colvarparse::getline_nocomments(is, line)) {
|
while (colvarparse::getline_nocomments(is, line)) {
|
||||||
size_t br = 0, br_old = 0;
|
size_t br = 0, br_old = 0;
|
||||||
while ( (br = line.find_first_of("{}", br)) != std::string::npos) {
|
while ((br = line.find_first_of("{}", br)) != std::string::npos) {
|
||||||
if (line[br] == '{') brace_count++;
|
if (line[br] == '{')
|
||||||
if (line[br] == '}') brace_count--;
|
brace_count++;
|
||||||
|
if (line[br] == '}')
|
||||||
|
brace_count--;
|
||||||
br_old = br;
|
br_old = br;
|
||||||
br++;
|
br++;
|
||||||
}
|
}
|
||||||
if (brace_count) {
|
if (brace_count || block_only) {
|
||||||
if (rb.data) {
|
// Add whole line if (1) brace are unmatched or (2) we're reading the whole stream anyway
|
||||||
(rb.data)->append(line + "\n");
|
if (data) {
|
||||||
|
data->append(line + "\n");
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
// Not reading whole block and braces are matched; add until before the last brace
|
||||||
if (rb.data) {
|
if (data) {
|
||||||
(rb.data)->append(line, 0, br_old);
|
data->append(line.substr(0, br_old) + "\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (brace_count) {
|
|
||||||
// end-of-file reached
|
if (block_only) {
|
||||||
// restore initial position
|
if (is.rdstate() & std::ios::eofbit) {
|
||||||
is.clear();
|
// Clear EOF errors if we were meant to read the whole block
|
||||||
is.seekg(start_pos, std::ios::beg);
|
is.clear();
|
||||||
is.setstate(std::ios::failbit);
|
}
|
||||||
|
} else {
|
||||||
|
if (brace_count) {
|
||||||
|
// Could not match braces, restore initial position and set fail bit
|
||||||
|
is.clear();
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream &operator>>(cvm::memory_stream &is, colvarparse::read_block const &rb)
|
||||||
|
{
|
||||||
|
auto const start_pos = is.tellg();
|
||||||
|
|
||||||
|
std::string read_key;
|
||||||
|
if ( !(is >> read_key) || !(read_key == rb.key) ) {
|
||||||
|
// the requested keyword has not been found
|
||||||
|
is.clear();
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string content;
|
||||||
|
if (is >> content) {
|
||||||
|
std::istringstream iss(content);
|
||||||
|
if (!rb.read_block_contents(iss, true)) {
|
||||||
|
is.seekg(start_pos);
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#define COLVARPARSE_H
|
#define COLVARPARSE_H
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
@ -40,7 +41,7 @@ public:
|
|||||||
void set_string(std::string const &conf);
|
void set_string(std::string const &conf);
|
||||||
|
|
||||||
/// Default destructor
|
/// Default destructor
|
||||||
virtual ~colvarparse();
|
~colvarparse() override;
|
||||||
|
|
||||||
/// Get the configuration string (includes comments)
|
/// Get the configuration string (includes comments)
|
||||||
inline std::string const & get_config() const
|
inline std::string const & get_config() const
|
||||||
@ -109,12 +110,12 @@ public:
|
|||||||
bool get_keyval(std::string const &conf,
|
bool get_keyval(std::string const &conf,
|
||||||
char const *key,
|
char const *key,
|
||||||
int &value,
|
int &value,
|
||||||
int const &def_value = (int)0,
|
int const &def_value = 0,
|
||||||
Parse_Mode const parse_mode = parse_normal);
|
Parse_Mode const parse_mode = parse_normal);
|
||||||
bool get_keyval(std::string const &conf,
|
bool get_keyval(std::string const &conf,
|
||||||
char const *key,
|
char const *key,
|
||||||
size_t &value,
|
size_t &value,
|
||||||
size_t const &def_value = (size_t)0,
|
size_t const &def_value = 0,
|
||||||
Parse_Mode const parse_mode = parse_normal);
|
Parse_Mode const parse_mode = parse_normal);
|
||||||
bool get_keyval(std::string const &conf,
|
bool get_keyval(std::string const &conf,
|
||||||
char const *key,
|
char const *key,
|
||||||
@ -134,7 +135,7 @@ public:
|
|||||||
bool get_keyval(std::string const &conf,
|
bool get_keyval(std::string const &conf,
|
||||||
char const *key,
|
char const *key,
|
||||||
cvm::real &value,
|
cvm::real &value,
|
||||||
cvm::real const &def_value = (cvm::real)0.0,
|
cvm::real const &def_value = 0.0,
|
||||||
Parse_Mode const parse_mode = parse_normal);
|
Parse_Mode const parse_mode = parse_normal);
|
||||||
bool get_keyval(std::string const &conf,
|
bool get_keyval(std::string const &conf,
|
||||||
char const *key,
|
char const *key,
|
||||||
@ -159,17 +160,17 @@ public:
|
|||||||
bool get_keyval(std::string const &conf,
|
bool get_keyval(std::string const &conf,
|
||||||
char const *key,
|
char const *key,
|
||||||
std::vector<int> &values,
|
std::vector<int> &values,
|
||||||
std::vector<int> const &def_values = std::vector<int>(0, (int)0),
|
std::vector<int> const &def_values = std::vector<int>(0, 0),
|
||||||
Parse_Mode const parse_mode = parse_normal);
|
Parse_Mode const parse_mode = parse_normal);
|
||||||
bool get_keyval(std::string const &conf,
|
bool get_keyval(std::string const &conf,
|
||||||
char const *key,
|
char const *key,
|
||||||
std::vector<size_t> &values,
|
std::vector<size_t> &values,
|
||||||
std::vector<size_t> const &def_values = std::vector<size_t>(0, (size_t)0),
|
std::vector<size_t> const &def_values = std::vector<size_t>(0, 0),
|
||||||
Parse_Mode const parse_mode = parse_normal);
|
Parse_Mode const parse_mode = parse_normal);
|
||||||
bool get_keyval(std::string const &conf,
|
bool get_keyval(std::string const &conf,
|
||||||
char const *key,
|
char const *key,
|
||||||
std::vector<long> &values,
|
std::vector<long> &values,
|
||||||
std::vector<long> const &def_values = std::vector<long>(0, (long)0),
|
std::vector<long> const &def_values = std::vector<long>(0, 0),
|
||||||
Parse_Mode const parse_mode = parse_normal);
|
Parse_Mode const parse_mode = parse_normal);
|
||||||
bool get_keyval(std::string const &conf,
|
bool get_keyval(std::string const &conf,
|
||||||
char const *key,
|
char const *key,
|
||||||
@ -179,7 +180,7 @@ public:
|
|||||||
bool get_keyval(std::string const &conf,
|
bool get_keyval(std::string const &conf,
|
||||||
char const *key,
|
char const *key,
|
||||||
std::vector<cvm::real> &values,
|
std::vector<cvm::real> &values,
|
||||||
std::vector<cvm::real> const &def_values = std::vector<cvm::real>(0, (cvm::real)0.0),
|
std::vector<cvm::real> const &def_values = std::vector<cvm::real>(0, 0.0),
|
||||||
Parse_Mode const parse_mode = parse_normal);
|
Parse_Mode const parse_mode = parse_normal);
|
||||||
bool get_keyval(std::string const &conf,
|
bool get_keyval(std::string const &conf,
|
||||||
char const *key,
|
char const *key,
|
||||||
@ -262,33 +263,41 @@ public:
|
|||||||
{
|
{
|
||||||
std::string out = "";
|
std::string out = "";
|
||||||
for (size_t i = 0; i < in.size(); i++) {
|
for (size_t i = 0; i < in.size(); i++) {
|
||||||
out.append(1, (char) ::tolower(in[i]) );
|
out.append(1, static_cast<char>( ::tolower(in[i])) );
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Helper class to read a block of the type "key { ... }"
|
/// Helper class to read a block "key { ... }" from a stream and store it in a string
|
||||||
/// from a stream and store it in a string
|
|
||||||
///
|
///
|
||||||
/// Useful on restarts, where the file is too big to be loaded in a
|
/// Useful on restarts, where the file is too big to be loaded in a string
|
||||||
/// string by key_lookup; it can only check that the keyword is
|
/// by key_lookup(); it can only check that the keyword is correct and the
|
||||||
/// correct and the block is properly delimited by braces, not
|
/// block is properly delimited by braces, not skipping other blocks
|
||||||
/// skipping other blocks
|
|
||||||
class read_block {
|
class read_block {
|
||||||
|
|
||||||
/// The keyword that identifies the block
|
|
||||||
std::string const key;
|
|
||||||
|
|
||||||
/// Where to keep the data (may be NULL)
|
|
||||||
std::string * const data;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
read_block(std::string const &key_in, std::string *data_in = NULL);
|
read_block(std::string const &key, std::string *data = nullptr);
|
||||||
|
|
||||||
~read_block();
|
~read_block();
|
||||||
|
|
||||||
|
/// Read block from stream, first check that key matches, then call read_contents()
|
||||||
friend std::istream & operator >> (std::istream &is, read_block const &rb);
|
friend std::istream & operator >> (std::istream &is, read_block const &rb);
|
||||||
|
|
||||||
|
/// Read block from stream, first check that key matches, then call read_contents()
|
||||||
|
friend cvm::memory_stream & operator >> (cvm::memory_stream &is, read_block const &rb);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// Keyword that identifies the block
|
||||||
|
std::string const key;
|
||||||
|
|
||||||
|
/// Where to keep the data
|
||||||
|
std::string * const data;
|
||||||
|
|
||||||
|
/// Read the contents of a formatted block after checking that the keyword matches
|
||||||
|
/// \param[in] is Stream object
|
||||||
|
/// \param[in] block_only If true, stream is assumed to contain only the block without braces
|
||||||
|
std::istream & read_block_contents(std::istream &is, bool block_only = false) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -304,8 +313,8 @@ public:
|
|||||||
/// within "conf", useful when doing multiple calls
|
/// within "conf", useful when doing multiple calls
|
||||||
bool key_lookup(std::string const &conf,
|
bool key_lookup(std::string const &conf,
|
||||||
char const *key,
|
char const *key,
|
||||||
std::string *data = NULL,
|
std::string *data = nullptr,
|
||||||
size_t *save_pos = NULL);
|
size_t *save_pos = nullptr);
|
||||||
|
|
||||||
/// \brief Reads a configuration line, adds it to config_string, and returns
|
/// \brief Reads a configuration line, adds it to config_string, and returns
|
||||||
/// the stream \param is Input stream \param line String that will hold the
|
/// the stream \param is Input stream \param line String that will hold the
|
||||||
|
|||||||
@ -13,8 +13,9 @@
|
|||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
|
#include "colvar.h"
|
||||||
|
#include "colvarbias.h"
|
||||||
#include "colvarscript.h"
|
#include "colvarscript.h"
|
||||||
#include "colvaratoms.h"
|
|
||||||
#include "colvarmodule_utils.h"
|
#include "colvarmodule_utils.h"
|
||||||
|
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ colvarproxy_atoms::colvarproxy_atoms()
|
|||||||
{
|
{
|
||||||
atoms_rms_applied_force_ = atoms_max_applied_force_ = 0.0;
|
atoms_rms_applied_force_ = atoms_max_applied_force_ = 0.0;
|
||||||
atoms_max_applied_force_id_ = -1;
|
atoms_max_applied_force_id_ = -1;
|
||||||
|
modified_atom_list_ = false;
|
||||||
updated_masses_ = updated_charges_ = false;
|
updated_masses_ = updated_charges_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +57,7 @@ int colvarproxy_atoms::add_atom_slot(int atom_id)
|
|||||||
atoms_positions.push_back(cvm::rvector(0.0, 0.0, 0.0));
|
atoms_positions.push_back(cvm::rvector(0.0, 0.0, 0.0));
|
||||||
atoms_total_forces.push_back(cvm::rvector(0.0, 0.0, 0.0));
|
atoms_total_forces.push_back(cvm::rvector(0.0, 0.0, 0.0));
|
||||||
atoms_new_colvar_forces.push_back(cvm::rvector(0.0, 0.0, 0.0));
|
atoms_new_colvar_forces.push_back(cvm::rvector(0.0, 0.0, 0.0));
|
||||||
|
modified_atom_list_ = true;
|
||||||
return (atoms_ids.size() - 1);
|
return (atoms_ids.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +74,12 @@ int colvarproxy_atoms::check_atom_id(int /* atom_number */)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarproxy_atoms::check_atom_name_selections_available()
|
||||||
|
{
|
||||||
|
return COLVARS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarproxy_atoms::init_atom(cvm::residue_id const & /* residue */,
|
int colvarproxy_atoms::init_atom(cvm::residue_id const & /* residue */,
|
||||||
std::string const & /* atom_name */,
|
std::string const & /* atom_name */,
|
||||||
std::string const & /* segment_id */)
|
std::string const & /* segment_id */)
|
||||||
@ -112,29 +121,6 @@ size_t colvarproxy_atoms::get_num_active_atoms() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarproxy_atoms::load_atoms(char const * /* filename */,
|
|
||||||
cvm::atom_group & /* atoms */,
|
|
||||||
std::string const & /* pdb_field */,
|
|
||||||
double)
|
|
||||||
{
|
|
||||||
return cvm::error("Error: loading atom identifiers from a file "
|
|
||||||
"is currently not implemented.\n",
|
|
||||||
COLVARS_NOT_IMPLEMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int colvarproxy_atoms::load_coords(char const * /* filename */,
|
|
||||||
std::vector<cvm::atom_pos> & /* pos */,
|
|
||||||
std::vector<int> const & /* sorted_ids */,
|
|
||||||
std::string const & /* pdb_field */,
|
|
||||||
double)
|
|
||||||
{
|
|
||||||
return cvm::error("Error: loading atomic coordinates from a file "
|
|
||||||
"is currently not implemented.\n",
|
|
||||||
COLVARS_NOT_IMPLEMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void colvarproxy_atoms::compute_rms_atoms_applied_force()
|
void colvarproxy_atoms::compute_rms_atoms_applied_force()
|
||||||
{
|
{
|
||||||
atoms_rms_applied_force_ =
|
atoms_rms_applied_force_ =
|
||||||
@ -280,7 +266,7 @@ colvarproxy_smp::~colvarproxy_smp()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarproxy_smp::smp_enabled()
|
int colvarproxy_smp::check_smp_enabled()
|
||||||
{
|
{
|
||||||
#if defined(_OPENMP)
|
#if defined(_OPENMP)
|
||||||
if (b_smp_active) {
|
if (b_smp_active) {
|
||||||
@ -299,7 +285,7 @@ int colvarproxy_smp::smp_colvars_loop()
|
|||||||
colvarmodule *cv = cvm::main();
|
colvarmodule *cv = cvm::main();
|
||||||
colvarproxy *proxy = cv->proxy;
|
colvarproxy *proxy = cv->proxy;
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for (size_t i = 0; i < cv->variables_active_smp()->size(); i++) {
|
for (int i = 0; i < static_cast<int>(cv->variables_active_smp()->size()); i++) {
|
||||||
colvar *x = (*(cv->variables_active_smp()))[i];
|
colvar *x = (*(cv->variables_active_smp()))[i];
|
||||||
int x_item = (*(cv->variables_active_smp_items()))[i];
|
int x_item = (*(cv->variables_active_smp_items()))[i];
|
||||||
if (cvm::debug()) {
|
if (cvm::debug()) {
|
||||||
@ -324,7 +310,7 @@ int colvarproxy_smp::smp_biases_loop()
|
|||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
{
|
{
|
||||||
#pragma omp for
|
#pragma omp for
|
||||||
for (size_t i = 0; i < cv->biases_active()->size(); i++) {
|
for (int i = 0; i < static_cast<int>(cv->biases_active()->size()); i++) {
|
||||||
colvarbias *b = (*(cv->biases_active()))[i];
|
colvarbias *b = (*(cv->biases_active()))[i];
|
||||||
if (cvm::debug()) {
|
if (cvm::debug()) {
|
||||||
cvm::log("Calculating bias \""+b->name+"\" on thread "+
|
cvm::log("Calculating bias \""+b->name+"\" on thread "+
|
||||||
@ -351,7 +337,7 @@ int colvarproxy_smp::smp_biases_script_loop()
|
|||||||
cv->calc_scripted_forces();
|
cv->calc_scripted_forces();
|
||||||
}
|
}
|
||||||
#pragma omp for
|
#pragma omp for
|
||||||
for (size_t i = 0; i < cv->biases_active()->size(); i++) {
|
for (int i = 0; i < static_cast<int>(cv->biases_active()->size()); i++) {
|
||||||
colvarbias *b = (*(cv->biases_active()))[i];
|
colvarbias *b = (*(cv->biases_active()))[i];
|
||||||
if (cvm::debug()) {
|
if (cvm::debug()) {
|
||||||
cvm::log("Calculating bias \""+b->name+"\" on thread "+
|
cvm::log("Calculating bias \""+b->name+"\" on thread "+
|
||||||
@ -484,16 +470,21 @@ colvarproxy::~colvarproxy()
|
|||||||
|
|
||||||
bool colvarproxy::io_available()
|
bool colvarproxy::io_available()
|
||||||
{
|
{
|
||||||
return (smp_enabled() == COLVARS_OK && smp_thread_id() == 0) ||
|
return (check_smp_enabled() == COLVARS_OK && smp_thread_id() == 0) ||
|
||||||
(smp_enabled() != COLVARS_OK);
|
(check_smp_enabled() != COLVARS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarproxy::reset()
|
int colvarproxy::reset()
|
||||||
{
|
{
|
||||||
|
if (cvm::debug()) {
|
||||||
|
cvm::log("colvarproxy::reset()\n");
|
||||||
|
}
|
||||||
int error_code = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
error_code |= colvarproxy_atoms::reset();
|
error_code |= colvarproxy_atoms::reset();
|
||||||
error_code |= colvarproxy_atom_groups::reset();
|
error_code |= colvarproxy_atom_groups::reset();
|
||||||
|
error_code |= colvarproxy_volmaps::reset();
|
||||||
|
total_force_requested = false;
|
||||||
return error_code;
|
return error_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,6 +532,31 @@ int colvarproxy::parse_module_config()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarproxy::load_atoms_pdb(char const * /* filename */,
|
||||||
|
cvm::atom_group & /* atoms */,
|
||||||
|
std::string const & /* pdb_field */,
|
||||||
|
double /* pdb_field_value */)
|
||||||
|
{
|
||||||
|
return cvm::error(
|
||||||
|
"Error: loading atom indices from a PDB file is currently not implemented in " +
|
||||||
|
engine_name() + ".\n",
|
||||||
|
COLVARS_NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarproxy::load_coords_pdb(char const * /* filename */,
|
||||||
|
std::vector<cvm::atom_pos> & /* pos */,
|
||||||
|
std::vector<int> const & /* sorted_ids */,
|
||||||
|
std::string const & /* pdb_field */,
|
||||||
|
double /* pdb_field_value */)
|
||||||
|
{
|
||||||
|
return cvm::error(
|
||||||
|
"Error: loading atomic coordinates from a PDB file is currently not implemented in " +
|
||||||
|
engine_name() + ".\n",
|
||||||
|
COLVARS_NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int colvarproxy::update_input()
|
int colvarproxy::update_input()
|
||||||
{
|
{
|
||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
@ -591,47 +607,78 @@ void colvarproxy::print_input_atomic_data()
|
|||||||
cvm::log(cvm::line_marker);
|
cvm::log(cvm::line_marker);
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"atoms_ids = "+cvm::to_str(atoms_ids)+"\n");
|
"atoms_ids[size = "+cvm::to_str(atoms_ids.size())+
|
||||||
|
"] = "+cvm::to_str(atoms_ids)+"\n");
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"atoms_refcount = "+cvm::to_str(atoms_refcount)+"\n");
|
"atoms_refcount[size = "+cvm::to_str(atoms_refcount.size())+
|
||||||
|
"] = "+cvm::to_str(atoms_refcount)+"\n");
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"atoms_masses = "+cvm::to_str(atoms_masses)+"\n");
|
"atoms_masses[size = "+cvm::to_str(atoms_masses.size())+
|
||||||
|
"] = "+cvm::to_str(atoms_masses)+"\n");
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"atoms_charges = "+cvm::to_str(atoms_charges)+"\n");
|
"atoms_charges[size = "+cvm::to_str(atoms_charges.size())+
|
||||||
|
"] = "+cvm::to_str(atoms_charges)+"\n");
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"atoms_positions = "+cvm::to_str(atoms_positions,
|
"atoms_positions[size = "+cvm::to_str(atoms_positions.size())+
|
||||||
cvm::cv_width,
|
"] = "+cvm::to_str(atoms_positions,
|
||||||
cvm::cv_prec)+"\n");
|
cvm::cv_width,
|
||||||
|
cvm::cv_prec)+"\n");
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"atoms_total_forces = "+cvm::to_str(atoms_total_forces,
|
"atoms_total_forces[size = "+
|
||||||
cvm::cv_width,
|
cvm::to_str(atoms_total_forces.size())+
|
||||||
cvm::cv_prec)+"\n");
|
"] = "+cvm::to_str(atoms_total_forces,
|
||||||
|
cvm::cv_width,
|
||||||
|
cvm::cv_prec)+"\n");
|
||||||
|
|
||||||
cvm::log(cvm::line_marker);
|
cvm::log(cvm::line_marker);
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"atom_groups_ids = "+cvm::to_str(atom_groups_ids)+"\n");
|
"atom_groups_ids[size = "+cvm::to_str(atom_groups_ids.size())+
|
||||||
|
"] = "+cvm::to_str(atom_groups_ids)+"\n");
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"atom_groups_refcount = "+cvm::to_str(atom_groups_refcount)+"\n");
|
"atom_groups_refcount[size = "+
|
||||||
|
cvm::to_str(atom_groups_refcount.size())+
|
||||||
|
"] = "+cvm::to_str(atom_groups_refcount)+"\n");
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"atom_groups_masses = "+cvm::to_str(atom_groups_masses)+"\n");
|
"atom_groups_masses[size = "+
|
||||||
|
cvm::to_str(atom_groups_masses.size())+
|
||||||
|
"] = "+cvm::to_str(atom_groups_masses)+"\n");
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"atom_groups_charges = "+cvm::to_str(atom_groups_charges)+"\n");
|
"atom_groups_charges[size = "+
|
||||||
|
cvm::to_str(atom_groups_charges.size())+
|
||||||
|
"] = "+cvm::to_str(atom_groups_charges)+"\n");
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"atom_groups_coms = "+cvm::to_str(atom_groups_coms,
|
"atom_groups_coms[size = "+
|
||||||
cvm::cv_width,
|
cvm::to_str(atom_groups_coms.size())+
|
||||||
cvm::cv_prec)+"\n");
|
"] = "+cvm::to_str(atom_groups_coms,
|
||||||
|
cvm::cv_width,
|
||||||
|
cvm::cv_prec)+"\n");
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"atom_groups_total_forces = "+cvm::to_str(atom_groups_total_forces,
|
"atom_groups_total_forces[size = "+
|
||||||
cvm::cv_width,
|
cvm::to_str(atom_groups_total_forces.size())+
|
||||||
cvm::cv_prec)+"\n");
|
"] = "+cvm::to_str(atom_groups_total_forces,
|
||||||
|
cvm::cv_width,
|
||||||
|
cvm::cv_prec)+"\n");
|
||||||
|
|
||||||
cvm::log(cvm::line_marker);
|
cvm::log(cvm::line_marker);
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"volmaps_ids = "+cvm::to_str(volmaps_ids)+"\n");
|
"volmaps_ids[size = "+cvm::to_str(volmaps_ids.size())+
|
||||||
|
"] = "+cvm::to_str(volmaps_ids)+"\n");
|
||||||
|
|
||||||
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+
|
||||||
"volmaps_values = "+cvm::to_str(volmaps_values)+"\n");
|
"volmaps_values[size = "+cvm::to_str(volmaps_values.size())+
|
||||||
|
"] = "+cvm::to_str(volmaps_values)+"\n");
|
||||||
|
|
||||||
cvm::log(cvm::line_marker);
|
cvm::log(cvm::line_marker);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvartypes.h"
|
#include "colvartypes.h"
|
||||||
#include "colvarvalue.h"
|
|
||||||
#include "colvarproxy_io.h"
|
#include "colvarproxy_io.h"
|
||||||
#include "colvarproxy_system.h"
|
#include "colvarproxy_system.h"
|
||||||
#include "colvarproxy_tcl.h"
|
#include "colvarproxy_tcl.h"
|
||||||
@ -56,6 +55,9 @@ public:
|
|||||||
/// corresponding atom yet
|
/// corresponding atom yet
|
||||||
virtual int check_atom_id(int atom_number);
|
virtual int check_atom_id(int atom_number);
|
||||||
|
|
||||||
|
/// Check whether it is possible to select atoms by residue number name
|
||||||
|
virtual int check_atom_name_selections_available();
|
||||||
|
|
||||||
/// Select this atom for collective variables calculation, using name and
|
/// Select this atom for collective variables calculation, using name and
|
||||||
/// residue number. Not all programs support this: leave this function as
|
/// residue number. Not all programs support this: leave this function as
|
||||||
/// is in those cases.
|
/// is in those cases.
|
||||||
@ -72,31 +74,6 @@ public:
|
|||||||
/// (costly) set the corresponding atoms_refcount to zero
|
/// (costly) set the corresponding atoms_refcount to zero
|
||||||
virtual void clear_atom(int index);
|
virtual void clear_atom(int index);
|
||||||
|
|
||||||
/// \brief Select atom IDs from a file (usually PDB) \param filename name of
|
|
||||||
/// the file \param atoms array to which atoms read from "filename" will be
|
|
||||||
/// appended \param pdb_field (optional) if the file is a PDB and this
|
|
||||||
/// string is non-empty, select atoms for which this field is non-zero
|
|
||||||
/// \param pdb_field_value (optional) if non-zero, select only atoms whose
|
|
||||||
/// pdb_field equals this
|
|
||||||
virtual int load_atoms(char const *filename,
|
|
||||||
cvm::atom_group &atoms,
|
|
||||||
std::string const &pdb_field,
|
|
||||||
double pdb_field_value = 0.0);
|
|
||||||
|
|
||||||
/// \brief Load a set of coordinates from a file (usually PDB); if "pos" is
|
|
||||||
/// already allocated, the number of its elements must match the number of
|
|
||||||
/// entries in "filename" \param filename name of the file \param pos array
|
|
||||||
/// of coordinates \param sorted_ids array of sorted internal IDs, used to
|
|
||||||
/// loop through the file only once \param pdb_field (optional) if the file
|
|
||||||
/// is a PDB and this string is non-empty, select atoms for which this field
|
|
||||||
/// is non-zero \param pdb_field_value (optional) if non-zero, select only
|
|
||||||
/// atoms whose pdb_field equals this
|
|
||||||
virtual int load_coords(char const *filename,
|
|
||||||
std::vector<cvm::atom_pos> &pos,
|
|
||||||
std::vector<int> const &sorted_ids,
|
|
||||||
std::string const &pdb_field,
|
|
||||||
double pdb_field_value = 0.0);
|
|
||||||
|
|
||||||
/// Clear atomic data
|
/// Clear atomic data
|
||||||
int reset();
|
int reset();
|
||||||
|
|
||||||
@ -245,6 +222,18 @@ public:
|
|||||||
return atoms_max_applied_force_id_;
|
return atoms_max_applied_force_id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether the atom list has been modified internally
|
||||||
|
inline bool modified_atom_list() const
|
||||||
|
{
|
||||||
|
return modified_atom_list_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reset the modified atom list flag
|
||||||
|
inline void reset_modified_atom_list()
|
||||||
|
{
|
||||||
|
modified_atom_list_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Record whether masses have been updated
|
/// Record whether masses have been updated
|
||||||
inline bool updated_masses() const
|
inline bool updated_masses() const
|
||||||
{
|
{
|
||||||
@ -284,6 +273,9 @@ protected:
|
|||||||
/// ID of the atom with the maximum norm among all applied forces
|
/// ID of the atom with the maximum norm among all applied forces
|
||||||
int atoms_max_applied_force_id_;
|
int atoms_max_applied_force_id_;
|
||||||
|
|
||||||
|
/// Whether the atom list has been modified internally
|
||||||
|
bool modified_atom_list_;
|
||||||
|
|
||||||
/// Whether the masses and charges have been updated from the host code
|
/// Whether the masses and charges have been updated from the host code
|
||||||
bool updated_masses_, updated_charges_;
|
bool updated_masses_, updated_charges_;
|
||||||
|
|
||||||
@ -466,7 +458,7 @@ public:
|
|||||||
bool b_smp_active;
|
bool b_smp_active;
|
||||||
|
|
||||||
/// Whether threaded parallelization is available (TODO: make this a cvm::deps feature)
|
/// Whether threaded parallelization is available (TODO: make this a cvm::deps feature)
|
||||||
virtual int smp_enabled();
|
virtual int check_smp_enabled();
|
||||||
|
|
||||||
/// Distribute calculation of colvars (and their components) across threads
|
/// Distribute calculation of colvars (and their components) across threads
|
||||||
virtual int smp_colvars_loop();
|
virtual int smp_colvars_loop();
|
||||||
@ -565,9 +557,9 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// \brief Interface between the collective variables module and
|
/// Interface between Colvars and MD engine (GROMACS, LAMMPS, NAMD, VMD...)
|
||||||
/// the simulation or analysis program (NAMD, VMD, LAMMPS...).
|
///
|
||||||
/// This is the base class: each interfaced program is supported by a derived class.
|
/// This is the base class: each engine is supported by a derived class.
|
||||||
class colvarproxy
|
class colvarproxy
|
||||||
: public colvarproxy_system,
|
: public colvarproxy_system,
|
||||||
public colvarproxy_atoms,
|
public colvarproxy_atoms,
|
||||||
@ -589,15 +581,20 @@ public:
|
|||||||
colvarproxy();
|
colvarproxy();
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~colvarproxy();
|
~colvarproxy() override;
|
||||||
|
|
||||||
virtual bool io_available() /* override */;
|
inline std::string const &engine_name() const
|
||||||
|
{
|
||||||
|
return engine_name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool io_available() override;
|
||||||
|
|
||||||
/// Request deallocation of the module (currently only implemented by VMD)
|
/// Request deallocation of the module (currently only implemented by VMD)
|
||||||
virtual int request_deletion();
|
virtual int request_deletion();
|
||||||
|
|
||||||
/// Whether deallocation was requested
|
/// Whether deallocation was requested
|
||||||
inline bool delete_requested()
|
inline bool delete_requested() const
|
||||||
{
|
{
|
||||||
return b_delete_requested;
|
return b_delete_requested;
|
||||||
}
|
}
|
||||||
@ -608,6 +605,26 @@ public:
|
|||||||
/// (Re)initialize the module
|
/// (Re)initialize the module
|
||||||
virtual int parse_module_config();
|
virtual int parse_module_config();
|
||||||
|
|
||||||
|
/// \brief Read a selection of atom IDs from a PDB coordinate file
|
||||||
|
/// \param[in] filename name of the file
|
||||||
|
/// \param[in,out] atoms array into which atoms will be read from "filename"
|
||||||
|
/// \param[in] pdb_field if the file is a PDB and this string is non-empty,
|
||||||
|
/// select atoms for which this field is non-zero
|
||||||
|
/// \param[in] pdb_field_value if non-zero, select only atoms whose pdb_field equals this
|
||||||
|
virtual int load_atoms_pdb(char const *filename, cvm::atom_group &atoms,
|
||||||
|
std::string const &pdb_field, double pdb_field_value);
|
||||||
|
|
||||||
|
/// \brief Load a set of coordinates from a PDB file
|
||||||
|
/// \param[in] filename name of the file
|
||||||
|
/// \param[in,out] pos array of coordinates to fill; if not empty, the number of its elements must match
|
||||||
|
/// the number of entries in "filename"
|
||||||
|
/// \param[in] sorted_ids array of sorted internal IDs, used to loop through the file only once
|
||||||
|
/// \param[in] pdb_field if non-empty, only atoms for which this field is non-zero will be processed
|
||||||
|
/// \param[in] pdb_field_value if non-zero, process only atoms whose pdb_field equals this
|
||||||
|
virtual int load_coords_pdb(char const *filename, std::vector<cvm::atom_pos> &pos,
|
||||||
|
std::vector<int> const &sorted_ids, std::string const &pdb_field,
|
||||||
|
double pdb_field_value);
|
||||||
|
|
||||||
/// (Re)initialize required member data (called after the module)
|
/// (Re)initialize required member data (called after the module)
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
|
|
||||||
@ -703,7 +720,10 @@ protected:
|
|||||||
/// Track which features have been acknowledged during the last run
|
/// Track which features have been acknowledged during the last run
|
||||||
size_t features_hash;
|
size_t features_hash;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
|
||||||
|
/// Name of the simulation engine that the derived proxy object supports
|
||||||
|
std::string engine_name_ = "standalone";
|
||||||
|
|
||||||
/// Queue of config strings or files to be fed to the module
|
/// Queue of config strings or files to be fed to the module
|
||||||
void *config_queue_;
|
void *config_queue_;
|
||||||
|
|||||||
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
colvarproxy_io::colvarproxy_io()
|
colvarproxy_io::colvarproxy_io()
|
||||||
{
|
{
|
||||||
input_buffer_ = NULL;
|
|
||||||
restart_frequency_engine = 0;
|
restart_frequency_engine = 0;
|
||||||
input_stream_error_ = new std::istringstream();
|
input_stream_error_ = new std::istringstream();
|
||||||
input_stream_error_->setstate(std::ios::badbit);
|
input_stream_error_->setstate(std::ios::badbit);
|
||||||
@ -135,7 +134,9 @@ int colvarproxy_io::rename_file(char const *filename, char const *newfilename)
|
|||||||
int error_code = COLVARS_OK;
|
int error_code = COLVARS_OK;
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
// On straight Windows, must remove the destination before renaming it
|
// On straight Windows, must remove the destination before renaming it
|
||||||
error_code |= remove_file(newfilename);
|
if (_access(newfilename, 00) == 0) {
|
||||||
|
error_code |= remove_file(newfilename);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
int rename_exit_code = 0;
|
int rename_exit_code = 0;
|
||||||
while ((rename_exit_code = std::rename(filename, newfilename)) != 0) {
|
while ((rename_exit_code = std::rename(filename, newfilename)) != 0) {
|
||||||
@ -151,6 +152,51 @@ int colvarproxy_io::rename_file(char const *filename, char const *newfilename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarproxy_io::set_input_prefix(std::string const &prefix)
|
||||||
|
{
|
||||||
|
// set input restart name and strip the extension, if present
|
||||||
|
input_prefix_str = prefix;
|
||||||
|
if (input_prefix_str.rfind(".colvars.state") != std::string::npos) {
|
||||||
|
input_prefix_str.erase(input_prefix_str.rfind(".colvars.state"),
|
||||||
|
std::string(".colvars.state").size());
|
||||||
|
}
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarproxy_io::set_output_prefix(std::string const &prefix)
|
||||||
|
{
|
||||||
|
// set input restart name and strip the extension, if present
|
||||||
|
output_prefix_str = prefix;
|
||||||
|
if (output_prefix_str.rfind(".colvars.state") != std::string::npos) {
|
||||||
|
output_prefix_str.erase(output_prefix_str.rfind(".colvars.state"),
|
||||||
|
std::string(".colvars.state").size());
|
||||||
|
}
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarproxy_io::set_restart_output_prefix(std::string const &prefix)
|
||||||
|
{
|
||||||
|
// set input restart name and strip the extension, if present
|
||||||
|
restart_output_prefix_str = prefix;
|
||||||
|
if (restart_output_prefix_str.rfind(".colvars.state") != std::string::npos) {
|
||||||
|
restart_output_prefix_str.erase(restart_output_prefix_str.rfind(".colvars.state"),
|
||||||
|
std::string(".colvars.state").size());
|
||||||
|
}
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarproxy_io::set_default_restart_frequency(int freq)
|
||||||
|
{
|
||||||
|
// TODO check for compatibility with colvarsRestartFrequency
|
||||||
|
restart_frequency_engine = freq;
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::istream &colvarproxy_io::input_stream(std::string const &input_name,
|
std::istream &colvarproxy_io::input_stream(std::string const &input_name,
|
||||||
std::string const description,
|
std::string const description,
|
||||||
bool error_on_fail)
|
bool error_on_fail)
|
||||||
@ -162,14 +208,19 @@ std::istream &colvarproxy_io::input_stream(std::string const &input_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (colvarproxy_io::input_stream_exists(input_name)) {
|
if (colvarproxy_io::input_stream_exists(input_name)) {
|
||||||
return *(input_streams_[input_name]);
|
std::ifstream *ifs =
|
||||||
|
dynamic_cast<std::ifstream *>(input_streams_[input_name]);
|
||||||
|
if (ifs && !ifs->is_open()) {
|
||||||
|
// This file was opened before, re-open it. Using std::ios::binary to
|
||||||
|
// work around differences in line termination conventions
|
||||||
|
// See https://github.com/Colvars/colvars/commit/8236879f7de4
|
||||||
|
ifs->open(input_name.c_str(), std::ios::binary);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
input_streams_[input_name] = new std::ifstream(input_name.c_str(),
|
||||||
|
std::ios::binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using binary to work around differences in line termination conventions
|
|
||||||
// See https://github.com/Colvars/colvars/commit/8236879f7de4
|
|
||||||
input_streams_[input_name] = new std::ifstream(input_name.c_str(),
|
|
||||||
std::ios::binary);
|
|
||||||
|
|
||||||
if (input_streams_[input_name]->fail() && error_on_fail) {
|
if (input_streams_[input_name]->fail() && error_on_fail) {
|
||||||
cvm::error("Error: cannot open "+description+" \""+input_name+"\".\n",
|
cvm::error("Error: cannot open "+description+" \""+input_name+"\".\n",
|
||||||
COLVARS_FILE_ERROR);
|
COLVARS_FILE_ERROR);
|
||||||
@ -179,6 +230,41 @@ std::istream &colvarproxy_io::input_stream(std::string const &input_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::istream &
|
||||||
|
colvarproxy_io::input_stream_from_string(std::string const &input_name,
|
||||||
|
std::string const &content,
|
||||||
|
std::string const description)
|
||||||
|
{
|
||||||
|
if (!io_available()) {
|
||||||
|
cvm::error("Error: trying to access an input file/channel "
|
||||||
|
"from the wrong thread.\n", COLVARS_BUG_ERROR);
|
||||||
|
return *input_stream_error_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colvarproxy_io::input_stream_exists(input_name)) {
|
||||||
|
|
||||||
|
std::istringstream *iss =
|
||||||
|
dynamic_cast<std::istringstream *>(input_streams_[input_name]);
|
||||||
|
if (iss) {
|
||||||
|
// If there is already a stringstream, replace it
|
||||||
|
delete iss;
|
||||||
|
} else {
|
||||||
|
std::ifstream *ifs =
|
||||||
|
dynamic_cast<std::ifstream *>(input_streams_[input_name]);
|
||||||
|
if (ifs) {
|
||||||
|
if (ifs->is_open()) {
|
||||||
|
ifs->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input_streams_[input_name] = new std::istringstream(content);
|
||||||
|
|
||||||
|
return *(input_streams_[input_name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool colvarproxy_io::input_stream_exists(std::string const &input_name)
|
bool colvarproxy_io::input_stream_exists(std::string const &input_name)
|
||||||
{
|
{
|
||||||
return (input_streams_.count(input_name) > 0);
|
return (input_streams_.count(input_name) > 0);
|
||||||
@ -188,7 +274,38 @@ bool colvarproxy_io::input_stream_exists(std::string const &input_name)
|
|||||||
int colvarproxy_io::close_input_stream(std::string const &input_name)
|
int colvarproxy_io::close_input_stream(std::string const &input_name)
|
||||||
{
|
{
|
||||||
if (colvarproxy_io::input_stream_exists(input_name)) {
|
if (colvarproxy_io::input_stream_exists(input_name)) {
|
||||||
delete input_streams_[input_name];
|
std::ifstream *ifs = dynamic_cast<std::ifstream *>(input_streams_[input_name]);
|
||||||
|
if (ifs) {
|
||||||
|
if (ifs->is_open()) {
|
||||||
|
ifs->close();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// From a string, just rewind to the begining
|
||||||
|
std::istringstream * iss = dynamic_cast<std::istringstream *>(input_streams_[input_name]);
|
||||||
|
if (iss) {
|
||||||
|
iss->clear();
|
||||||
|
iss->seekg(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return COLVARS_OK;
|
||||||
|
}
|
||||||
|
return cvm::error("Error: input file/channel \""+input_name+
|
||||||
|
"\" does not exist.\n", COLVARS_FILE_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int colvarproxy_io::delete_input_stream(std::string const &input_name)
|
||||||
|
{
|
||||||
|
if (colvarproxy_io::close_input_stream(input_name) == COLVARS_OK) {
|
||||||
|
std::ifstream *ifs = dynamic_cast<std::ifstream *>(input_streams_[input_name]);
|
||||||
|
if (ifs) {
|
||||||
|
delete ifs;
|
||||||
|
} else {
|
||||||
|
std::istringstream * iss = dynamic_cast<std::istringstream *>(input_streams_[input_name]);
|
||||||
|
if (iss) {
|
||||||
|
delete iss;
|
||||||
|
}
|
||||||
|
}
|
||||||
input_streams_.erase(input_name);
|
input_streams_.erase(input_name);
|
||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
}
|
}
|
||||||
@ -199,7 +316,8 @@ int colvarproxy_io::close_input_stream(std::string const &input_name)
|
|||||||
|
|
||||||
int colvarproxy_io::close_input_streams()
|
int colvarproxy_io::close_input_streams()
|
||||||
{
|
{
|
||||||
for (std::map<std::string, std::istream *>::iterator ii = input_streams_.begin();
|
for (std::map<std::string,
|
||||||
|
std::istream *>::iterator ii = input_streams_.begin();
|
||||||
ii != input_streams_.end();
|
ii != input_streams_.end();
|
||||||
ii++) {
|
ii++) {
|
||||||
delete ii->second;
|
delete ii->second;
|
||||||
@ -209,6 +327,19 @@ int colvarproxy_io::close_input_streams()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::list<std::string> colvarproxy_io::list_input_stream_names() const
|
||||||
|
{
|
||||||
|
std::list<std::string> result;
|
||||||
|
for (std::map<std::string,
|
||||||
|
std::istream *>::const_iterator ii = input_streams_.begin();
|
||||||
|
ii != input_streams_.end();
|
||||||
|
ii++) {
|
||||||
|
result.push_back(ii->first);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::ostream & colvarproxy_io::output_stream(std::string const &output_name,
|
std::ostream & colvarproxy_io::output_stream(std::string const &output_name,
|
||||||
std::string const description)
|
std::string const description)
|
||||||
{
|
{
|
||||||
@ -228,7 +359,7 @@ std::ostream & colvarproxy_io::output_stream(std::string const &output_name,
|
|||||||
|
|
||||||
backup_file(output_name.c_str());
|
backup_file(output_name.c_str());
|
||||||
|
|
||||||
output_streams_[output_name] = new std::ofstream(output_name.c_str());
|
output_streams_[output_name] = new std::ofstream(output_name.c_str(), std::ios::binary);
|
||||||
if (!*(output_streams_[output_name])) {
|
if (!*(output_streams_[output_name])) {
|
||||||
cvm::error("Error: cannot write to "+description+" \""+output_name+"\".\n",
|
cvm::error("Error: cannot write to "+description+" \""+output_name+"\".\n",
|
||||||
COLVARS_FILE_ERROR);
|
COLVARS_FILE_ERROR);
|
||||||
@ -303,6 +434,7 @@ int colvarproxy_io::close_output_streams()
|
|||||||
osi != output_streams_.end();
|
osi != output_streams_.end();
|
||||||
osi++) {
|
osi++) {
|
||||||
(dynamic_cast<std::ofstream *>(osi->second))->close();
|
(dynamic_cast<std::ofstream *>(osi->second))->close();
|
||||||
|
delete osi->second;
|
||||||
}
|
}
|
||||||
output_streams_.clear();
|
output_streams_.clear();
|
||||||
|
|
||||||
|
|||||||
@ -10,9 +10,10 @@
|
|||||||
#ifndef COLVARPROXY_IO_H
|
#ifndef COLVARPROXY_IO_H
|
||||||
#define COLVARPROXY_IO_H
|
#define COLVARPROXY_IO_H
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iosfwd>
|
|
||||||
|
|
||||||
|
|
||||||
/// Methods for data input/output
|
/// Methods for data input/output
|
||||||
@ -66,57 +67,80 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Prefix of the input state file to be read next
|
/// Prefix of the input state file to be read next
|
||||||
inline std::string & input_prefix()
|
inline std::string const & input_prefix() const
|
||||||
{
|
{
|
||||||
return input_prefix_str;
|
return input_prefix_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initialize input_prefix (NOTE: it will be erased after state file is read)
|
||||||
|
virtual int set_input_prefix(std::string const &prefix);
|
||||||
|
|
||||||
/// Default prefix to be used for all output files (final configuration)
|
/// Default prefix to be used for all output files (final configuration)
|
||||||
inline std::string & output_prefix()
|
inline std::string const & output_prefix() const
|
||||||
{
|
{
|
||||||
return output_prefix_str;
|
return output_prefix_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set default output prefix
|
||||||
|
virtual int set_output_prefix(std::string const &prefix);
|
||||||
|
|
||||||
/// Prefix of the restart (checkpoint) file to be written next
|
/// Prefix of the restart (checkpoint) file to be written next
|
||||||
inline std::string & restart_output_prefix()
|
inline std::string const & restart_output_prefix() const
|
||||||
{
|
{
|
||||||
return restart_output_prefix_str;
|
return restart_output_prefix_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set default restart state file prefix
|
||||||
|
virtual int set_restart_output_prefix(std::string const &prefix);
|
||||||
|
|
||||||
/// Default restart frequency (as set by the simulation engine)
|
/// Default restart frequency (as set by the simulation engine)
|
||||||
inline int default_restart_frequency() const
|
inline int default_restart_frequency() const
|
||||||
{
|
{
|
||||||
return restart_frequency_engine;
|
return restart_frequency_engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Buffer from which the input state information may be read
|
/// Communicate/set the restart frequency of the simulation engine
|
||||||
inline char const * & input_buffer()
|
virtual int set_default_restart_frequency(int freq);
|
||||||
{
|
|
||||||
return input_buffer_;
|
// The input stream functions below are not virtual, because they currently
|
||||||
}
|
// rely on the fact that either std::ifstream or std::istringstream is used
|
||||||
|
|
||||||
/// Returns a reference to given input stream, creating it if needed
|
/// Returns a reference to given input stream, creating it if needed
|
||||||
/// \param input_name File name (later only a handle)
|
/// \param input_name File name (later only a handle)
|
||||||
/// \param description Purpose of the file
|
/// \param description Purpose of the file
|
||||||
/// \param error_on_fail Raise error when failing to open (allow testing)
|
/// \param error_on_fail Raise error when failing to open (allow testing)
|
||||||
virtual std::istream &input_stream(std::string const &input_name,
|
std::istream & input_stream(std::string const &input_name,
|
||||||
std::string const description = "file/channel",
|
std::string const description = "file/channel",
|
||||||
bool error_on_fail = true);
|
bool error_on_fail = true);
|
||||||
|
|
||||||
|
/// Returns a reference to given input stream, creating it if needed
|
||||||
|
/// \param input_name Identifier of the input stream
|
||||||
|
/// \param content Set this string as the stream's buffer
|
||||||
|
/// \param description Purpose of the stream
|
||||||
|
std::istream & input_stream_from_string(std::string const &input_name,
|
||||||
|
std::string const &content,
|
||||||
|
std::string const description = "string");
|
||||||
|
|
||||||
/// Check if the file/channel is open (without opening it if not)
|
/// Check if the file/channel is open (without opening it if not)
|
||||||
virtual bool input_stream_exists(std::string const &input_name);
|
bool input_stream_exists(std::string const &input_name);
|
||||||
|
|
||||||
/// Closes the given input stream
|
/// Closes the given input stream
|
||||||
virtual int close_input_stream(std::string const &input_name);
|
int close_input_stream(std::string const &input_name);
|
||||||
|
|
||||||
/// Closes all input streams
|
/// Closes all input streams
|
||||||
virtual int close_input_streams();
|
int close_input_streams();
|
||||||
|
|
||||||
|
/// Same as close_input_stream(), but also removes the corresponding entry from memory
|
||||||
|
int delete_input_stream(std::string const &input_name);
|
||||||
|
|
||||||
|
/// List all input streams that were opened at some point
|
||||||
|
std::list<std::string> list_input_stream_names() const;
|
||||||
|
|
||||||
/// Returns a reference to the named output file/channel (open it if needed)
|
/// Returns a reference to the named output file/channel (open it if needed)
|
||||||
/// \param output_name File name or identifier
|
/// \param output_name File name or identifier
|
||||||
/// \param description Purpose of the file
|
/// \param description Purpose of the file
|
||||||
virtual std::ostream &output_stream(std::string const &output_name,
|
virtual std::ostream &output_stream(std::string const &output_name,
|
||||||
std::string const description = "file/channel");
|
std::string const description);
|
||||||
|
|
||||||
/// Check if the file/channel is open (without opening it if not)
|
/// Check if the file/channel is open (without opening it if not)
|
||||||
virtual bool output_stream_exists(std::string const &output_name);
|
virtual bool output_stream_exists(std::string const &output_name);
|
||||||
@ -158,9 +182,6 @@ protected:
|
|||||||
|
|
||||||
/// Object whose reference is returned when write errors occur
|
/// Object whose reference is returned when write errors occur
|
||||||
std::ostream *output_stream_error_;
|
std::ostream *output_stream_error_;
|
||||||
|
|
||||||
/// Buffer from which the input state information may be read
|
|
||||||
char const *input_buffer_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@ colvarproxy_system::colvarproxy_system()
|
|||||||
{
|
{
|
||||||
angstrom_value_ = 0.0;
|
angstrom_value_ = 0.0;
|
||||||
kcal_mol_value_ = 0.0;
|
kcal_mol_value_ = 0.0;
|
||||||
|
timestep_ = 1.0;
|
||||||
target_temperature_ = 0.0;
|
target_temperature_ = 0.0;
|
||||||
boltzmann_ = 0.001987191; // Default: kcal/mol/K
|
boltzmann_ = 0.001987191; // Default: kcal/mol/K
|
||||||
boundaries_type = boundaries_unsupported;
|
boundaries_type = boundaries_unsupported;
|
||||||
@ -46,10 +47,10 @@ int colvarproxy_system::set_target_temperature(cvm::real T)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cvm::real colvarproxy_system::dt()
|
int colvarproxy_system::set_integration_timestep(cvm::real dt)
|
||||||
{
|
{
|
||||||
// TODO define, document and implement a user method to set the value of this
|
timestep_ = dt;
|
||||||
return 1.0;
|
return COLVARS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -61,8 +61,14 @@ public:
|
|||||||
/// Set the current target temperature of the simulation (K units)
|
/// Set the current target temperature of the simulation (K units)
|
||||||
virtual int set_target_temperature(cvm::real T);
|
virtual int set_target_temperature(cvm::real T);
|
||||||
|
|
||||||
/// \brief Time step of the simulation (fs)
|
/// Time step of the simulation (fs units)
|
||||||
virtual cvm::real dt();
|
inline double dt() const
|
||||||
|
{
|
||||||
|
return timestep_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the current integration timestep of the simulation (fs units)
|
||||||
|
virtual int set_integration_timestep(cvm::real dt);
|
||||||
|
|
||||||
/// \brief Pseudo-random number with Gaussian distribution
|
/// \brief Pseudo-random number with Gaussian distribution
|
||||||
virtual cvm::real rand_gaussian(void);
|
virtual cvm::real rand_gaussian(void);
|
||||||
@ -137,9 +143,12 @@ protected:
|
|||||||
/// Boltzmann constant in internal Colvars units
|
/// Boltzmann constant in internal Colvars units
|
||||||
cvm::real boltzmann_;
|
cvm::real boltzmann_;
|
||||||
|
|
||||||
/// Most up to date target temperature for the system (in K)
|
/// Most up to date target temperature (K units); default to 0.0 if undefined
|
||||||
cvm::real target_temperature_;
|
cvm::real target_temperature_;
|
||||||
|
|
||||||
|
/// Current integration timestep (engine units); default to 1.0 if undefined
|
||||||
|
double timestep_;
|
||||||
|
|
||||||
/// \brief Value of 1 Angstrom in the internal (front-end) Colvars unit for atomic coordinates
|
/// \brief Value of 1 Angstrom in the internal (front-end) Colvars unit for atomic coordinates
|
||||||
/// * defaults to 0 in the base class; derived proxy classes must set it
|
/// * defaults to 0 in the base class; derived proxy classes must set it
|
||||||
/// * in VMD proxy, can only be changed when no variables are defined
|
/// * in VMD proxy, can only be changed when no variables are defined
|
||||||
|
|||||||
@ -83,7 +83,7 @@ int colvarproxy_tcl::tcl_run_file(std::string const &fileName)
|
|||||||
Tcl_Interp *const interp = get_tcl_interp();
|
Tcl_Interp *const interp = get_tcl_interp();
|
||||||
int err = Tcl_EvalFile(interp, fileName.c_str());
|
int err = Tcl_EvalFile(interp, fileName.c_str());
|
||||||
if (err != TCL_OK) {
|
if (err != TCL_OK) {
|
||||||
cvm::log("Error while executing Tcl script file" + fileName + ":\n");
|
cvm::log("Error while executing Tcl script file \"" + fileName + "\":\n");
|
||||||
cvm::error(Tcl_GetStringResult(interp));
|
cvm::error(Tcl_GetStringResult(interp));
|
||||||
return COLVARS_ERROR;
|
return COLVARS_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ colvarproxy_volmaps::colvarproxy_volmaps()
|
|||||||
colvarproxy_volmaps::~colvarproxy_volmaps() {}
|
colvarproxy_volmaps::~colvarproxy_volmaps() {}
|
||||||
|
|
||||||
|
|
||||||
int colvarproxy_volmaps::volmaps_available()
|
int colvarproxy_volmaps::check_volmaps_available()
|
||||||
{
|
{
|
||||||
return COLVARS_NOT_IMPLEMENTED;
|
return COLVARS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,8 +18,8 @@ public:
|
|||||||
/// Clear volumetric map data
|
/// Clear volumetric map data
|
||||||
int reset();
|
int reset();
|
||||||
|
|
||||||
/// \brief Whether this implementation has capability to use volumetric maps
|
/// Test whether this implementation can use volumetric maps as CVs
|
||||||
virtual int volmaps_available();
|
virtual int check_volmaps_available();
|
||||||
|
|
||||||
/// Create a slot for a volumetric map not requested yet
|
/// Create a slot for a volumetric map not requested yet
|
||||||
int add_volmap_slot(int volmap_id);
|
int add_volmap_slot(int volmap_id);
|
||||||
|
|||||||
102
lib/colvars/colvars_memstream.cpp
Normal file
102
lib/colvars/colvars_memstream.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// -*- 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 "colvartypes.h"
|
||||||
|
#include "colvarvalue.h"
|
||||||
|
#include "colvars_memstream.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool cvm::memory_stream::expand_output_buffer(size_t add_bytes)
|
||||||
|
{
|
||||||
|
auto &buffer = external_output_buffer_ ? *external_output_buffer_ : internal_buffer_;
|
||||||
|
if ((buffer.size() + add_bytes) <= max_length_) {
|
||||||
|
buffer.resize((buffer.size() + add_bytes));
|
||||||
|
} else {
|
||||||
|
setstate(std::ios::badbit);
|
||||||
|
}
|
||||||
|
return bool(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <> void cvm::memory_stream::write_object(std::string const &t)
|
||||||
|
{
|
||||||
|
size_t const string_length = t.size();
|
||||||
|
size_t const new_data_size = sizeof(size_t) + sizeof(char) * string_length;
|
||||||
|
if (expand_output_buffer(new_data_size)) {
|
||||||
|
std::memcpy(output_location(), &string_length, sizeof(size_t));
|
||||||
|
incr_write_pos(sizeof(size_t));
|
||||||
|
std::memcpy(output_location(), t.c_str(), t.size() * sizeof(char));
|
||||||
|
incr_write_pos(t.size() * sizeof(char));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> cvm::memory_stream &operator<<(cvm::memory_stream &os, std::string const &t)
|
||||||
|
{
|
||||||
|
os.write_object<std::string>(t);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> void cvm::memory_stream::write_object(colvarvalue const &t)
|
||||||
|
{
|
||||||
|
*this << t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> void cvm::memory_stream::write_object(cvm::vector1d<cvm::real> const &t)
|
||||||
|
{
|
||||||
|
return write_vector<cvm::real>(t.data_array());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
cvm::memory_stream &operator<<(cvm::memory_stream &os, cvm::vector1d<cvm::real> const &t)
|
||||||
|
{
|
||||||
|
os.write_vector<cvm::real>(t.data_array());
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <> void cvm::memory_stream::read_object(std::string &t)
|
||||||
|
{
|
||||||
|
begin_reading();
|
||||||
|
size_t string_length = 0;
|
||||||
|
if (has_remaining(sizeof(size_t))) {
|
||||||
|
std::memcpy(&string_length, input_location(), sizeof(size_t));
|
||||||
|
incr_read_pos(sizeof(size_t));
|
||||||
|
if (has_remaining(string_length * sizeof(char))) {
|
||||||
|
t.assign(reinterpret_cast<char const *>(input_location()), string_length);
|
||||||
|
incr_read_pos(string_length * sizeof(char));
|
||||||
|
done_reading();
|
||||||
|
} else {
|
||||||
|
setstate(std::ios::failbit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> cvm::memory_stream &operator>>(cvm::memory_stream &is, std::string &t)
|
||||||
|
{
|
||||||
|
is.read_object<std::string>(t);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> void cvm::memory_stream::read_object(colvarvalue &t)
|
||||||
|
{
|
||||||
|
*this >> t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> void cvm::memory_stream::read_object(cvm::vector1d<cvm::real> &t)
|
||||||
|
{
|
||||||
|
return read_vector<cvm::real>(t.data_array());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> cvm::memory_stream &operator>>(cvm::memory_stream &is, cvm::vector1d<cvm::real> &t)
|
||||||
|
{
|
||||||
|
is.read_vector<cvm::real>(t.data_array());
|
||||||
|
return is;
|
||||||
|
}
|
||||||
289
lib/colvars/colvars_memstream.h
Normal file
289
lib/colvars/colvars_memstream.h
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
// -*- 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 MEMORY_STREAM_H
|
||||||
|
#define MEMORY_STREAM_H
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <vector>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
|
||||||
|
// Work around missing std::is_trivially_copyable in old GCC and Clang versions
|
||||||
|
// TODO remove this after CentOS 7 has been beyond EOL for a while
|
||||||
|
#if (defined(__GNUC__) && (__GNUC__ < 5) && !defined(__clang__)) || (defined(__clang__) && (__clang_major__ < 7))
|
||||||
|
// Clang needs an exception, because it defines __GNUC__ as well
|
||||||
|
#define IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T)
|
||||||
|
#else
|
||||||
|
#define IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable<T>::value
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
class cvm::memory_stream {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Set up an empty stream with an internal buffer, suitable for writing to
|
||||||
|
/// \param max_length Maximum allowed capacity (default is 64 GiB)
|
||||||
|
memory_stream(size_t max_length = (static_cast<size_t>(1L) << 36)) : max_length_(max_length) {}
|
||||||
|
|
||||||
|
/// Set up a stream based on an external input buffer
|
||||||
|
memory_stream(size_t n, unsigned char const *buf)
|
||||||
|
: external_input_buffer_(buf), internal_buffer_(), data_length_(n), max_length_(data_length_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set up a stream based on an external output buffer
|
||||||
|
memory_stream(std::vector<unsigned char> &buf) : memory_stream()
|
||||||
|
{
|
||||||
|
external_output_buffer_ = &buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Length of the buffer
|
||||||
|
inline size_t length() const { return data_length_; }
|
||||||
|
|
||||||
|
/// Output buffer
|
||||||
|
inline unsigned char *output_buffer()
|
||||||
|
{
|
||||||
|
return (external_output_buffer_ ? external_output_buffer_->data() : internal_buffer_.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Next location to write to
|
||||||
|
inline unsigned char *output_location() { return output_buffer() + data_length_; }
|
||||||
|
|
||||||
|
/// Input buffer
|
||||||
|
inline unsigned char const *input_buffer() const
|
||||||
|
{
|
||||||
|
return (external_input_buffer_ ? external_input_buffer_ : internal_buffer_.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Next location to read from
|
||||||
|
inline unsigned char const *input_location() const { return input_buffer() + read_pos_; }
|
||||||
|
|
||||||
|
/// Cast operator to be used to test for errors
|
||||||
|
inline explicit operator bool() const { return state_ == std::ios::goodbit; }
|
||||||
|
|
||||||
|
/// Write a simple object to the output buffer
|
||||||
|
template <typename T> void write_object(T const &t);
|
||||||
|
|
||||||
|
/// Wrapper to write_object()
|
||||||
|
template <typename T> friend memory_stream &operator<<(memory_stream &os, T const &t);
|
||||||
|
|
||||||
|
/// Write a vector of simple objects to the output buffer
|
||||||
|
template <typename T> void write_vector(std::vector<T> const &t);
|
||||||
|
|
||||||
|
/// Wrapper to write_vector()
|
||||||
|
template <typename T>
|
||||||
|
friend memory_stream &operator<<(memory_stream &os, std::vector<T> const &t);
|
||||||
|
|
||||||
|
/// Read a simple object from the buffer
|
||||||
|
template <typename T> void read_object(T &t);
|
||||||
|
|
||||||
|
/// Wrapper to read_object()
|
||||||
|
template <typename T> friend memory_stream &operator>>(memory_stream &is, T &t);
|
||||||
|
|
||||||
|
/// Read a vector of simple objects from the buffer
|
||||||
|
template <typename T> void read_vector(std::vector<T> &t);
|
||||||
|
|
||||||
|
/// Wrapper to read_vector()
|
||||||
|
template <typename T> friend memory_stream &operator>>(memory_stream &is, std::vector<T> &t);
|
||||||
|
|
||||||
|
|
||||||
|
// Compatibility with STL stream functions
|
||||||
|
|
||||||
|
/// Report the current position in the buffer
|
||||||
|
inline size_t tellg() const { return read_pos_; }
|
||||||
|
|
||||||
|
/// Report the current position in the buffer
|
||||||
|
inline memory_stream & seekg(size_t pos) { read_pos_ = pos; return *this; }
|
||||||
|
|
||||||
|
/// Ignore formatting operators
|
||||||
|
inline void setf(decltype(std::ios::fmtflags(0)), decltype(std::ios::floatfield)) {}
|
||||||
|
|
||||||
|
/// Ignore formatting operators
|
||||||
|
inline void flags(decltype(std::ios::fmtflags(0))) {}
|
||||||
|
|
||||||
|
/// Get the current formatting flags (i.e. none because this stream is unformatted)
|
||||||
|
inline decltype(std::ios::fmtflags(0)) flags() const { return std::ios::fmtflags(0); }
|
||||||
|
|
||||||
|
/// Get the error code
|
||||||
|
inline std::ios::iostate rdstate() const { return state_; }
|
||||||
|
|
||||||
|
/// Set the error code
|
||||||
|
inline void setstate(std::ios::iostate new_state) { state_ |= new_state; }
|
||||||
|
|
||||||
|
/// Clear the error code
|
||||||
|
inline void clear() { state_ = std::ios::goodbit; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// External output buffer
|
||||||
|
std::vector<unsigned char> *external_output_buffer_ = nullptr;
|
||||||
|
|
||||||
|
/// External input buffer
|
||||||
|
unsigned char const *external_input_buffer_ = nullptr;
|
||||||
|
|
||||||
|
/// Internal buffer (may server for both input and output)
|
||||||
|
std::vector<unsigned char> internal_buffer_;
|
||||||
|
|
||||||
|
/// Length of the data buffer (either internal or external)
|
||||||
|
size_t data_length_ = 0L;
|
||||||
|
|
||||||
|
/// Largest allowed capacity of the data buffer
|
||||||
|
size_t const max_length_;
|
||||||
|
|
||||||
|
/// Error status
|
||||||
|
std::ios::iostate state_ = std::ios::goodbit;
|
||||||
|
|
||||||
|
/// Add the requester number of bytes to the array capacity; return false if buffer is external
|
||||||
|
bool expand_output_buffer(size_t add_bytes);
|
||||||
|
|
||||||
|
/// Move the buffer position past the data just written
|
||||||
|
inline void incr_write_pos(size_t c) { data_length_ += c; }
|
||||||
|
|
||||||
|
/// Current position when reading from the buffer
|
||||||
|
size_t read_pos_ = 0L;
|
||||||
|
|
||||||
|
/// Begin an attempt to read an object; assume EOF unless there is space remaining
|
||||||
|
inline void begin_reading() { setstate(std::ios::eofbit); }
|
||||||
|
|
||||||
|
/// Mark the reading attempt succesful
|
||||||
|
inline void done_reading() { clear(); }
|
||||||
|
|
||||||
|
/// Move the buffer position past the data just read
|
||||||
|
inline void incr_read_pos(size_t c) { read_pos_ += c; }
|
||||||
|
|
||||||
|
/// Check that the buffer contains enough bytes to read as the argument says, set error
|
||||||
|
/// otherwise
|
||||||
|
inline bool has_remaining(size_t c) { return c <= (data_length_ - read_pos_); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> void cvm::memory_stream::write_object(T const &t)
|
||||||
|
{
|
||||||
|
static_assert(IS_TRIVIALLY_COPYABLE(T), "Cannot use write_object() on complex type");
|
||||||
|
size_t const new_data_size = sizeof(T);
|
||||||
|
if (expand_output_buffer(new_data_size)) {
|
||||||
|
std::memcpy(output_location(), &t, sizeof(T));
|
||||||
|
incr_write_pos(new_data_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> cvm::memory_stream &operator<<(cvm::memory_stream &os, T const &t)
|
||||||
|
{
|
||||||
|
os.write_object<T>(t);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void cvm::memory_stream::write_vector(std::vector<T> const &t)
|
||||||
|
{
|
||||||
|
static_assert(IS_TRIVIALLY_COPYABLE(T), "Cannot use write_vector() on complex type");
|
||||||
|
size_t const vector_length = t.size();
|
||||||
|
size_t const new_data_size = sizeof(size_t) + sizeof(T) * vector_length;
|
||||||
|
if (expand_output_buffer(new_data_size)) {
|
||||||
|
std::memcpy(output_location(), &vector_length, sizeof(size_t));
|
||||||
|
incr_write_pos(sizeof(T));
|
||||||
|
std::memcpy(output_location(), t.data(), t.size() * sizeof(T));
|
||||||
|
incr_write_pos(t.size() * sizeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
cvm::memory_stream &operator<<(cvm::memory_stream &os, std::vector<T> const &t)
|
||||||
|
{
|
||||||
|
os.write_vector<T>(t);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void cvm::memory_stream::read_object(T &t)
|
||||||
|
{
|
||||||
|
static_assert(IS_TRIVIALLY_COPYABLE(T), "Cannot use read_object() on complex type");
|
||||||
|
begin_reading();
|
||||||
|
if (has_remaining(sizeof(T))) {
|
||||||
|
std::memcpy(&t, input_location(), sizeof(T));
|
||||||
|
incr_read_pos(sizeof(T));
|
||||||
|
done_reading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> cvm::memory_stream &operator>>(cvm::memory_stream &is, T &t)
|
||||||
|
{
|
||||||
|
is.read_object<T>(t);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void cvm::memory_stream::read_vector(std::vector<T> &t)
|
||||||
|
{
|
||||||
|
static_assert(IS_TRIVIALLY_COPYABLE(T), "Cannot use read_vector() on complex type");
|
||||||
|
begin_reading();
|
||||||
|
size_t vector_length = 0;
|
||||||
|
if (has_remaining(sizeof(size_t))) {
|
||||||
|
std::memcpy(&vector_length, input_location(), sizeof(size_t));
|
||||||
|
incr_read_pos(sizeof(size_t));
|
||||||
|
if (has_remaining(vector_length * sizeof(T))) {
|
||||||
|
t.resize(vector_length);
|
||||||
|
std::memcpy(t.data(), input_location(), vector_length * sizeof(T));
|
||||||
|
incr_read_pos(vector_length * sizeof(T));
|
||||||
|
done_reading();
|
||||||
|
} else {
|
||||||
|
setstate(std::ios::failbit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> cvm::memory_stream &operator>>(cvm::memory_stream &is, std::vector<T> &t)
|
||||||
|
{
|
||||||
|
is.read_vector<T>(t);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> cvm::memory_stream &operator<<(cvm::memory_stream &os,
|
||||||
|
decltype(std::setprecision(10)) const &)
|
||||||
|
{
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(_MSC_VER) && !defined(__SUNPRO_CC)
|
||||||
|
// Visual Studio and MSVC use the same return type for both modifiers
|
||||||
|
template <typename T> cvm::memory_stream &operator<<(cvm::memory_stream &os,
|
||||||
|
decltype(std::setw(10)) const &)
|
||||||
|
{
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Declare specializations
|
||||||
|
|
||||||
|
template <> void cvm::memory_stream::write_object(std::string const &t);
|
||||||
|
|
||||||
|
template <> cvm::memory_stream &operator<<(cvm::memory_stream &os, std::string const &t);
|
||||||
|
|
||||||
|
template <> void cvm::memory_stream::write_object(colvarvalue const &t);
|
||||||
|
|
||||||
|
template <> cvm::memory_stream &operator<<(cvm::memory_stream &os, colvarvalue const &x);
|
||||||
|
|
||||||
|
template <> void cvm::memory_stream::write_object(cvm::vector1d<cvm::real> const &t);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
cvm::memory_stream &operator<<(cvm::memory_stream &os, cvm::vector1d<cvm::real> const &t);
|
||||||
|
|
||||||
|
template <> void cvm::memory_stream::read_object(std::string &t);
|
||||||
|
|
||||||
|
template <> cvm::memory_stream &operator>>(cvm::memory_stream &is, std::string &t);
|
||||||
|
|
||||||
|
template <> void cvm::memory_stream::read_object(colvarvalue &t);
|
||||||
|
|
||||||
|
template <> cvm::memory_stream &operator>>(cvm::memory_stream &is, colvarvalue &t);
|
||||||
|
|
||||||
|
template <> void cvm::memory_stream::read_object(cvm::vector1d<cvm::real> &t);
|
||||||
|
|
||||||
|
template <> cvm::memory_stream &operator>>(cvm::memory_stream &is, cvm::vector1d<cvm::real> &t);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,3 +1,3 @@
|
|||||||
#ifndef COLVARS_VERSION
|
#ifndef COLVARS_VERSION
|
||||||
#define COLVARS_VERSION "2023-05-01"
|
#define COLVARS_VERSION "2024-06-04"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -7,8 +7,6 @@
|
|||||||
// 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 <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
@ -35,6 +33,7 @@ colvarscript::colvarscript(colvarproxy *p, colvarmodule *m)
|
|||||||
: proxy_(p),
|
: proxy_(p),
|
||||||
colvars(m)
|
colvars(m)
|
||||||
{
|
{
|
||||||
|
cmdline_main_cmd_ = std::string("cv");
|
||||||
cmd_names = NULL;
|
cmd_names = NULL;
|
||||||
init_commands();
|
init_commands();
|
||||||
#ifdef COLVARS_TCL
|
#ifdef COLVARS_TCL
|
||||||
@ -141,7 +140,7 @@ int colvarscript::init_command(colvarscript::command const &comm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd_full_help[comm] = cmd_help[comm]+"\n";
|
cmd_full_help[comm] = cmd_help[comm]+"\n";
|
||||||
if (cmd_n_args_min[comm] > 0) {
|
if (cmd_n_args_max[comm] > 0) {
|
||||||
cmd_full_help[comm] += "\nParameters\n";
|
cmd_full_help[comm] += "\nParameters\n";
|
||||||
cmd_full_help[comm] += "----------\n\n";
|
cmd_full_help[comm] += "----------\n\n";
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -281,11 +280,15 @@ std::string colvarscript::get_command_cmdline_syntax(colvarscript::Object_type t
|
|||||||
|
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case use_module:
|
case use_module:
|
||||||
return std::string("cv "+cmdline_cmd+cmdline_args); break;
|
return std::string(cmdline_main_cmd_ + " " + cmdline_cmd + cmdline_args);
|
||||||
|
break;
|
||||||
case use_colvar:
|
case use_colvar:
|
||||||
return std::string("cv colvar name "+cmdline_cmd+cmdline_args); break;
|
return std::string(cmdline_main_cmd_ + " colvar name " + cmdline_cmd+
|
||||||
|
cmdline_args);
|
||||||
|
break;
|
||||||
case use_bias:
|
case use_bias:
|
||||||
return std::string("cv bias name "+cmdline_cmd+cmdline_args); break;
|
return std::string(cmdline_main_cmd_ + " bias name " + cmdline_cmd+cmdline_args);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Already handled, but silence the warning
|
// Already handled, but silence the warning
|
||||||
return std::string("");
|
return std::string("");
|
||||||
@ -353,7 +356,7 @@ int colvarscript::run(int objc, unsigned char *const objv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (objc < 2) {
|
if (objc < 2) {
|
||||||
set_result_str("No commands given: use \"cv help\" "
|
set_result_str("No commands given: use \""+cmdline_main_cmd_+" help\" "
|
||||||
"for a list of commands.");
|
"for a list of commands.");
|
||||||
return COLVARSCRIPT_ERROR;
|
return COLVARSCRIPT_ERROR;
|
||||||
}
|
}
|
||||||
@ -436,7 +439,8 @@ int colvarscript::run(int objc, unsigned char *const objv[])
|
|||||||
error_code = (*cmd_fn)(obj_for_cmd, objc, objv);
|
error_code = (*cmd_fn)(obj_for_cmd, objc, objv);
|
||||||
} else {
|
} else {
|
||||||
add_error_msg("Syntax error: "+cmdline+"\n"
|
add_error_msg("Syntax error: "+cmdline+"\n"
|
||||||
" Run \"cv help\" or \"cv help <command>\" "
|
" Run \""+main_cmd+" help\" or \""+
|
||||||
|
main_cmd+" help <command>\" "
|
||||||
"to get the correct syntax.\n");
|
"to get the correct syntax.\n");
|
||||||
error_code = COLVARSCRIPT_ERROR;
|
error_code = COLVARSCRIPT_ERROR;
|
||||||
}
|
}
|
||||||
@ -763,7 +767,7 @@ extern "C" int tcl_run_colvarscript_command(ClientData /* clientData */,
|
|||||||
int colvarscript::set_result_text_from_str(std::string const &x_str,
|
int colvarscript::set_result_text_from_str(std::string const &x_str,
|
||||||
unsigned char *obj) {
|
unsigned char *obj) {
|
||||||
if (obj) {
|
if (obj) {
|
||||||
strcpy(reinterpret_cast<char *>(obj), x_str.c_str());
|
std::memcpy(reinterpret_cast<char *>(obj), x_str.c_str(), x_str.size());
|
||||||
} else {
|
} else {
|
||||||
set_result_str(x_str);
|
set_result_str(x_str);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
#include "colvarbias.h"
|
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
|
|
||||||
|
|
||||||
@ -25,6 +24,8 @@
|
|||||||
#define COLVARSCRIPT_OK 0
|
#define COLVARSCRIPT_OK 0
|
||||||
|
|
||||||
|
|
||||||
|
class colvardeps;
|
||||||
|
|
||||||
class colvarscript {
|
class colvarscript {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -161,6 +162,11 @@ public:
|
|||||||
/// \param cmd Name of the command's function (e.g. "cv_units")
|
/// \param cmd Name of the command's function (e.g. "cv_units")
|
||||||
int get_command_n_args_max(char const *cmd);
|
int get_command_n_args_max(char const *cmd);
|
||||||
|
|
||||||
|
/// Set the main command for the CLI, when it is not "cv" (e.g. LAMMPS)
|
||||||
|
inline void set_cmdline_main_cmd(std::string const &cmd) {
|
||||||
|
cmdline_main_cmd_ = cmd;
|
||||||
|
}
|
||||||
|
|
||||||
/// Get help string for a command (does not specify how it is launched)
|
/// Get help string for a command (does not specify how it is launched)
|
||||||
/// \param cmd Name of the command's function (e.g. "cv_units")
|
/// \param cmd Name of the command's function (e.g. "cv_units")
|
||||||
char const *get_command_full_help(char const *cmd);
|
char const *get_command_full_help(char const *cmd);
|
||||||
@ -263,6 +269,9 @@ private: // TODO
|
|||||||
/// Internal identifiers of command strings
|
/// Internal identifiers of command strings
|
||||||
std::map<std::string, command> cmd_str_map;
|
std::map<std::string, command> cmd_str_map;
|
||||||
|
|
||||||
|
/// Main command used in command line ("cv" by default)
|
||||||
|
std::string cmdline_main_cmd_;
|
||||||
|
|
||||||
/// Inverse of cmd_str_map (to be exported outside this class)
|
/// Inverse of cmd_str_map (to be exported outside this class)
|
||||||
char const **cmd_names;
|
char const **cmd_names;
|
||||||
|
|
||||||
|
|||||||
@ -8,9 +8,9 @@
|
|||||||
// Colvars repository at GitHub.
|
// Colvars repository at GitHub.
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdlib>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
#include "colvar.h"
|
||||||
|
#include "colvarbias.h"
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
#include "colvardeps.h"
|
#include "colvardeps.h"
|
||||||
#include "colvarscript.h"
|
#include "colvarscript.h"
|
||||||
|
|||||||
@ -47,14 +47,10 @@
|
|||||||
// If CVSCRIPT is not defined, this file yields the function prototypes
|
// If CVSCRIPT is not defined, this file yields the function prototypes
|
||||||
#ifndef CVSCRIPT
|
#ifndef CVSCRIPT
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#define CVSCRIPT_COMM_PROTO(COMM) \
|
#define CVSCRIPT_COMM_PROTO(COMM) \
|
||||||
extern "C" int CVSCRIPT_COMM_FNAME(COMM)(void *, \
|
extern "C" int CVSCRIPT_COMM_FNAME(COMM)(void *, \
|
||||||
int, unsigned char *const *);
|
int, \
|
||||||
#else
|
unsigned char *const *);
|
||||||
#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) \
|
#define CVSCRIPT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
|
||||||
CVSCRIPT_COMM_PROTO(COMM)
|
CVSCRIPT_COMM_PROTO(COMM)
|
||||||
@ -454,7 +450,8 @@ CVSCRIPT(cv_listcommands,
|
|||||||
)
|
)
|
||||||
|
|
||||||
CVSCRIPT(cv_listindexfiles,
|
CVSCRIPT(cv_listindexfiles,
|
||||||
"Get a list of the index files loaded in this session",
|
"Get a list of the index files loaded in this session\n"
|
||||||
|
"list : sequence of strings - List of index file names",
|
||||||
0, 0,
|
0, 0,
|
||||||
"",
|
"",
|
||||||
int const n_files = script->module()->index_file_names.size();
|
int const n_files = script->module()->index_file_names.size();
|
||||||
@ -467,19 +464,36 @@ CVSCRIPT(cv_listindexfiles,
|
|||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CVSCRIPT(cv_listinputfiles,
|
||||||
|
"Get a list of all input/configuration files loaded in this session\n"
|
||||||
|
"list : sequence of strings - List of file names",
|
||||||
|
0, 0,
|
||||||
|
"",
|
||||||
|
std::list<std::string> const l =
|
||||||
|
script->proxy()->list_input_stream_names();
|
||||||
|
std::string result;
|
||||||
|
for (std::list<std::string>::const_iterator li = l.begin();
|
||||||
|
li != l.end(); li++) {
|
||||||
|
if (li != l.begin()) result.append(1, ' ');
|
||||||
|
result.append(*li);
|
||||||
|
}
|
||||||
|
script->set_result_str(result);
|
||||||
|
return COLVARS_OK;
|
||||||
|
)
|
||||||
|
|
||||||
CVSCRIPT(cv_load,
|
CVSCRIPT(cv_load,
|
||||||
"Load data from a state file into all matching colvars and biases",
|
"Load data from a state file into all matching colvars and biases",
|
||||||
1, 1,
|
1, 1,
|
||||||
"prefix : string - Path to existing state file or input prefix",
|
"prefix : string - Path to existing state file or input prefix",
|
||||||
char const *arg =
|
char const *arg =
|
||||||
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
|
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
|
||||||
script->proxy()->input_prefix() = cvm::state_file_prefix(arg);
|
int error_code =
|
||||||
if (script->module()->setup_input() == COLVARS_OK) {
|
script->proxy()->set_input_prefix(cvm::state_file_prefix(arg));
|
||||||
return COLVARS_OK;
|
error_code |= script->module()->setup_input();
|
||||||
} else {
|
if (error_code != COLVARS_OK) {
|
||||||
script->add_error_msg("Error loading state file");
|
script->add_error_msg("Error loading state file");
|
||||||
return COLVARSCRIPT_ERROR;
|
|
||||||
}
|
}
|
||||||
|
return error_code;
|
||||||
)
|
)
|
||||||
|
|
||||||
CVSCRIPT(cv_loadfromstring,
|
CVSCRIPT(cv_loadfromstring,
|
||||||
@ -488,7 +502,8 @@ CVSCRIPT(cv_loadfromstring,
|
|||||||
"buffer : string - String buffer containing the state information",
|
"buffer : string - String buffer containing the state information",
|
||||||
char const *arg =
|
char const *arg =
|
||||||
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
|
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
|
||||||
script->proxy()->input_buffer() = arg;
|
script->proxy()->input_stream_from_string("input state string",
|
||||||
|
std::string(arg));
|
||||||
if (script->module()->setup_input() == COLVARS_OK) {
|
if (script->module()->setup_input() == COLVARS_OK) {
|
||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
} else {
|
} else {
|
||||||
@ -560,8 +575,7 @@ CVSCRIPT(cv_save,
|
|||||||
"prefix : string - Output prefix with trailing \".colvars.state\" gets removed)",
|
"prefix : string - Output prefix with trailing \".colvars.state\" gets removed)",
|
||||||
std::string const prefix =
|
std::string const prefix =
|
||||||
cvm::state_file_prefix(script->obj_to_str(script->get_module_cmd_arg(0, objc, objv)));
|
cvm::state_file_prefix(script->obj_to_str(script->get_module_cmd_arg(0, objc, objv)));
|
||||||
script->proxy()->output_prefix() = prefix;
|
int error_code = script->proxy()->set_output_prefix(prefix);
|
||||||
int error_code = COLVARS_OK;
|
|
||||||
error_code |= script->module()->setup_output();
|
error_code |= script->module()->setup_output();
|
||||||
error_code |= script->module()->write_restart_file(prefix+
|
error_code |= script->module()->write_restart_file(prefix+
|
||||||
".colvars.state");
|
".colvars.state");
|
||||||
@ -578,10 +592,10 @@ CVSCRIPT(cv_savetostring,
|
|||||||
)
|
)
|
||||||
|
|
||||||
CVSCRIPT(cv_targettemperature,
|
CVSCRIPT(cv_targettemperature,
|
||||||
"Get/set target temperature, overriding what the MD engine provides\n"
|
"Get/set target temperature, overriding internally what the MD engine reports\n"
|
||||||
"T : float - Current target temperature in K",
|
"T : float - Current target temperature in K",
|
||||||
0, 1,
|
0, 1,
|
||||||
"T : float - New target temperature in K",
|
"T : float - New target temperature in K (internal use)",
|
||||||
char const *Targ =
|
char const *Targ =
|
||||||
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
|
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
|
||||||
if (Targ == NULL) {
|
if (Targ == NULL) {
|
||||||
@ -591,6 +605,20 @@ CVSCRIPT(cv_targettemperature,
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CVSCRIPT(cv_timestep,
|
||||||
|
"Get/set integration timestep, overriding internally what the MD engine reports\n"
|
||||||
|
"dt : float - Current integration timestep in MD engine units",
|
||||||
|
0, 1,
|
||||||
|
"dt : float - New integration timestep in MD engine units",
|
||||||
|
char const *arg =
|
||||||
|
script->obj_to_str(script->get_module_cmd_arg(0, objc, objv));
|
||||||
|
if (arg == NULL) {
|
||||||
|
return script->set_result_real(script->proxy()->dt());
|
||||||
|
} else {
|
||||||
|
return script->proxy()->set_integration_timestep(strtod(arg, NULL));
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
CVSCRIPT(cv_units,
|
CVSCRIPT(cv_units,
|
||||||
"Get or set the current Colvars unit system\n"
|
"Get or set the current Colvars unit system\n"
|
||||||
"units : string - The current unit system",
|
"units : string - The current unit system",
|
||||||
|
|||||||
@ -9,11 +9,9 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdlib>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
|
#include "colvarbias.h"
|
||||||
#include "colvardeps.h"
|
#include "colvardeps.h"
|
||||||
#include "colvarscript.h"
|
#include "colvarscript.h"
|
||||||
#include "colvarscript_commands.h"
|
#include "colvarscript_commands.h"
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
|
|
||||||
CVSCRIPT(bias_bin,
|
CVSCRIPT(bias_bin,
|
||||||
"Get the current grid bin index (1D ABF only for now)\n"
|
"Get the current grid bin index (flattened if more than 1d)\n"
|
||||||
"bin : integer - Bin index",
|
"bin : integer - Bin index",
|
||||||
0, 0,
|
0, 0,
|
||||||
"",
|
"",
|
||||||
@ -17,6 +17,8 @@ CVSCRIPT(bias_bin,
|
|||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/// This is deprecated in the context of mwABF; no other known uses
|
||||||
|
/// But removing it may break user scripts
|
||||||
CVSCRIPT(bias_bincount,
|
CVSCRIPT(bias_bincount,
|
||||||
"Get the number of samples at the given grid bin (1D ABF only for now)\n"
|
"Get the number of samples at the given grid bin (1D ABF only for now)\n"
|
||||||
"samples : integer - Number of samples",
|
"samples : integer - Number of samples",
|
||||||
@ -36,6 +38,25 @@ CVSCRIPT(bias_bincount,
|
|||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CVSCRIPT(bias_local_sample_count,
|
||||||
|
"Get the number of samples around the current bin"
|
||||||
|
"samples : integer - Number of samples",
|
||||||
|
0, 1,
|
||||||
|
"radius : integer - Sum over radius bins around current bin",
|
||||||
|
int radius = 0;
|
||||||
|
char const *arg =
|
||||||
|
script->obj_to_str(script->get_bias_cmd_arg(0, objc, objv));
|
||||||
|
if (arg) {
|
||||||
|
std::string const param(arg);
|
||||||
|
if (!(std::istringstream(param) >> radius)) {
|
||||||
|
script->add_error_msg("local_sample_count: error parsing radius");
|
||||||
|
return COLVARSCRIPT_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
script->set_result_str(cvm::to_str(this_bias->local_sample_count(radius)));
|
||||||
|
return COLVARS_OK;
|
||||||
|
)
|
||||||
|
|
||||||
CVSCRIPT(bias_binnum,
|
CVSCRIPT(bias_binnum,
|
||||||
"Get the total number of grid points of this bias (1D ABF only for now)\n"
|
"Get the total number of grid points of this bias (1D ABF only for now)\n"
|
||||||
"Bins : integer - Number of grid points",
|
"Bins : integer - Number of grid points",
|
||||||
|
|||||||
@ -11,8 +11,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
#include "colvar.h"
|
||||||
#include "colvarproxy.h"
|
#include "colvarproxy.h"
|
||||||
#include "colvardeps.h"
|
#include "colvardeps.h"
|
||||||
#include "colvarscript.h"
|
#include "colvarscript.h"
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
|
|
||||||
CVSCRIPT(colvar_addforce,
|
CVSCRIPT(colvar_addforce,
|
||||||
"Apply the given force onto this colvar and return the same\n"
|
"Apply the given force onto this colvar (no effects outside run)\n"
|
||||||
"force : float or array - Applied force; matches colvar dimensionality",
|
"force : float or array - Applied force; matches colvar dimensionality",
|
||||||
1, 1,
|
1, 1,
|
||||||
"force : float or array - Applied force; must match colvar dimensionality",
|
"force : float or array - Applied force; must match colvar dimensionality",
|
||||||
|
|||||||
@ -7,12 +7,10 @@
|
|||||||
// 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 <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvartypes.h"
|
#include "colvartypes.h"
|
||||||
#include "colvarparse.h"
|
#include "colvaratoms.h"
|
||||||
|
#include "colvar_rotation_derivative.h"
|
||||||
|
|
||||||
#ifdef COLVARS_LAMMPS
|
#ifdef COLVARS_LAMMPS
|
||||||
// Use open-source Jacobi implementation
|
// Use open-source Jacobi implementation
|
||||||
@ -204,14 +202,6 @@ cvm::quaternion::position_derivative_inner(cvm::rvector const &pos,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate the optimal rotation between two groups, and implement it
|
|
||||||
// as a quaternion. Uses the method documented in: Coutsias EA,
|
|
||||||
// Seok C, Dill KA. Using quaternions to calculate RMSD. J Comput
|
|
||||||
// Chem. 25(15):1849-57 (2004) DOI: 10.1002/jcc.20110 PubMed: 15376254
|
|
||||||
|
|
||||||
#ifdef COLVARS_LAMMPS
|
#ifdef COLVARS_LAMMPS
|
||||||
namespace {
|
namespace {
|
||||||
inline void *new_Jacobi_solver(int size) {
|
inline void *new_Jacobi_solver(int size) {
|
||||||
@ -226,7 +216,7 @@ namespace {
|
|||||||
int colvarmodule::rotation::init()
|
int colvarmodule::rotation::init()
|
||||||
{
|
{
|
||||||
b_debug_gradients = false;
|
b_debug_gradients = false;
|
||||||
lambda = 0.0;
|
// lambda = 0.0;
|
||||||
cvm::main()->cite_feature("Optimal rotation via flexible fitting");
|
cvm::main()->cite_feature("Optimal rotation via flexible fitting");
|
||||||
return COLVARS_OK;
|
return COLVARS_OK;
|
||||||
}
|
}
|
||||||
@ -300,6 +290,25 @@ void colvarmodule::rotation::build_correlation_matrix(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void colvarmodule::rotation::build_correlation_matrix(
|
||||||
|
std::vector<cvm::atom> const &pos1,
|
||||||
|
std::vector<cvm::atom_pos> const &pos2)
|
||||||
|
{
|
||||||
|
// build the correlation matrix
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < pos1.size(); i++) {
|
||||||
|
C.xx += pos1[i].pos.x * pos2[i].x;
|
||||||
|
C.xy += pos1[i].pos.x * pos2[i].y;
|
||||||
|
C.xz += pos1[i].pos.x * pos2[i].z;
|
||||||
|
C.yx += pos1[i].pos.y * pos2[i].x;
|
||||||
|
C.yy += pos1[i].pos.y * pos2[i].y;
|
||||||
|
C.yz += pos1[i].pos.y * pos2[i].z;
|
||||||
|
C.zx += pos1[i].pos.z * pos2[i].x;
|
||||||
|
C.zy += pos1[i].pos.z * pos2[i].y;
|
||||||
|
C.zz += pos1[i].pos.z * pos2[i].z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void colvarmodule::rotation::compute_overlap_matrix()
|
void colvarmodule::rotation::compute_overlap_matrix()
|
||||||
{
|
{
|
||||||
@ -325,28 +334,26 @@ void colvarmodule::rotation::compute_overlap_matrix()
|
|||||||
|
|
||||||
|
|
||||||
#ifndef COLVARS_LAMMPS
|
#ifndef COLVARS_LAMMPS
|
||||||
namespace {
|
namespace NR {
|
||||||
|
|
||||||
void diagonalize_matrix(cvm::matrix2d<cvm::real> &m,
|
void diagonalize_matrix(cvm::real m[4][4],
|
||||||
cvm::vector1d<cvm::real> &eigval,
|
cvm::real eigval[4],
|
||||||
cvm::matrix2d<cvm::real> &eigvec)
|
cvm::real eigvec[4][4])
|
||||||
{
|
{
|
||||||
eigval.resize(4);
|
std::memset(eigval, 0, sizeof(cvm::real) * 4);
|
||||||
eigval.reset();
|
std::memset(eigvec, 0, sizeof(cvm::real) * 4 * 4);
|
||||||
eigvec.resize(4, 4);
|
|
||||||
eigvec.reset();
|
|
||||||
|
|
||||||
// diagonalize
|
// diagonalize
|
||||||
int jac_nrot = 0;
|
int jac_nrot = 0;
|
||||||
if (NR_Jacobi::jacobi(m.c_array(), eigval.c_array(), eigvec.c_array(), &jac_nrot) !=
|
if (NR_Jacobi::jacobi(m, eigval, eigvec, &jac_nrot) !=
|
||||||
COLVARS_OK) {
|
COLVARS_OK) {
|
||||||
cvm::error("Too many iterations in jacobi diagonalization.\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");
|
||||||
}
|
}
|
||||||
NR_Jacobi::eigsrt(eigval.c_array(), eigvec.c_array());
|
NR_Jacobi::eigsrt(eigval, eigvec);
|
||||||
// jacobi saves eigenvectors by columns
|
// jacobi saves eigenvectors by columns
|
||||||
NR_Jacobi::transpose(eigvec.c_array());
|
NR_Jacobi::transpose(eigvec);
|
||||||
|
|
||||||
// normalize eigenvectors
|
// normalize eigenvectors
|
||||||
for (size_t ie = 0; ie < 4; ie++) {
|
for (size_t ie = 0; ie < 4; ie++) {
|
||||||
@ -375,27 +382,51 @@ void colvarmodule::rotation::calc_optimal_rotation(
|
|||||||
C.reset();
|
C.reset();
|
||||||
build_correlation_matrix(pos1, pos2);
|
build_correlation_matrix(pos1, pos2);
|
||||||
|
|
||||||
S.resize(4, 4);
|
calc_optimal_rotation_impl();
|
||||||
S.reset();
|
|
||||||
|
if (b_debug_gradients) debug_gradients<cvm::atom_pos, cvm::atom_pos>(*this, pos1, pos2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void colvarmodule::rotation::calc_optimal_rotation(
|
||||||
|
std::vector<cvm::atom> const &pos1,
|
||||||
|
std::vector<cvm::atom_pos> const &pos2)
|
||||||
|
{
|
||||||
|
C.reset();
|
||||||
|
build_correlation_matrix(pos1, pos2);
|
||||||
|
|
||||||
|
calc_optimal_rotation_impl();
|
||||||
|
|
||||||
|
if (b_debug_gradients) debug_gradients<cvm::atom, cvm::atom_pos>(*this, pos1, pos2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the optimal rotation between two groups, and implement it
|
||||||
|
// as a quaternion. Uses the method documented in: Coutsias EA,
|
||||||
|
// Seok C, Dill KA. Using quaternions to calculate RMSD. J Comput
|
||||||
|
// Chem. 25(15):1849-57 (2004) DOI: 10.1002/jcc.20110 PubMed: 15376254
|
||||||
|
void colvarmodule::rotation::calc_optimal_rotation_impl() {
|
||||||
compute_overlap_matrix();
|
compute_overlap_matrix();
|
||||||
|
|
||||||
S_backup.resize(4, 4);
|
// S_backup = S;
|
||||||
S_backup = S;
|
std::memcpy(&S_backup[0][0], &S, 4*4*sizeof(cvm::real));
|
||||||
|
|
||||||
if (b_debug_gradients) {
|
if (b_debug_gradients) {
|
||||||
cvm::log("S = "+cvm::to_str(S_backup, cvm::cv_width, cvm::cv_prec)+"\n");
|
cvm::matrix2d<cvm::real> S_backup_out(4, 4);
|
||||||
|
for (size_t i = 0; i < 4; ++i) {
|
||||||
|
for (size_t j = 0; j < 4; ++j) {
|
||||||
|
S_backup_out[i][j] = S_backup[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cvm::log("S = "+cvm::to_str(S_backup_out, cvm::cv_width, cvm::cv_prec)+"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
S_eigval.resize(4);
|
|
||||||
S_eigvec.resize(4, 4);
|
|
||||||
|
|
||||||
#ifdef COLVARS_LAMMPS
|
#ifdef COLVARS_LAMMPS
|
||||||
MathEigen::Jacobi<cvm::real,
|
MathEigen::Jacobi<cvm::real,
|
||||||
cvm::vector1d<cvm::real> &,
|
cvm::real[4],
|
||||||
cvm::matrix2d<cvm::real> &> *ecalc =
|
cvm::real[4][4]> *ecalc =
|
||||||
reinterpret_cast<MathEigen::Jacobi<cvm::real,
|
reinterpret_cast<MathEigen::Jacobi<cvm::real,
|
||||||
cvm::vector1d<cvm::real> &,
|
cvm::real[4],
|
||||||
cvm::matrix2d<cvm::real> &> *>(jacobi);
|
cvm::real[4][4]> *>(jacobi);
|
||||||
|
|
||||||
int ierror = ecalc->Diagonalize(S, S_eigval, S_eigvec);
|
int ierror = ecalc->Diagonalize(S, S_eigval, S_eigvec);
|
||||||
if (ierror) {
|
if (ierror) {
|
||||||
@ -404,22 +435,9 @@ void colvarmodule::rotation::calc_optimal_rotation(
|
|||||||
"rotational alignment (RMSD, rotateReference, etc).\n");
|
"rotational alignment (RMSD, rotateReference, etc).\n");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
diagonalize_matrix(S, S_eigval, S_eigvec);
|
NR::diagonalize_matrix(S, S_eigval, S_eigvec);
|
||||||
#endif
|
#endif
|
||||||
|
q = cvm::quaternion{S_eigvec[0][0], S_eigvec[0][1], S_eigvec[0][2], S_eigvec[0][3]};
|
||||||
|
|
||||||
// eigenvalues and eigenvectors
|
|
||||||
cvm::real const L0 = S_eigval[0];
|
|
||||||
cvm::real const L1 = S_eigval[1];
|
|
||||||
cvm::real const L2 = S_eigval[2];
|
|
||||||
cvm::real const L3 = S_eigval[3];
|
|
||||||
cvm::quaternion const Q0(S_eigvec[0]);
|
|
||||||
cvm::quaternion const Q1(S_eigvec[1]);
|
|
||||||
cvm::quaternion const Q2(S_eigvec[2]);
|
|
||||||
cvm::quaternion const Q3(S_eigvec[3]);
|
|
||||||
|
|
||||||
lambda = L0;
|
|
||||||
q = Q0;
|
|
||||||
|
|
||||||
if (cvm::rotation::monitor_crossings) {
|
if (cvm::rotation::monitor_crossings) {
|
||||||
if (q_old.norm2() > 0.0) {
|
if (q_old.norm2() > 0.0) {
|
||||||
@ -431,178 +449,4 @@ void colvarmodule::rotation::calc_optimal_rotation(
|
|||||||
}
|
}
|
||||||
q_old = q;
|
q_old = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b_debug_gradients) {
|
|
||||||
cvm::log("L0 = "+cvm::to_str(L0, cvm::cv_width, cvm::cv_prec)+
|
|
||||||
", Q0 = "+cvm::to_str(Q0, cvm::cv_width, cvm::cv_prec)+
|
|
||||||
", Q0*Q0 = "+cvm::to_str(Q0.inner(Q0), cvm::cv_width, cvm::cv_prec)+
|
|
||||||
"\n");
|
|
||||||
cvm::log("L1 = "+cvm::to_str(L1, cvm::cv_width, cvm::cv_prec)+
|
|
||||||
", Q1 = "+cvm::to_str(Q1, cvm::cv_width, cvm::cv_prec)+
|
|
||||||
", Q0*Q1 = "+cvm::to_str(Q0.inner(Q1), cvm::cv_width, cvm::cv_prec)+
|
|
||||||
"\n");
|
|
||||||
cvm::log("L2 = "+cvm::to_str(L2, cvm::cv_width, cvm::cv_prec)+
|
|
||||||
", Q2 = "+cvm::to_str(Q2, cvm::cv_width, cvm::cv_prec)+
|
|
||||||
", Q0*Q2 = "+cvm::to_str(Q0.inner(Q2), cvm::cv_width, cvm::cv_prec)+
|
|
||||||
"\n");
|
|
||||||
cvm::log("L3 = "+cvm::to_str(L3, cvm::cv_width, cvm::cv_prec)+
|
|
||||||
", Q3 = "+cvm::to_str(Q3, cvm::cv_width, cvm::cv_prec)+
|
|
||||||
", Q0*Q3 = "+cvm::to_str(Q0.inner(Q3), cvm::cv_width, cvm::cv_prec)+
|
|
||||||
"\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate derivatives of L0 and Q0 with respect to each atom in
|
|
||||||
// either group; note: if dS_1 is a null vector, nothing will be
|
|
||||||
// calculated
|
|
||||||
size_t ia;
|
|
||||||
for (ia = 0; ia < dS_1.size(); ia++) {
|
|
||||||
|
|
||||||
cvm::real const &a2x = pos2[ia].x;
|
|
||||||
cvm::real const &a2y = pos2[ia].y;
|
|
||||||
cvm::real const &a2z = pos2[ia].z;
|
|
||||||
|
|
||||||
cvm::matrix2d<cvm::rvector> &ds_1 = dS_1[ia];
|
|
||||||
|
|
||||||
// derivative of the S matrix
|
|
||||||
ds_1.reset();
|
|
||||||
ds_1[0][0].set( a2x, a2y, a2z);
|
|
||||||
ds_1[1][0].set( 0.0, a2z, -a2y);
|
|
||||||
ds_1[0][1] = ds_1[1][0];
|
|
||||||
ds_1[2][0].set(-a2z, 0.0, a2x);
|
|
||||||
ds_1[0][2] = ds_1[2][0];
|
|
||||||
ds_1[3][0].set( a2y, -a2x, 0.0);
|
|
||||||
ds_1[0][3] = ds_1[3][0];
|
|
||||||
ds_1[1][1].set( a2x, -a2y, -a2z);
|
|
||||||
ds_1[2][1].set( a2y, a2x, 0.0);
|
|
||||||
ds_1[1][2] = ds_1[2][1];
|
|
||||||
ds_1[3][1].set( a2z, 0.0, a2x);
|
|
||||||
ds_1[1][3] = ds_1[3][1];
|
|
||||||
ds_1[2][2].set(-a2x, a2y, -a2z);
|
|
||||||
ds_1[3][2].set( 0.0, a2z, a2y);
|
|
||||||
ds_1[2][3] = ds_1[3][2];
|
|
||||||
ds_1[3][3].set(-a2x, -a2y, a2z);
|
|
||||||
|
|
||||||
cvm::rvector &dl0_1 = dL0_1[ia];
|
|
||||||
cvm::vector1d<cvm::rvector> &dq0_1 = dQ0_1[ia];
|
|
||||||
|
|
||||||
// matrix multiplications; derivatives of L_0 and Q_0 are
|
|
||||||
// calculated using Hellmann-Feynman theorem (i.e. exploiting the
|
|
||||||
// fact that the eigenvectors Q_i form an orthonormal basis)
|
|
||||||
|
|
||||||
dl0_1.reset();
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
|
||||||
for (size_t j = 0; j < 4; j++) {
|
|
||||||
dl0_1 += Q0[i] * ds_1[i][j] * Q0[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dq0_1.reset();
|
|
||||||
for (size_t p = 0; p < 4; p++) {
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
|
||||||
for (size_t j = 0; j < 4; j++) {
|
|
||||||
dq0_1[p] +=
|
|
||||||
(Q1[i] * ds_1[i][j] * Q0[j]) / (L0-L1) * Q1[p] +
|
|
||||||
(Q2[i] * ds_1[i][j] * Q0[j]) / (L0-L2) * Q2[p] +
|
|
||||||
(Q3[i] * ds_1[i][j] * Q0[j]) / (L0-L3) * Q3[p];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// do the same for the second group
|
|
||||||
for (ia = 0; ia < dS_2.size(); ia++) {
|
|
||||||
|
|
||||||
cvm::real const &a1x = pos1[ia].x;
|
|
||||||
cvm::real const &a1y = pos1[ia].y;
|
|
||||||
cvm::real const &a1z = pos1[ia].z;
|
|
||||||
|
|
||||||
cvm::matrix2d<cvm::rvector> &ds_2 = dS_2[ia];
|
|
||||||
|
|
||||||
ds_2.reset();
|
|
||||||
ds_2[0][0].set( a1x, a1y, a1z);
|
|
||||||
ds_2[1][0].set( 0.0, -a1z, a1y);
|
|
||||||
ds_2[0][1] = ds_2[1][0];
|
|
||||||
ds_2[2][0].set( a1z, 0.0, -a1x);
|
|
||||||
ds_2[0][2] = ds_2[2][0];
|
|
||||||
ds_2[3][0].set(-a1y, a1x, 0.0);
|
|
||||||
ds_2[0][3] = ds_2[3][0];
|
|
||||||
ds_2[1][1].set( a1x, -a1y, -a1z);
|
|
||||||
ds_2[2][1].set( a1y, a1x, 0.0);
|
|
||||||
ds_2[1][2] = ds_2[2][1];
|
|
||||||
ds_2[3][1].set( a1z, 0.0, a1x);
|
|
||||||
ds_2[1][3] = ds_2[3][1];
|
|
||||||
ds_2[2][2].set(-a1x, a1y, -a1z);
|
|
||||||
ds_2[3][2].set( 0.0, a1z, a1y);
|
|
||||||
ds_2[2][3] = ds_2[3][2];
|
|
||||||
ds_2[3][3].set(-a1x, -a1y, a1z);
|
|
||||||
|
|
||||||
cvm::rvector &dl0_2 = dL0_2[ia];
|
|
||||||
cvm::vector1d<cvm::rvector> &dq0_2 = dQ0_2[ia];
|
|
||||||
|
|
||||||
dl0_2.reset();
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
|
||||||
for (size_t j = 0; j < 4; j++) {
|
|
||||||
dl0_2 += Q0[i] * ds_2[i][j] * Q0[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dq0_2.reset();
|
|
||||||
for (size_t p = 0; p < 4; p++) {
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
|
||||||
for (size_t j = 0; j < 4; j++) {
|
|
||||||
dq0_2[p] +=
|
|
||||||
(Q1[i] * ds_2[i][j] * Q0[j]) / (L0-L1) * Q1[p] +
|
|
||||||
(Q2[i] * ds_2[i][j] * Q0[j]) / (L0-L2) * Q2[p] +
|
|
||||||
(Q3[i] * ds_2[i][j] * Q0[j]) / (L0-L3) * Q3[p];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b_debug_gradients) {
|
|
||||||
|
|
||||||
cvm::matrix2d<cvm::real> S_new(4, 4);
|
|
||||||
cvm::vector1d<cvm::real> S_new_eigval(4);
|
|
||||||
cvm::matrix2d<cvm::real> S_new_eigvec(4, 4);
|
|
||||||
|
|
||||||
// make an infitesimal move along each cartesian coordinate of
|
|
||||||
// this atom, and solve again the eigenvector problem
|
|
||||||
for (size_t comp = 0; comp < 3; comp++) {
|
|
||||||
|
|
||||||
S_new = S_backup;
|
|
||||||
// diagonalize the new overlap matrix
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
|
||||||
for (size_t j = 0; j < 4; j++) {
|
|
||||||
S_new[i][j] +=
|
|
||||||
colvarmodule::debug_gradients_step_size * ds_2[i][j][comp];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cvm::real const &L0_new = S_new_eigval[0];
|
|
||||||
cvm::quaternion const Q0_new(S_new_eigvec[0]);
|
|
||||||
|
|
||||||
cvm::real const DL0 = (dl0_2[comp]) * colvarmodule::debug_gradients_step_size;
|
|
||||||
cvm::quaternion const DQ0(dq0_2[0][comp] * colvarmodule::debug_gradients_step_size,
|
|
||||||
dq0_2[1][comp] * colvarmodule::debug_gradients_step_size,
|
|
||||||
dq0_2[2][comp] * colvarmodule::debug_gradients_step_size,
|
|
||||||
dq0_2[3][comp] * colvarmodule::debug_gradients_step_size);
|
|
||||||
|
|
||||||
cvm::log( "|(l_0+dl_0) - l_0^new|/l_0 = "+
|
|
||||||
cvm::to_str(cvm::fabs(L0+DL0 - L0_new)/L0, cvm::cv_width, cvm::cv_prec)+
|
|
||||||
", |(q_0+dq_0) - q_0^new| = "+
|
|
||||||
cvm::to_str((Q0+DQ0 - Q0_new).norm(), cvm::cv_width, cvm::cv_prec)+
|
|
||||||
"\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -10,8 +10,14 @@
|
|||||||
#ifndef COLVARTYPES_H
|
#ifndef COLVARTYPES_H
|
||||||
#define COLVARTYPES_H
|
#define COLVARTYPES_H
|
||||||
|
|
||||||
|
#include <sstream> // TODO specialize templates and replace this with iosfwd
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef COLVARS_LAMMPS
|
||||||
|
// Use open-source Jacobi implementation
|
||||||
|
#include "math_eigen_impl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
|
|
||||||
#ifndef PI
|
#ifndef PI
|
||||||
@ -53,6 +59,12 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Explicit Copy constructor
|
||||||
|
inline vector1d(const vector1d&) = default;
|
||||||
|
|
||||||
|
/// Explicit Copy assignement
|
||||||
|
inline vector1d& operator=(const vector1d&) = default;
|
||||||
|
|
||||||
/// Return a pointer to the data location
|
/// Return a pointer to the data location
|
||||||
inline T * c_array()
|
inline T * c_array()
|
||||||
{
|
{
|
||||||
@ -69,6 +81,12 @@ public:
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a reference to the data
|
||||||
|
inline std::vector<T> const &data_array() const
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
inline ~vector1d()
|
inline ~vector1d()
|
||||||
{
|
{
|
||||||
data.clear();
|
data.clear();
|
||||||
@ -493,6 +511,12 @@ public:
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a reference to the data
|
||||||
|
inline std::vector<T> const &data_array() const
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
inline row & operator [] (size_t const i)
|
inline row & operator [] (size_t const i)
|
||||||
{
|
{
|
||||||
return rows[i];
|
return rows[i];
|
||||||
@ -896,9 +920,6 @@ public:
|
|||||||
zz = zzi;
|
zz = zzi;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructor
|
|
||||||
inline ~rmatrix()
|
|
||||||
{}
|
|
||||||
|
|
||||||
inline void reset()
|
inline void reset()
|
||||||
{
|
{
|
||||||
@ -1278,59 +1299,50 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef COLVARS_LAMMPS
|
||||||
|
namespace NR {
|
||||||
|
void diagonalize_matrix(cvm::real m[4][4],
|
||||||
|
cvm::real eigval[4],
|
||||||
|
cvm::real eigvec[4][4]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/// \brief A rotation between two sets of coordinates (for the moment
|
/// \brief A rotation between two sets of coordinates (for the moment
|
||||||
/// a wrapper for colvarmodule::quaternion)
|
/// a wrapper for colvarmodule::quaternion)
|
||||||
class colvarmodule::rotation
|
class colvarmodule::rotation
|
||||||
{
|
{
|
||||||
public:
|
private:
|
||||||
|
|
||||||
/// \brief The rotation itself (implemented as a quaternion)
|
|
||||||
cvm::quaternion q;
|
|
||||||
|
|
||||||
/// \brief Eigenvalue corresponding to the optimal rotation
|
|
||||||
cvm::real lambda;
|
|
||||||
|
|
||||||
/// \brief Perform gradient tests
|
|
||||||
bool b_debug_gradients;
|
|
||||||
|
|
||||||
/// Correlation matrix C (3, 3)
|
/// Correlation matrix C (3, 3)
|
||||||
cvm::rmatrix C;
|
cvm::rmatrix C;
|
||||||
|
|
||||||
/// Overlap matrix S (4, 4)
|
/// Overlap matrix S (4, 4)
|
||||||
cvm::matrix2d<cvm::real> S;
|
cvm::real S[4][4];
|
||||||
|
|
||||||
/// Eigenvalues of S
|
/// Eigenvalues of S
|
||||||
cvm::vector1d<cvm::real> S_eigval;
|
cvm::real S_eigval[4];
|
||||||
|
|
||||||
/// Eigenvectors of S
|
/// Eigenvectors of S
|
||||||
cvm::matrix2d<cvm::real> S_eigvec;
|
cvm::real S_eigvec[4][4];
|
||||||
|
|
||||||
/// Used for debugging gradients
|
/// Used for debugging gradients
|
||||||
cvm::matrix2d<cvm::real> S_backup;
|
cvm::real S_backup[4][4];
|
||||||
|
|
||||||
/// Derivatives of S
|
public:
|
||||||
std::vector< cvm::matrix2d<cvm::rvector> > dS_1, dS_2;
|
/// \brief Perform gradient tests
|
||||||
/// Derivatives of leading eigenvalue
|
bool b_debug_gradients;
|
||||||
std::vector< cvm::rvector > dL0_1, dL0_2;
|
|
||||||
/// Derivatives of leading eigenvector
|
|
||||||
std::vector< cvm::vector1d<cvm::rvector> > dQ0_1, dQ0_2;
|
|
||||||
|
|
||||||
/// Allocate space for the derivatives of the rotation
|
/// \brief The rotation itself (implemented as a quaternion)
|
||||||
inline void request_group1_gradients(size_t n)
|
cvm::quaternion q;
|
||||||
{
|
|
||||||
dS_1.resize(n, cvm::matrix2d<cvm::rvector>(4, 4));
|
|
||||||
dL0_1.resize(n, cvm::rvector(0.0, 0.0, 0.0));
|
|
||||||
dQ0_1.resize(n, cvm::vector1d<cvm::rvector>(4));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Allocate space for the derivatives of the rotation
|
template <typename T1, typename T2>
|
||||||
inline void request_group2_gradients(size_t n)
|
friend struct rotation_derivative;
|
||||||
{
|
|
||||||
dS_2.resize(n, cvm::matrix2d<cvm::rvector>(4, 4));
|
template<typename T1, typename T2>
|
||||||
dL0_2.resize(n, cvm::rvector(0.0, 0.0, 0.0));
|
friend void debug_gradients(
|
||||||
dQ0_2.resize(n, cvm::vector1d<cvm::rvector>(4));
|
cvm::rotation &rot,
|
||||||
}
|
const std::vector<T1> &pos1,
|
||||||
|
const std::vector<T2> &pos2);
|
||||||
|
|
||||||
/// \brief Calculate the optimal rotation and store the
|
/// \brief Calculate the optimal rotation and store the
|
||||||
/// corresponding eigenvalue and eigenvector in the arguments l0 and
|
/// corresponding eigenvalue and eigenvector in the arguments l0 and
|
||||||
@ -1344,6 +1356,8 @@ public:
|
|||||||
/// DOI: 10.1002/jcc.20110 PubMed: 15376254
|
/// DOI: 10.1002/jcc.20110 PubMed: 15376254
|
||||||
void calc_optimal_rotation(std::vector<atom_pos> const &pos1,
|
void calc_optimal_rotation(std::vector<atom_pos> const &pos1,
|
||||||
std::vector<atom_pos> const &pos2);
|
std::vector<atom_pos> const &pos2);
|
||||||
|
void calc_optimal_rotation(std::vector<cvm::atom> const &pos1,
|
||||||
|
std::vector<atom_pos> const &pos2);
|
||||||
|
|
||||||
/// Initialize member data
|
/// Initialize member data
|
||||||
int init();
|
int init();
|
||||||
@ -1478,6 +1492,11 @@ protected:
|
|||||||
/// Build the correlation matrix C (used by calc_optimal_rotation())
|
/// Build the correlation matrix C (used by calc_optimal_rotation())
|
||||||
void build_correlation_matrix(std::vector<cvm::atom_pos> const &pos1,
|
void build_correlation_matrix(std::vector<cvm::atom_pos> const &pos1,
|
||||||
std::vector<cvm::atom_pos> const &pos2);
|
std::vector<cvm::atom_pos> const &pos2);
|
||||||
|
void build_correlation_matrix(std::vector<cvm::atom> const &pos1,
|
||||||
|
std::vector<cvm::atom_pos> const &pos2);
|
||||||
|
|
||||||
|
/// \brief Actual implementation of `calc_optimal_rotation` (and called by it)
|
||||||
|
void calc_optimal_rotation_impl();
|
||||||
|
|
||||||
/// 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();
|
||||||
|
|||||||
@ -8,11 +8,10 @@
|
|||||||
// Colvars repository at GitHub.
|
// Colvars repository at GitHub.
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvarvalue.h"
|
#include "colvarvalue.h"
|
||||||
|
#include "colvars_memstream.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -721,29 +720,43 @@ int colvarvalue::from_simple_string(std::string const &s)
|
|||||||
return COLVARS_ERROR;
|
return COLVARS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream &os, colvarvalue const &x)
|
|
||||||
|
template <typename OST> void colvarvalue::write_to_stream_template_(OST &os) const
|
||||||
{
|
{
|
||||||
switch (x.type()) {
|
switch (type()) {
|
||||||
case colvarvalue::type_scalar:
|
case colvarvalue::type_scalar:
|
||||||
os << x.real_value;
|
os << real_value;
|
||||||
break;
|
break;
|
||||||
case colvarvalue::type_3vector:
|
case colvarvalue::type_3vector:
|
||||||
case colvarvalue::type_unit3vector:
|
case colvarvalue::type_unit3vector:
|
||||||
case colvarvalue::type_unit3vectorderiv:
|
case colvarvalue::type_unit3vectorderiv:
|
||||||
os << x.rvector_value;
|
os << rvector_value;
|
||||||
break;
|
break;
|
||||||
case colvarvalue::type_quaternion:
|
case colvarvalue::type_quaternion:
|
||||||
case colvarvalue::type_quaternionderiv:
|
case colvarvalue::type_quaternionderiv:
|
||||||
os << x.quaternion_value;
|
os << quaternion_value;
|
||||||
break;
|
break;
|
||||||
case colvarvalue::type_vector:
|
case colvarvalue::type_vector:
|
||||||
os << x.vector1d_value;
|
os << vector1d_value;
|
||||||
break;
|
break;
|
||||||
case colvarvalue::type_notset:
|
case colvarvalue::type_notset:
|
||||||
default:
|
default:
|
||||||
os << "not set";
|
os << "not set";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream & operator << (std::ostream &os, colvarvalue const &x)
|
||||||
|
{
|
||||||
|
x.write_to_stream_template_<std::ostream>(os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream & operator << (cvm::memory_stream &os, colvarvalue const &x)
|
||||||
|
{
|
||||||
|
x.write_to_stream_template_<cvm::memory_stream>(os);
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -758,44 +771,55 @@ std::ostream & operator << (std::ostream &os, std::vector<colvarvalue> const &v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::istream & operator >> (std::istream &is, colvarvalue &x)
|
template <typename IST> void colvarvalue::read_from_stream_template_(IST &is)
|
||||||
{
|
{
|
||||||
if (x.type() == colvarvalue::type_notset) {
|
if (type() == colvarvalue::type_notset) {
|
||||||
cvm::error("Trying to read from a stream a colvarvalue, "
|
cvm::error("Trying to read from a stream a colvarvalue, "
|
||||||
"which has not yet been assigned a data type.\n");
|
"which has not yet been assigned a data type.\n");
|
||||||
return is;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (x.type()) {
|
switch (type()) {
|
||||||
case colvarvalue::type_scalar:
|
case colvarvalue::type_scalar:
|
||||||
is >> x.real_value;
|
is >> real_value;
|
||||||
break;
|
break;
|
||||||
case colvarvalue::type_3vector:
|
case colvarvalue::type_3vector:
|
||||||
case colvarvalue::type_unit3vectorderiv:
|
case colvarvalue::type_unit3vectorderiv:
|
||||||
is >> x.rvector_value;
|
is >> rvector_value;
|
||||||
break;
|
break;
|
||||||
case colvarvalue::type_unit3vector:
|
case colvarvalue::type_unit3vector:
|
||||||
is >> x.rvector_value;
|
is >> rvector_value;
|
||||||
x.apply_constraints();
|
apply_constraints();
|
||||||
break;
|
break;
|
||||||
case colvarvalue::type_quaternion:
|
case colvarvalue::type_quaternion:
|
||||||
is >> x.quaternion_value;
|
is >> quaternion_value;
|
||||||
x.apply_constraints();
|
apply_constraints();
|
||||||
break;
|
break;
|
||||||
case colvarvalue::type_quaternionderiv:
|
case colvarvalue::type_quaternionderiv:
|
||||||
is >> x.quaternion_value;
|
is >> quaternion_value;
|
||||||
break;
|
break;
|
||||||
case colvarvalue::type_vector:
|
case colvarvalue::type_vector:
|
||||||
is >> x.vector1d_value;
|
is >> vector1d_value;
|
||||||
break;
|
break;
|
||||||
case colvarvalue::type_notset:
|
case colvarvalue::type_notset:
|
||||||
default:
|
default:
|
||||||
x.undef_op();
|
undef_op();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::istream & operator >> (std::istream &is, colvarvalue &x)
|
||||||
|
{
|
||||||
|
x.read_from_stream_template_<std::istream>(is);
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cvm::memory_stream & operator >> (cvm::memory_stream &is, colvarvalue &x)
|
||||||
|
{
|
||||||
|
x.read_from_stream_template_<cvm::memory_stream>(is);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
size_t colvarvalue::output_width(size_t const &real_width) const
|
size_t colvarvalue::output_width(size_t const &real_width) const
|
||||||
{
|
{
|
||||||
switch (this->value_type) {
|
switch (this->value_type) {
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
#ifndef COLVARVALUE_H
|
#ifndef COLVARVALUE_H
|
||||||
#define COLVARVALUE_H
|
#define COLVARVALUE_H
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "colvarmodule.h"
|
#include "colvarmodule.h"
|
||||||
#include "colvartypes.h"
|
#include "colvartypes.h"
|
||||||
|
|
||||||
@ -120,7 +122,8 @@ public:
|
|||||||
/// number and always behaves like it unless you change its type
|
/// number and always behaves like it unless you change its type
|
||||||
colvarvalue();
|
colvarvalue();
|
||||||
|
|
||||||
/// Constructor from a type specification
|
/// Constructor from a type flag (note: type_vector also needs the vector length to be set)
|
||||||
|
/// \param[in] vti Value of the \link Type \endlink enum
|
||||||
colvarvalue(Type const &vti);
|
colvarvalue(Type const &vti);
|
||||||
|
|
||||||
/// Copy constructor from real base type
|
/// Copy constructor from real base type
|
||||||
@ -297,12 +300,31 @@ public:
|
|||||||
/// Undefined operation
|
/// Undefined operation
|
||||||
void undef_op() const;
|
void undef_op() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
/// \brief Formatted output operator
|
/// Generic stream writing function (formatted and not)
|
||||||
friend std::ostream & operator << (std::ostream &os, colvarvalue const &q);
|
template <typename OST> void write_to_stream_template_(OST &os) const;
|
||||||
|
|
||||||
/// \brief Formatted input operator
|
public:
|
||||||
friend std::istream & operator >> (std::istream &is, colvarvalue &q);
|
|
||||||
|
/// Formatted output operator
|
||||||
|
friend std::ostream & operator << (std::ostream &os, colvarvalue const &x);
|
||||||
|
|
||||||
|
/// Unformatted output operator
|
||||||
|
friend cvm::memory_stream & operator << (cvm::memory_stream &os, colvarvalue const &x);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// Generic stream reading function (formatted and not)
|
||||||
|
template <typename IST> void read_from_stream_template_(IST &is);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Formatted input operator
|
||||||
|
friend std::istream & operator >> (std::istream &is, colvarvalue &x);
|
||||||
|
|
||||||
|
/// Unformatted input operator
|
||||||
|
friend cvm::memory_stream & operator >> (cvm::memory_stream &is, colvarvalue &x);
|
||||||
|
|
||||||
/// Give the number of characters required to output this
|
/// Give the number of characters required to output this
|
||||||
/// colvarvalue, given the current type assigned and the number of
|
/// colvarvalue, given the current type assigned and the number of
|
||||||
|
|||||||
Reference in New Issue
Block a user