source: ThirdParty/mpqc_open/src/lib/chemistry/molecule/molecule.h@ 7516f6

Action_Thermostats Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.1 ChemicalSpaceEvaluator Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Exclude_Hydrogens_annealWithBondGraph Fix_Verbose_Codepatterns ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion Gui_displays_atomic_force_velocity JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool PythonUI_with_named_parameters Recreated_GuiChecks StoppableMakroAction TremoloParser_IncreasedPrecision
Last change on this file since 7516f6 was 860145, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit '0b990dfaa8c6007a996d030163a25f7f5fc8a7e7' as 'ThirdParty/mpqc_open'

  • Property mode set to 100644
File size: 17.5 KB
Line 
1//
2// molecule.h
3//
4// Copyright (C) 1996 Limit Point Systems, Inc.
5//
6// Author: Curtis Janssen <cljanss@limitpt.com>
7// Maintainer: LPS
8//
9// This file is part of the SC Toolkit.
10//
11// The SC Toolkit is free software; you can redistribute it and/or modify
12// it under the terms of the GNU Library General Public License as published by
13// the Free Software Foundation; either version 2, or (at your option)
14// any later version.
15//
16// The SC Toolkit is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU Library General Public License for more details.
20//
21// You should have received a copy of the GNU Library General Public License
22// along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24//
25// The U.S. Government is granted a limited license as per AL 91-7.
26//
27
28#ifndef _chemistry_molecule_molecule_h
29#define _chemistry_molecule_molecule_h
30
31#ifdef __GNUC__
32#pragma interface
33#endif
34
35#include <stdio.h>
36#include <iostream>
37#include <util/class/class.h>
38#include <util/state/state.h>
39#include <util/keyval/keyval.h>
40#include <util/misc/units.h>
41#include <math/symmetry/pointgrp.h>
42#include <math/scmat/vector3.h>
43#include <math/scmat/matrix.h>
44#include <chemistry/molecule/atominfo.h>
45
46namespace sc {
47
48/**
49The Molecule class contains information about molecules. It has a
50KeyVal constructor that can create a new molecule from either a
51PDB file or from a list of Cartesian coordinates.
52
53The following ParsedKeyVal input reads from the PDB
54file <tt>h2o.pdb</tt>:
55<pre>
56molecule<Molecule>: (
57 pdb_file = "h2o.pdb"
58 )
59</pre>
60
61The following input explicitly gives the atom coordinates, using the
62ParsedKeyVal table notation:
63<pre>
64molecule<Molecule>: (
65 unit=angstrom
66 { atom_labels atoms geometry } = {
67 O1 O [ 0.000000000 0 0.369372944 ]
68 H1 H [ 0.783975899 0 -0.184686472 ]
69 H2 H [-0.783975899 0 -0.184686472 ]
70 }
71 )
72 )
73</pre>
74The default units are Bohr which can be overridden with
75<tt>unit=angstrom</tt>. The <tt>atom_labels</tt> array can be
76omitted. The <tt>atoms</tt> and <tt>geometry</tt> arrays
77are required.
78
79As a special case, an atom can be given with the symbol <tt>Q</tt> or the
80name <tt>charge</tt>. Such centers are treated as point charges and not
81given basis functions. The values of the charges must be specified with a
82<tt>charge</tt> vector in the Molecule input. Since the charge vector
83assign charges to all centers, including atoms, it is easiest to place all
84point charge centers first in the geometry, and then give a charge vector
85with a number of elements equal to the number of point charges. The
86following example shows a water molecule interacting with a point charge
87having value 0.1:
88<pre>
89molecule<Molecule>: (
90 unit=angstrom
91 charge = [ 0.1 ]
92 { atom_labels atoms geometry } = {
93 Q1 Q [ 0.0 0 10.0 ]
94 O1 O [ 0.000000000 0 0.369372944 ]
95 H1 H [ 0.783975899 0 -0.184686472 ]
96 H2 H [-0.783975899 0 -0.184686472 ]
97 }
98 )
99 )
100</pre>
101
102This feature is designed for doing QM/MM calculations, so, by default,
103methods will not include interactions between the <tt>Q</tt> centers when
104computing the energy or the gradient. To include these interactions, set
105<tt>include_qq=1</tt>.
106
107The Molecule class has a PointGroup
108member object, which also has a KeyVal constructor
109that is called when a Molecule is made. The
110following example constructs a molecule with \f$C_{2v}\f$ symmetry:
111<pre>
112molecule<Molecule>: (
113 symmetry=c2v
114 unit=angstrom
115 { atoms geometry } = {
116 O [0.000000000 0 0.369372944 ]
117 H [0.783975899 0 -0.184686472 ]
118 }
119 )
120 )
121</pre>
122Only the symmetry unique atoms need to be specified. Nonunique
123atoms can be given too, however, numerical errors in the
124geometry specification can result in the generation of extra
125atoms so be careful.
126*/
127class Molecule: public SavableState
128{
129 protected:
130 int natoms_;
131 Ref<AtomInfo> atominfo_;
132 Ref<PointGroup> pg_;
133 Ref<Units> geometry_units_;
134 double **r_;
135 int *Z_;
136 double *charges_;
137
138 // symmetry equiv info
139 int nuniq_;
140 int *nequiv_;
141 int **equiv_;
142 int *atom_to_uniq_;
143 void init_symmetry_info(double tol=0.5);
144 void clear_symmetry_info();
145
146 // these are optional
147 double *mass_;
148 char **labels_;
149
150 // The Z that represents a "Q" type atom.
151 int q_Z_;
152
153 // If true, include the q terms in the charge and efield routines
154 bool include_q_;
155
156 // If true, include the coupling between q-q pairs when
157 // computing nuclear repulsion energy and gradients.
158 bool include_qq_;
159
160 // These vectors contain the atom indices of atoms that are not type
161 // "Q" and those that are.
162 std::vector<int> q_atoms_;
163 std::vector<int> non_q_atoms_;
164
165 void clear();
166
167 // Throw an exception if an atom is duplicated. The
168 // atoms in the range [begin, natom_) are checked.
169 void throw_if_atom_duplicated(int begin=0, double tol = 1e-3);
170 public:
171 Molecule();
172 Molecule(const Molecule&);
173 Molecule(StateIn&);
174 /** The Molecule KeyVal constructor is used to generate a Molecule
175 object from the input. Several examples are given in the Molecule
176 class overview. The full list of keywords that are accepted is
177 below.
178
179 <table border="1">
180
181 <tr><td>Keyword<td>Type<td>Default<td>Description
182
183 <tr><td><tt>include_q</tt><td>boolean<td>false<td>Some of the
184 atoms can be specified as <tt>Q</tt> and given a customizable
185 charge. Such atoms are a point charge that do not have basis
186 functions. If this option is true, then the <tt>Q</tt> atoms are
187 included when computing the nuclear charge and the electric field
188 due to the nuclear charge.
189
190 <tr><td><tt>include_qq</tt><td>boolean<td>false<td>Some of the
191 atoms can be specified as <tt>Q</tt> and given a customizable
192 charge. Such atoms are a point charge that do not have basis
193 functions. If this option is true, then the <tt>Q</tt> atoms are
194 included when computing the nuclear repulsion energy and its
195 derivatives.
196
197 <tr><td><tt>atominfo</tt><td>AtomInfo<td>library values<td>This
198 gives information about each atom, such as the symbol, name, and
199 various atomic radii.
200
201 <tr><td><tt>symmetry</tt><td>string<td><tt>C1</tt><td>The
202 Schoenflies symbol of the point group. This is case insensitive.
203 It should be a subgroup of D<sub>2h</sub>. If it is <tt>auto</tt>,
204 then the appropriate subgroup of D<sub>2h</sub> will be found.
205
206 <tr><td><tt>symmetry_tolerance</tt><td>double<td>1.0e-4<td>When
207 a molecule has symmetry, some atoms may be related by symmetry
208 operations. The distance between given atoms and atoms generated
209 by symmetry operations is compared to this threshold to determine
210 if they are the same. If they are the same, then the coordinates
211 are cleaned up to make them exactly symmetry equivalent. If the
212 given molecule was produced by a optimization that started in C1
213 symmetry, but produced a roughly symmetric structure and you would
214 like to begin using symmetry, then this may need to be increased a
215 bit to properly symmetrize the molecule.
216
217 <tr><td><tt>symmetry_frame</tt><td>double[3][3]<td>[[1 0 0][0 1
218 0][0 0 1]]<td>The symmetry frame. Ignored for <tt>symmetry =
219 auto</tt>.
220
221 <tr><td><tt>origin</tt><td>double[3]<td>[0 0 0]<td>The origin of
222 the symmetry frame. Ignored for <tt>symmetry = auto</tt>.
223
224 <tr><td><tt>redundant_atoms</tt><td>boolean<td>false<td>If true,
225 do not generate symmetry equivalent atoms; they are already given
226 in the input. It should not be necessary to specify this option,
227 since, by default, if a symmetry operation duplicates an atom, the
228 generated atom will not be added to the list of atoms. Ignored for
229 <tt>symmetry = auto</tt>.
230
231 <tr><td><tt>pdb_file</tt><td>string<td>undefined<td>This gives
232 the name of a PDB file, from which the nuclear coordinates will be
233 read. If this is given, the following options will be ignored.
234
235 <tr><td><tt>unit</tt><td>string<td>bohr<td>This gives the name
236 of the units used for the geometry. See the Units class for
237 information about the known units. This replaces deprecated
238 keywords that are still recognized: <tt>angstrom</tt> and
239 <tt>angstroms</tt>. This is ignored if <tt>pdb_file</tt> is given.
240
241 <tr><td><tt>geometry</tt><td>double[][3]<td>none<td>This gives
242 the Cartesian coordinates of the molecule. This is ignored if
243 <tt>pdb_file</tt> is given.
244
245 <tr><td><tt>atoms</tt><td>string[]<td>none<td>This gives the
246 Cartesian coordinates of the molecule. This is ignored if
247 <tt>pdb_file</tt> is given.
248
249 <tr><td><tt>ghost</tt><td>boolean[]<td>none<td>If true, the atom
250 will be given zero charge. It will still have basis functions,
251 however. This is used to estimate basis set superposition error.
252 This is ignored if <tt>pdb_file</tt> is given.
253
254 <tr><td><tt>charge</tt><td>double[]<td>Z for each atom<td>Allows
255 specification of the charge for each atom. This is ignored if
256 <tt>pdb_file</tt> is given.
257
258 <tr><td><tt>atom_labels</tt><td>string[]<td>none<td>This gives a
259 user defined atom label for each atom. This is ignored if
260 <tt>pdb_file</tt> is given.
261
262 <tr><td><tt>mass</tt><td>double[]<td>Taken from AtomInfo given by
263 the <tt>atominfo</tt> keyword. <td>This gives a user defined mass
264 for each atom. This is ignored if <tt>pdb_file</tt> is given.
265
266 </table>
267
268 */
269 Molecule(const Ref<KeyVal>&input);
270
271 virtual ~Molecule();
272
273 Molecule& operator=(const Molecule&);
274
275 /// Add an AtomicCenter to the Molecule.
276 void add_atom(int Z,double x,double y,double z,
277 const char * = 0, double mass = 0.0,
278 int have_charge = 0, double charge = 0.0);
279
280 /// Print information about the molecule.
281 virtual void print(std::ostream& =ExEnv::out0()) const;
282 virtual void print_parsedkeyval(std::ostream& =ExEnv::out0(),
283 int print_pg = 1,
284 int print_unit = 1,
285 int number_atoms = 1) const;
286
287 /// Returns the number of atoms in the molcule.
288 int natom() const { return natoms_; }
289
290 int Z(int atom) const { return Z_[atom]; }
291 double &r(int atom, int xyz) { return r_[atom][xyz]; }
292 const double &r(int atom, int xyz) const { return r_[atom][xyz]; }
293 double *r(int atom) { return r_[atom]; }
294 const double *r(int atom) const { return r_[atom]; }
295 double mass(int atom) const;
296 /** Returns the label explicitly assigned to atom. If
297 no label has been assigned, then null is returned. */
298 const char *label(int atom) const;
299
300 /** Takes an (x, y, z) postion and finds an atom within the
301 given tolerance distance. If no atom is found -1 is returned. */
302 int atom_at_position(double *, double tol = 0.05) const;
303
304 /** Returns the index of the atom with the given label.
305 If the label cannot be found -1 is returned. */
306 int atom_label_to_index(const char *label) const;
307
308 /** Returns a double* containing the nuclear
309 charges of the atoms. The caller is responsible for
310 freeing the return value. */
311 double *charges() const;
312
313 /// Return the charge of the atom.
314 double charge(int iatom) const;
315
316 /// Returns the total nuclear charge.
317 double nuclear_charge() const;
318
319 /// Sets the PointGroup of the molecule.
320 void set_point_group(const Ref<PointGroup>&, double tol=1.0e-7);
321 /// Returns the PointGroup of the molecule.
322 Ref<PointGroup> point_group() const;
323
324 /** Find this molecules true point group (limited to abelian groups).
325 If the point group of this molecule is set to the highest point
326 group, then the origin must first be set to the center of mass. */
327 Ref<PointGroup> highest_point_group(double tol = 1.0e-8) const;
328
329 /** Return 1 if this given axis is a symmetry element for the molecule.
330 The direction vector must be a unit vector. */
331 int is_axis(SCVector3 &origin,
332 SCVector3 &udirection, int order, double tol=1.0e-8) const;
333
334 /** Return 1 if the given plane is a symmetry element for the molecule.
335 The perpendicular vector must be a unit vector. */
336 int is_plane(SCVector3 &origin, SCVector3 &uperp, double tol=1.0e-8) const;
337
338 /// Return 1 if the molecule has an inversion center.
339 int has_inversion(SCVector3 &origin, double tol = 1.0e-8) const;
340
341 /// Returns 1 if the molecule is linear, 0 otherwise.
342 int is_linear(double tolerance = 1.0e-5) const;
343 /// Returns 1 if the molecule is planar, 0 otherwise.
344 int is_planar(double tolerance = 1.0e-5) const;
345 /** Sets linear to 1 if the molecular is linear, 0 otherwise.
346 Sets planar to 1 if the molecular is planar, 0 otherwise. */
347 void is_linear_planar(int&linear,int&planar,double tol = 1.0e-5) const;
348
349 /** Returns a SCVector3 containing the cartesian coordinates of
350 the center of mass for the molecule. */
351 SCVector3 center_of_mass() const;
352
353 /// Returns the nuclear repulsion energy for the molecule
354 double nuclear_repulsion_energy();
355
356 /** Compute the nuclear repulsion energy first derivative with respect
357 to the given center. */
358 void nuclear_repulsion_1der(int center, double xyz[3]);
359
360 /// Compute the electric field due to the nuclei at the given point.
361 void nuclear_efield(const double *position, double* efield);
362
363 /** Compute the electric field due to the given charges at the
364 positions of the nuclei at the given point. */
365 void nuclear_charge_efield(const double *charges,
366 const double *position, double* efield);
367
368 /** If the molecule contains only symmetry unique atoms, this function
369 will generate the other, redundant atoms. The redundant atom
370 will only be generated if there is no other atoms within a distance
371 of tol. If the is another atom and it is not identical, then
372 abort will be called. */
373 void symmetrize(double tol = 0.5);
374
375 /// Set the point group and then symmetrize.
376 void symmetrize(const Ref<PointGroup> &pg, double tol = 0.5);
377
378 /** This will try to carefully correct symmetry errors
379 in molecules. If any atom is out of place by more then
380 tol, abort will be called. */
381 void cleanup_molecule(double tol = 0.1);
382
383 void translate(const double *r);
384 void move_to_com();
385 void transform_to_principal_axes(int trans_frame=1);
386 void transform_to_symmetry_frame();
387 void print_pdb(std::ostream& =ExEnv::out0(), char *title =0) const;
388
389 void read_pdb(const char *filename);
390
391 /** Compute the principal moments of inertia and, possibly, the
392 principal axes. */
393 void principal_moments_of_inertia(double *evals, double **evecs=0) const;
394
395 /// Return information about symmetry unique and equivalent atoms.
396 int nunique() const { return nuniq_; }
397 /// Returns the overall number of the iuniq'th unique atom.
398 int unique(int iuniq) const { return equiv_[iuniq][0]; }
399 /// Returns the number of atoms equivalent to iuniq.
400 int nequivalent(int iuniq) const { return nequiv_[iuniq]; }
401 /// Returns the j'th atom equivalent to iuniq.
402 int equivalent(int iuniq, int j) const { return equiv_[iuniq][j]; }
403 /** Converts an atom number to the number of its generating unique atom.
404 The return value is in [0, nunique). */
405 int atom_to_unique(int iatom) const { return atom_to_uniq_[iatom]; }
406 /** Converts an atom number to the offset of this atom in the list of
407 generated atoms. The unique atom itself is allows offset 0. */
408 int atom_to_unique_offset(int iatom) const;
409
410 /// Return the number of core electrons.
411 int n_core_electrons();
412
413 /// Return the maximum atomic number.
414 int max_z();
415
416 /// Return the molecule's AtomInfo object.
417 Ref<AtomInfo> atominfo() const { return atominfo_; }
418
419 /// Returns the element name of the atom.
420 std::string atom_name(int iatom) const;
421
422 /// Returns the element symbol of the atom.
423 std::string atom_symbol(int iatom) const;
424
425 /** If include_q is true, then include the "Q" atoms in the charge and
426 efield routines. */
427 void set_include_q(bool iq) { include_q_ = iq; }
428 /// Returns include_q. See set_include_q.
429 bool include_q() const { return include_q_; }
430
431 /** If include_qq is true, include the coupling between pairs of "Q"
432 atoms when computing nuclear repulsion energy and gradients. */
433 void set_include_qq(bool iqq) { include_qq_ = iqq; }
434 /// Returns include_qq. See set_include_qq.
435 bool include_qq() const { return include_qq_; }
436
437 /// Retrieve the number of "Q" atoms.
438 int n_q_atom() const { return q_atoms_.size(); }
439 /// Retrieve the "Q" atoms.
440 int q_atom(int i) const { return q_atoms_[i]; }
441
442 /// Retrieve the number of non-"Q" atoms.
443 int n_non_q_atom() const { return non_q_atoms_.size(); }
444 /// Retrieve the of non-"Q" atoms.
445 int non_q_atom(int i) const { return non_q_atoms_[i]; }
446
447 void save_data_state(StateOut&);
448};
449
450}
451
452#endif
453
454// Local Variables:
455// mode: c++
456// c-file-style: "CLJ"
457// End:
Note: See TracBrowser for help on using the repository browser.