NAMD
Public Member Functions | Protected Member Functions | Protected Attributes | Friends | List of all members
colvarproxy_namd Class Reference

Communication between colvars and NAMD (implementation of colvarproxy) More...

#include <colvarproxy_namd.h>

Inheritance diagram for colvarproxy_namd:
GlobalMaster

Public Member Functions

void init_tcl_pointers () override
 
 colvarproxy_namd ()
 
 ~colvarproxy_namd ()
 
int setup () override
 
int reset () override
 
int update_target_temperature ()
 Get the target temperature from the NAMD thermostats supported so far. More...
 
void init_atoms_map ()
 Allocate an atoms map with the same size as the NAMD topology. More...
 
int update_atoms_map (AtomIDList::const_iterator begin, AtomIDList::const_iterator end)
 
void calculate ()
 
void log (std::string const &message) override
 
void error (std::string const &message) override
 
int set_unit_system (std::string const &units_in, bool check_only) override
 
void add_energy (cvm::real energy) override
 
void request_total_force (bool yesno) override
 
bool total_forces_enabled () const override
 
int run_force_callback () override
 
int run_colvar_callback (std::string const &name, std::vector< const colvarvalue *> const &cvcs, colvarvalue &value) override
 
int run_colvar_gradient_callback (std::string const &name, std::vector< const colvarvalue *> const &cvcs, std::vector< cvm::matrix2d< cvm::real > > &gradient) override
 
cvm::real rand_gaussian () override
 
cvm::real get_accelMD_factor () const override
 
bool accelMD_enabled () const override
 
int check_replicas_enabled () override
 
int replica_index () override
 
int num_replicas () override
 
void replica_comm_barrier () override
 
int replica_comm_recv (char *msg_data, int buf_len, int src_rep) override
 
int replica_comm_send (char *msg_data, int msg_len, int dest_rep) override
 
int check_atom_name_selections_available () override
 
int init_atom (int atom_number) override
 
int check_atom_id (int atom_number) override
 
int init_atom (cvm::residue_id const &residue, std::string const &atom_name, std::string const &segment_id) override
 
int check_atom_id (cvm::residue_id const &residue, std::string const &atom_name, std::string const &segment_id) override
 
void clear_atom (int index) override
 
void update_atom_properties (int index)
 
cvm::rvector position_distance (cvm::atom_pos const &pos1, cvm::atom_pos const &pos2) const
 
int load_atoms_pdb (char const *filename, cvm::atom_group &atoms, std::string const &pdb_field, double const pdb_field_value) override
 
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
 
int scalable_group_coms () override
 
int init_atom_group (std::vector< int > const &atoms_ids) override
 
void clear_atom_group (int index) override
 
int update_group_properties (int index)
 
int check_volmaps_available () override
 
int init_volmap_by_id (int volmap_id) override
 
int init_volmap_by_name (const char *volmap_name) override
 
int check_volmap_by_id (int volmap_id) override
 
int check_volmap_by_name (char const *volmap_name) override
 
int get_volmap_id_from_name (char const *volmap_name) override
 
void clear_volmap (int index) 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
 
template<class T >
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. More...
 
template<class T , int flags>
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. More...
 
std::ostream & output_stream (std::string const &output_name, std::string const description) override
 
int flush_output_stream (std::string const &output_name) override
 
int flush_output_streams () override
 
int close_output_stream (std::string const &output_name) override
 
int close_output_streams () override
 
int backup_file (char const *filename) override
 
int get_alch_lambda (cvm::real *lambda)
 Get value of alchemical lambda parameter from back-end. More...
 
int send_alch_lambda (void)
 Set value of alchemical lambda parameter in back-end. More...
 
int request_alch_energy_freq (int const freq)
 Request energy computation every freq steps. More...
 
int get_dE_dlambda (cvm::real *dE_dlambda)
 Get energy derivative with respect to lambda. More...
 
- Public Member Functions inherited from GlobalMaster
void processData (AtomIDList::iterator a_i, AtomIDList::iterator a_e, PositionList::iterator p_i, PositionList::iterator g_i, PositionList::iterator g_e, BigRealList::iterator gm_i, BigRealList::iterator gm_e, ForceList::iterator gtf_i, ForceList::iterator gtf_e, IntList::iterator goi_i, IntList::iterator goi_e, BigRealList::iterator gov_i, BigRealList::iterator gov_e, AtomIDList::iterator last_atoms_forced_i, AtomIDList::iterator last_atoms_forced_e, ForceList::iterator last_forces_i, AtomIDList::iterator, AtomIDList::iterator, ForceList::iterator)
 
bool changedAtoms ()
 
const AtomIDListrequestedAtoms ()
 
bool changedForces ()
 
const AtomIDListforcedAtoms ()
 
const ForceListappliedForces ()
 
bool changedGroups ()
 
const ResizeArray< AtomIDList > & requestedGroups ()
 
const ForceListgroupForces ()
 
bool changedGridObjs ()
 
const IntListrequestedGridObjs ()
 
const BigRealListgridObjForces ()
 
bool requestedTotalForces ()
 
void clearChanged ()
 
virtual ~GlobalMaster ()
 
void check () const
 
void setLattice (const Lattice *lat)
 

Protected Member Functions

void update_accelMD_info ()
 
- Protected Member Functions inherited from GlobalMaster
 GlobalMaster ()
 
AtomIDListmodifyRequestedAtoms ()
 
AtomIDListmodifyForcedAtoms ()
 
ForceListmodifyAppliedForces ()
 
ResizeArray< AtomIDList > & modifyRequestedGroups ()
 
ForceListmodifyGroupForces ()
 
IntListmodifyRequestedGridObjects ()
 
BigRealListmodifyGridObjForces ()
 
AtomIDList::const_iterator getAtomIdBegin ()
 
AtomIDList::const_iterator getAtomIdEnd ()
 
PositionList::const_iterator getAtomPositionBegin ()
 
PositionList::const_iterator getGroupPositionBegin ()
 
PositionList::const_iterator getGroupPositionEnd ()
 
ForceList::const_iterator getGroupTotalForceBegin ()
 
ForceList::const_iterator getGroupTotalForceEnd ()
 
IntList::const_iterator getGridObjIndexBegin ()
 
IntList::const_iterator getGridObjIndexEnd ()
 
BigRealList::const_iterator getGridObjValueBegin ()
 
BigRealList::const_iterator getGridObjValueEnd ()
 
AtomIDList::const_iterator getLastAtomsForcedBegin ()
 
AtomIDList::const_iterator getLastAtomsForcedEnd ()
 
ForceList::const_iterator getLastForcesBegin ()
 
AtomIDList::const_iterator getForceIdBegin ()
 
AtomIDList::const_iterator getForceIdEnd ()
 
ForceList::const_iterator getTotalForce ()
 
void requestTotalForce (bool yesno=true)
 
BigRealList::const_iterator getGroupMassBegin ()
 
BigRealList::const_iterator getGroupMassEnd ()
 
void addReductionEnergy (int reductionTag, BigReal energy)
 
SubmitReductiongetCurrentReduction ()
 
void submitReduction ()
 

Protected Attributes

std::vector< int > atoms_map
 Array of atom indices (relative to the colvarproxy arrays), usedfor faster copy of atomic data. More...
 
SimParameterssimparams
 Pointer to the NAMD simulation input object. More...
 
Controller const * controller
 Pointer to Controller object. More...
 
Random random
 NAMD-style PRNG object. More...
 
bool first_timestep
 
cvm::step_number previous_NAMD_step
 
bool accelMDOn
 Used to submit restraint energy as MISC. More...
 
cvm::real amd_weight_factor
 
- Protected Attributes inherited from GlobalMaster
bool totalForceRequested
 
const Latticelattice
 
AtomIDList::iterator atomIdBegin
 
AtomIDList::iterator atomIdEnd
 
PositionList::iterator atomPositionBegin
 
PositionList::iterator groupPositionBegin
 
PositionList::iterator groupPositionEnd
 
BigRealList::iterator groupMassBegin
 
BigRealList::iterator groupMassEnd
 
ForceList::iterator groupTotalForceBegin
 
ForceList::iterator groupTotalForceEnd
 
IntList::iterator gridObjIndexBegin
 
IntList::iterator gridObjIndexEnd
 
BigRealList::iterator gridObjValueBegin
 
BigRealList::iterator gridObjValueEnd
 
AtomIDList::iterator lastAtomsForcedBegin
 
ForceList::iterator lastForcesBegin
 
AtomIDList::iterator lastAtomsForcedEnd
 
AtomIDList::iterator forceIdBegin
 
AtomIDList::iterator forceIdEnd
 
ForceList::iterator totalForceBegin
 
bool reqAtomsChanged
 
AtomIDList reqAtoms
 
bool appForcesChanged
 
AtomIDList fAtoms
 
ForceList appForces
 
bool reqGroupsChanged
 
ResizeArray< AtomIDListreqGroups
 
ForceList grpForces
 
bool reqGridObjsChanged
 
IntList reqGridObjs
 
BigRealList gridobjForces
 

Friends

class cvm::atom
 

Additional Inherited Members

- Public Attributes inherited from GlobalMaster
int step
 
int globalMasterStep
 
int old_num_groups_requested
 

Detailed Description

Communication between colvars and NAMD (implementation of colvarproxy)

Definition at line 39 of file colvarproxy_namd.h.

Constructor & Destructor Documentation

◆ colvarproxy_namd()

colvarproxy_namd::colvarproxy_namd ( )

Definition at line 46 of file colvarproxy_namd.C.

References accelMDOn, SimParameters::accelMDOn, amd_weight_factor, COLVARPROXY_VERSION, Node::colvars, Node::configList, StringList::data, debug, SimParameters::dt, endi(), error(), ConfigList::find(), first_timestep, SimParameters::firstTimestep, GLOBAL_MASTER_CKLOOP_CALC_BIASES, GLOBAL_MASTER_CKLOOP_CALC_ITEM, GLOBAL_MASTER_CKLOOP_CALC_SCRIPTED_BIASES, init_atoms_map(), iout, StringList::next, Node::Object(), ReductionMgr::Object(), SimParameters::outputFilename, random, SimParameters::randomSeed, PatchData::reduction, REDUCTIONS_BASIC, GlobalMaster::requestTotalForce(), SimParameters::restartFilename, SimParameters::restartFrequency, setup(), Node::simParameters, simparams, update_target_temperature(), and ReductionMgr::willSubmit().

