diff --git a/tests/QS/regtest-moments-kpoints/TEST_FILES.toml b/tests/QS/regtest-moments-kpoints/TEST_FILES.toml index 663e097bfd..9608b8c700 100644 --- a/tests/QS/regtest-moments-kpoints/TEST_FILES.toml +++ b/tests/QS/regtest-moments-kpoints/TEST_FILES.toml @@ -6,12 +6,12 @@ # # compute ground state for graphene with PBE and SZV # compute the dipole moments for kpoints in the &DFT section -"C2_pbe_scf_kp.inp" = [{matcher="Dipole_abs_dx_at_kp_1", tol=1.0E-06, ref=0.5705436}] +"C2_pbe_scf_kp.inp" = [{matcher="Dipole_at_kp_1", tol=1.0E-06, ref=0.544}] # compute the dipole moments for kpoints provided via &KPOINTS in the &MOMENTS section -"C2_pbe_moment_kp.inp" = [{matcher="Dipole_abs_dx_at_kp_1", tol=1.0E-06, ref=0.3695416}] +"C2_pbe_moment_kp.inp" = [{matcher="Dipole_at_kp_1", tol=1.0E-06, ref=0.344}] # compute the dipole moments for kpoints provided via &KPOINT_SET in the &MOMENTS section # and ensure matching of Berry Curvature "C2_pbe_moment_kpset.inp" = [{matcher="BC_near_K_point", tol=1.0E-01, ref=-7100}] # compute dipole for open shell system of monolayer CrSBr -"CrSBr_open_shell.inp" = [{matcher="Dipole_abs_dx_for_CrSBr", tol=1.0E-06, ref=0.4214356E-01}] +"CrSBr_open_shell.inp" = [{matcher="Dipole_for_CrSBr", tol=1.0E-06, ref=0.298E-01}] #EOF diff --git a/tests/matchers.py b/tests/matchers.py index 4057e13f82..11b025c82c 100644 --- a/tests/matchers.py +++ b/tests/matchers.py @@ -35,12 +35,15 @@ class Matcher(Protocol): # ====================================================================================== class GenericMatcher(Matcher): - def __init__(self, pattern: str, col: int, regex: bool = False): + def __init__( + self, pattern: str, col: int, regex: bool = False, abs_value: bool = False + ): self.pattern = pattern self.regex_mode = regex + self.abs_value = abs_value if not regex: for c in r"[]()|+*?": - pattern = pattern.replace(c, f"\\{c}") # escape special chars + pattern = pattern.replace(c, f"\\{c}") self.regex = re.compile(pattern) self.col = col @@ -64,6 +67,8 @@ class GenericMatcher(Matcher): # parse result try: value = float(value_str.replace("D", "E")) + if self.abs_value: + value = abs(value) except: error = f"Could not parse result as float: '{value_str}'.\n" return MatchResult("WRONG RESULT", error, value=None) @@ -78,54 +83,6 @@ class GenericMatcher(Matcher): return MatchResult("OK", error=None, value=value) # passed -# ====================================================================================== -class ComplexAbsMatcher(Matcher): - def __init__(self, pattern: str, re_col: int, im_col: int, regex: bool = False): - self.pattern = pattern - self.regex_mode = regex - if not regex: - for c in r"[]()|+*?": - pattern = pattern.replace(c, f"\\{c}") # escape special chars - self.regex = re.compile(pattern) - self.re_col = re_col - self.im_col = im_col - - def run(self, output: str, **kwargs: Any) -> MatchResult: - tol, ref = kwargs["tol"], kwargs["ref"] - assert isinstance(tol, (float, int)) - assert isinstance(ref, (float, int)) - - for line in reversed(output.split("\n")): - match = self.regex.search(line) - if match: - if self.regex_mode and len(match.groups()) >= 2: - re_str, im_str = match.group(1), match.group(2) - else: - fields = line.split() - re_str = fields[self.re_col - 1] - im_str = fields[self.im_col - 1] - break - else: - error = f"Result not found: '{self.pattern}'.\n" - return MatchResult("WRONG RESULT", error, value=None) - - try: - re_val = float(re_str.replace("D", "E")) - im_val = float(im_str.replace("D", "E")) - value = (re_val * re_val + im_val * im_val) ** 0.5 - except: - error = f"Could not parse result as complex float: '{re_str} {im_str}'.\n" - return MatchResult("WRONG RESULT", error, value=None) - - diff = value - ref - rel_error = abs(diff / ref if ref != 0.0 else diff) - if rel_error > tol: - error = f"Difference too large: {rel_error:.2e} > {tol}, value: {value}.\n" - return MatchResult("WRONG RESULT", error, value) - - return MatchResult("OK", error=None, value=value) - - # ====================================================================================== class TextPresenceMatcher(Matcher): def __init__(self, text: str): @@ -410,18 +367,10 @@ registry["M126"] = GenericMatcher(r" # Total charge ", col=5) registry["M127"] = GenericMatcher(r"Checksum (Acoustic Sum Rule):", col=5) # Dipole moment calculated at a specific k-point (-0.375,-0.375, 0.00) -registry["Dipole_at_kp_1"] = GenericMatcher(r" 1 1 2", col=4) - -# Phase-independent |dx_nm| for the same matrix element. -registry["Dipole_abs_dx_at_kp_1"] = ComplexAbsMatcher( - r" 1 1 2", re_col=4, im_col=5 -) +registry["Dipole_at_kp_1"] = GenericMatcher(r" 1 1 2", col=4, abs_value=True) # Dipole moment calculated at a specific k-point (-0.375,-0.375, 0.00) -# registry["Dipole_for_CrSBr"] = GenericMatcher(r" 1 31 32", col=4) -registry["Dipole_abs_dx_for_CrSBr"] = ComplexAbsMatcher( - r" 1 31 32", re_col=4, im_col=5 -) +registry["Dipole_for_CrSBr"] = GenericMatcher(r" 1 31 32", col=4, abs_value=True) # Berry curvature calculated from dipoles near K point in graphene BZ registry["BC_near_K_point"] = GenericMatcher(r" 1 4", col=5)