Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

colvarcomp_rotations.C

Go to the documentation of this file.
00001 #include <cmath>
00002 
00003 #include "colvarmodule.h"
00004 #include "colvarvalue.h"
00005 #include "colvarparse.h"
00006 #include "colvar.h"
00007 #include "colvarcomp.h"
00008 
00009 
00010 
00011 colvar::orientation::orientation (std::string const &conf)
00012   : cvc (conf)
00013 {
00014   function_type = "orientation";
00015   parse_group (conf, "atoms", atoms);
00016   x.type (colvarvalue::type_quaternion);
00017 
00018   ref_pos.reserve (atoms.size());
00019 
00020   if (get_keyval (conf, "refPositions", ref_pos, ref_pos)) {
00021     cvm::log ("Using reference positions from input file.\n");
00022     if (ref_pos.size() != atoms.size()) {
00023       cvm::fatal_error ("Error: reference positions do not "
00024                         "match the number of atom indexes.\n");
00025     }
00026   }
00027 
00028   {
00029     std::string file_name;
00030     if (get_keyval (conf, "refPositionsFile", file_name)) {
00031 
00032       std::string file_col;
00033       get_keyval (conf, "refPositionsCol", file_col, std::string ("O"));
00034 
00035       double file_col_value;
00036       bool found = get_keyval (conf, "refPositionsColValue", file_col_value, 0.0);
00037       if (found && !file_col_value)
00038         cvm::fatal_error ("Error: refPositionsColValue, "
00039                           "if provided, must be non-zero.\n");
00040 
00041       ref_pos.resize (atoms.size());
00042       cvm::load_coords (file_name.c_str(), ref_pos, file_col, file_col_value);
00043     }
00044   }
00045 
00046   if (!ref_pos.size()) {
00047     cvm::fatal_error ("Error: must define a set of "
00048                       "reference coordinates.\n");
00049   }
00050 
00051 
00052   cvm::log ("Centering the reference coordinates: it is "
00053             "assumed that each atom is the closest "
00054             "periodic image to the center of geometry.\n");
00055   cvm::rvector cog (0.0, 0.0, 0.0);
00056   for (size_t i = 0; i < ref_pos.size(); i++) {
00057     cog += ref_pos[i];
00058   }
00059   cog /= cvm::real (ref_pos.size());
00060   for (size_t i = 0; i < ref_pos.size(); i++) {
00061     ref_pos[i] -= cog;
00062   }
00063 
00064   get_keyval (conf, "closestToQuaternion", ref_quat, cvm::quaternion (1.0, 0.0, 0.0, 0.0));
00065 
00066   // initialize rot member data
00067   if (!atoms.noforce) {
00068     rot.request_group2_gradients (atoms.size());
00069   }
00070 
00071   rot.b_debug_gradients = this->b_debug_gradients;
00072 }
00073 
00074   
00075 colvar::orientation::orientation()
00076   : cvc ()
00077 {
00078   function_type = "orientation";
00079   x.type (colvarvalue::type_quaternion);
00080 }
00081 
00082 
00083 void colvar::orientation::calc_value()
00084 {
00085   atoms.reset_atoms_data();
00086   atoms.read_positions();
00087 
00088   atoms_cog = atoms.center_of_geometry();
00089 
00090   rot.calc_optimal_rotation (ref_pos, atoms.positions_shifted (-1.0 * atoms_cog));
00091 
00092   if ((rot.q).inner (ref_quat) >= 0.0) {
00093     x.quaternion_value = rot.q;
00094   } else {
00095     x.quaternion_value = -1.0 * rot.q;
00096   }
00097 }
00098 
00099 
00100 void colvar::orientation::calc_gradients()
00101 {
00102   // gradients have already been calculated and stored within the
00103   // member object "rot"; we're not using the "grad" member of each
00104   // atom object, because it only can represent the gradient of a
00105   // scalar colvar
00106 }
00107 
00108 
00109 void colvar::orientation::apply_force (colvarvalue const &force)
00110 {
00111   cvm::quaternion const &FQ = force.quaternion_value;
00112 
00113   if (!atoms.noforce) {
00114     for (size_t ia = 0; ia < atoms.size(); ia++) {
00115       for (size_t i = 0; i < 4; i++) {
00116         atoms[ia].apply_force (FQ[i] * rot.dQ0_2[ia][i]);
00117       }
00118     }
00119   }
00120 }
00121 
00122 
00123 
00124 colvar::orientation_angle::orientation_angle (std::string const &conf)
00125   : orientation (conf)
00126 {
00127   function_type = "orientation_angle";
00128   x.type (colvarvalue::type_scalar);
00129 }
00130 
00131 
00132 colvar::orientation_angle::orientation_angle()
00133   : orientation()
00134 {
00135   function_type = "orientation_angle";
00136   x.type (colvarvalue::type_scalar);
00137 }
00138 
00139 
00140 void colvar::orientation_angle::calc_value()
00141 {
00142   atoms.reset_atoms_data();
00143   atoms.read_positions();
00144 
00145   atoms_cog = atoms.center_of_geometry();
00146 
00147   rot.calc_optimal_rotation (ref_pos, atoms.positions_shifted (-1.0 * atoms_cog));
00148 
00149   if ((rot.q).q0 >= 0.0) {
00150     x.real_value = (180.0/PI) * 2.0 * ::acos ((rot.q).q0);
00151   } else {
00152     x.real_value = (180.0/PI) * 2.0 * ::acos (-1.0 * (rot.q).q0);
00153   }
00154 }
00155 
00156 
00157 void colvar::orientation_angle::calc_gradients()
00158 {
00159   cvm::real const dxdq0 =
00160     ( ((rot.q).q0 * (rot.q).q0 < 1.0) ? 
00161       ((180.0 / PI) * (-2.0) / ::sqrt (1.0 - ((rot.q).q0 * (rot.q).q0))) :
00162       0.0 );
00163 
00164   for (size_t ia = 0; ia < atoms.size(); ia++) {
00165     atoms[ia].grad = (dxdq0 * (rot.dQ0_2[ia])[0]);
00166   }
00167 }
00168 
00169 
00170 void colvar::orientation_angle::apply_force (colvarvalue const &force)
00171 {
00172   cvm::real const &fw = force.real_value;
00173 
00174   if (!atoms.noforce) {
00175     atoms.apply_colvar_force (fw);
00176   }
00177 }

Generated on Mon Nov 23 04:59:18 2009 for NAMD by  doxygen 1.3.9.1