47 {
48  engine_name_ = "NAMD";
49 #if CMK_SMP && USE_CKLOOP
50  charm_lock_state = CmiCreateLock();
51 #endif
52 
53  version_int = get_version_from_string(COLVARPROXY_VERSION);
54 #if CMK_TRACE_ENABLED
55  if ( 0 == CkMyPe() ) {
56  traceRegisterUserEvent("GM COLVAR item", GLOBAL_MASTER_CKLOOP_CALC_ITEM);
57  traceRegisterUserEvent("GM COLVAR bias", GLOBAL_MASTER_CKLOOP_CALC_BIASES );
58  traceRegisterUserEvent("GM COLVAR scripted bias", GLOBAL_MASTER_CKLOOP_CALC_SCRIPTED_BIASES );
59  }
60 #endif
61  first_timestep = true;
62  requestTotalForce(total_force_requested);
63 
64  boltzmann_ = 0.001987191;
65 
66  angstrom_value_ = 1.;
67 
68  // initialize pointers to NAMD configuration data
70 
71  if (cvm::debug())
72  iout << "Info: initializing the colvars proxy object.\n" << endi;
73 
74  // find the configuration file, if provided
75  StringList *config = Node::Object()->configList->find("colvarsConfig");
76 
77  // find the input state file
78  StringList *input_restart = Node::Object()->configList->find("colvarsInput");
79  colvarproxy_io::set_input_prefix(input_restart ? input_restart->data : "");
80 
82  set_integration_timestep(simparams->dt);
83 
85 
86  // both fields are taken from data structures already available
87  updated_masses_ = updated_charges_ = true;
88 
89  // Take the output prefixes from the NAMD input
90  colvarproxy_io::set_output_prefix(std::string(simparams->outputFilename));
91  colvarproxy_io::set_restart_output_prefix(std::string(simparams->restartFilename));
92  colvarproxy_io::set_default_restart_frequency(simparams->restartFrequency);
93 
94  if (simparams->accelMDOn) {
95  accelMDOn = true;
96  } else {
97  accelMDOn = false;
98  }
99  amd_weight_factor = 1.0;
100 
101  // check if it is possible to save output configuration
102  if ((!output_prefix_str.size()) && (!restart_output_prefix_str.size())) {
103  error("Error: neither the final output state file or "
104  "the output restart file could be defined, exiting.\n");
105  }
106 
107  init_atoms_map();
108 
109  // initialize module: this object will be the communication proxy
110  colvars = new colvarmodule(this);
111 
112  cvm::log("Using NAMD interface, version "+
113  cvm::to_str(COLVARPROXY_VERSION)+".\n");
114  colvars->cite_feature("NAMD engine");
115  colvars->cite_feature("Colvars-NAMD interface");
116 
117  errno = 0;
118  for ( ; config; config = config->next ) {
119  add_config("configfile", config->data);
120  }
121 
122  // Trigger immediate initialization of the module
123  colvarproxy::parse_module_config();
125  colvars->update_engine_parameters();
126  colvars->setup_input();
127  colvars->setup_output();
128 
129  // save to Node for Tcl script access
130  Node::Object()->colvars = colvars;
131 
132 #ifdef NAMD_TCL
133  have_scripts = true;
134 #else
135  have_scripts = false;
136 #endif
137 
138  if (simparams->firstTimestep != 0) {
139  colvars->set_initial_step(static_cast<cvm::step_number>(simparams->firstTimestep));
140  }
141 
142 #if !defined (NAMD_UNIFIED_REDUCTION)
144 #endif
145 
146  #if defined(NODEGROUP_FORCE_REGISTER) && !defined(NAMD_UNIFIED_REDUCTION)
147  CProxy_PatchData cpdata(CkpvAccess(BOCclass_group).patchData);
148  PatchData *patchData = cpdata.ckLocalBranch();
149  nodeReduction = patchData->reduction;
150  #endif
151 
152  if (cvm::debug())
153  iout << "Info: done initializing the colvars proxy object.\n" << endi;
154 }
static Node * Object()
Definition: Node.h:86
SimParameters * simparams
Pointer to the NAMD simulation input object.
Random random
NAMD-style PRNG object.
#define GLOBAL_MASTER_CKLOOP_CALC_ITEM
void error(std::string const &message) override
SimParameters * simParameters
Definition: Node.h:181
cvm::real amd_weight_factor
std::ostream & endi(std::ostream &s)
Definition: InfoStream.C:54
SubmitReduction * willSubmit(int setID, int size=-1)
Definition: ReductionMgr.C:368
int update_target_temperature()
Get the target temperature from the NAMD thermostats supported so far.
static int debug
Definition: parm.C:36
static ReductionMgr * Object(void)
Definition: ReductionMgr.h:290
#define iout
Definition: InfoStream.h:51
NodeReduction * reduction
Definition: PatchData.h:139
char outputFilename[NAMD_FILENAME_BUFFER_SIZE]
int setup() override
#define COLVARPROXY_VERSION
#define GLOBAL_MASTER_CKLOOP_CALC_SCRIPTED_BIASES
Definition: Random.h:37
bool accelMDOn
Used to submit restraint energy as MISC.
void init_atoms_map()
Allocate an atoms map with the same size as the NAMD topology.
#define GLOBAL_MASTER_CKLOOP_CALC_BIASES
ConfigList * configList
Definition: Node.h:182
char restartFilename[NAMD_FILENAME_BUFFER_SIZE]
unsigned int randomSeed
void requestTotalForce(bool yesno=true)
Definition: GlobalMaster.h:135
StringList * next
Definition: ConfigList.h:49
char * data
Definition: ConfigList.h:48
colvarmodule * colvars
Definition: Node.h:187
StringList * find(const char *name) const
Definition: ConfigList.C:341

◆ ~colvarproxy_namd()

colvarproxy_namd::~colvarproxy_namd ( )

Definition at line 157 of file colvarproxy_namd.C.

158 {
159 #if CMK_SMP && USE_CKLOOP
160  CmiDestroyLock(charm_lock_state);
161 #endif
162 #if !defined (NAMD_UNIFIED_REDUCTION)
163  delete reduction;
164 #endif
165 }

Member Function Documentation

◆ accelMD_enabled()

bool colvarproxy_namd::accelMD_enabled ( ) const
inlineoverride

Definition at line 124 of file colvarproxy_namd.h.

References accelMDOn.

124  {
125  return accelMDOn;
126  }
bool accelMDOn
Used to submit restraint energy as MISC.

◆ add_energy()

void colvarproxy_namd::add_energy ( cvm::real  energy)
override

Definition at line 663 of file colvarproxy_namd.C.

References GlobalMaster::addReductionEnergy(), SimParameters::CUDASOAintegrate, REDUCTION_MISC_ENERGY, and simparams.

664 {
665  #if defined(NODEGROUP_FORCE_REGISTER) && !defined(NAMD_UNIFIED_REDUCTION)
667  nodeReduction->item(REDUCTION_MISC_ENERGY) += energy;
668  } else {
669  reduction->item(REDUCTION_MISC_ENERGY) += energy;
670  }
671  #else
672  #if !defined(NAMD_UNIFIED_REDUCTION)
673  reduction->item(REDUCTION_MISC_ENERGY) += energy;
674  #else
676  #endif
677  #endif
678 }
SimParameters * simparams
Pointer to the NAMD simulation input object.
void addReductionEnergy(int reductionTag, BigReal energy)
Definition: GlobalMaster.C:142

◆ backup_file()

int colvarproxy_namd::backup_file ( char const *  filename)
override

Definition at line 1188 of file colvarproxy_namd.C.

References NAMD_backup_file().

Referenced by output_stream().

1189 {
1190  if (std::string(filename).rfind(std::string(".colvars.state")) != std::string::npos) {
1191  NAMD_backup_file(filename, ".old");
1192  } else {
1193  NAMD_backup_file(filename, ".BAK");
1194  }
1195  return COLVARS_OK;
1196 }
void NAMD_backup_file(const char *filename, const char *extension)
Definition: common.C:235

◆ calculate()

void colvarproxy_namd::calculate ( )
virtual

Reimplemented from GlobalMaster.

Definition at line 345 of file colvarproxy_namd.C.

References Lattice::a(), Lattice::a_p(), accelMDOn, ResizeArray< Elem >::add(), atoms_map, Lattice::b(), Lattice::b_p(), ResizeArray< Elem >::begin(), Lattice::c(), Lattice::c_p(), ResizeArray< Elem >::clear(), controller, SimParameters::CUDASOAintegrate, debug, ResizeArray< Elem >::end(), first_timestep, GlobalMaster::getAtomIdBegin(), GlobalMaster::getAtomIdEnd(), GlobalMaster::getAtomPositionBegin(), NamdState::getController(), GlobalMaster::getForceIdBegin(), GlobalMaster::getForceIdEnd(), GlobalMaster::getGridObjIndexBegin(), GlobalMaster::getGridObjIndexEnd(), GlobalMaster::getGridObjValueBegin(), GlobalMaster::getGridObjValueEnd(), GlobalMaster::getGroupPositionBegin(), GlobalMaster::getGroupPositionEnd(), GlobalMaster::getGroupTotalForceBegin(), GlobalMaster::getGroupTotalForceEnd(), GlobalMaster::getTotalForce(), GlobalMaster::lattice, log(), GlobalMaster::modifyAppliedForces(), GlobalMaster::modifyForcedAtoms(), GlobalMaster::modifyGridObjForces(), GlobalMaster::modifyGroupForces(), Node::molecule, SimParameters::N, Molecule::numAtoms, Node::Object(), Lattice::orthogonal(), SimParameters::outputFilename, previous_NAMD_step, GlobalMaster::requestedGridObjs(), GlobalMaster::requestedGroups(), ResizeArray< Elem >::resize(), SimParameters::restartFilename, SimParameters::restartFrequency, Vector::set(), ResizeArray< Elem >::setall(), setup(), simparams, Node::state, GlobalMaster::step, update_accelMD_info(), update_atoms_map(), Vector::x, Vector::y, and Vector::z.

