votca 2026-dev
Loading...
Searching...
No Matches
fragmentsaturator.h
Go to the documentation of this file.
1/*
2 * Copyright 2009-2026 The VOTCA Development Team
3 * (http://www.votca.org)
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License")
6 *
7 * You may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20#pragma once
21#ifndef VOTCA_XTP_FRAGMENTSATURATOR_H
22#define VOTCA_XTP_FRAGMENTSATURATOR_H
23
24// Local VOTCA includes
25#include "qmmolecule.h"
26
27namespace votca {
28namespace xtp {
29
53 public:
54 // A generic, "typical" C-H bond length (Angstrom) -- not specific to
55 // any one hybridization/element (this class only ever adds H atoms,
56 // never any other element, matching the "H-saturation" scope this
57 // whole feature was designed around from the start). Deliberately
58 // just a reasonable, generic default, not a carefully-chosen,
59 // atom-specific value -- the caller can override this directly via
60 // SaturateExternalBonds's own bond_length_angstrom parameter, and,
61 // in any case, this initial placement is only ever a starting point
62 // for a later, separate relaxation step, not the final, trusted
63 // position.
64 static constexpr double kDefaultCHBondLengthAngstrom = 1.09;
65
66 // Direct answer to a real, genuine gap surfaced while designing
67 // IPodCoupling::EvalJob, worked through directly with the user
68 // before implementing this: PODCoupling's own constructor needs to
69 // know which fragment (A or B) every atom belongs to, including
70 // every new, saturating H atom -- but which fragment a given H
71 // belongs to is NOT recoverable from its own final position or
72 // index alone (it must inherit whichever ORIGINAL atom it is
73 // saturating). new_atom_parent_ids is sized to mol's own,
74 // resulting, saturated size (result.mol.size()), and directly
75 // indexed by atom id: new_atom_parent_ids[i] is -1 for every atom
76 // that was already in the original, input molecule (i <
77 // original mol.size()), and the ORIGINAL atom's own id (i.e. the
78 // atom whose own external bond this new H is saturating) for every
79 // new H atom appended (i >= original mol.size()) -- deliberately
80 // NOT "which fragment", since SaturateExternalBonds itself has no
81 // concept of fragments at all (a generic, "saturate whatever
82 // molecule you are given" method); the caller (which does know
83 // which atom ids belong to which fragment) can translate this
84 // directly, itself.
87 std::vector<Index> new_atom_parent_ids;
88 };
89
90 // Returns a NEW QMMolecule (the input mol is never modified) with an
91 // additional H atom appended for every atom in mol that has
92 // hasExternalBond() == true, placed at bond_length_angstrom along
93 // that atom's own, already-recorded, already-transformed external-
94 // bond direction. Atoms without an external bond are copied
95 // unchanged, at their own, original indices -- the new H atoms are
96 // appended strictly after all of mol's own, original atoms, so
97 // every original atom's own index is preserved exactly (matching
98 // the same, direct requirement already confirmed, earlier this
99 // session, to be necessary for fragment_A/fragment_B atom-index
100 // definitions computed before this saturation step to remain valid
101 // afterward). See SaturationResult's own comment above for the new
102 // atoms' own parent-atom tracking.
104 const QMMolecule& mol,
105 double bond_length_angstrom = kDefaultCHBondLengthAngstrom);
106 // Returns a NEW QMMolecule (the input mol is never modified) with a
107 // constrained MMFF94 (or, if MMFF94 typing fails for some atom,
108 // UFF -- see this method's own .cc implementation for exactly when
109 // that fallback is used) relaxation applied: every atom with index
110 // < n_original_atoms is held fixed at its own, current position;
111 // every atom with index >= n_original_atoms (i.e. the new H atom(s)
112 // SaturateExternalBonds appended, per its own, documented
113 // convention of appending strictly after all original atoms) is
114 // free to move. Genuinely needs mol's own, real, full internal bond
115 // connectivity (via QMAtom::getBondedPartnerIds(), populated by the
116 // SegmentMapper/Md2QmEngine pipeline already built earlier this
117 // session) to build a real OpenBabel OBMol and correctly set up its
118 // own force field at all -- confirmed directly, earlier this
119 // session, that OpenBabel's own OBMol::PerceiveBondOrders() (used
120 // here to derive bond order/hybridization from this known
121 // connectivity plus real 3D geometry) needs that connectivity as
122 // real input, it does not itself guess which atoms are bonded at
123 // all -- and confirmed, separately, that geometry-only bond
124 // perception (no known connectivity at all) is genuinely unreliable
125 // for exactly this kind of situation (a newly-added atom), via a
126 // real, earlier, direct RDKit test this same session that gave a
127 // chemically wrong result for an analogous case.
128 //
129 // n_steps is the maximum number of conjugate-gradient steps
130 // (OBForceField::ConjugateGradients's own argument, passed through
131 // directly, unmodified).
132 static QMMolecule RelaxNewAtoms(const QMMolecule& mol, Index n_original_atoms,
133 Index n_steps = 500);
134};
135
136} // namespace xtp
137} // namespace votca
138
139#endif // VOTCA_XTP_FRAGMENTSATURATOR_H
Saturates a mapped QMMolecule's own, real, external (i.e. covalently bonded at the MD level,...
static QMMolecule RelaxNewAtoms(const QMMolecule &mol, Index n_original_atoms, Index n_steps=500)
static constexpr double kDefaultCHBondLengthAngstrom
static SaturationResult SaturateExternalBonds(const QMMolecule &mol, double bond_length_angstrom=kDefaultCHBondLengthAngstrom)
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26