XtalOptimizer: Fix how monoclinic is generated
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 10m3s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 11m32s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 12m37s
Build Packages / Generate python client (push) Successful in 30s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 13m7s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 13m35s
Build Packages / Create release (push) Has been skipped
Build Packages / Build documentation (push) Successful in 1m0s
Build Packages / build:rpm (rocky8) (push) Successful in 14m27s
Build Packages / build:rpm (rocky9) (push) Successful in 14m50s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 15m15s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 9m25s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 8m1s
Build Packages / Unit tests (push) Has been cancelled
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 10m3s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 11m32s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 12m37s
Build Packages / Generate python client (push) Successful in 30s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 13m7s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 13m35s
Build Packages / Create release (push) Has been skipped
Build Packages / Build documentation (push) Successful in 1m0s
Build Packages / build:rpm (rocky8) (push) Successful in 14m27s
Build Packages / build:rpm (rocky9) (push) Successful in 14m50s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 15m15s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 9m25s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 8m1s
Build Packages / Unit tests (push) Has been cancelled
This commit is contained in:
@@ -307,11 +307,11 @@ inline void LatticeToRodriguesLengthsBeta_Mono(const CrystalLattice &latt,
|
||||
const Coord c = latt.Vec2();
|
||||
|
||||
Eigen::Vector3d A(a[0], a[1], a[2]);
|
||||
Eigen::Vector3d B(b[0], b[1], b[2]);
|
||||
Eigen::Vector3d Bv(b[0], b[1], b[2]);
|
||||
Eigen::Vector3d C(c[0], c[1], c[2]);
|
||||
|
||||
const double a_len = A.norm();
|
||||
const double b_len = B.norm();
|
||||
const double b_len = Bv.norm();
|
||||
const double c_len = C.norm();
|
||||
|
||||
lengths[0] = a_len;
|
||||
@@ -323,35 +323,34 @@ inline void LatticeToRodriguesLengthsBeta_Mono(const CrystalLattice &latt,
|
||||
if (a_len > 0.0 && c_len > 0.0)
|
||||
cos_beta = std::max(-1.0, std::min(1.0, A.dot(C) / (a_len * c_len)));
|
||||
beta_rad = std::acos(cos_beta);
|
||||
Eigen::Vector3d e2, ax;
|
||||
|
||||
// e2 along b (unique axis)
|
||||
if (b_len > 0.0)
|
||||
e2 = B / b_len;
|
||||
else
|
||||
e2 = Eigen::Vector3d::UnitY();
|
||||
// Recover R from the same forward model used in refinement:
|
||||
// L ≈ R * D(a,b,c) * B(beta) => R ≈ L * (D*B)^-1
|
||||
Eigen::Matrix3d L;
|
||||
L.col(0) = A;
|
||||
L.col(1) = Bv;
|
||||
L.col(2) = C;
|
||||
|
||||
if (a_len > 0.0)
|
||||
ax = A / a_len;
|
||||
else
|
||||
ax = Eigen::Vector3d::UnitX();
|
||||
Eigen::Matrix3d Bmono = Eigen::Matrix3d::Identity();
|
||||
Bmono(0, 2) = std::cos(beta_rad);
|
||||
Bmono(2, 2) = std::sin(beta_rad);
|
||||
|
||||
Eigen::Vector3d e1 = ax - (ax.dot(e2)) * e2;
|
||||
double n1 = e1.norm();
|
||||
if (n1 < 1e-15) {
|
||||
// Fallback: use any perpendicular to e2
|
||||
e1 = (std::abs(e2.x()) < 0.9
|
||||
? Eigen::Vector3d::UnitX().cross(e2)
|
||||
: Eigen::Vector3d::UnitY().cross(e2));
|
||||
Eigen::DiagonalMatrix<double, 3> D(lengths[0], lengths[1], lengths[2]);
|
||||
Eigen::Matrix3d M = D * Bmono;
|
||||
|
||||
Eigen::Matrix3d R_est = Eigen::Matrix3d::Identity();
|
||||
if (std::abs(M.determinant()) > 1e-15) {
|
||||
R_est = L * M.inverse();
|
||||
}
|
||||
e1.normalize();
|
||||
// e3 completes the right-handed frame
|
||||
Eigen::Vector3d e3 = e1.cross(e2).normalized();
|
||||
|
||||
Eigen::Matrix3d R;
|
||||
R.col(0) = e1;
|
||||
R.col(1) = e2;
|
||||
R.col(2) = e3;
|
||||
// Project to nearest proper rotation (polar decomposition via SVD)
|
||||
Eigen::JacobiSVD<Eigen::Matrix3d> svd(R_est, Eigen::ComputeFullU | Eigen::ComputeFullV);
|
||||
Eigen::Matrix3d R = svd.matrixU() * svd.matrixV().transpose();
|
||||
if (R.determinant() < 0.0) {
|
||||
Eigen::Matrix3d U = svd.matrixU();
|
||||
U.col(2) *= -1.0;
|
||||
R = U * svd.matrixV().transpose();
|
||||
}
|
||||
|
||||
Eigen::AngleAxisd aa(R);
|
||||
Eigen::Vector3d r = aa.angle() * aa.axis();
|
||||
@@ -520,7 +519,7 @@ bool XtalOptimizerInternal(XtalOptimizerData &data,
|
||||
else {
|
||||
const double dist_range = 0.1;
|
||||
problem.SetParameterLowerBound(&distance_mm, 0, distance_mm * (1.0 - dist_range));
|
||||
problem.SetParameterLowerBound(&distance_mm, 0, distance_mm * (1.0 + dist_range));
|
||||
problem.SetParameterUpperBound(&distance_mm, 0, distance_mm * (1.0 + dist_range));
|
||||
}
|
||||
|
||||
if (!data.refine_beam_center) {
|
||||
|
||||
Reference in New Issue
Block a user