346 {
347  errno = 0;
348 
349  if (first_timestep) {
350 
351  // First run after the proxy is constructed
352 
354  colvars->update_engine_parameters();
355  colvars->setup_input();
356  colvars->setup_output();
357  // Controller is only available after full startup phase, so now
359 
360  first_timestep = false;
361 
362  } else {
363 
364  // Use the time step number inherited from GlobalMaster
365  if ( step - previous_NAMD_step == 1 ) {
366  colvars->it++;
367  b_simulation_continuing = false;
368  } else {
369 
370  // Cases covered by this condition:
371  // - run 0
372  // - beginning of a new run statement
373  // The internal counter is not incremented, and the objects are made
374  // aware of this via the following flag
375  b_simulation_continuing = true;
376 
377  // Update NAMD output and restart prefixes
378  colvarproxy_io::set_output_prefix(std::string(simparams->outputFilename));
379  colvarproxy_io::set_restart_output_prefix(std::string(simparams->restartFilename));
380  colvarproxy_io::set_default_restart_frequency(simparams->restartFrequency);
381  colvars->setup_output();
382 
383  }
384  }
385 
388 
389  {
390  Vector const a = lattice->a();
391  Vector const b = lattice->b();
392  Vector const c = lattice->c();
393  unit_cell_x.set(a.x, a.y, a.z);
394  unit_cell_y.set(b.x, b.y, c.z);
395  unit_cell_z.set(c.x, c.y, c.z);
396  }
397 
398  if (!lattice->a_p() && !lattice->b_p() && !lattice->c_p()) {
399  boundaries_type = boundaries_non_periodic;
400  reset_pbc_lattice();
401  } else if (lattice->a_p() && lattice->b_p() && lattice->c_p()) {
402  if (lattice->orthogonal()) {
403  boundaries_type = boundaries_pbc_ortho;
404  } else {
405  boundaries_type = boundaries_pbc_triclinic;
406  }
407  colvarproxy_system::update_pbc_lattice();
408  } else {
409  boundaries_type = boundaries_unsupported;
410  }
411 
412  if (cvm::debug()) {
413  cvm::log(std::string(cvm::line_marker)+
414  "colvarproxy_namd, step no. "+cvm::to_str(colvars->it)+"\n"+
415  "Updating atomic data arrays.\n");
416  }
417 
418  // must delete the forces applied at the previous step: we can do
419  // that because they have already been used and copied to other
420  // memory locations
423 
424  // If new atomic positions or forces have been requested by other
425  // GlobalMaster objects, add these to the atom map as well
426  size_t const n_all_atoms = Node::Object()->molecule->numAtoms;
427  if ( (atoms_map.size() != n_all_atoms) ||
428  (int(atoms_ids.size()) < (getAtomIdEnd() - getAtomIdBegin())) ||
429  (int(atoms_ids.size()) < (getForceIdEnd() - getForceIdBegin())) ) {
432  }
433 
434  // prepare local arrays
435  for (size_t i = 0; i < atoms_ids.size(); i++) {
436  atoms_positions[i] = cvm::rvector(0.0, 0.0, 0.0);
437  atoms_total_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
438  atoms_new_colvar_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
439  }
440 
441  for (size_t i = 0; i < atom_groups_ids.size(); i++) {
442  atom_groups_total_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
443  atom_groups_new_colvar_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
444  }
445 
446 #if NAMD_VERSION_NUMBER >= 34471681
447  for (int imap = 0; imap < volmaps_ids.size(); imap++) {
448  volmaps_new_colvar_forces[imap] = 0.0;
449  }
450 #endif
451 
452  {
453  if (cvm::debug()) {
454  cvm::log("Updating positions arrays.\n");
455  }
456  size_t n_positions = 0;
460 
461  for ( ; a_i != a_e; ++a_i, ++p_i ) {
462  atoms_positions[atoms_map[*a_i]] = cvm::rvector((*p_i).x, (*p_i).y, (*p_i).z);
463  n_positions++;
464  }
465 
466  // The following had to be relaxed because some atoms may be forced without their position being requested
467  // if (n_positions < atoms_ids.size()) {
468  // cvm::error("Error: did not receive the positions of all atoms.\n", COLVARS_BUG_ERROR);
469  // }
470  }
471 
472  if (total_force_requested && cvm::step_relative() > 0) {
473 
474  // sort the force arrays the previous step
475  // (but only do so if there *is* a previous step!)
476 
477  {
478  if (cvm::debug()) {
479  cvm::log("Updating total forces arrays.\n");
480  }
481  size_t n_total_forces = 0;
485 
486  for ( ; a_i != a_e; ++a_i, ++f_i ) {
487  atoms_total_forces[atoms_map[*a_i]] = cvm::rvector((*f_i).x, (*f_i).y, (*f_i).z);
488  n_total_forces++;
489  }
490 
491  if ( (! b_simulation_continuing) &&
492  (n_total_forces < atoms_ids.size()) ) {
493  cvm::error("Error: total forces were requested, but total forces "
494  "were not received for all atoms.\n"
495  "The most probable cause is combination of energy "
496  "minimization with a biasing method that requires MD (e.g. ABF).\n"
497  "Always run minimization and ABF separately.", COLVARS_INPUT_ERROR);
498  }
499  }
500 
501  {
502  if (cvm::debug()) {
503  cvm::log("Updating group total forces arrays.\n");
504  }
507  size_t i = 0;
508  if ( (! b_simulation_continuing) &&
509  ((f_e - f_i) != ((int) atom_groups_ids.size())) ) {
510  cvm::error("Error: total forces were requested for scalable groups, "
511  "but they are not in the same number from the number of groups.\n"
512  "The most probable cause is combination of energy "
513  "minimization with a biasing method that requires MD (e.g. ABF).\n"
514  "Always run minimization and ABF separately.", COLVARS_INPUT_ERROR);
515  }
516  for ( ; f_i != f_e; f_i++, i++) {
517  atom_groups_total_forces[i] = cvm::rvector((*f_i).x, (*f_i).y, (*f_i).z);
518  }
519  }
520  }
521 
522  {
523  if (cvm::debug()) {
524  cvm::log("Updating group positions arrays.\n");
525  }
526  // update group data (only coms available so far)
527  size_t ig;
528  // note: getGroupMassBegin() could be used here, but masses and charges
529  // have already been calculated from the last call to setup()
531  for (ig = 0; gp_i != getGroupPositionEnd(); gp_i++, ig++) {
532  atom_groups_coms[ig] = cvm::rvector(gp_i->x, gp_i->y, gp_i->z);
533  }
534  }
535 
536 #if NAMD_VERSION_NUMBER >= 34471681
537  {
538  if (cvm::debug()) {
539  log("Updating grid objects.\n");
540  }
541  // Using a simple nested loop: there probably won't be so many maps that
542  // this becomes performance-limiting
545  for ( ; gov_i != getGridObjValueEnd(); goi_i++, gov_i++) {
546  for (size_t imap = 0; imap < volmaps_ids.size(); imap++) {
547  if (volmaps_ids[imap] == *goi_i) {
548  volmaps_values[imap] = *gov_i;
549  break;
550  }
551  }
552  }
553  }
554 #endif
555 
556  if (cvm::debug()) {
557  print_input_atomic_data();
558  }
559 
560  // call the collective variable module
561  if (colvars->calc() != COLVARS_OK) {
562  cvm::error("Error in the collective variables module.\n", COLVARS_ERROR);
563  }
564 
565  if (cvm::debug()) {
566  print_output_atomic_data();
567  }
568 
569  // communicate all forces to the MD integrator
570  for (size_t i = 0; i < atoms_ids.size(); i++) {
571  cvm::rvector const &f = atoms_new_colvar_forces[i];
572  modifyForcedAtoms().add(atoms_ids[i]);
573  modifyAppliedForces().add(Vector(f.x, f.y, f.z));
574  }
575 
576  if (atom_groups_new_colvar_forces.size() > 0) {
579  for (int ig = 0; gf_i != modifyGroupForces().end(); gf_i++, ig++) {
580  cvm::rvector const &f = atom_groups_new_colvar_forces[ig];
581  *gf_i = Vector(f.x, f.y, f.z);
582  }
583  }
584 
585 #if NAMD_VERSION_NUMBER >= 34471681
586  if (volmaps_new_colvar_forces.size() > 0) {
591  for ( ; goi_i != getGridObjIndexEnd(); goi_i++, gof_i++) {
592  for (size_t imap = 0; imap < volmaps_ids.size(); imap++) {
593  if (volmaps_ids[imap] == *goi_i) {
594  *gof_i = volmaps_new_colvar_forces[imap];
595  break;
596  }
597  }
598  }
599  }
600 #endif
601 
602  // send MISC energy
603  #if defined(NODEGROUP_FORCE_REGISTER) && !defined(NAMD_UNIFIED_REDUCTION)
605  reduction->submit();
606  }
607  #else
608  #if !defined(NAMD_UNIFIED_REDUCTION)
609  reduction->submit();
610  #else
611  // submitReduction();
612  #endif
613  #endif
614 
615  // NAMD does not destruct GlobalMaster objects, so we must remember
616  // to write all output files at the end of a run
617  if (step == simparams->N) {
618  post_run();
619  }
620 }
static Node * Object()
Definition: Node.h:86
const Controller & getController() const
Definition: NamdState.h:51
ForceList & modifyAppliedForces()
Definition: GlobalMaster.C:202
BigRealList & modifyGridObjForces()
Definition: GlobalMaster.C:219
SimParameters * simparams
Pointer to the NAMD simulation input object.
NAMD_HOST_DEVICE Vector c() const
Definition: Lattice.h:270
NAMD_HOST_DEVICE int c_p() const
Definition: Lattice.h:291
AtomIDList::const_iterator getForceIdEnd()
Definition: GlobalMaster.C:300
AtomIDList::const_iterator getAtomIdBegin()
Definition: GlobalMaster.C:230
PositionList::const_iterator getGroupPositionEnd()
Definition: GlobalMaster.C:246
Controller const * controller
Pointer to Controller object.
Definition: Vector.h:72
BigReal z
Definition: Vector.h:74
ForceList::const_iterator getGroupTotalForceBegin()
Definition: GlobalMaster.C:250
cvm::step_number previous_NAMD_step
static int debug
Definition: parm.C:36
NAMD_HOST_DEVICE int orthogonal() const
Definition: Lattice.h:273
void clear()
Definition: ResizeArray.h:91
int add(const Elem &elem)
Definition: ResizeArray.h:101
PositionList::const_iterator getAtomPositionBegin()
Definition: GlobalMaster.C:238
NAMD_HOST_DEVICE int b_p() const
Definition: Lattice.h:290
const ResizeArray< AtomIDList > & requestedGroups()
Definition: GlobalMaster.C:189
char outputFilename[NAMD_FILENAME_BUFFER_SIZE]
int setup() override
AtomIDList::const_iterator getForceIdBegin()
Definition: GlobalMaster.C:295
void resize(int i)
Definition: ResizeArray.h:84
void setall(const Elem &elem)
Definition: ResizeArray.h:94
std::vector< int > atoms_map
Array of atom indices (relative to the colvarproxy arrays), usedfor faster copy of atomic data...
void log(std::string const &message) override
IntList::const_iterator getGridObjIndexBegin()
Definition: GlobalMaster.C:258
bool accelMDOn
Used to submit restraint energy as MISC.
const Elem * const_iterator
Definition: ResizeArray.h:38
NamdState * state
Definition: Node.h:184
BigReal x
Definition: Vector.h:74
NAMD_HOST_DEVICE int a_p() const
Definition: Lattice.h:289
AtomIDList & modifyForcedAtoms()
Definition: GlobalMaster.C:197
int numAtoms
Definition: Molecule.h:586
ForceList & modifyGroupForces()
Definition: GlobalMaster.C:207
NAMD_HOST_DEVICE Vector b() const
Definition: Lattice.h:269
char restartFilename[NAMD_FILENAME_BUFFER_SIZE]
Bool set(const char *s)
Definition: Vector.h:261
BigRealList::const_iterator getGridObjValueBegin()
Definition: GlobalMaster.C:266
IntList::const_iterator getGridObjIndexEnd()
Definition: GlobalMaster.C:262
const Lattice * lattice
Definition: GlobalMaster.h:147
iterator begin(void)
Definition: ResizeArray.h:36
AtomIDList::const_iterator getAtomIdEnd()
Definition: GlobalMaster.C:234
iterator end(void)
Definition: ResizeArray.h:37
BigReal y
Definition: Vector.h:74
const IntList & requestedGridObjs()
Definition: GlobalMaster.C:193
NAMD_HOST_DEVICE Vector a() const
Definition: Lattice.h:268
int update_atoms_map(AtomIDList::const_iterator begin, AtomIDList::const_iterator end)
PositionList::const_iterator getGroupPositionBegin()
Definition: GlobalMaster.C:242
Molecule * molecule
Definition: Node.h:179
ForceList::const_iterator getTotalForce()
Definition: GlobalMaster.C:305
BigRealList::const_iterator getGridObjValueEnd()
Definition: GlobalMaster.C:270
ForceList::const_iterator getGroupTotalForceEnd()
Definition: GlobalMaster.C:254

◆ check_atom_id() [1/2]

int colvarproxy_namd::check_atom_id ( int  atom_number)
override

Definition at line 724 of file colvarproxy_namd.C.

References debug, Node::molecule, Molecule::numAtoms, and Node::Object().

Referenced by init_atom().

725 {
726  // NAMD's internal numbering starts from zero
727  int const aid = (atom_number-1);
728 
729  if (cvm::debug())
730  cvm::log("Adding atom "+cvm::to_str(atom_number)+
731  " for collective variables calculation.\n");
732 
733  if ( (aid < 0) || (aid >= Node::Object()->molecule->numAtoms) ) {
734  cvm::error("Error: invalid atom number specified, "+
735  cvm::to_str(atom_number)+"\n", COLVARS_INPUT_ERROR);
736  return COLVARS_INPUT_ERROR;
737  }
738 
739  return aid;
740 }
static Node * Object()
Definition: Node.h:86
static int debug
Definition: parm.C:36
int numAtoms
Definition: Molecule.h:586
Molecule * molecule
Definition: Node.h:179

◆ check_atom_id() [2/2]

int colvarproxy_namd::check_atom_id ( cvm::residue_id const &  residue,
std::string const &  atom_name,
std::string const &  segment_id 
)
override

