1 // ENGINE.H : the "engine" base class for computation engine classes. 2 3 // Copyright (C) 1998 Tommi Hassinen. 4 5 // This package is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation; either version 2 of the License, or 8 // (at your option) any later version. 9 10 // This package is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 15 // You should have received a copy of the GNU General Public License 16 // along with this package; if not, write to the Free Software 17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 19 /*################################################################################################*/ 20 21 #ifndef ENGINE_H 22 #define ENGINE_H 23 24 #include "libghemicaldefine.h" 25 26 class setup; 27 28 struct ecomp_store; 29 30 class engine; 31 32 class engine_bp; // boundary potential 33 class engine_pbc; // periodic boundary conditions 34 35 class number_density_evaluator; 36 class radial_density_function_evaluator; 37 38 /*################################################################################################*/ 39 40 class atom; // atom.h 41 class bond; // bond.h 42 43 class model; // model.h 44 45 #include <stdlib.h> 46 47 #include <vector> 48 using namespace std; 49 50 #include "typedef.h" 51 52 /*################################################################################################*/ 53 54 /// The setup class is used to define the submodel boundaries in the model. 55 /** There can be only a single setup object for each model object. 56 The setup object will create the engine objects. */ 57 58 class setup 59 { 60 private: 61 62 model * mdl; 63 64 protected: 65 66 engine * current_eng; 67 i32s current_eng_index; 68 69 bool has_setup_tables; 70 71 // the global tables. 72 // ^^^^^^^^^^^^^^^^^^ 73 74 atom ** atmtab; i32s natm; 75 76 // the local tables. 77 // ^^^^^^^^^^^^^^^^^ 78 79 atom ** qm_atmtab; i32s qm_natm; 80 bond ** qm_bndtab; i32s qm_nbnd; 81 82 atom ** mm_atmtab; i32s mm_natm; 83 bond ** mm_bndtab; i32s mm_nbnd; 84 85 bond ** boundary_bndtab; i32s boundary_nbnd; 86 87 atom ** sf_atmtab; i32s sf_natm; 88 89 public: 90 91 setup(model *); 92 virtual ~setup(void); 93 GetModel(void)94 model * GetModel(void) { return mdl; } 95 HasSetupTables(void)96 bool HasSetupTables(void) { return has_setup_tables; } 97 98 // access to global tables. 99 // ^^^^^^^^^^^^^^^^^^^^^^^^ 100 GetAtoms(void)101 atom ** GetAtoms(void) { return atmtab; } GetAtomCount(void)102 i32s GetAtomCount(void) { return natm; } 103 104 // access to local tables. 105 // ^^^^^^^^^^^^^^^^^^^^^^^ 106 GetQMAtoms(void)107 atom ** GetQMAtoms(void) { return qm_atmtab; } GetQMAtomCount(void)108 i32s GetQMAtomCount(void) { return qm_natm; } GetQMBonds(void)109 bond ** GetQMBonds(void) { return qm_bndtab; } GetQMBondCount(void)110 i32s GetQMBondCount(void) { return qm_nbnd; } 111 GetMMAtoms(void)112 atom ** GetMMAtoms(void) { return mm_atmtab; } GetMMAtomCount(void)113 i32s GetMMAtomCount(void) { return mm_natm; } GetMMBonds(void)114 bond ** GetMMBonds(void) { return mm_bndtab; } GetMMBondCount(void)115 i32s GetMMBondCount(void) { return mm_nbnd; } 116 GetBoundaryBonds(void)117 bond ** GetBoundaryBonds(void) { return boundary_bndtab; } GetBoundaryBondCount(void)118 i32s GetBoundaryBondCount(void) { return boundary_nbnd; } 119 GetSFAtoms(void)120 atom ** GetSFAtoms(void) { return sf_atmtab; } GetSFAtomCount(void)121 i32s GetSFAtomCount(void) { return sf_natm; } 122 GetCurrentEngine(void)123 engine * GetCurrentEngine(void) { return current_eng; } 124 GetCurrEngIndex(void)125 i32s GetCurrEngIndex(void) { return current_eng_index; } SetCurrEngIndex(i32s index)126 void SetCurrEngIndex(i32s index) { current_eng_index = index; } // only file operations etc should use this... 127 128 virtual void UpdateAtomFlags(void) = 0; 129 130 void DiscardSetupInfo(void); 131 void UpdateSetupInfo(void); 132 133 // functions for obtaining information about available eng objects. 134 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 135 136 virtual i32u GetEngineCount(void) = 0; 137 virtual i32u GetEngineIDNumber(i32u) = 0; // this is not much used yet. for saving eng info in files?!?!?! 138 virtual const char * GetEngineName(i32u) = 0; 139 virtual const char * GetClassName_lg(void) = 0; // also see model::AddAtom_lg() ; this is an another Win32 API conflict... 140 141 void CreateCurrentEngine(void); ///< Create the current_eng object for plotting... 142 void DiscardCurrentEngine(void); 143 144 virtual engine * CreateEngineByIndex(i32u) = 0; ///< Create an engine object. 145 engine * CreateEngineByIDNumber(i32u); 146 }; 147 148 /*################################################################################################*/ 149 150 typedef double ecomp_data[5]; 151 152 #define ECOMP_DATA_IND_B_bs 0 // bond stretching 153 #define ECOMP_DATA_IND_B_ab 1 // angle bending 154 #define ECOMP_DATA_IND_B_ti 2 // torsion + imp.tor. interactions 155 #define ECOMP_DATA_IND_NB_lj 3 // nonbonded interactions 156 #define ECOMP_DATA_IND_NB_es 4 // electrostatic interactions 157 158 /// A virtual base class for computations. 159 160 /** The engine classes are used to implement the computational details of various models 161 (like different quantum-mechanical models and molecular mechanics models). 162 163 The engine class will store it's own atom coordinates. 164 165 When we want to compute something, we create an instance of some suitable engine-class using 166 our setup-class. The engine-class will copy that information it needs, and calculates those results 167 it is supposed to calculate. If we calculate some useful results that change our original system, 168 we can copy those results back to our model-class. 169 170 The setup class will create two kinds of atom and bond tables using contents of the model object; 171 one (global) contains all atoms/bonds, and the others (local ones) contain only those atoms/bonds 172 that belong to a submodel (say, QM or MM submodel). 173 174 Since there is, for example, only one table for coordinates and derivatives at the engine base class, 175 the different derived engine classes must create a suitable lookup table that maps the local tables 176 back to the global one. */ 177 178 // here are some common error/warning messages: 179 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 180 181 #define CONSTRAINTS_NOT_SUPPORTED "Sorry ; constraints are not yet supported by this engine class." 182 183 class engine 184 { 185 private: 186 187 setup * stp; 188 189 protected: 190 191 i32s natm; 192 193 f64 * crd; 194 195 f64 energy; 196 197 // add atom::ecomp_grp_ind ; define/register the new groups in the model object (and save them in files). 198 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 199 // ecomp_grp vector<const char *> <- in model!!! 200 // ecomp_ngrp int <- in engine!!! 201 // ecomp_data double * 202 // ecomp_map int * <- make the size (n*n). 203 ////////////////////////////////////////////////////////////////////////////// 204 // f64 E_solute; 205 // f64 E_solvent; 206 // f64 E_solusolv; 207 ////////////////////////////////////////////////////////////////////////////// 208 209 f64 * d1; // GetD1() ??? 210 f64 * d2; // GetD2() ??? 211 212 f64 virial[3]; 213 214 bool update_neighbor_list; 215 216 int ECOMPcycles; 217 218 int ECOMPstore_size; 219 ecomp_data * ECOMPstore; 220 221 friend void CopyCRD(model *, engine *, i32u); 222 friend void CopyCRD(engine *, model *, i32u); 223 224 friend class model; 225 226 friend class geomopt; 227 228 friend class moldyn; 229 friend class moldyn_langevin; 230 231 friend class sasaeval; 232 233 friend class random_search; 234 friend class systematic_search; 235 friend class monte_carlo_search; 236 friend class transition_state_search; 237 friend class stationary_state_search; 238 239 public: 240 241 engine(setup *, i32u); 242 virtual ~engine(void); 243 GetSetup(void)244 setup * GetSetup(void) { return stp; } GetAtomCount(void)245 i32s GetAtomCount(void) { return natm; } 246 247 void Check(i32u); ///< This is for debugging; will compare the computed gradient to a numerical one. 248 f64 GetGradientVectorLength(void); ///< This calculates the gradient vector length (using the d1 array). 249 250 void ScaleCRD(f64, f64, f64); 251 252 /** This will request an update for the NB-term list (neighbor list) at the next 253 energy evaluation. 254 */ RequestNeighborListUpdate(void)255 void RequestNeighborListUpdate(void) { update_neighbor_list = true; } 256 257 virtual void Compute(i32u, bool = false) = 0; ///< Will compute the energy, and the gradient if needed. 258 259 virtual void DoSHAKE(bool); ///< This is an optional method that contains some SHAKE-like corrections to atomic coordinates ; is called before calculating forces in MD. 260 261 // these are added to make it easier to set torsional constraints (like for plotting etc). 262 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 263 264 virtual bool SetTorsionConstraint(atom *, atom *, atom *, atom *, f64, f64, bool) = 0; 265 virtual bool RemoveTorsionConstraint(atom *, atom *, atom *, atom *) = 0; 266 267 // these are mainly for drawing energy level diagrams... 268 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 269 270 virtual i32s GetOrbitalCount(void) = 0; 271 virtual f64 GetOrbitalEnergy(i32s) = 0; 272 273 virtual i32s GetElectronCount(void) = 0; 274 275 // these are for plotting purposes... 276 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 277 278 virtual void SetupPlotting(void) = 0; 279 280 virtual fGL GetVDWSurf(fGL *, fGL *) = 0; 281 282 virtual fGL GetESP(fGL *, fGL *) = 0; 283 284 virtual fGL GetElDens(fGL *, fGL *) = 0; 285 286 virtual fGL GetOrbital(fGL *, fGL *) = 0; 287 virtual fGL GetOrbDens(fGL *, fGL *) = 0; 288 289 // these are to take data out for external apps etc... 290 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 291 292 f64 GetEnergy(void); ///< Compute() must be called before this one! 293 294 f64 ReadCRD(int); 295 296 protected: 297 298 void ecomp_AddCycle(void); // called in every energy evaluation! 299 void ecomp_AddStore2(int, int, int, double); // called in every energy evaluation! 300 void ecomp_AddStoreX(vector<int> &, int, double); // called in every energy evaluation! 301 302 public: 303 304 void ecomp_Reset(void); 305 double ecomp_ReadStore(int, int, int); 306 }; 307 308 /*################################################################################################*/ 309 310 fGL value_VDWSurf(engine *, fGL *, fGL *); 311 fGL value_ESP(engine *, fGL *, fGL *); 312 fGL value_ElDens(engine *, fGL *, fGL *); 313 fGL value_Orbital(engine *, fGL *, fGL *); 314 fGL value_OrbDens(engine *, fGL *, fGL *); 315 316 void CopyCRD(model *, engine *, i32u); 317 void CopyCRD(engine *, model *, i32u); 318 319 /*################################################################################################*/ 320 321 /// A base engine class for systems that utilize a boundary potential. 322 323 class engine_bp : virtual public engine 324 { 325 protected: 326 327 bool use_bp; 328 f64 bp_rad_solute; f64 bp_fc_solute; 329 f64 bp_rad_solvent; f64 bp_fc_solvent; 330 331 number_density_evaluator * nd_eval; 332 radial_density_function_evaluator * rdf_eval; 333 334 friend class model; 335 336 friend class number_density_evaluator; 337 friend class radial_density_function_evaluator; 338 339 public: 340 341 engine_bp(setup *, i32u); 342 virtual ~engine_bp(void); 343 }; 344 345 /*################################################################################################*/ 346 347 /// A base engine class for systems with periodic boundary conditions. 348 349 class engine_pbc : virtual public engine 350 { 351 protected: 352 353 f64 box_HALFdim[3]; 354 355 i32s num_mol; 356 i32s * mrange; 357 358 // TODO : how to use RDF-evaluator also here??? 359 360 friend class model; 361 friend class moldyn; 362 363 public: 364 365 engine_pbc(setup *, i32u); 366 virtual ~engine_pbc(void); 367 368 /** This will check that molecules have not escaped from the periodic box. 369 If we doing geometry optimization or molecular dynamics for periodic models, 370 we should remember to call this at suitable intervals... 371 */ 372 void CheckLocations(void); 373 }; 374 375 /*################################################################################################*/ 376 377 /// Calculates "number density" of solvent molecules -> engine::bp_center. 378 379 class number_density_evaluator 380 { 381 protected: 382 383 engine_bp * eng; 384 bool linear; 385 386 i32s classes; 387 f64 * upper_limits; 388 f64 * class_volumes; 389 390 i32u cycles; 391 i32u * counts; 392 393 public: 394 395 number_density_evaluator(engine_bp *, bool, i32s); 396 ~number_density_evaluator(void); 397 398 private: 399 400 void UpdateClassLimits(void); 401 void ResetCounters(void); 402 403 public: 404 405 void PrintResults(ostream &); 406 AddCycle(void)407 inline void AddCycle(void) 408 { 409 cycles++; 410 } 411 AddValue(f64 p1)412 inline void AddValue(f64 p1) 413 { 414 i32s index = 0; 415 while (index < classes) 416 { 417 if (p1 >= upper_limits[index]) index++; 418 else break; 419 } 420 421 counts[index]++; 422 } 423 }; 424 425 /*################################################################################################*/ 426 427 /// Calculates radial density function of solvent molecules (in practive O-O distances of H2O) -> engine::bp_center. 428 429 class radial_density_function_evaluator 430 { 431 protected: 432 433 engine_bp * eng; 434 435 i32s classes; 436 f64 graph_begin; 437 f64 graph_end; 438 f64 count_begin; 439 f64 count_end; 440 441 f64 * upper_limits; 442 f64 * class_volumes; 443 444 i32u cycles; 445 i32u * counts; 446 447 friend class eng1_mm_tripos52_nbt_bp; 448 friend class eng1_mm_default_nbt_bp; 449 friend class eng1_sf; 450 451 public: 452 453 radial_density_function_evaluator(engine_bp *, i32s, f64, f64, f64 = -1.0, f64 = -1.0); 454 ~radial_density_function_evaluator(void); 455 456 private: 457 458 void ResetCounters(void); 459 460 public: 461 462 void PrintResults(ostream &); 463 AddCycle(void)464 inline void AddCycle(void) 465 { 466 cycles++; 467 } 468 AddValue(f64 p1)469 inline void AddValue(f64 p1) 470 { 471 if (p1 < graph_begin) return; 472 if (p1 >= graph_end) return; 473 474 i32s index = 0; 475 while (index < classes) 476 { 477 if (p1 >= upper_limits[index]) index++; 478 else break; 479 } 480 481 counts[index]++; 482 } 483 }; 484 485 /*################################################################################################*/ 486 487 #endif // ENGINE_H 488 489 // eof 490