Symmetrization M1: derive orbital-op U_S from H0 (shadow mode)#368
Symmetrization M1: derive orbital-op U_S from H0 (shadow mode)#368tylersax wants to merge 4 commits into
Conversation
PDoakORNL
left a comment
There was a problem hiding this comment.
Ok I didn't have time to completely work through this in full detail but I think there is something up with the folded_phase and solveSignsForOp that is a bit subtle and not correct right now.
But that also depends on whether I understand your intent right from the comments with respect to this method and U_S. You may have just deferred this to a future PR.
A unit test that GPT-5.5 "extracted" for me from the three band hubbard that hits this
TEST(SolveOrbitalOpSigns, ThreebandBoundaryFoldDoesNotMaskPxParity) {
struct Sym {
std::pair<int, int> operator()(int k, int b, int s) const {
return {0, b}; // one folded k representative: (pi,0), no band permutation.
}
};
struct H0 {
std::complex<double> operator()(int b0, int, int b1, int, int) const {
const std::complex<double> I(0., 1.);
if (b0 == 0 && b1 == 1)
return 2. * I; // d-px at k=(pi,0), t_pd=1
if (b0 == 1 && b1 == 0)
return -2. * I; // Hermitian partner as in threeband_hubbard.hpp
return 0.;
}
};
struct U {
double data[3][3] = {};
double& operator()(int r, int c, int) {
return data[r][c];
}
};
U u;
dca::phys::detail::solveSignsForOp(0, 3, 1, Sym{}, H0{}, u);
EXPECT_DOUBLE_EQ(u(0, 0, 0), +1.);
EXPECT_DOUBLE_EQ(u(1, 1, 0), -1.); // Fails today: current solver gives +1.
EXPECT_DOUBLE_EQ(u(2, 2, 0), +1.);
}
Well allegedly, I was already going down this path so it may have picked up on this.
I will try and put together a mock setup that actually uses the real model and not llm brute force in the next day or two.
|
@PDoakORNL great catch. I don't fully have my head around it but I do think you're onto something. The fold phases are quite tricky. Let me noodle on this more tomorrow and see if I can get to the bottom of it. Regarding all of the other inlines: ack, will address. |
Address PR CompFUSE#368 review: solveSignsForOp previously compared H0 at k against the folded representative k_new = S k - G without undressing the folding phase phi_b = e^{i G.a_b}, so the solved U_S absorbed the dressing instead of the intrinsic orbital transform (e.g. masking the odd parity of p_x under a mirror at a zone-boundary momentum). The stored get_fold_phase() table was populated but unconsumed. solveSignsForOp now takes the fold phase and divides it out of the coupling ratio. The test cases now redress accordingly, and a new regression BoundaryFoldDoesNotMaskPxParity covers the exact case raised in the PR comment. Also: adjust copyright, promote complex-fold notes to \todo, and clarify comment wording
|
OK @PDoakORNL - have a look at this update. It's more clear to me now where the fold phase was sneakily getting absorbed. This commit properly dresses and undresses the sign, and adds a test to pin it down in exactly the way you suggested. So back to you: is there anything else we should be thinking about here? What other geometric edge cases come to mind? |
|
I have not looked at the details yet, but Tyler and I discussed the overall concept and came to the conclusion that it makes sense and should work. |
PDoakORNL
left a comment
There was a problem hiding this comment.
Ok this LGTM now.
There is some new issue with the CI which I need to resolve but assuming checks still pass when that is fixed I think this is ready to merge.
Derive each point-group operation's orbital transform U_S directly from H0(k), replacing the hand-coded transformationSignOf* lookups, and verify it against the deterministic G0 oracle. All shadow-mode: nothing consumes the record for imposition yet, so production output is unchanged.
solve_orbital_op_signs.hpp(new): U_S = D.P, where the band permutation P is the geometry-given symmetry-table image and the +/-1 signs D are solved from the H0 coupling constraints by enumerate-and-verify.cluster_symmetry: add shadow accessors get_mapped_point and get_orbital_op.set_symmetry_matrices: populate mapped_point (the band-independent momentum image, ".first" promoted out of the symmetry-matrix pair).Integration test: add
PerOpMapMomentumUS(ensure U_S is well formed),GroupShadowCrossCheck(the H0-verified group equals the declared group on every shipped model),MappedPointShadow, and synthetic H0 rejection fixtures covering all three throw branches. Note these are designed under the assumption that we will encounter more complex forms of H0 in the material models.Candidates still come from the declared point group, so DCA_point_group is the shadow oracle.
Mini-roadmap
Snapshot of where we are in the project (subject to change but this is what I'm thinking):
M0: Characterization harness