Definition at line 777 of file colvarproxy_namd.C.

References Molecule::get_atom_from_name(), Node::molecule, and Node::Object().

780 {
781  int const aid =
782  (segment_id.size() ?
783  Node::Object()->molecule->get_atom_from_name(segment_id.c_str(),
784  residue,
785  atom_name.c_str()) :
787  residue,
788  atom_name.c_str()));
789 
790  if (aid < 0) {
791  // get_atom_from_name() has returned an error value
792  cvm::error("Error: could not find atom \""+
793  atom_name+"\" in residue "+
794  cvm::to_str(residue)+
795  ( (segment_id != "MAIN") ?
796  (", segment \""+segment_id+"\"") :
797  ("") )+
798  "\n", COLVARS_INPUT_ERROR);
799  return COLVARS_INPUT_ERROR;
800  }
801 
802  return aid;
803 }
static Node * Object()
Definition: Node.h:86
int get_atom_from_name(const char *segid, int resid, const char *aname) const
Definition: Molecule.C:126
Molecule * molecule
Definition: Node.h:179

◆ check_atom_name_selections_available()

int colvarproxy_namd::check_atom_name_selections_available ( )
override

Definition at line 743 of file colvarproxy_namd.C.

744 {
745  return COLVARS_OK;
746 }

◆ check_replicas_enabled()

int colvarproxy_namd::check_replicas_enabled ( )
override

Definition at line 1614 of file colvarproxy_namd.C.

1614  {
1615 #if CMK_HAS_PARTITION
1616  return COLVARS_OK;
1617 #else
1618  return COLVARS_NOT_IMPLEMENTED;
1619 #endif
1620 }

◆ check_volmap_by_id()

int colvarproxy_namd::check_volmap_by_id ( int  volmap_id)
override

Definition at line 1387 of file colvarproxy_namd.C.

References Node::molecule, Molecule::numGridforceGrids, and Node::Object().

Referenced by init_volmap_by_id().

1388 {
1389  Molecule *mol = Node::Object()->molecule;
1390  if ((volmap_id < 0) || (volmap_id >= mol->numGridforceGrids)) {
1391  return cvm::error("Error: invalid numeric ID ("+cvm::to_str(volmap_id)+
1392  ") for map.\n", COLVARS_INPUT_ERROR);
1393  }
1394  colvars->cite_feature("GridForces volumetric map implementation for NAMD");
1395  return COLVARS_OK;
1396 }
static Node * Object()
Definition: Node.h:86
int numGridforceGrids
Definition: Molecule.h:626
Molecule stores the structural information for the system.
Definition: Molecule.h:174
Molecule * molecule
Definition: Node.h:179

◆ check_volmap_by_name()

int colvarproxy_namd::check_volmap_by_name ( char const *  volmap_name)
override

Definition at line 1399 of file colvarproxy_namd.C.

References MGridforceParamsList::index_for_key(), SimParameters::mgridforcelist, and simparams.

Referenced by get_volmap_id_from_name(), and init_volmap_by_name().

1400 {
1401  if (volmap_name == NULL) {
1402  return cvm::error("Error: no grid object name provided.", COLVARS_INPUT_ERROR);
1403  }
1404  int volmap_id = simparams->mgridforcelist.index_for_key(volmap_name);
1405  if (volmap_id < 0) {
1406  return cvm::error("Error: invalid map name \""+std::string(volmap_name)+
1407  "\".\n", COLVARS_INPUT_ERROR);
1408  }
1409  colvars->cite_feature("GridForces volumetric map implementation for NAMD");
1410  return COLVARS_OK;
1411 }
SimParameters * simparams
Pointer to the NAMD simulation input object.
int index_for_key(const char *key)
MGridforceParamsList mgridforcelist

◆ check_volmaps_available()

int colvarproxy_namd::check_volmaps_available ( )
override

Definition at line 1318 of file colvarproxy_namd.C.

1319 {
1320  return COLVARS_OK;
1321 }

◆ clear_atom()

void colvarproxy_namd::clear_atom ( int  index)
override

Definition at line 839 of file colvarproxy_namd.C.

840 {
841  colvarproxy::clear_atom(index);
842  // TODO remove it from GlobalMaster arrays?
843 }

◆ clear_atom_group()

void colvarproxy_namd::clear_atom_group ( int  index)
override

Definition at line 1271 of file colvarproxy_namd.C.

1272 {
1273  // do nothing, keep the NAMD arrays in sync with the colvarproxy ones
1274  colvarproxy::clear_atom_group(index);
1275 }

◆ clear_volmap()

void colvarproxy_namd::clear_volmap ( int  index)
override

Definition at line 1414 of file colvarproxy_namd.C.

1415 {
1416  // TODO remove from GlobalMaster
1417  colvarproxy::clear_volmap(index);
1418 }

◆ close_output_stream()

int colvarproxy_namd::close_output_stream ( std::string const &  output_name)
override

Definition at line 1154 of file colvarproxy_namd.C.

1155 {
1156  if (!io_available()) {
1157  return cvm::error("Error: trying to access an output file/channel "
1158  "from the wrong thread.\n", COLVARS_BUG_ERROR);
1159  }
1160 
1161  if (output_streams_.count(output_name) > 0) {
1162  (reinterpret_cast<ofstream_namd *>(output_streams_[output_name]))->close();
1163  delete output_streams_[output_name];
1164  output_streams_.erase(output_name);
1165  }
1166 
1167  return COLVARS_OK;
1168 }

◆ close_output_streams()

int colvarproxy_namd::close_output_streams ( )
override

Definition at line 1171 of file colvarproxy_namd.C.

1172 {
1173  if (! io_available()) {
1174  return COLVARS_OK;
1175  }
1176 
1177  for (std::map<std::string, std::ostream *>::iterator osi = output_streams_.begin();
1178  osi != output_streams_.end();
1179  osi++) {
1180  (reinterpret_cast<ofstream_namd *>(osi->second))->close();
1181  }
1182  output_streams_.clear();
1183 
1184  return COLVARS_OK;
1185 }

◆ compute_volmap()

int colvarproxy_namd::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

Definition at line 1486 of file colvarproxy_namd.C.

References GridforceGrid::get_grid_type(), Molecule::get_gridfrc_grid(), GridforceGrid::GridforceGridTypeFull, GridforceGrid::GridforceGridTypeLite, Node::molecule, and Node::Object().

1492 {
1493  Molecule *mol = Node::Object()->molecule;
1494  GridforceGrid *grid = mol->get_gridfrc_grid(volmap_id);
1495  // Inheritance is not possible with GridForceGrid's design
1497  GridforceFullMainGrid *g = dynamic_cast<GridforceFullMainGrid *>(grid);
1498  getGridForceGridValue<GridforceFullMainGrid>(flags, g, atom_begin, atom_end,
1499  value, atom_field);
1500  } else if (grid->get_grid_type() == GridforceGrid::GridforceGridTypeLite) {
1501  GridforceLiteGrid *g = dynamic_cast<GridforceLiteGrid *>(grid);
1502  getGridForceGridValue<GridforceLiteGrid>(flags, g, atom_begin, atom_end,
1503  value, atom_field);
1504  }
1505  return COLVARS_OK;
1506 }
static Node * Object()
Definition: Node.h:86
GridforceGrid * get_gridfrc_grid(int gridnum) const
Definition: Molecule.h:1368
Molecule stores the structural information for the system.
Definition: Molecule.h:174
GridforceGridType get_grid_type(void)
Definition: GridForceGrid.h:64
Molecule * molecule
Definition: Node.h:179

◆ error()

void colvarproxy_namd::error ( std::string const &  message)
override

Definition at line 703 of file colvarproxy_namd.C.

References log(), NAMD_die(), and NAMD_err().

Referenced by colvarproxy_namd().

704 {
705  log(message);
706  switch (cvm::get_error()) {
707  case COLVARS_FILE_ERROR:
708  errno = EIO; break;
709  case COLVARS_NOT_IMPLEMENTED:
710  errno = ENOSYS; break;
711  case COLVARS_MEMORY_ERROR:
712  errno = ENOMEM; break;
713  }
714  char const *msg = "Error in the collective variables module "
715  "(see above for details)";
716  if (errno) {
717  NAMD_err(msg);
718  } else {
719  NAMD_die(msg);
720  }
721 }
void NAMD_err(const char *err_msg)
Definition: common.C:170
void log(std::string const &message) override
void NAMD_die(const char *err_msg)
Definition: common.C:147

◆ flush_output_stream()

int colvarproxy_namd::flush_output_stream ( std::string const &  output_name)
override

Definition at line 1122 of file colvarproxy_namd.C.

1123 {
1124  if (!io_available()) {
1125  return COLVARS_OK;
1126  }
1127 
1128  if (output_streams_.count(output_name) > 0) {
1129  (reinterpret_cast<ofstream_namd *>(output_streams_[output_name]))->flush();
1130  return COLVARS_OK;
1131  }
1132 
1133  return cvm::error("Error: trying to flush an output file/channel "
1134  "that wasn't open.\n", COLVARS_BUG_ERROR);
1135 }

◆ flush_output_streams()

int colvarproxy_namd::flush_output_streams ( )
override

Definition at line 1138 of file colvarproxy_namd.C.

1139 {
1140  if (!io_available()) {
1141  return COLVARS_OK;
1142  }
1143 
1144  for (std::map<std::string, std::ostream *>::iterator osi = output_streams_.begin();
1145  osi != output_streams_.end();
1146  osi++) {
1147  (reinterpret_cast<ofstream_namd *>(osi->second))->flush();
1148  }
1149 
1150  return COLVARS_OK;
1151 }

◆ get_accelMD_factor()

cvm::real colvarproxy_namd::get_accelMD_factor ( ) const
inlineoverride

Definition at line 120 of file colvarproxy_namd.h.

References amd_weight_factor.

120  {
121  return amd_weight_factor;
122  }
cvm::real amd_weight_factor

◆ get_alch_lambda()

int colvarproxy_namd::get_alch_lambda ( cvm::real *  lambda)

Get value of alchemical lambda parameter from back-end.

Definition at line 1681 of file colvarproxy_namd.C.

References SimParameters::getCurrentLambda(), simparams, and GlobalMaster::step.

1681  {
1682  *lambda = simparams->getCurrentLambda(step);
1683  return COLVARS_OK;
1684 }
SimParameters * simparams
Pointer to the NAMD simulation input object.
BigReal getCurrentLambda(const int) const

◆ get_dE_dlambda()

int colvarproxy_namd::get_dE_dlambda ( cvm::real *  dE_dlambda)

Get energy derivative with respect to lambda.

Definition at line 1702 of file colvarproxy_namd.C.

References controller, and Controller::getTIderivative().

1702  {
1703  // Force data at step zero is garbage in NAMD3, zero in NAMD2
1704  if (cvm::step_relative() > 0) {
1705  *dE_dlambda = controller->getTIderivative();
1706  } else {
1707  *dE_dlambda = 0.0;
1708  }
1709  return COLVARS_OK;
1710 }
BigReal getTIderivative(void) const
Definition: Controller.h:121
Controller const * controller
Pointer to Controller object.

◆ get_volmap_id_from_name()

int colvarproxy_namd::get_volmap_id_from_name ( char const *  volmap_name)
override

Definition at line 1421 of file colvarproxy_namd.C.

References check_volmap_by_name(), MGridforceParamsList::index_for_key(), SimParameters::mgridforcelist, and simparams.

