38 #include "colvarmodule.h" 40 #include "colvarbias.h" 41 #include "colvaratoms.h" 42 #include "colvarproxy.h" 44 #include "colvarscript.h" 49 engine_name_ =
"NAMD";
53 if ( 0 == CkMyPe() ) {
62 boltzmann_ = 0.001987191;
70 iout <<
"Info: initializing the colvars proxy object.\n" <<
endi;
77 colvarproxy_io::set_input_prefix(input_restart ? input_restart->
data :
"");
85 updated_masses_ = updated_charges_ =
true;
100 if ((!output_prefix_str.size()) && (!restart_output_prefix_str.size())) {
101 error(
"Error: neither the final output state file or " 102 "the output restart file could be defined, exiting.\n");
108 colvars =
new colvarmodule(
this);
110 cvm::log(
"Using NAMD interface, version "+
112 colvars->cite_feature(
"NAMD engine");
113 colvars->cite_feature(
"Colvars-NAMD interface");
116 for ( ; config; config = config->
next ) {
117 add_config(
"configfile", config->
data);
121 colvarproxy::parse_module_config();
123 colvars->update_engine_parameters();
124 colvars->setup_input();
125 colvars->setup_output();
133 have_scripts =
false;
142 #ifdef NODEGROUP_FORCE_REGISTER 143 CProxy_PatchData cpdata(CkpvAccess(BOCclass_group).patchData);
144 PatchData *patchData = cpdata.ckLocalBranch();
149 iout <<
"Info: done initializing the colvars proxy object.\n" <<
endi;
161 int error_code = COLVARS_OK;
175 error_code |= set_target_temperature(0.0);
200 for (
size_t i = 0; i < atoms_ids.size(); i++) {
201 if (atoms_ids[i] == *a_i) {
210 int const index = add_atom_slot(*a_i);
218 cvm::log(
"atoms_map = "+cvm::to_str(
atoms_map)+
".\n");
227 int error_code = colvarproxy::setup();
229 if (colvars->size() == 0) {
234 log(
"Updating NAMD interface:\n");
239 log(
"Warning: enabling wrapAll can lead to inconsistent results " 240 "for Colvars calculations: please disable wrapAll, " 241 "as is the default option in NAMD.\n");
244 log(
"updating atomic data ("+cvm::to_str(atoms_ids.size())+
" atoms).\n");
247 for (i = 0; i < atoms_ids.size(); i++) {
251 atoms_positions[i] = cvm::rvector(0.0, 0.0, 0.0);
252 atoms_total_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
253 atoms_new_colvar_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
256 size_t n_group_atoms = 0;
261 log(
"updating group data ("+cvm::to_str(atom_groups_ids.size())+
262 " scalable groups, "+
263 cvm::to_str(n_group_atoms)+
" atoms in total).\n");
271 atom_groups_coms[ig] = cvm::rvector(0.0, 0.0, 0.0);
272 atom_groups_total_forces[ig] = cvm::rvector(0.0, 0.0, 0.0);
273 atom_groups_new_colvar_forces[ig] = cvm::rvector(0.0, 0.0, 0.0);
276 #if NAMD_VERSION_NUMBER >= 34471681 277 log(
"updating grid object data ("+cvm::to_str(volmaps_ids.size())+
278 " grid objects in total).\n");
280 volmaps_new_colvar_forces[imap] = 0.0;
284 size_t const new_features_hash =
285 std::hash<std::string>{}(colvars->feature_report(0));
286 if (new_features_hash != features_hash) {
288 log(std::string(
"\n")+colvars->feature_report(0)+std::string(
"\n"));
289 features_hash = new_features_hash;
293 log(
"updating target temperature (T = "+
294 cvm::to_str(target_temperature())+
" K).\n");
307 cvm::log(
"colvarproxy_namd::reset()\n");
310 int error_code = COLVARS_OK;
320 #if NAMD_VERSION_NUMBER >= 34471681 330 error_code |= colvarproxy::reset();
345 colvars->update_engine_parameters();
346 colvars->setup_input();
347 colvars->setup_output();
356 b_simulation_continuing =
false;
364 b_simulation_continuing =
true;
370 colvars->setup_output();
382 unit_cell_x.
set(a.
x, a.
y, a.
z);
383 unit_cell_y.set(b.
x, b.
y, c.
z);
384 unit_cell_z.set(c.
x, c.
y, c.
z);
388 boundaries_type = boundaries_non_periodic;
392 boundaries_type = boundaries_pbc_ortho;
394 boundaries_type = boundaries_pbc_triclinic;
396 colvarproxy_system::update_pbc_lattice();
398 boundaries_type = boundaries_unsupported;
402 cvm::log(std::string(cvm::line_marker)+
403 "colvarproxy_namd, step no. "+cvm::to_str(colvars->it)+
"\n"+
404 "Updating atomic data arrays.\n");
416 if ( (
atoms_map.size() != n_all_atoms) ||
424 for (
size_t i = 0; i < atoms_ids.size(); i++) {
425 atoms_positions[i] = cvm::rvector(0.0, 0.0, 0.0);
426 atoms_total_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
427 atoms_new_colvar_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
430 for (
size_t i = 0; i < atom_groups_ids.size(); i++) {
431 atom_groups_total_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
432 atom_groups_new_colvar_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
435 #if NAMD_VERSION_NUMBER >= 34471681 436 for (
int imap = 0; imap < volmaps_ids.size(); imap++) {
437 volmaps_new_colvar_forces[imap] = 0.0;
443 cvm::log(
"Updating positions arrays.\n");
445 size_t n_positions = 0;
450 for ( ; a_i != a_e; ++a_i, ++p_i ) {
451 atoms_positions[
atoms_map[*a_i]] = cvm::rvector((*p_i).x, (*p_i).y, (*p_i).z);
461 if (total_force_requested && cvm::step_relative() > 0) {
468 cvm::log(
"Updating total forces arrays.\n");
470 size_t n_total_forces = 0;
475 for ( ; a_i != a_e; ++a_i, ++f_i ) {
476 atoms_total_forces[
atoms_map[*a_i]] = cvm::rvector((*f_i).x, (*f_i).y, (*f_i).z);
480 if ( (! b_simulation_continuing) &&
481 (n_total_forces < atoms_ids.size()) ) {
482 cvm::error(
"Error: total forces were requested, but total forces " 483 "were not received for all atoms.\n" 484 "The most probable cause is combination of energy " 485 "minimization with a biasing method that requires MD (e.g. ABF).\n" 486 "Always run minimization and ABF separately.", COLVARS_INPUT_ERROR);
492 cvm::log(
"Updating group total forces arrays.\n");
497 if ( (! b_simulation_continuing) &&
498 ((f_e - f_i) != ((
int) atom_groups_ids.size())) ) {
499 cvm::error(
"Error: total forces were requested for scalable groups, " 500 "but they are not in the same number from the number of groups.\n" 501 "The most probable cause is combination of energy " 502 "minimization with a biasing method that requires MD (e.g. ABF).\n" 503 "Always run minimization and ABF separately.", COLVARS_INPUT_ERROR);
505 for ( ; f_i != f_e; f_i++, i++) {
506 atom_groups_total_forces[i] = cvm::rvector((*f_i).x, (*f_i).y, (*f_i).z);
513 cvm::log(
"Updating group positions arrays.\n");
521 atom_groups_coms[ig] = cvm::rvector(gp_i->
x, gp_i->
y, gp_i->
z);
525 #if NAMD_VERSION_NUMBER >= 34471681 528 log(
"Updating grid objects.\n");
535 for (
size_t imap = 0; imap < volmaps_ids.size(); imap++) {
536 if (volmaps_ids[imap] == *goi_i) {
537 volmaps_values[imap] = *gov_i;
546 print_input_atomic_data();
550 if (colvars->calc() != COLVARS_OK) {
551 cvm::error(
"Error in the collective variables module.\n", COLVARS_ERROR);
555 print_output_atomic_data();
559 for (
size_t i = 0; i < atoms_ids.size(); i++) {
560 cvm::rvector
const &f = atoms_new_colvar_forces[i];
565 if (atom_groups_new_colvar_forces.size() > 0) {
569 cvm::rvector
const &f = atom_groups_new_colvar_forces[ig];
570 *gf_i =
Vector(f.x, f.y, f.z);
574 #if NAMD_VERSION_NUMBER >= 34471681 575 if (volmaps_new_colvar_forces.size() > 0) {
581 for (
size_t imap = 0; imap < volmaps_ids.size(); imap++) {
582 if (volmaps_ids[imap] == *goi_i) {
583 *gof_i = volmaps_new_colvar_forces[imap];
592 #ifdef NODEGROUP_FORCE_REGISTER 614 (target_temperature() * boltzmann()));
627 colvarproxy::init_tcl_pointers();
633 return colvarproxy::tcl_run_force_callback();
637 std::string
const &name,
638 std::vector<const colvarvalue *>
const &cvc_values,
641 return colvarproxy::tcl_run_colvar_callback(name, cvc_values, value);
645 std::string
const &name,
646 std::vector<const colvarvalue *>
const &cvc_values,
647 std::vector<cvm::matrix2d<cvm::real> > &gradient)
649 return colvarproxy::tcl_run_colvar_gradient_callback(name, cvc_values,
656 #ifdef NODEGROUP_FORCE_REGISTER 670 cvm::log(
"colvarproxy_namd::request_total_force()\n");
672 total_force_requested = yesno;
675 cvm::log(
"colvarproxy_namd::request_total_force() end\n");
682 std::istringstream is(message);
684 while (std::getline(is, line))
685 iout <<
"colvars: " << line <<
"\n";
693 switch (cvm::get_error()) {
694 case COLVARS_FILE_ERROR:
696 case COLVARS_NOT_IMPLEMENTED:
697 errno = ENOSYS;
break;
698 case COLVARS_MEMORY_ERROR:
699 errno = ENOMEM;
break;
701 char const *msg =
"Error in the collective variables module " 702 "(see above for details)";
714 int const aid = (atom_number-1);
717 cvm::log(
"Adding atom "+cvm::to_str(atom_number)+
718 " for collective variables calculation.\n");
721 cvm::error(
"Error: invalid atom number specified, "+
722 cvm::to_str(atom_number)+
"\n", COLVARS_INPUT_ERROR);
723 return COLVARS_INPUT_ERROR;
740 int aid = (atom_number-1);
742 for (
size_t i = 0; i < atoms_ids.size(); i++) {
743 if (atoms_ids[i] == aid) {
745 atoms_refcount[i] += 1;
753 return COLVARS_INPUT_ERROR;
756 int const index = add_atom_slot(aid);
765 std::string
const &atom_name,
766 std::string
const &segment_id)
779 cvm::error(
"Error: could not find atom \""+
780 atom_name+
"\" in residue "+
781 cvm::to_str(residue)+
782 ( (segment_id !=
"MAIN") ?
783 (
", segment \""+segment_id+
"\"") :
785 "\n", COLVARS_INPUT_ERROR);
786 return COLVARS_INPUT_ERROR;
798 std::string
const &atom_name,
799 std::string
const &segment_id)
801 int const aid =
check_atom_id(residue, atom_name, segment_id);
803 for (
size_t i = 0; i < atoms_ids.size(); i++) {
804 if (atoms_ids[i] == aid) {
806 atoms_refcount[i] += 1;
812 cvm::log(
"Adding atom \""+
813 atom_name+
"\" in residue "+
814 cvm::to_str(residue)+
815 " (index "+cvm::to_str(aid)+
816 ") for collective variables calculation.\n");
818 int const index = add_atom_slot(aid);
828 colvarproxy::clear_atom(index);
837 double const mass = mol->
atommass(atoms_ids[index]);
839 this->
log(
"Warning: near-zero mass for atom "+
840 cvm::to_str(atoms_ids[index]+1)+
841 "; expect unstable dynamics if you apply forces to it.\n");
843 atoms_masses[index] = mass;
845 atoms_charges[index] = mol->
atomcharge(atoms_ids[index]);
850 cvm::atom_pos
const &pos2)
853 Position const p1(pos1.x, pos1.y, pos1.z);
854 Position const p2(pos2.x, pos2.y, pos2.z);
857 return cvm::rvector(d.
x, d.
y, d.
z);
877 if (colvarparse::to_lower_cppstr(pdb_field_str) ==
878 colvarparse::to_lower_cppstr(
"O")) {
882 if (colvarparse::to_lower_cppstr(pdb_field_str) ==
883 colvarparse::to_lower_cppstr(
"B")) {
887 if (colvarparse::to_lower_cppstr(pdb_field_str) ==
888 colvarparse::to_lower_cppstr(
"X")) {
892 if (colvarparse::to_lower_cppstr(pdb_field_str) ==
893 colvarparse::to_lower_cppstr(
"Y")) {
897 if (colvarparse::to_lower_cppstr(pdb_field_str) ==
898 colvarparse::to_lower_cppstr(
"Z")) {
903 cvm::error(
"Error: unsupported PDB field, \""+
904 pdb_field_str+
"\".\n", COLVARS_INPUT_ERROR);
912 std::vector<cvm::atom_pos> &pos,
913 const std::vector<int> &indices,
914 std::string
const &pdb_field_str,
915 double const pdb_field_value)
917 if (pdb_field_str.size() == 0 && indices.size() == 0) {
918 cvm::error(
"Bug alert: either PDB field should be defined or list of " 919 "atom IDs should be available when loading atom coordinates!\n", COLVARS_BUG_ERROR);
923 bool const use_pdb_field = (pdb_field_str.size() > 0);
929 std::vector<int>::const_iterator current_index = indices.begin();
931 PDB *pdb =
new PDB(pdb_filename);
932 size_t const pdb_natoms = pdb->
num_atoms();
934 if (pos.size() != pdb_natoms) {
936 bool const pos_allocated = (pos.size() > 0);
938 size_t ipos = 0, ipdb = 0;
939 for ( ; ipdb < pdb_natoms; ipdb++) {
943 double atom_pdb_field_value = 0.0;
945 switch (pdb_field_index) {
947 atom_pdb_field_value = (pdb->
atom(ipdb))->occupancy();
950 atom_pdb_field_value = (pdb->
atom(ipdb))->temperaturefactor();
953 atom_pdb_field_value = (pdb->
atom(ipdb))->xcoor();
956 atom_pdb_field_value = (pdb->
atom(ipdb))->ycoor();
959 atom_pdb_field_value = (pdb->
atom(ipdb))->zcoor();
965 if ( (pdb_field_value) &&
966 (atom_pdb_field_value != pdb_field_value) ) {
968 }
else if (atom_pdb_field_value == 0.0) {
974 if (((
int) ipdb) != *current_index) {
982 if (!pos_allocated) {
983 pos.push_back(cvm::atom_pos(0.0, 0.0, 0.0));
984 }
else if (ipos >= pos.size()) {
985 cvm::error(
"Error: the PDB file \""+
986 std::string(pdb_filename)+
987 "\" contains coordinates for " 988 "more atoms than needed.\n", COLVARS_BUG_ERROR);
991 pos[ipos] = cvm::atom_pos((pdb->
atom(ipdb))->xcoor(),
992 (pdb->
atom(ipdb))->ycoor(),
993 (pdb->
atom(ipdb))->zcoor());
995 if (!use_pdb_field && current_index == indices.end())
999 if (ipos < pos.size() || (!use_pdb_field && current_index != indices.end())) {
1000 size_t n_requested = use_pdb_field ? pos.size() : indices.size();
1001 cvm::error(
"Error: number of matching records in the PDB file \""+
1002 std::string(pdb_filename)+
"\" ("+cvm::to_str(ipos)+
1003 ") does not match the number of requested coordinates ("+
1004 cvm::to_str(n_requested)+
").\n", COLVARS_INPUT_ERROR);
1005 return COLVARS_ERROR;
1011 for (
size_t ia = 0; ia < pos.size(); ia++) {
1012 pos[ia] = cvm::atom_pos((pdb->
atom(ia))->xcoor(),
1013 (pdb->
atom(ia))->ycoor(),
1014 (pdb->
atom(ia))->zcoor());
1024 cvm::atom_group &atoms,
1025 std::string
const &pdb_field_str,
1026 double const pdb_field_value)
1028 if (pdb_field_str.size() == 0)
1029 cvm::error(
"Error: must define which PDB field to use " 1030 "in order to define atoms from a PDB file.\n", COLVARS_INPUT_ERROR);
1032 PDB *pdb =
new PDB(pdb_filename);
1033 size_t const pdb_natoms = pdb->
num_atoms();
1037 for (
size_t ipdb = 0; ipdb < pdb_natoms; ipdb++) {
1039 double atom_pdb_field_value = 0.0;
1041 switch (pdb_field_index) {
1043 atom_pdb_field_value = (pdb->
atom(ipdb))->occupancy();
1046 atom_pdb_field_value = (pdb->
atom(ipdb))->temperaturefactor();
1049 atom_pdb_field_value = (pdb->
atom(ipdb))->xcoor();
1052 atom_pdb_field_value = (pdb->
atom(ipdb))->ycoor();
1055 atom_pdb_field_value = (pdb->
atom(ipdb))->zcoor();
1061 if ( (pdb_field_value) &&
1062 (atom_pdb_field_value != pdb_field_value) ) {
1064 }
else if (atom_pdb_field_value == 0.0) {
1068 if (atoms.is_enabled(colvardeps::f_ag_scalable)) {
1069 atoms.add_atom_id(ipdb);
1076 return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
1081 std::string
const description)
1084 cvm::log(
"Using colvarproxy_namd::output_stream()\n");
1087 if (!io_available()) {
1088 cvm::error(
"Error: trying to access an output file/channel " 1089 "from the wrong thread.\n", COLVARS_BUG_ERROR);
1090 return *output_stream_error_;
1093 if (output_streams_.count(output_name) > 0) {
1094 return *(output_streams_[output_name]);
1099 output_streams_[output_name] =
new ofstream_namd(output_name.c_str(), std::ios::binary);
1100 if (! output_streams_[output_name]->good()) {
1101 cvm::error(
"Error: cannot write to "+description+
" \""+output_name+
"\".\n",
1102 COLVARS_FILE_ERROR);
1105 return *(output_streams_[output_name]);
1111 if (!io_available()) {
1115 if (output_streams_.count(output_name) > 0) {
1116 (
reinterpret_cast<ofstream_namd *
>(output_streams_[output_name]))->flush();
1120 return cvm::error(
"Error: trying to flush an output file/channel " 1121 "that wasn't open.\n", COLVARS_BUG_ERROR);
1127 if (!io_available()) {
1131 for (std::map<std::string, std::ostream *>::iterator osi = output_streams_.begin();
1132 osi != output_streams_.end();
1143 if (!io_available()) {
1144 return cvm::error(
"Error: trying to access an output file/channel " 1145 "from the wrong thread.\n", COLVARS_BUG_ERROR);
1148 if (output_streams_.count(output_name) > 0) {
1149 (
reinterpret_cast<ofstream_namd *
>(output_streams_[output_name]))->close();
1150 delete output_streams_[output_name];
1151 output_streams_.erase(output_name);
1160 if (! io_available()) {
1164 for (std::map<std::string, std::ostream *>::iterator osi = output_streams_.begin();
1165 osi != output_streams_.end();
1169 output_streams_.clear();
1177 if (std::string(filename).rfind(std::string(
".colvars.state")) != std::string::npos) {
1189 cvm::log(
"Requesting from NAMD a group of size "+cvm::to_str(atoms_ids.size())+
1190 " for collective variables calculation.\n");
1192 colvars->cite_feature(
"Scalable center-of-mass computation (NAMD)");
1201 bool b_match =
true;
1203 if (namd_group.
size() != ((int) atoms_ids.size())) {
1207 for (ia = 0; ia < namd_group.
size(); ia++) {
1208 int const aid = atoms_ids[ia];
1209 if (namd_group[ia] != aid) {
1218 cvm::log(
"Group was already added.\n");
1220 atom_groups_refcount[ig] += 1;
1226 size_t const index = add_atom_group_slot(atom_groups_ids.size());
1231 namd_group.
resize(atoms_ids.size());
1233 for (
size_t ia = 0; ia < atoms_ids.size(); ia++) {
1234 int const aid = atoms_ids[ia];
1236 cvm::log(
"Adding atom "+cvm::to_str(aid+1)+
1237 " for collective variables calculation.\n");
1238 if ( (aid < 0) || (aid >= n_all_atoms) ) {
1239 cvm::error(
"Error: invalid atom number specified, "+
1240 cvm::to_str(aid+1)+
"\n", COLVARS_INPUT_ERROR);
1243 namd_group[ia] = aid;
1249 cvm::log(
"Group has index "+cvm::to_str(index)+
"\n");
1261 colvarproxy::clear_atom_group(index);
1269 cvm::log(
"Re-calculating total mass and charge for scalable group no. "+cvm::to_str(index+1)+
" ("+
1270 cvm::to_str(namd_group.
size())+
" atoms).\n");
1273 cvm::real total_mass = 0.0;
1274 cvm::real total_charge = 0.0;
1275 for (
int i = 0; i < namd_group.
size(); i++) {
1279 atom_groups_masses[index] = total_mass;
1280 atom_groups_charges[index] = total_charge;
1283 cvm::log(
"total mass = "+cvm::to_str(total_mass)+
1284 ", total charge = "+cvm::to_str(total_charge)+
"\n");
1294 if (units_in !=
"real") {
1295 cvm::error(
"Error: Specified unit system \"" + units_in +
"\" is unsupported in NAMD. Supported units are \"real\" (A, kcal/mol).\n");
1296 return COLVARS_ERROR;
1302 #if NAMD_VERSION_NUMBER >= 34471681 1313 for (
size_t i = 0; i < volmaps_ids.size(); i++) {
1314 if (volmaps_ids[i] == volmap_id) {
1316 volmaps_refcount[i] += 1;
1323 if (error_code == COLVARS_OK) {
1324 index = add_volmap_slot(volmap_id);
1328 return (error_code == COLVARS_OK) ? index : -1;
1334 if (volmap_name == NULL) {
1335 return cvm::error(
"Error: no grid object name provided.", COLVARS_INPUT_ERROR);
1338 int error_code = COLVARS_OK;
1343 if (error_code == COLVARS_OK) {
1351 if ((gfScale.
x != 0.0) || (gfScale.
y != 0.0) || (gfScale.
z != 0.0)) {
1352 error_code |= cvm::error(
"Error: GridForce map \""+
1353 std::string(volmap_name)+
1354 "\" has non-zero scale factors.\n",
1355 COLVARS_INPUT_ERROR);
1358 for (
size_t i = 0; i < volmaps_ids.size(); i++) {
1359 if (volmaps_ids[i] == volmap_id) {
1361 volmaps_refcount[i] += 1;
1366 index = add_volmap_slot(volmap_id);
1370 return (error_code == COLVARS_OK) ? index : -1;
1378 return cvm::error(
"Error: invalid numeric ID ("+cvm::to_str(volmap_id)+
1379 ") for map.\n", COLVARS_INPUT_ERROR);
1381 colvars->cite_feature(
"GridForces volumetric map implementation for NAMD");
1388 if (volmap_name == NULL) {
1389 return cvm::error(
"Error: no grid object name provided.", COLVARS_INPUT_ERROR);
1392 if (volmap_id < 0) {
1393 return cvm::error(
"Error: invalid map name \""+std::string(volmap_name)+
1394 "\".\n", COLVARS_INPUT_ERROR);
1396 colvars->cite_feature(
"GridForces volumetric map implementation for NAMD");
1404 colvarproxy::clear_volmap(index);
1410 int const volmap_id =
1412 if (volmap_id < 0) {
1420 template<
class T,
int flags>
1422 cvm::atom_iter atom_begin,
1423 cvm::atom_iter atom_end,
1425 cvm::real *atom_field)
1430 cvm::atom_iter ai = atom_begin;
1431 for ( ; ai != atom_end; ai++, i++) {
1432 if (g->compute_VdV(
Position(ai->pos.x, ai->pos.y, ai->pos.z), V, dV)) {
1437 if (flags & volmap_flag_use_atom_field) {
1438 *value += V * atom_field[i];
1439 if (flags & volmap_flag_gradients) {
1440 ai->grad += atom_field[i] * cvm::rvector(dV.
x, dV.
y, dV.
z);
1444 if (flags & volmap_flag_gradients) {
1445 ai->grad += cvm::rvector(dV.
x, dV.
y, dV.
z);
1456 cvm::atom_iter atom_begin,
1457 cvm::atom_iter atom_end,
1459 cvm::real *atom_field)
1461 if (flags & volmap_flag_use_atom_field) {
1462 int const new_flags = volmap_flag_use_atom_field | volmap_flag_gradients;
1463 GridForceGridLoop<T, new_flags>(g, atom_begin, atom_end,
1466 int const new_flags = volmap_flag_gradients;
1467 GridForceGridLoop<T, new_flags>(g, atom_begin, atom_end,
1475 cvm::atom_iter atom_begin,
1476 cvm::atom_iter atom_end,
1478 cvm::real *atom_field)
1485 getGridForceGridValue<GridforceFullMainGrid>(flags, g, atom_begin, atom_end,
1489 getGridForceGridValue<GridforceLiteGrid>(flags, g, atom_begin, atom_end,
1497 #if CMK_SMP && USE_CKLOOP // SMP only 1499 int colvarproxy_namd::check_smp_enabled()
1504 return COLVARS_ERROR;
1508 void calc_colvars_items_smp(
int first,
int last,
void *result,
int paramNum,
void *param)
1511 colvarmodule *cv = proxy->colvars;
1512 #if CMK_TRACE_ENABLED 1513 double before = CmiWallTimer();
1515 cvm::increase_depth();
1516 for (
int i = first; i <= last; i++) {
1517 colvar *x = (*(cv->variables_active_smp()))[i];
1518 int x_item = (*(cv->variables_active_smp_items()))[i];
1520 cvm::log(
"["+cvm::to_str(proxy->smp_thread_id())+
"/"+cvm::to_str(proxy->smp_num_threads())+
1521 "]: calc_colvars_items_smp(), first = "+cvm::to_str(first)+
1522 ", last = "+cvm::to_str(last)+
", cv = "+
1523 x->name+
", cvc = "+cvm::to_str(x_item)+
"\n");
1525 x->calc_cvcs(x_item, 1);
1527 cvm::decrease_depth();
1528 #if CMK_TRACE_ENABLED 1534 int colvarproxy_namd::smp_colvars_loop()
1536 colvarmodule *cv = this->colvars;
1537 CkLoop_Parallelize(calc_colvars_items_smp, 1,
this,
1538 cv->variables_active_smp()->size(),
1539 0, cv->variables_active_smp()->size()-1);
1540 return cvm::get_error();
1544 void calc_cv_biases_smp(
int first,
int last,
void *result,
int paramNum,
void *param)
1547 colvarmodule *cv = proxy->colvars;
1548 #if CMK_TRACE_ENABLED 1549 double before = CmiWallTimer();
1551 cvm::increase_depth();
1552 for (
int i = first; i <= last; i++) {
1553 colvarbias *b = (*(cv->biases_active()))[i];
1555 cvm::log(
"["+cvm::to_str(proxy->smp_thread_id())+
"/"+cvm::to_str(proxy->smp_num_threads())+
1556 "]: calc_cv_biases_smp(), first = "+cvm::to_str(first)+
1557 ", last = "+cvm::to_str(last)+
", bias = "+
1562 cvm::decrease_depth();
1563 #if CMK_TRACE_ENABLED 1569 int colvarproxy_namd::smp_biases_loop()
1571 colvarmodule *cv = this->colvars;
1572 CkLoop_Parallelize(calc_cv_biases_smp, 1,
this,
1573 cv->biases_active()->size(), 0, cv->biases_active()->size()-1);
1574 return cvm::get_error();
1578 void calc_cv_scripted_forces(
int paramNum,
void *param)
1581 colvarmodule *cv = proxy->colvars;
1582 #if CMK_TRACE_ENABLED 1583 double before = CmiWallTimer();
1586 cvm::log(
"["+cvm::to_str(proxy->smp_thread_id())+
"/"+cvm::to_str(proxy->smp_num_threads())+
1587 "]: calc_cv_scripted_forces()\n");
1589 cv->calc_scripted_forces();
1590 #if CMK_TRACE_ENABLED 1596 int colvarproxy_namd::smp_biases_script_loop()
1598 colvarmodule *cv = this->colvars;
1599 CkLoop_Parallelize(calc_cv_biases_smp, 1,
this,
1600 cv->biases_active()->size(), 0, cv->biases_active()->size()-1,
1601 1, NULL, CKLOOP_NONE,
1602 calc_cv_scripted_forces, 1,
this);
1603 return cvm::get_error();
1606 #endif // #if CMK_SMP && USE_CKLOOP 1610 #if CMK_HAS_PARTITION 1613 return COLVARS_NOT_IMPLEMENTED;
1619 return CmiMyPartition();
1624 return CmiNumPartitions();
1637 CmiAssert(recvMsg != NULL);
1638 int retval = recvMsg->
size;
1639 if (buf_len >= retval) {
1640 memcpy(msg_data,recvMsg->
data,retval);
Real atomcharge(int anum) const
int check_volmaps_available() override
std::ostream & output_stream(std::string const &output_name, std::string const description) override
const Controller & getController() const
void clear_atom_group(int index) override
ForceList & modifyAppliedForces()
int get_volmap_id_from_name(char const *volmap_name) override
AtomIDList & modifyRequestedAtoms()
void clear_volmap(int index) override
GridforceGrid * get_gridfrc_grid(int gridnum) const
BigRealList & modifyGridObjForces()
void getGridForceGridValue(int flags, T const *grid, cvm::atom_iter atom_begin, cvm::atom_iter atom_end, cvm::real *value, cvm::real *atom_field)
Abstraction of the two types of NAMD volumetric maps.
SimParameters * simparams
Pointer to the NAMD simulation input object.
NAMD_HOST_DEVICE Vector c() const
Random random
NAMD-style PRNG object.
void NAMD_err(const char *err_msg)
int init_atom_group(std::vector< int > const &atoms_ids) override
int compute_volmap(int flags, int volmap_id, cvm::atom_iter atom_begin, cvm::atom_iter atom_end, cvm::real *value, cvm::real *atom_field) override
NAMD_HOST_DEVICE int c_p() const
int set_unit_system(std::string const &units_in, bool check_only) override
#define GLOBAL_MASTER_CKLOOP_CALC_ITEM
void error(std::string const &message) override
void update_accelMD_info()
int replica_comm_send(char *msg_data, int msg_len, int dest_rep) override
int init_atom(int atom_number) override
AtomIDList::const_iterator getForceIdEnd()
AtomIDList::const_iterator getAtomIdBegin()
PositionList::const_iterator getGroupPositionEnd()
Communication between colvars and NAMD (implementation of colvarproxy)
int init_volmap_by_id(int volmap_id) override
SimParameters * simParameters
int check_volmap_by_name(char const *volmap_name) override
void clear_atom(int index) override
cvm::real amd_weight_factor
e_pdb_field pdb_field_str2enum(std::string const &pdb_field_str)
void replica_send(const char *sndbuf, int sendcount, int destPart, int destPE)
std::ostream & endi(std::ostream &s)
void GridForceGridLoop(T const *g, cvm::atom_iter atom_begin, cvm::atom_iter atom_end, cvm::real *value, cvm::real *atom_field)
Implementation of inner loop; allows for atom list computation and use.
ForceList::const_iterator getGroupTotalForceBegin()
cvm::step_number previous_NAMD_step
SubmitReduction * willSubmit(int setID, int size=-1)
int update_target_temperature()
Get the target temperature from the NAMD thermostats supported so far.
static ReductionMgr * Object(void)
NAMD_HOST_DEVICE int orthogonal() const
NodeReduction * reduction
int add(const Elem &elem)
PositionList::const_iterator getAtomPositionBegin()
Molecule stores the structural information for the system.
NAMD_HOST_DEVICE int b_p() const
const ResizeArray< AtomIDList > & requestedGroups()
void request_total_force(bool yesno) override
char outputFilename[NAMD_FILENAME_BUFFER_SIZE]
AtomIDList::const_iterator getForceIdBegin()
int init_volmap_by_name(const char *volmap_name) override
void setall(const Elem &elem)
int check_atom_id(int atom_number) override
#define COLVARPROXY_VERSION
int run_colvar_gradient_callback(std::string const &name, std::vector< const colvarvalue *> const &cvcs, std::vector< cvm::matrix2d< cvm::real > > &gradient) override
#define GLOBAL_MASTER_CKLOOP_CALC_SCRIPTED_BIASES
std::vector< int > atoms_map
Array of atom indices (relative to the colvarproxy arrays), usedfor faster copy of atomic data...
void replica_recv(DataMessage **precvMsg, int srcPart, int srcPE)
int check_atom_name_selections_available() override
int index_for_key(const char *key)
void log(std::string const &message) override
IntList::const_iterator getGridObjIndexBegin()
int get_atom_from_name(const char *segid, int resid, const char *aname) const
bool accelMDOn
Accelerated MD reweighting factor.
const AtomID * const_iterator
int backup_file(char const *filename) override
PDBAtom * atom(int place)
int load_atoms_pdb(char const *filename, cvm::atom_group &atoms, std::string const &pdb_field, double const pdb_field_value) override
void init_atoms_map()
Allocate an atoms map with the same size as the NAMD topology.
int flush_output_streams() override
IntList & modifyRequestedGridObjects()
#define GLOBAL_MASTER_CKLOOP_CALC_BIASES
void replica_comm_barrier() override
int check_replicas_enabled() override
int close_output_stream(std::string const &output_name) override
int replica_index() override
NAMD_HOST_DEVICE int a_p() const
AtomIDList & modifyForcedAtoms()
ResizeArray< AtomIDList > & modifyRequestedGroups()
int update_group_properties(int index)
void NAMD_die(const char *err_msg)
int flush_output_stream(std::string const &output_name) override
ForceList & modifyGroupForces()
Real atommass(int anum) const
NAMD_HOST_DEVICE Vector b() const
MGridforceParamsList mgridforcelist
void init_tcl_pointers() override
void update_atom_properties(int index)
void NAMD_backup_file(const char *filename, const char *extension)
virtual Vector get_scale(void) const =0
char restartFilename[NAMD_FILENAME_BUFFER_SIZE]
BigRealList::const_iterator getGridObjValueBegin()
cvm::rvector position_distance(cvm::atom_pos const &pos1, cvm::atom_pos const &pos2) const
int check_volmap_by_id(int volmap_id) override
IntList::const_iterator getGridObjIndexEnd()
void add_energy(cvm::real energy) override
int close_output_streams() override
void requestTotalForce(bool yesno=true)
AtomIDList::const_iterator getAtomIdEnd()
int run_colvar_callback(std::string const &name, std::vector< const colvarvalue *> const &cvcs, colvarvalue &value) override
GridforceGridType get_grid_type(void)
int num_replicas() override
const IntList & requestedGridObjs()
int run_force_callback() override
SubmitReduction * reduction
Used to submit restraint energy as MISC.
int replica_comm_recv(char *msg_data, int buf_len, int src_rep) override
StringList * find(const char *name) const
NAMD_HOST_DEVICE Vector a() const
int update_atoms_map(AtomIDList::const_iterator begin, AtomIDList::const_iterator end)
PositionList::const_iterator getGroupPositionBegin()
ForceList::const_iterator getTotalForce()
int load_coords_pdb(char const *filename, std::vector< cvm::atom_pos > &pos, const std::vector< int > &indices, std::string const &pdb_field, double const pdb_field_value) override
BigRealList::const_iterator getGridObjValueEnd()
NAMD_HOST_DEVICE Vector delta(const Position &pos1, const Position &pos2) const
ForceList::const_iterator getGroupTotalForceEnd()