Loading...
Searching...
No Matches
GPRHelpers.cpp
Go to the documentation of this file.
1/*
2** This file is part of eOn.
3**
4** SPDX-License-Identifier: BSD-3-Clause
5**
6** Copyright (c) 2010--present, eOn Development Team
7** All rights reserved.
8**
9** Repo:
10** https://github.com/TheochemUI/eOn
11*/
12#include "eon/GPRHelpers.h"
13#include "eon/EonLogger.h"
14
15#include "subprojects/gpr_optim/data_types/EigenHelpers.h"
16
17#include <cstring>
18#include <map>
19#include <set>
20#include <stdexcept>
21#include <unordered_map>
22
23namespace eonc {
24
25gpr::InputParameters
27 gpr::InputParameters p;
28 // Problem parameters
29 p.actdist_fro.value = parameters.gpr_dimer_options().active_radius;
30 p.dimer_sep.value = parameters.gpr_dimer_options().dimer_sep;
31 p.method_rot.value = parameters.gpr_dimer_options().rot_opt_method;
32 p.method_trans.value = parameters.gpr_dimer_options().trans_opt_method;
33 p.param_trans.value[0] = parameters.gpr_dimer_options().conv_step;
34 p.param_trans.value[1] = parameters.gpr_dimer_options().max_step;
35 // Saddle point convergence parameter
36 p.T_dimer.value = parameters.saddle_search_options().converged_force;
37 p.T_anglerot_init.value = parameters.gpr_dimer_options().converged_angle;
38 // ---
39 p.initrot_nogp.value = parameters.gpr_dimer_options().init_rot_gp;
40 p.num_iter_initrot.value = parameters.gpr_dimer_options().init_rotations_max;
41 // unused except in the capnp for now
42 // p.inittrans_nogp.value = parameters.gpr_dimer_options().init_trans_gp;
43 p.T_anglerot_gp.value = parameters.gpr_dimer_options().relax_conv_angle;
44 p.num_iter_rot_gp.value = parameters.gpr_dimer_options().relax_rotations_max;
45 p.divisor_T_dimer_gp.value =
47 p.disp_max.value = parameters.gpr_dimer_options().midpoint_max_disp;
48 p.ratio_at_limit.value = parameters.gpr_dimer_options().ratio_at_limit;
49 p.num_bigiter.value = parameters.gpr_dimer_options().max_outer_iterations;
50 p.num_iter.value = parameters.gpr_dimer_options().max_inner_iterations;
51 p.islarge_num_iter.value = parameters.gpr_dimer_options().many_iterations;
52 // GPR Parameters
53 p.gp_sigma2.value = parameters.gpr_dimer_options().gpr_params.sigma2;
54 p.jitter_sigma2.value =
56 p.sigma2.value = parameters.gpr_dimer_options().gpr_params.noise_sigma2;
57 p.prior_mu.value = parameters.gpr_dimer_options().gpr_params.prior_mu;
58 p.prior_nu.value = parameters.gpr_dimer_options().gpr_params.prior_nu;
59 p.prior_s2.value = parameters.gpr_dimer_options().gpr_params.prior_sigma2;
60 // gpr_optim enables the check only when this string equals "true".
61 // A bool assigns as one char, so the flag never turns on.
62 p.check_derivative.value =
64 : "false";
65 p.max_iter.value = parameters.gpr_dimer_options().opt_params.max_iterations;
66 p.tolerance_func.value = parameters.gpr_dimer_options().opt_params.tol_func;
67 p.tolerance_sol.value = parameters.gpr_dimer_options().opt_params.tol_sol;
68 p.lambda_limit.value = parameters.gpr_dimer_options().opt_params.lambda_limit;
69 p.lambda.value = parameters.gpr_dimer_options().opt_params.lambda_init;
70 // Prune
71 p.use_prune.value = parameters.gpr_dimer_options().prune_params.use_prune;
72 p.start_prune_at.value = parameters.gpr_dimer_options().prune_params.begin;
73 p.nprune_vals.value = parameters.gpr_dimer_options().prune_params.n_vals;
74 p.prune_threshold.value =
76 // Debugging
77 p.report_level.value =
79 p.debug_level.value = parameters.gpr_dimer_options().debug_params.debug_level;
80 p.debug_output_dir.value =
82 p.debug_output_file_R.value =
84 p.debug_output_file_E.value =
86 p.debug_output_file_G.value =
88 p.debug_output_file_extension.value =
90 p.debug_offset_from_mid_point.value =
92 p.debug_dy.value = parameters.gpr_dimer_options().debug_params.dy;
93 p.debug_dz.value = parameters.gpr_dimer_options().debug_params.dz;
94 return p;
95}
96
97namespace {
98
99// AtomMatrix is row-major N×3; gpr::Coord is 1×(3N) with the same flat packing.
100void copyAtomMatrixToCoord(const AtomMatrix &src, gpr::Coord &dst) {
101 dst.resize(1, static_cast<Eigen::Index>(src.size()));
102 if (src.size() > 0) {
103 std::memcpy(dst.data(), src.data(),
104 static_cast<size_t>(src.size()) * sizeof(double));
105 }
106}
107
108} // namespace
109
110// gpr_optim pairtype is an n_species × n_species matrix indexed 0..n-1.
111// Matter stores real Z; remap here rather than changing the GPR kernel.
112gpr::AtomsConfiguration eonc::helpers::eon_matter_to_atmconf(Matter *matter) {
113 if (!matter) {
114 throw std::invalid_argument("eon_matter_to_atmconf: null Matter");
115 }
116 gpr::AtomsConfiguration atoms_config;
117 aux::ProblemSetUp problem_setup;
118 gpr::Index_t number_of_mov_atoms;
119 gpr::Index_t number_of_fro_atoms;
120 std::set<int> unique_atomtypes;
121 gpr::Index_t n_at;
122 std::vector<int> atomnrs;
123 std::unordered_map<int, int>
124 atype_to_gprd_atype;
127 int fake_atype;
128
129 atoms_config.clear();
130 // gpr_optim stores positions as row-major 1×(3N), matching AtomMatrix flat
131 // layout.
132 copyAtomMatrixToCoord(matter->getPositions(), atoms_config.positions);
133 const auto nAtoms = matter->numberOfAtoms();
134 atoms_config.is_frozen.resize(1, nAtoms);
135 atoms_config.id.resize(1, nAtoms);
136 atoms_config.atomicNrs.resize(1, nAtoms);
137 for (auto i = 0; i < nAtoms; i++) {
138 atomnrs.push_back(matter->getAtomicNr(i));
139 // Field matrices are 1×N; use (0, i). getFixed is bool → MOVING/FROZEN.
140 atoms_config.atomicNrs(0, i) = matter->getAtomicNr(i);
141 atoms_config.is_frozen(0, i) =
142 matter->getFixed(i) ? FROZEN_ATOM : MOVING_ATOM;
143 atoms_config.id(0, i) = static_cast<gpr::Index_t>(i + 1);
144 }
145
146 unique_atomtypes = std::set<int>(atomnrs.begin(), atomnrs.end());
147 n_at = unique_atomtypes.size();
148 fake_atype = 0;
149 for (auto uatom : unique_atomtypes) {
150 atype_to_gprd_atype.insert(
151 std::pair<int, int>(static_cast<int>(uatom), fake_atype));
152 fake_atype++;
153 }
154
155 number_of_mov_atoms = atoms_config.countMovingAtoms();
156 number_of_fro_atoms =
157 static_cast<gpr::Index_t>(atoms_config.is_frozen.size()) -
158 number_of_mov_atoms;
159
160 if (number_of_fro_atoms > 0 && number_of_mov_atoms > 0) {
161 // Resize structures for moving and frozen atoms
162 atoms_config.atoms_mov.resize(number_of_mov_atoms);
163 atoms_config.atoms_froz_inactive.resize(number_of_fro_atoms);
164
165 // Dense GPR types from the Z→0..n-1 map.
166 if (atype_to_gprd_atype.size() > 1) {
167 int mov_counter = 0;
168 int froz_inactive_counter = 0;
169 for (auto i = 0; i < nAtoms; i++) {
170 if (matter->getFixed(i)) {
173 atoms_config.atoms_froz_inactive.type(0, froz_inactive_counter) =
174 atype_to_gprd_atype.at(atomnrs[i]);
175 froz_inactive_counter++;
176 } else {
178 atoms_config.atoms_mov.type(0, mov_counter) =
179 atype_to_gprd_atype.at(atomnrs[i]);
180 mov_counter++;
181 }
182 }
183 }
186 else if (atype_to_gprd_atype.size() == 1) {
187 atoms_config.atoms_mov.type.setConstant(
188 atype_to_gprd_atype.at(atomnrs[0]));
189 atoms_config.atoms_froz_inactive.type.setConstant(
190 atype_to_gprd_atype.at(atomnrs[0]));
191 }
192 // Assign moving and frozen atoms and list all frozen atoms as inactive
193 gpr::Index_t counter_f = 0, counter_m = 0;
194 for (gpr::Index_t n = 0;
195 n < static_cast<gpr::Index_t>(atoms_config.is_frozen.size()); ++n) {
196 if (atoms_config.is_frozen(0, n) == MOVING_ATOM)
197 gpr::coord::set(atoms_config.atoms_mov.positions, 0, counter_m++,
198 gpr::coord::at(atoms_config.positions, n));
199 else
200 gpr::coord::set(atoms_config.atoms_froz_inactive.positions, 0,
201 counter_f++, gpr::coord::at(atoms_config.positions, n));
202 }
204 } else {
205 if (number_of_mov_atoms == 0) {
206 throw std::runtime_error("eon_matter_to_atmconf: no moving atoms");
207 }
210 atoms_config.atoms_mov.resize(number_of_mov_atoms);
211
212 // Dense GPR types from the Z→0..n-1 map.
213 if (atype_to_gprd_atype.size() > 1) {
214 int mov_counter = 0;
215 for (auto i = 0; i < nAtoms; i++) {
216 atoms_config.atoms_mov.type(0, mov_counter) =
217 atype_to_gprd_atype.at(atomnrs[i]);
218 mov_counter++;
219 }
220 }
223 else if (atype_to_gprd_atype.size() == 1) {
224 atoms_config.atoms_mov.type.setConstant(
225 atype_to_gprd_atype.at(atomnrs[0]));
226 }
227 }
228 // Pairtype indices for pairs of atomtypes (n_at x n_at)
229 // Active pairtypes are indexed as 0,1,...,n_pt-1. Inactive pairtypes are
230 // given index EMPTY.
231 atoms_config.pairtype.resize(n_at, n_at);
232 atoms_config.pairtype.setConstant(EMPTY);
233
234 // Set pairtype indices for moving+moving atom pairs (and update number of
235 // active pairtypes)
236 problem_setup.setPairtypeForMovingAtoms(
237 atoms_config.atoms_mov.type, atoms_config.n_pt, atoms_config.pairtype);
238
239 return atoms_config;
240}
241
242gpr::Observation eonc::helpers::eon_matter_to_init_obs(Matter *matter) {
243 gpr::Observation o;
244 o.clear();
245 copyAtomMatrixToCoord(matter->getPositions(), o.R);
246 // Forces as negative gradients; same N×3 → 1×(3N) packing as positions.
247 AtomMatrix neg_forces = -matter->getForces();
248 copyAtomMatrixToCoord(neg_forces, o.G);
249 o.E.resize(1, 1);
250 o.E(0, 0) = matter->getPotentialEnergy();
251 return o;
252}
253
254} // namespace eonc
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
Definition Eigen.h:37
const AtomMatrix & getPositions() const
Definition Matter.cpp:308
long int numberOfAtoms() const
Definition Matter.cpp:273
double getPotentialEnergy() const
Definition Matter.cpp:554
long getAtomicNr(long int atom) const
Definition Matter.cpp:495
const AtomMatrix & getForces() const
Definition Matter.cpp:412
int getFixed(long int atom) const
1 if every Cartesian axis of the atom is fixed, else 0.
Definition Matter.cpp:505
const saddle_search_options_t & saddle_search_options() const
const gpr_dimer_options_t & gpr_dimer_options() const
gpr::InputParameters eon_parameters_to_gpr(const Parameters &parameters)
Create a parameters object for gpr_dimer.
gpr::AtomsConfiguration eon_matter_to_atmconf(Matter *matter)
Create a configuration of atoms for gpr_dimer.
gpr::Observation eon_matter_to_init_obs(Matter *matter)
Create an initial Observation object for gpr_dimer.
RAII resource manager for the ARTn C library with global synchronization.
struct eonc::gpr_dimer_options_t::prune_params_t prune_params
struct eonc::gpr_dimer_options_t::gpr_params_t gpr_params
struct eonc::gpr_dimer_options_t::debug_params_t debug_params
struct eonc::gpr_dimer_options_t::opt_params_t opt_params