1422 {
1423  int const volmap_id =
1424  simparams->mgridforcelist.index_for_key(volmap_name);
1425  if (volmap_id < 0) {
1426  // Print error
1427  check_volmap_by_name(volmap_name);
1428  }
1429  return volmap_id;
1430 }
SimParameters * simparams
Pointer to the NAMD simulation input object.
int check_volmap_by_name(char const *volmap_name) override
int index_for_key(const char *key)
MGridforceParamsList mgridforcelist

◆ getGridForceGridValue()

template<class T >
void colvarproxy_namd::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.

Definition at line 1467 of file colvarproxy_namd.C.

1473 {
1474  if (flags & volmap_flag_use_atom_field) {
1475  int const new_flags = volmap_flag_use_atom_field | volmap_flag_gradients;
1476  GridForceGridLoop<T, new_flags>(g, atom_begin, atom_end,
1477  value, atom_field);
1478  } else {
1479  int const new_flags = volmap_flag_gradients;
1480  GridForceGridLoop<T, new_flags>(g, atom_begin, atom_end,
1481  value, atom_field);
1482  }
1483 }

◆ GridForceGridLoop()

template<class T , int flags>
void colvarproxy_namd::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.

Definition at line 1434 of file colvarproxy_namd.C.

References Vector::x, Vector::y, and Vector::z.

1439 {
1440  float V = 0.0f;
1441  Vector dV(0.0);
1442  int i = 0;
1443  cvm::atom_iter ai = atom_begin;
1444  for ( ; ai != atom_end; ai++, i++) {
1445  if (g->compute_VdV(Position(ai->pos.x, ai->pos.y, ai->pos.z), V, dV)) {
1446  // out-of-bounds atom
1447  V = 0.0f;
1448  dV = 0.0;
1449  } else {
1450  if (flags & volmap_flag_use_atom_field) {
1451  *value += V * atom_field[i];
1452  if (flags & volmap_flag_gradients) {
1453  ai->grad += atom_field[i] * cvm::rvector(dV.x, dV.y, dV.z);
1454  }
1455  } else {
1456  *value += V;
1457  if (flags & volmap_flag_gradients) {
1458  ai->grad += cvm::rvector(dV.x, dV.y, dV.z);
1459  }
1460  }
1461  }
1462  }
1463 }
Definition: Vector.h:72

◆ init_atom() [1/2]

int colvarproxy_namd::init_atom ( int  atom_number)
override

Definition at line 749 of file colvarproxy_namd.C.

References ResizeArray< Elem >::add(), atoms_map, check_atom_id(), GlobalMaster::modifyRequestedAtoms(), and update_atom_properties().

750 {
751  // save time by checking first whether this atom has been requested before
752  // (this is more common than a non-valid atom number)
753  int aid = (atom_number-1);
754 
755  for (size_t i = 0; i < atoms_ids.size(); i++) {
756  if (atoms_ids[i] == aid) {
757  // this atom id was already recorded
758  atoms_refcount[i] += 1;
759  return i;
760  }
761  }
762 
763  aid = check_atom_id(atom_number);
764 
765  if (aid < 0) {
766  return COLVARS_INPUT_ERROR;
767  }
768 
769  int const index = add_atom_slot(aid);
770  atoms_map[aid] = index;
771  modifyRequestedAtoms().add(aid);
772  update_atom_properties(index);
773  return index;
774 }
AtomIDList & modifyRequestedAtoms()
Definition: GlobalMaster.C:167
int add(const Elem &elem)
Definition: ResizeArray.h:101
int check_atom_id(int atom_number) override
std::vector< int > atoms_map
Array of atom indices (relative to the colvarproxy arrays), usedfor faster copy of atomic data...
void update_atom_properties(int index)

◆ init_atom() [2/2]

int colvarproxy_namd::init_atom ( cvm::residue_id const &  residue,
std::string const &  atom_name,
std::string const &  segment_id 
)
override

