26 double distThreshold) {
32 std::lock_guard<std::mutex> lock(res.library_mutex);
36 }
catch (
const std::exception &e) {
45 std::vector<int> typ1(nat1), typ2(nat2);
48 for (
int i = 0; i < nat1; i++)
50 for (
int i = 0; i < nat2; i++)
59 Eigen::Map<const AtomMatrixF> coords1_map(pos1.data(), 3, nat1);
60 Eigen::Map<const AtomMatrixF> coords2_map(pos2.data(), 3, nat2);
64 std::vector<int> cand1(nat1, 0), cand2(nat2, 0);
70 for (
int i = 0; i < nat2; i++)
75 std::vector<double> rmat_buf(9);
76 std::vector<double> tr_buf(3);
77 std::vector<int> perm_buf(nat2);
83 double *rmat_ptr = rmat_buf.data();
84 double *tr_ptr = tr_buf.data();
85 int *perm_ptr = perm_buf.data();
87 res.get_match_fn()(nat1, typ1.data(), coords1_map.data(), cand1.data(), nat2,
88 typ2.data(), coords2_map.data(), cand2.data(),
89 distThreshold, &rmat_ptr, &tr_ptr, &perm_ptr, &hd, &ierr);
93 result.
permutation.assign(perm_ptr, perm_ptr + nat2);
97 Eigen::Map<const Matrix3d> rot_map(rmat_ptr);
100 result.
translation = Eigen::Map<const Vector3d>(tr_ptr);
107 if (rmat_ptr != rmat_buf.data())
109 if (tr_ptr != tr_buf.data())
111 if (perm_ptr != perm_buf.data())
120 double distThreshold) {
126 std::lock_guard<std::mutex> lock(res.library_mutex);
129 res.require_loaded();
130 }
catch (
const std::exception &e) {
138 std::vector<int> typ1(nat1), typ2(nat2);
141 for (
int i = 0; i < nat1; i++)
143 for (
int i = 0; i < nat2; i++)
150 Eigen::Map<const AtomMatrixF> coords1_map(pos1.data(), 3, nat1);
151 Eigen::Map<const AtomMatrixF> coords2_map(pos2.data(), 3, nat2);
156 for (
int i = 0; i < 3; i++)
157 for (
int j = 0; j < 3; j++)
158 lat[j * 3 + i] = cell(i, j);
161 std::vector<int> found_buf(nat1);
162 std::vector<double> dists_buf(nat1);
163 int *found_ptr = found_buf.data();
164 double *dists_ptr = dists_buf.data();
169 res.get_cshda_pbc_fn()(nat1, typ1.data(), coords1_map.data(), nat2,
170 typ2.data(), coords2_map.data(), lat, distThreshold,
171 &found_ptr, &dists_ptr);
173 result.
permutation.assign(found_ptr, found_ptr + nat1);
175 for (
int i = 0; i < nat1; i++) {
178 result.
rotation = Eigen::Matrix3d::Identity();
194 std::lock_guard<std::mutex> lock(res.library_mutex);
197 res.require_loaded();
198 }
catch (
const std::exception &e) {
204 std::vector<int> typ(nat);
206 for (
int i = 0; i < nat; i++)
211 Eigen::Map<const AtomMatrixF> coords_map(pos.data(), 3, nat);
214 int nmax = res.get_get_nmax_fn()();
217 std::vector<double> mat_buf(9 * nmax);
218 std::vector<int> perm_buf(nat * nmax);
219 std::vector<char> op_buf(nmax + 1);
220 std::vector<int> n_buf(nmax);
221 std::vector<int> p_buf(nmax);
222 std::vector<double> ax_buf(3 * nmax);
223 std::vector<double> angle_buf(nmax);
224 std::vector<double> dH_buf(nmax);
225 std::vector<char> pg_buf(11);
227 std::vector<double> prin_ax_buf(3 * nmax);
230 double *mat_data = mat_buf.data();
231 int *perm_data = perm_buf.data();
232 char *op_data = op_buf.data();
233 int *n_data = n_buf.data();
234 int *p_data = p_buf.data();
235 double *ax_data = ax_buf.data();
236 double *angle_data = angle_buf.data();
237 double *dH_data = dH_buf.data();
238 char *pg = pg_buf.data();
239 double *prin_ax = prin_ax_buf.data();
241 res.get_compute_all_fn()(nat, typ.data(), coords_map.data(), threshold,
242 prescreenIh ? 1 : 0, &n_mat, &mat_data, &perm_data,
243 &op_data, &n_data, &p_data, &ax_data, &angle_data,
244 &dH_data, &pg, &n_prin_ax, &prin_ax, &cerr);
254 for (
int k = 0; k < n_mat; k++) {
255 Eigen::Map<const Matrix3d> op_map(&mat_data[k * 9]);
261 result.
angles.assign(angle_data, angle_data + n_mat);
264 result.
axes.resize(n_mat);
265 for (
int k = 0; k < n_mat; k++) {
266 result.
axes[k] = Eigen::Map<const Vector3d>(&ax_data[k * 3]);
275 if (mat_data != mat_buf.data())
277 if (perm_data != perm_buf.data())
278 std::free(perm_data);
279 if (op_data != op_buf.data())
281 if (n_data != n_buf.data())
283 if (p_data != p_buf.data())
285 if (ax_data != ax_buf.data())
287 if (angle_data != angle_buf.data())
288 std::free(angle_data);
289 if (dH_data != dH_buf.data())
291 if (pg != pg_buf.data())
293 if (prin_ax != prin_ax_buf.data())
static MatchResult matchPBC(const Matter &m1, const Matter &m2, double distThreshold)
Atom assignment under periodic boundary conditions (CShDA only, no rotation/SVD).