64 const int *typ2,
const double *pos2,
71 }
catch (
const std::exception &e) {
76 if (nat1 <= 0 || nat2 <= 0 || typ1 ==
nullptr || typ2 ==
nullptr ||
77 pos1 ==
nullptr || pos2 ==
nullptr) {
84 Eigen::Map<const AtomMatrixF> coords1_map(pos1, 3, nat1);
85 Eigen::Map<const AtomMatrixF> coords2_map(pos2, 3, nat2);
89 std::vector<int> cand1(nat1, 0), cand2(nat2, 0);
95 for (
int i = 0; i < nat2; i++)
100 std::vector<double> rmat_buf(9);
101 std::vector<double> tr_buf(3);
102 std::vector<int> perm_buf(nat2);
108 double *rmat_ptr = rmat_buf.data();
109 double *tr_ptr = tr_buf.data();
110 int *perm_ptr = perm_buf.data();
112 res.
get_match_fn()(nat1, typ1, coords1_map.data(), cand1.data(), nat2, typ2,
113 coords2_map.data(), cand2.data(), distThreshold, &rmat_ptr,
114 &tr_ptr, &perm_ptr, &hd, &ierr);
118 result.
permutation.assign(perm_ptr, perm_ptr + nat2);
122 Eigen::Map<const Matrix3d> rot_map(rmat_ptr);
125 result.
translation = Eigen::Map<const Vector3d>(tr_ptr);
132 if (rmat_ptr != rmat_buf.data())
134 if (tr_ptr != tr_buf.data())
136 if (perm_ptr != perm_buf.data())
153 double distThreshold,
160 }
catch (
const std::exception &e) {
167 if (nat1 <= 0 || nat2 <= 0) {
172 std::vector<int> typ1(nat1), typ2(nat2);
175 for (
int i = 0; i < nat1; i++)
177 for (
int i = 0; i < nat2; i++)
184 Eigen::Map<const AtomMatrixF> coords1_map(pos1.data(), 3, nat1);
185 Eigen::Map<const AtomMatrixF> coords2_map(pos2.data(), 3, nat2);
190 for (
int i = 0; i < 3; i++)
191 for (
int j = 0; j < 3; j++)
192 lat[j * 3 + i] = cell(i, j);
195 std::vector<int> found_buf(nat1);
196 std::vector<double> dists_buf(nat1);
197 int *found_ptr = found_buf.data();
198 double *dists_ptr = dists_buf.data();
204 typ2.data(), coords2_map.data(), lat, distThreshold,
205 &found_ptr, &dists_ptr);
207 result.
permutation.assign(found_ptr, found_ptr + nat1);
209 for (
int i = 0; i < nat1; i++) {
212 result.
rotation = Eigen::Matrix3d::Identity();
238 }
catch (
const std::exception &e) {
244 std::vector<int> typ(nat);
246 for (
int i = 0; i < nat; i++)
251 Eigen::Map<const AtomMatrixF> coords_map(pos.data(), 3, nat);
257 std::vector<double> mat_buf(9 * nmax);
258 std::vector<int> perm_buf(nat * nmax);
259 std::vector<char> op_buf(nmax + 1);
260 std::vector<int> n_buf(nmax);
261 std::vector<int> p_buf(nmax);
262 std::vector<double> ax_buf(3 * nmax);
263 std::vector<double> angle_buf(nmax);
264 std::vector<double> dH_buf(nmax);
265 std::vector<char> pg_buf(11);
267 std::vector<double> prin_ax_buf(3 * nmax);
270 double *mat_data = mat_buf.data();
271 int *perm_data = perm_buf.data();
272 char *op_data = op_buf.data();
273 int *n_data = n_buf.data();
274 int *p_data = p_buf.data();
275 double *ax_data = ax_buf.data();
276 double *angle_data = angle_buf.data();
277 double *dH_data = dH_buf.data();
278 char *pg = pg_buf.data();
279 double *prin_ax = prin_ax_buf.data();
282 prescreenIh ? 1 : 0, &n_mat, &mat_data, &perm_data,
283 &op_data, &n_data, &p_data, &ax_data, &angle_data,
284 &dH_data, &pg, &n_prin_ax, &prin_ax, &cerr);
294 for (
int k = 0; k < n_mat; k++) {
295 Eigen::Map<const Matrix3d> op_map(&mat_data[k * 9]);
301 result.
angles.assign(angle_data, angle_data + n_mat);
304 result.
axes.resize(n_mat);
305 for (
int k = 0; k < n_mat; k++) {
306 result.
axes[k] = Eigen::Map<const Vector3d>(&ax_data[k * 3]);
315 if (mat_data != mat_buf.data())
317 if (perm_data != perm_buf.data())
318 std::free(perm_data);
319 if (op_data != op_buf.data())
321 if (n_data != n_buf.data())
323 if (p_data != p_buf.data())
325 if (ax_data != ax_buf.data())
327 if (angle_data != angle_buf.data())
328 std::free(angle_data);
329 if (dH_data != dH_buf.data())
331 if (pg != pg_buf.data())
333 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).
static MatchResult match(const Matter &m1, const Matter &m2, double distThreshold)
Match two structures using CShDA + SVD (optimal rotation + assignment).
static MatchResult matchArrays(int nat1, const int *typ1, const double *pos1, int nat2, const int *typ2, const double *pos2, double distThreshold)
Same as match(), from packed (n,3) row-major coordinates and Z arrays.