For AMBER topologies, the segment id is automatically set to "MAIN" (the segment id assigned by NAMD's AMBER topology parser), and is therefore optional when an AMBER topology is used

Definition at line 810 of file colvarproxy_namd.C.

References ResizeArray< Elem >::add(), atoms_map, check_atom_id(), debug, GlobalMaster::modifyRequestedAtoms(), and update_atom_properties().

813 {
814  int const aid = check_atom_id(residue, atom_name, segment_id);
815 
816  for (size_t i = 0; i < atoms_ids.size(); i++) {
817  if (atoms_ids[i] == aid) {
818  // this atom id was already recorded
819  atoms_refcount[i] += 1;
820  return i;
821  }
822  }
823 
824  if (cvm::debug())
825  cvm::log("Adding atom \""+
826  atom_name+"\" in residue "+
827  cvm::to_str(residue)+
828  " (index "+cvm::to_str(aid)+
829  ") for collective variables calculation.\n");
830 
831  int const index = add_atom_slot(aid);
832  atoms_map[aid] = index;
833  modifyRequestedAtoms().add(aid);
834  update_atom_properties(index);
835  return index;
836 }
AtomIDList & modifyRequestedAtoms()
Definition: GlobalMaster.C:167
static int debug
Definition: parm.C:36
int add(const Elem &elem)
Definition: ResizeArray.h:101
int check_atom_id(int atom_number) override
std::vector< int > atoms_map
Array of atom indices (relative to the colvarproxy arrays), usedfor faster copy of atomic data...
void update_atom_properties(int index)

◆ init_atom_group()

int colvarproxy_namd::init_atom_group ( std::vector< int > const &  atoms_ids)
override

Definition at line 1199 of file colvarproxy_namd.C.

References debug, GlobalMaster::modifyGroupForces(), GlobalMaster::modifyRequestedGroups(), Node::molecule, Molecule::numAtoms, Node::Object(), ResizeArray< Elem >::resize(), ResizeArray< Elem >::size(), and update_group_properties().

1200 {
1201  if (cvm::debug())
1202  cvm::log("Requesting from NAMD a group of size "+cvm::to_str(atoms_ids.size())+
1203  " for collective variables calculation.\n");
1204 
1205  colvars->cite_feature("Scalable center-of-mass computation (NAMD)");
1206 
1207  // Note: modifyRequestedGroups is supposed to be in sync with the colvarproxy arrays,
1208  // and to stay that way during a simulation
1209 
1210  // compare this new group to those already allocated inside GlobalMaster
1211  int ig;
1212  for (ig = 0; ig < modifyRequestedGroups().size(); ig++) {
1213  AtomIDList const &namd_group = modifyRequestedGroups()[ig];
1214  bool b_match = true;
1215 
1216  if (namd_group.size() != ((int) atoms_ids.size())) {
1217  b_match = false;
1218  } else {
1219  int ia;
1220  for (ia = 0; ia < namd_group.size(); ia++) {
1221  int const aid = atoms_ids[ia];
1222  if (namd_group[ia] != aid) {
1223  b_match = false;
1224  break;
1225  }
1226  }
1227  }
1228 
1229  if (b_match) {
1230  if (cvm::debug())
1231  cvm::log("Group was already added.\n");
1232  // this group already exists
1233  atom_groups_refcount[ig] += 1;
1234  return ig;
1235  }
1236  }
1237 
1238  // add this group (note: the argument of add_atom_group_slot() is redundant for NAMD, and provided only for consistency)
1239  size_t const index = add_atom_group_slot(atom_groups_ids.size());
1240  modifyRequestedGroups().resize(atom_groups_ids.size());
1241  // the following is done in calculate()
1242  // modifyGroupForces().resize(atom_groups_ids.size());
1243  AtomIDList &namd_group = modifyRequestedGroups()[index];
1244  namd_group.resize(atoms_ids.size());
1245  int const n_all_atoms = Node::Object()->molecule->numAtoms;
1246  for (size_t ia = 0; ia < atoms_ids.size(); ia++) {
1247  int const aid = atoms_ids[ia];
1248  if (cvm::debug())
1249  cvm::log("Adding atom "+cvm::to_str(aid+1)+
1250  " for collective variables calculation.\n");
1251  if ( (aid < 0) || (aid >= n_all_atoms) ) {
1252  cvm::error("Error: invalid atom number specified, "+
1253  cvm::to_str(aid+1)+"\n", COLVARS_INPUT_ERROR);
1254  return -1;
1255  }
1256  namd_group[ia] = aid;
1257  }
1258 
1259  update_group_properties(index);
1260 
1261  if (cvm::debug()) {
1262  cvm::log("Group has index "+cvm::to_str(index)+"\n");
1263  cvm::log("modifyRequestedGroups length = "+cvm::to_str(modifyRequestedGroups().size())+
1264  ", modifyGroupForces length = "+cvm::to_str(modifyGroupForces().size())+"\n");
1265  }
1266 
1267  return index;
1268 }
static Node * Object()
Definition: Node.h:86
int size(void) const
Definition: ResizeArray.h:131
static int debug
Definition: parm.C:36
void resize(int i)
Definition: ResizeArray.h:84
int numAtoms
Definition: Molecule.h:586
ResizeArray< AtomIDList > & modifyRequestedGroups()
Definition: GlobalMaster.C:224
int update_group_properties(int index)
ForceList & modifyGroupForces()
Definition: GlobalMaster.C:207
Molecule * molecule
Definition: Node.h:179

◆ init_atoms_map()

void colvarproxy_namd::init_atoms_map ( )

Allocate an atoms map with the same size as the NAMD topology.

Definition at line 191 of file colvarproxy_namd.C.

References atoms_map, Node::molecule, Molecule::numAtoms, and Node::Object().

Referenced by colvarproxy_namd(), and update_atoms_map().

192 {
193  size_t const n_all_atoms = Node::Object()->molecule->numAtoms;
194  atoms_map.assign(n_all_atoms, -1);
195 }
static Node * Object()
Definition: Node.h:86
std::vector< int > atoms_map
Array of atom indices (relative to the colvarproxy arrays), usedfor faster copy of atomic data...
int numAtoms
Definition: Molecule.h:586
Molecule * molecule
Definition: Node.h:179

◆ init_tcl_pointers()

void colvarproxy_namd::init_tcl_pointers ( )
override

Definition at line 630 of file colvarproxy_namd.C.

References Node::Object().

631 {
632 #ifdef NAMD_TCL
633  // Store pointer to NAMD's Tcl interpreter
634  set_tcl_interp(Node::Object()->getScript()->interp);
635 #else
636  colvarproxy::init_tcl_pointers(); // Create dedicated interpreter
637 #endif
638 }
static Node * Object()
Definition: Node.h:86

◆ init_volmap_by_id()

int colvarproxy_namd::init_volmap_by_id ( int  volmap_id)
override

Definition at line 1324 of file colvarproxy_namd.C.

References ResizeArray< Elem >::add(), check_volmap_by_id(), and GlobalMaster::modifyRequestedGridObjects().

1325 {
1326  for (size_t i = 0; i < volmaps_ids.size(); i++) {
1327  if (volmaps_ids[i] == volmap_id) {
1328  // this map has already been requested
1329  volmaps_refcount[i] += 1;
1330  return i;
1331  }
1332  }
1333 
1334  int error_code = check_volmap_by_id(volmap_id);
1335  int index = -1;
1336  if (error_code == COLVARS_OK) {
1337  index = add_volmap_slot(volmap_id);
1338  modifyRequestedGridObjects().add(volmap_id);
1339  }
1340 
1341  return (error_code == COLVARS_OK) ? index : -1;
1342 }
int add(const Elem &elem)
Definition: ResizeArray.h:101
IntList & modifyRequestedGridObjects()
Definition: GlobalMaster.C:213
int check_volmap_by_id(int volmap_id) override

◆ init_volmap_by_name()

int colvarproxy_namd::init_volmap_by_name ( const char *  volmap_name)
override

Definition at line 1345 of file colvarproxy_namd.C.

References ResizeArray< Elem >::add(), check_volmap_by_name(), Molecule::get_gridfrc_grid(), GridforceGrid::get_scale(), MGridforceParamsList::index_for_key(), SimParameters::mgridforcelist, GlobalMaster::modifyRequestedGridObjects(), Node::molecule, Node::Object(), simparams, Vector::x, Vector::y, and Vector::z.

1346 {
1347  if (volmap_name == NULL) {
1348  return cvm::error("Error: no grid object name provided.", COLVARS_INPUT_ERROR);
1349  }
1350 
1351  int error_code = COLVARS_OK;
1352 
1353  error_code |= check_volmap_by_name(volmap_name);
1354 
1355  int index = -1;
1356  if (error_code == COLVARS_OK) {
1357 
1358  int volmap_id = simparams->mgridforcelist.index_for_key(volmap_name);
1359 
1360  // Check that the scale factor is correctly set to zero
1361  Molecule *mol = Node::Object()->molecule;
1362  GridforceGrid const *grid = mol->get_gridfrc_grid(volmap_id);
1363  Vector const gfScale = grid->get_scale();
1364  if ((gfScale.x != 0.0) || (gfScale.y != 0.0) || (gfScale.z != 0.0)) {
1365  error_code |= cvm::error("Error: GridForce map \""+
1366  std::string(volmap_name)+
1367  "\" has non-zero scale factors.\n",
1368  COLVARS_INPUT_ERROR);
1369  }
1370 
1371  for (size_t i = 0; i < volmaps_ids.size(); i++) {
1372  if (volmaps_ids[i] == volmap_id) {
1373  // this map has already been requested
1374  volmaps_refcount[i] += 1;
1375  return i;
1376  }
1377  }
1378 
1379  index = add_volmap_slot(volmap_id);
1380  modifyRequestedGridObjects().add(volmap_id);
1381  }
1382 
1383  return (error_code == COLVARS_OK) ? index : -1;
1384 }
static Node * Object()
Definition: Node.h:86
GridforceGrid * get_gridfrc_grid(int gridnum) const
Definition: Molecule.h:1368
SimParameters * simparams
Pointer to the NAMD simulation input object.
Definition: Vector.h:72
int check_volmap_by_name(char const *volmap_name) override
BigReal z
Definition: Vector.h:74
int add(const Elem &elem)
Definition: ResizeArray.h:101
Molecule stores the structural information for the system.
Definition: Molecule.h:174
int index_for_key(const char *key)
IntList & modifyRequestedGridObjects()
Definition: GlobalMaster.C:213
BigReal x
Definition: Vector.h:74
MGridforceParamsList mgridforcelist
virtual Vector get_scale(void) const =0
BigReal y
Definition: Vector.h:74
Molecule * molecule
Definition: Node.h:179

◆ load_atoms_pdb()

int colvarproxy_namd::load_atoms_pdb ( char const *  filename,
cvm::atom_group &  atoms,
std::string const &  pdb_field,
double const  pdb_field_value 
)
override

Definition at line 1036 of file colvarproxy_namd.C.

References PDB::atom(), cvm::atom, e_pdb_beta, e_pdb_occ, e_pdb_x, e_pdb_y, e_pdb_z, PDB::num_atoms(), and pdb_field_str2enum().

1040 {
1041  if (pdb_field_str.size() == 0)
1042  cvm::error("Error: must define which PDB field to use "
1043  "in order to define atoms from a PDB file.\n", COLVARS_INPUT_ERROR);
1044 
1045  PDB *pdb = new PDB(pdb_filename);
1046  size_t const pdb_natoms = pdb->num_atoms();
1047 
1048  e_pdb_field pdb_field_index = pdb_field_str2enum(pdb_field_str);
1049 
1050  for (size_t ipdb = 0; ipdb < pdb_natoms; ipdb++) {
1051 
1052  double atom_pdb_field_value = 0.0;
1053 
1054  switch (pdb_field_index) {
1055  case e_pdb_occ:
1056  atom_pdb_field_value = (pdb->atom(ipdb))->occupancy();
1057  break;
1058  case e_pdb_beta:
1059  atom_pdb_field_value = (pdb->atom(ipdb))->temperaturefactor();
1060  break;
1061  case e_pdb_x:
1062  atom_pdb_field_value = (pdb->atom(ipdb))->xcoor();
1063  break;
1064  case e_pdb_y:
1065  atom_pdb_field_value = (pdb->atom(ipdb))->ycoor();
1066  break;
1067  case e_pdb_z:
1068  atom_pdb_field_value = (pdb->atom(ipdb))->zcoor();
1069  break;
1070  default:
1071  break;
1072  }
1073 
1074  if ( (pdb_field_value) &&
1075  (atom_pdb_field_value != pdb_field_value) ) {
1076  continue;
1077  } else if (atom_pdb_field_value == 0.0) {
1078  continue;
1079  }
1080 
1081  if (atoms.is_enabled(colvardeps::f_ag_scalable)) {
1082  atoms.add_atom_id(ipdb);
1083  } else {
1084  atoms.add_atom(cvm::atom(ipdb+1));
1085  }
1086  }
1087 
1088  delete pdb;
1089  return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
1090 }
Definition: PDB.h:36
e_pdb_field pdb_field_str2enum(std::string const &pdb_field_str)
int num_atoms(void)
Definition: PDB.C:323
e_pdb_field
PDBAtom * atom(int place)
Definition: PDB.C:393

◆ load_coords_pdb()

int colvarproxy_namd::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

Definition at line 924 of file colvarproxy_namd.C.

References PDB::atom(), e_pdb_beta, e_pdb_occ, e_pdb_x, e_pdb_y, e_pdb_z, PDB::num_atoms(), and pdb_field_str2enum().

929 {
930  if (pdb_field_str.size() == 0 && indices.size() == 0) {
931  cvm::error("Bug alert: either PDB field should be defined or list of "
932  "atom IDs should be available when loading atom coordinates!\n", COLVARS_BUG_ERROR);
933  }
934 
935  e_pdb_field pdb_field_index;
936  bool const use_pdb_field = (pdb_field_str.size() > 0);
937  if (use_pdb_field) {
938  pdb_field_index = pdb_field_str2enum(pdb_field_str);
939  }
940 
941  // next index to be looked up in PDB file (if list is supplied)
942  std::vector<int>::const_iterator current_index = indices.begin();
943 
944  PDB *pdb = new PDB(pdb_filename);
945  size_t const pdb_natoms = pdb->num_atoms();
946 
947  if (pos.size() != pdb_natoms) {
948 
949  bool const pos_allocated = (pos.size() > 0);
950 
951  size_t ipos = 0, ipdb = 0;
952  for ( ; ipdb < pdb_natoms; ipdb++) {
953 
954  if (use_pdb_field) {
955  // PDB field mode: skip atoms with wrong value in PDB field
956  double atom_pdb_field_value = 0.0;
957 
958  switch (pdb_field_index) {
959  case e_pdb_occ:
960  atom_pdb_field_value = (pdb->atom(ipdb))->occupancy();
961  break;
962  case e_pdb_beta:
963  atom_pdb_field_value = (pdb->atom(ipdb))->temperaturefactor();
964  break;
965  case e_pdb_x:
966  atom_pdb_field_value = (pdb->atom(ipdb))->xcoor();
967  break;
968  case e_pdb_y:
969  atom_pdb_field_value = (pdb->atom(ipdb))->ycoor();
970  break;
971  case e_pdb_z:
972  atom_pdb_field_value = (pdb->atom(ipdb))->zcoor();
973  break;
974  default:
975  break;
976  }
977 
978  if ( (pdb_field_value) &&
979  (atom_pdb_field_value != pdb_field_value) ) {
980  continue;
981  } else if (atom_pdb_field_value == 0.0) {
982  continue;
983  }
984 
985  } else {
986  // Atom ID mode: use predefined atom IDs from the atom group
987  if (((int) ipdb) != *current_index) {
988  // Skip atoms not in the list
989  continue;
990  } else {
991  current_index++;
992  }
993  }
994 
995  if (!pos_allocated) {
996  pos.push_back(cvm::atom_pos(0.0, 0.0, 0.0));
997  } else if (ipos >= pos.size()) {
998  cvm::error("Error: the PDB file \""+
999  std::string(pdb_filename)+
1000  "\" contains coordinates for "
1001  "more atoms than needed.\n", COLVARS_BUG_ERROR);
1002  }
1003 
1004  pos[ipos] = cvm::atom_pos((pdb->atom(ipdb))->xcoor(),
1005  (pdb->atom(ipdb))->ycoor(),
1006  (pdb->atom(ipdb))->zcoor());
1007  ipos++;
1008  if (!use_pdb_field && current_index == indices.end())
1009  break;
1010  }
1011 
1012  if (ipos < pos.size() || (!use_pdb_field && current_index != indices.end())) {
1013  size_t n_requested = use_pdb_field ? pos.size() : indices.size();
1014  cvm::error("Error: number of matching records in the PDB file \""+
1015  std::string(pdb_filename)+"\" ("+cvm::to_str(ipos)+
1016  ") does not match the number of requested coordinates ("+
1017  cvm::to_str(n_requested)+").\n", COLVARS_INPUT_ERROR);
1018  return COLVARS_ERROR;
1019  }
1020  } else {
1021 
1022  // when the PDB contains exactly the number of atoms of the array,
1023  // ignore the fields and just read coordinates
1024  for (size_t ia = 0; ia < pos.size(); ia++) {
1025  pos[ia] = cvm::atom_pos((pdb->atom(ia))->xcoor(),
1026  (pdb->atom(ia))->ycoor(),
1027  (pdb->atom(ia))->zcoor());
1028  }
1029  }
1030 
1031  delete pdb;
1032  return COLVARS_OK;
1033 }
Definition: PDB.h:36
e_pdb_field pdb_field_str2enum(std::string const &pdb_field_str)
int num_atoms(void)
Definition: PDB.C:323
e_pdb_field
PDBAtom * atom(int place)
Definition: PDB.C:393

◆ log()

void colvarproxy_namd::log ( std::string const &  message)
override

Definition at line 693 of file colvarproxy_namd.C.

References endi(), and iout.

Referenced by calculate(), error(), setup(), and update_atom_properties().

694 {
695  std::istringstream is(message);
696  std::string line;
697  while (std::getline(is, line))
698  iout << "colvars: " << line << "\n";
699  iout << endi;
700 }
std::ostream & endi(std::ostream &s)
Definition: InfoStream.C:54
#define iout
Definition: InfoStream.h:51

◆ num_replicas()

int colvarproxy_namd::num_replicas ( )
override

Definition at line 1628 of file colvarproxy_namd.C.

1628  {
1629  return CmiNumPartitions();
1630 }

◆ output_stream()

std::ostream & colvarproxy_namd::output_stream ( std::string const &  output_name,
std::string const  description 
)
override

Definition at line 1093 of file colvarproxy_namd.C.

References backup_file(), and debug.

1095 {
1096  if (cvm::debug()) {
1097  cvm::log("Using colvarproxy_namd::output_stream()\n");
1098  }
1099 
1100  if (!io_available()) {
1101  cvm::error("Error: trying to access an output file/channel "
1102  "from the wrong thread.\n", COLVARS_BUG_ERROR);
1103  return *output_stream_error_;
1104  }
1105 
1106  if (output_streams_.count(output_name) > 0) {
1107  return *(output_streams_[output_name]);
1108  }
1109 
1110  backup_file(output_name.c_str());
1111 
1112  output_streams_[output_name] = new ofstream_namd(output_name.c_str(), std::ios::binary);
1113  if (! output_streams_[output_name]->good()) {
1114  cvm::error("Error: cannot write to "+description+" \""+output_name+"\".\n",
1115  COLVARS_FILE_ERROR);
1116  }
1117 
1118  return *(output_streams_[output_name]);
1119 }
static int debug
Definition: parm.C:36
int backup_file(char const *filename) override

◆ position_distance()

cvm::rvector colvarproxy_namd::position_distance ( cvm::atom_pos const &  pos1,
cvm::atom_pos const &  pos2 
) const

Definition at line 862 of file colvarproxy_namd.C.

References Lattice::delta(), GlobalMaster::lattice, Vector::x, Vector::y, and Vector::z.

865 {
866  Position const p1(pos1.x, pos1.y, pos1.z);
867  Position const p2(pos2.x, pos2.y, pos2.z);
868  // return p2 - p1
869  Vector const d = this->lattice->delta(p2, p1);
870  return cvm::rvector(d.x, d.y, d.z);
871 }
Definition: Vector.h:72
BigReal z
Definition: Vector.h:74
BigReal x
Definition: Vector.h:74
const Lattice * lattice
Definition: GlobalMaster.h:147
BigReal y
Definition: Vector.h:74
NAMD_HOST_DEVICE Vector delta(const Position &pos1, const Position &pos2) const
Definition: Lattice.h:149

◆ rand_gaussian()

cvm::real colvarproxy_namd::rand_gaussian ( )
inlineoverride

Definition at line 115 of file colvarproxy_namd.h.

References Random::gaussian(), and random.

116  {
117  return random.gaussian();
118  }
Random random
NAMD-style PRNG object.
BigReal gaussian(void)
Definition: Random.h:116

◆ replica_comm_barrier()

void colvarproxy_namd::replica_comm_barrier ( )
override

Definition at line 1633 of file colvarproxy_namd.C.

References replica_barrier().

1633  {
1634  replica_barrier();
1635 }
void replica_barrier()

◆ replica_comm_recv()

int colvarproxy_namd::replica_comm_recv ( char *  msg_data,
int  buf_len,
int  src_rep 
)
override

Definition at line 1638 of file colvarproxy_namd.C.

References DataMessage::data, replica_recv(), and DataMessage::size.

1639  {
1640  DataMessage *recvMsg = NULL;
1641  replica_recv(&recvMsg, src_rep, CkMyPe());
1642  CmiAssert(recvMsg != NULL);
1643  int retval = recvMsg->size;
1644  if (buf_len >= retval) {
1645  memcpy(msg_data,recvMsg->data,retval);
1646  } else {
1647  retval = 0;
1648  }
1649  CmiFree(recvMsg);
1650  return retval;
1651 }
void replica_recv(DataMessage **precvMsg, int srcPart, int srcPE)
char data[1]
Definition: DataExchanger.h:23

◆ replica_comm_send()

int colvarproxy_namd::replica_comm_send ( char *  msg_data,
int  msg_len,
int  dest_rep 
)
override

Definition at line 1654 of file colvarproxy_namd.C.

References replica_send().

1655  {
1656  replica_send(msg_data, msg_len, dest_rep, CkMyPe());
1657  return msg_len;
1658 }
void replica_send(const char *sndbuf, int sendcount, int destPart, int destPE)

◆ replica_index()

int colvarproxy_namd::replica_index ( )
override

Definition at line 1623 of file colvarproxy_namd.C.

1623  {
1624  return CmiMyPartition();
1625 }

◆ request_alch_energy_freq()

int colvarproxy_namd::request_alch_energy_freq ( int const  freq)

Request energy computation every freq steps.

Request alchemical energy computation every freq steps.

Definition at line 1662 of file colvarproxy_namd.C.

References SimParameters::alchOn, SimParameters::alchThermIntOn, SimParameters::computeEnergies, and simparams.

1662  {
1663  // This test is only valid for NAMD3
1664  if (freq % simparams->computeEnergies) {
1665  cvm::error("computeEnergies must be a divisor of lambda-dynamics period (" + cvm::to_str(freq) + ").\n");
1666  return COLVARS_INPUT_ERROR;
1667  }
1668  if (!simparams->alchOn) {
1669  cvm::error("alchOn must be enabled for lambda-dynamics.\n");
1670  return COLVARS_INPUT_ERROR;
1671  }
1672  if (!simparams->alchThermIntOn) {
1673  cvm::error("alchType must be set to TI for lambda-dynamics.\n");
1674  return COLVARS_INPUT_ERROR;
1675  }
1676  return COLVARS_OK;
1677 }
SimParameters * simparams
Pointer to the NAMD simulation input object.

◆ request_total_force()

void colvarproxy_namd::request_total_force ( bool  yesno)
override

Definition at line 680 of file colvarproxy_namd.C.

References debug, and GlobalMaster::requestTotalForce().

681 {
682  if (cvm::debug()) {
683  cvm::log("colvarproxy_namd::request_total_force()\n");
684  }
685  total_force_requested = yesno;
686  requestTotalForce(total_force_requested);
687  if (cvm::debug()) {
688  cvm::log("colvarproxy_namd::request_total_force() end\n");
689  }
690 }
static int debug
Definition: parm.C:36
void requestTotalForce(bool yesno=true)
Definition: GlobalMaster.h:135

◆ reset()

int colvarproxy_namd::reset ( )
override

Definition at line 313 of file colvarproxy_namd.C.

References atoms_map, ResizeArray< Elem >::clear(), debug, GlobalMaster::modifyAppliedForces(), GlobalMaster::modifyForcedAtoms(), GlobalMaster::modifyGridObjForces(), GlobalMaster::modifyGroupForces(), GlobalMaster::modifyRequestedAtoms(), GlobalMaster::modifyRequestedGridObjects(), GlobalMaster::modifyRequestedGroups(), and GlobalMaster::requestTotalForce().

314 {
315  if (cvm::debug()) {
316  cvm::log("colvarproxy_namd::reset()\n");
317  }
318 
319  int error_code = COLVARS_OK;
320 
321  // Unrequest all positions, total forces, etc from NAMD
325 
326  modifyRequestedGroups().clear();
328 
329 #if NAMD_VERSION_NUMBER >= 34471681
332 #endif
333 
334  requestTotalForce(false);
335 
336  atoms_map.clear();
337 
338  // Clear internal atomic data
339  error_code |= colvarproxy::reset();
340 
341  return error_code;
342 }
ForceList & modifyAppliedForces()
Definition: GlobalMaster.C:202
AtomIDList & modifyRequestedAtoms()
Definition: GlobalMaster.C:167
BigRealList & modifyGridObjForces()
Definition: GlobalMaster.C:219
static int debug
Definition: parm.C:36
void clear()
Definition: ResizeArray.h:91
std::vector< int > atoms_map
Array of atom indices (relative to the colvarproxy arrays), usedfor faster copy of atomic data...
IntList & modifyRequestedGridObjects()
Definition: GlobalMaster.C:213
AtomIDList & modifyForcedAtoms()
Definition: GlobalMaster.C:197
ResizeArray< AtomIDList > & modifyRequestedGroups()
Definition: GlobalMaster.C:224
ForceList & modifyGroupForces()
Definition: GlobalMaster.C:207
void requestTotalForce(bool yesno=true)
Definition: GlobalMaster.h:135

◆ run_colvar_callback()

int colvarproxy_namd::run_colvar_callback ( std::string const &  name,
std::vector< const colvarvalue *> const &  cvcs,
colvarvalue &  value 
)
override

Definition at line 645 of file colvarproxy_namd.C.

649 {
650  return colvarproxy::tcl_run_colvar_callback(name, cvc_values, value);
651 }

◆ run_colvar_gradient_callback()

int colvarproxy_namd::run_colvar_gradient_callback ( std::string const &  name,
std::vector< const colvarvalue *> const &  cvcs,
std::vector< cvm::matrix2d< cvm::real > > &  gradient 
)
override

Definition at line 653 of file colvarproxy_namd.C.

657 {
658  return colvarproxy::tcl_run_colvar_gradient_callback(name, cvc_values,
659  gradient);
660 }

◆ run_force_callback()

int colvarproxy_namd::run_force_callback ( )
override

Definition at line 640 of file colvarproxy_namd.C.

641 {
642  return colvarproxy::tcl_run_force_callback();
643 }

◆ scalable_group_coms()

int colvarproxy_namd::scalable_group_coms ( )
inlineoverride

Definition at line 215 of file colvarproxy_namd.h.

216  {
217  return COLVARS_OK;
218  }

◆ send_alch_lambda()

int colvarproxy_namd::send_alch_lambda ( void  )

Set value of alchemical lambda parameter in back-end.

Definition at line 1688 of file colvarproxy_namd.C.

References SimParameters::alchLambda, SimParameters::alchLambdaFreq, and simparams.

1688  {
1689  if (simparams->alchLambdaFreq > 0) {
1690  cvm::error("Cannot set lambda from Colvars because alchLambdaFreq is enabled. "
1691  "Either remove biasing forces and extended Lagrangian dynamics on the alchemical coordinate, "
1692  "or disable alchLambdaFreq.\n");
1693  return COLVARS_INPUT_ERROR;
1694  } else {
1695  simparams->alchLambda = cached_alch_lambda;
1696  }
1697  return COLVARS_OK;
1698 }
SimParameters * simparams
Pointer to the NAMD simulation input object.
BigReal alchLambda

◆ set_unit_system()

int colvarproxy_namd::set_unit_system ( std::string const &  units_in,
bool  check_only 
)
override

Definition at line 1305 of file colvarproxy_namd.C.

1306 {
1307  if (units_in != "real") {
1308  cvm::error("Error: Specified unit system \"" + units_in + "\" is unsupported in NAMD. Supported units are \"real\" (A, kcal/mol).\n");
1309  return COLVARS_ERROR;
1310  }
1311  return COLVARS_OK;
1312 }

◆ setup()

int colvarproxy_namd::setup ( )
override

Definition at line 234 of file colvarproxy_namd.C.

References SimParameters::dt, log(), GlobalMaster::modifyGridObjForces(), GlobalMaster::modifyRequestedGroups(), simparams, ResizeArray< Elem >::size(), update_atom_properties(), update_group_properties(), update_target_temperature(), and SimParameters::wrapAll.

Referenced by calculate(), and colvarproxy_namd().

235 {
236  int error_code = colvarproxy::setup();
237 
238  if (colvars->size() == 0) {
239  // Module is empty, nothing to do
240  return COLVARS_OK;
241  }
242 
243  log("Updating NAMD interface:\n");
244 
245  errno = 0;
246 
247  if (simparams->wrapAll) {
248  log("Warning: enabling wrapAll can lead to inconsistent results "
249  "for Colvars calculations: please disable wrapAll, "
250  "as is the default option in NAMD.\n");
251  }
252 
253  log("updating atomic data ("+cvm::to_str(atoms_ids.size())+" atoms).\n");
254 
255  size_t i;
256  for (i = 0; i < atoms_ids.size(); i++) {
258 
259  // zero out mutable arrays
260  atoms_positions[i] = cvm::rvector(0.0, 0.0, 0.0);
261  atoms_total_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
262  atoms_new_colvar_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
263  }
264 
265  size_t n_group_atoms = 0;
266  for (int ig = 0; ig < modifyRequestedGroups().size(); ig++) {
267  n_group_atoms += modifyRequestedGroups()[ig].size();
268  }
269 
270  log("updating group data ("+cvm::to_str(atom_groups_ids.size())+
271  " scalable groups, "+
272  cvm::to_str(n_group_atoms)+" atoms in total).\n");
273 
274  // Note: groupMassBegin, groupMassEnd may be used here, but they won't work for charges
275  for (int ig = 0; ig < modifyRequestedGroups().size(); ig++) {
276 
277  // update mass and charge
279 
280  atom_groups_coms[ig] = cvm::rvector(0.0, 0.0, 0.0);
281  atom_groups_total_forces[ig] = cvm::rvector(0.0, 0.0, 0.0);
282  atom_groups_new_colvar_forces[ig] = cvm::rvector(0.0, 0.0, 0.0);
283  }
284 
285 #if NAMD_VERSION_NUMBER >= 34471681
286  log("updating grid object data ("+cvm::to_str(volmaps_ids.size())+
287  " grid objects in total).\n");
288  for (int imap = 0; imap < modifyGridObjForces().size(); imap++) {
289  volmaps_new_colvar_forces[imap] = 0.0;
290  }
291 #endif
292 
293  size_t const new_features_hash =
294  std::hash<std::string>{}(colvars->feature_report(0));
295  if (new_features_hash != features_hash) {
296  // Nag only once, there may be many run commands
297  log(std::string("\n")+colvars->feature_report(0)+std::string("\n"));
298  features_hash = new_features_hash;
299  }
300 
302  log("updating target temperature (T = "+
303  cvm::to_str(target_temperature())+" K).\n");
304 
305  // Note: not needed currently, but may be in the future if NAMD allows
306  // redefining the timestep
307  set_integration_timestep(simparams->dt);
308 
309  return error_code;
310 }
BigRealList & modifyGridObjForces()
Definition: GlobalMaster.C:219
int size(void) const
Definition: ResizeArray.h:131
SimParameters * simparams
Pointer to the NAMD simulation input object.
int update_target_temperature()
Get the target temperature from the NAMD thermostats supported so far.
void log(std::string const &message) override
ResizeArray< AtomIDList > & modifyRequestedGroups()
Definition: GlobalMaster.C:224
int update_group_properties(int index)
void update_atom_properties(int index)

◆ total_forces_enabled()

bool colvarproxy_namd::total_forces_enabled ( ) const
inlineoverride

Definition at line 102 of file colvarproxy_namd.h.

103  {
104  return total_force_requested;
105  }

◆ update_accelMD_info()

void colvarproxy_namd::update_accelMD_info ( )
protected

Definition at line 622 of file colvarproxy_namd.C.

References Controller::accelMDdV, amd_weight_factor, and controller.

Referenced by calculate().

622  {
623  // This aMD factor is from previous step!
624  amd_weight_factor = std::exp(controller->accelMDdV / (target_temperature() * boltzmann()));
625 }
Controller const * controller
Pointer to Controller object.
cvm::real amd_weight_factor
BigReal accelMDdV
Definition: Controller.h:116

◆ update_atom_properties()

void colvarproxy_namd::update_atom_properties ( int  index)

Definition at line 846 of file colvarproxy_namd.C.

References Molecule::atomcharge(), Molecule::atommass(), log(), Node::molecule, and Node::Object().

Referenced by init_atom(), setup(), and update_atoms_map().

847 {
848  Molecule *mol = Node::Object()->molecule;
849  // update mass
850  double const mass = mol->atommass(atoms_ids[index]);
851  if (mass <= 0.001) {
852  this->log("Warning: near-zero mass for atom "+
853  cvm::to_str(atoms_ids[index]+1)+
854  "; expect unstable dynamics if you apply forces to it.\n");
855  }
856  atoms_masses[index] = mass;
857  // update charge
858  atoms_charges[index] = mol->atomcharge(atoms_ids[index]);
859 }
static Node * Object()
Definition: Node.h:86
Real atomcharge(int anum) const
Definition: Molecule.h:1124
Molecule stores the structural information for the system.
Definition: Molecule.h:174
void log(std::string const &message) override
Real atommass(int anum) const
Definition: Molecule.h:1114
Molecule * molecule
Definition: Node.h:179

◆ update_atoms_map()

int colvarproxy_namd::update_atoms_map ( AtomIDList::const_iterator  begin,
AtomIDList::const_iterator  end 
)

Definition at line 198 of file colvarproxy_namd.C.

References ResizeArray< Elem >::add(), atoms_map, debug, init_atoms_map(), GlobalMaster::modifyRequestedAtoms(), Node::molecule, Molecule::numAtoms, Node::Object(), and update_atom_properties().

Referenced by calculate().

200 {
201  if (atoms_map.size() != Node::Object()->molecule->numAtoms) {
202  init_atoms_map();
203  }
204 
205  for (AtomIDList::const_iterator a_i = begin; a_i != end; a_i++) {
206 
207  if (atoms_map[*a_i] >= 0) continue;
208 
209  for (size_t i = 0; i < atoms_ids.size(); i++) {
210  if (atoms_ids[i] == *a_i) {
211  atoms_map[*a_i] = i;
212  break;
213  }
214  }
215 
216  if (atoms_map[*a_i] < 0) {
217  // this atom is probably managed by another GlobalMaster:
218  // add it here anyway to avoid having to test for array boundaries at each step
219  int const index = add_atom_slot(*a_i);
220  atoms_map[*a_i] = index;
221  modifyRequestedAtoms().add(*a_i);
222  update_atom_properties(index);
223  }
224  }
225 
226  if (cvm::debug()) {
227  cvm::log("atoms_map = "+cvm::to_str(atoms_map)+".\n");
228  }
229 
230  return COLVARS_OK;
231 }
static Node * Object()
Definition: Node.h:86
AtomIDList & modifyRequestedAtoms()
Definition: GlobalMaster.C:167
static int debug
Definition: parm.C:36
int add(const Elem &elem)
Definition: ResizeArray.h:101
std::vector< int > atoms_map
Array of atom indices (relative to the colvarproxy arrays), usedfor faster copy of atomic data...
const Elem * const_iterator
Definition: ResizeArray.h:38
void init_atoms_map()
Allocate an atoms map with the same size as the NAMD topology.
int numAtoms
Definition: Molecule.h:586
void update_atom_properties(int index)
Molecule * molecule
Definition: Node.h:179

◆ update_group_properties()

int colvarproxy_namd::update_group_properties ( int  index)

Definition at line 1278 of file colvarproxy_namd.C.

References Molecule::atomcharge(), Molecule::atommass(), debug, GlobalMaster::modifyRequestedGroups(), Node::molecule, Node::Object(), and ResizeArray< Elem >::size().

Referenced by init_atom_group(), and setup().

1279 {
1280  AtomIDList const &namd_group = modifyRequestedGroups()[index];
1281  if (cvm::debug()) {
1282  cvm::log("Re-calculating total mass and charge for scalable group no. "+cvm::to_str(index+1)+" ("+
1283  cvm::to_str(namd_group.size())+" atoms).\n");
1284  }
1285 
1286  cvm::real total_mass = 0.0;
1287  cvm::real total_charge = 0.0;
1288  for (int i = 0; i < namd_group.size(); i++) {
1289  total_mass += Node::Object()->molecule->atommass(namd_group[i]);
1290  total_charge += Node::Object()->molecule->atomcharge(namd_group[i]);
1291  }
1292  atom_groups_masses[index] = total_mass;
1293  atom_groups_charges[index] = total_charge;
1294 
1295  if (cvm::debug()) {
1296  cvm::log("total mass = "+cvm::to_str(total_mass)+
1297  ", total charge = "+cvm::to_str(total_charge)+"\n");
1298  }
1299 
1300  return COLVARS_OK;
1301 }
static Node * Object()
Definition: Node.h:86
Real atomcharge(int anum) const
Definition: Molecule.h:1124
int size(void) const
Definition: ResizeArray.h:131
static int debug
Definition: parm.C:36
ResizeArray< AtomIDList > & modifyRequestedGroups()
Definition: GlobalMaster.C:224
Real atommass(int anum) const
Definition: Molecule.h:1114
Molecule * molecule
Definition: Node.h:179

◆ update_target_temperature()

int colvarproxy_namd::update_target_temperature ( )

Get the target temperature from the NAMD thermostats supported so far.

Definition at line 168 of file colvarproxy_namd.C.

References SimParameters::langevinOn, SimParameters::langevinTemp, SimParameters::loweAndersenOn, SimParameters::loweAndersenTemp, SimParameters::reassignFreq, SimParameters::reassignTemp, SimParameters::rescaleFreq, SimParameters::rescaleTemp, simparams, SimParameters::stochRescaleOn, SimParameters::stochRescaleTemp, SimParameters::tCoupleOn, and SimParameters::tCoupleTemp.

Referenced by colvarproxy_namd(), and setup().

169 {
170  int error_code = COLVARS_OK;
171  if (simparams->rescaleFreq > 0) {
172  error_code |= set_target_temperature(simparams->rescaleTemp);
173  } else if (simparams->reassignFreq > 0) {
174  error_code |= set_target_temperature(simparams->reassignTemp);
175  } else if (simparams->langevinOn) {
176  error_code |= set_target_temperature(simparams->langevinTemp);
177  } else if (simparams->tCoupleOn) {
178  error_code |= set_target_temperature(simparams->tCoupleTemp);
179  } else if (simparams->loweAndersenOn) {
180  error_code |= set_target_temperature(simparams->loweAndersenTemp);
181  } else if (simparams->stochRescaleOn) {
182  error_code |= set_target_temperature(simparams->stochRescaleTemp);
183  } else {
184  error_code |= set_target_temperature(0.0);
185  }
186  return error_code;
187 }
SimParameters * simparams
Pointer to the NAMD simulation input object.
BigReal reassignTemp
BigReal rescaleTemp
BigReal langevinTemp
BigReal tCoupleTemp
BigReal stochRescaleTemp
BigReal loweAndersenTemp

Friends And Related Function Documentation

◆ cvm::atom

friend class cvm::atom
friend

Definition at line 76 of file colvarproxy_namd.h.

Referenced by load_atoms_pdb().

Member Data Documentation

◆ accelMDOn

bool colvarproxy_namd::accelMDOn
protected

Used to submit restraint energy as MISC.

Accelerated MD reweighting factor

Definition at line 68 of file colvarproxy_namd.h.

Referenced by accelMD_enabled(), calculate(), and colvarproxy_namd().

◆ amd_weight_factor

cvm::real colvarproxy_namd::amd_weight_factor
protected

Definition at line 69 of file colvarproxy_namd.h.

Referenced by colvarproxy_namd(), get_accelMD_factor(), and update_accelMD_info().

◆ atoms_map

std::vector<int> colvarproxy_namd::atoms_map
protected

Array of atom indices (relative to the colvarproxy arrays), usedfor faster copy of atomic data.

Definition at line 45 of file colvarproxy_namd.h.

Referenced by calculate(), init_atom(), init_atoms_map(), reset(), and update_atoms_map().

◆ controller

Controller const* colvarproxy_namd::controller
protected

Pointer to Controller object.

Definition at line 51 of file colvarproxy_namd.h.

Referenced by calculate(), get_dE_dlambda(), and update_accelMD_info().

◆ first_timestep

bool colvarproxy_namd::first_timestep
protected

Definition at line 56 of file colvarproxy_namd.h.

Referenced by calculate(), and colvarproxy_namd().

◆ previous_NAMD_step

cvm::step_number colvarproxy_namd::previous_NAMD_step
protected

Definition at line 57 of file colvarproxy_namd.h.

Referenced by calculate().

◆ random

Random colvarproxy_namd::random
protected

NAMD-style PRNG object.

Definition at line 54 of file colvarproxy_namd.h.

Referenced by colvarproxy_namd(), and rand_gaussian().

◆ simparams

SimParameters* colvarproxy_namd::simparams
protected

The documentation for this class was generated from the following files: