diff --git a/openmc/data/mf33_njoy.py b/openmc/data/mf33_njoy.py index 6fcf4af5a0..0c687eeab2 100644 --- a/openmc/data/mf33_njoy.py +++ b/openmc/data/mf33_njoy.py @@ -46,6 +46,20 @@ def _read_mat_from_endf(endf_path: Path) -> int: raise ValueError(f"Could not infer MAT from ENDF file: {endf_path}") return first_nonzero +def _endf_has_mf33(endf_path: Path, mat: int) -> bool: + """Return True if the ENDF tape contains any MF=33 section for this MAT.""" + with endf_path.open("r", errors="ignore") as f: + for line in f: + if len(line) < 75: + continue + try: + m = int(line[66:70]) + mf = int(line[70:72]) + except ValueError: + continue + if m == mat and mf == 33: + return True + return False def _validate_energy_grid_ev(ek: Sequence[float]) -> List[float]: ek = [float(x) for x in ek] @@ -130,7 +144,7 @@ def _errorr_mf33_input( mat: int, temperature: float, ek: Sequence[float], - iwt: int = 2, + iwt: int = 6, spectrum: Optional[Sequence[float]] = None, relative: bool = True, irespr: int = 1, @@ -288,12 +302,12 @@ def generate_errorr_mf33( temperature: float = 293.6, # processing chain err: float = NJOY_tolerance, - minimal_processing: bool = True, + minimal_processing: bool = False, thermr: bool = False, - unresr: bool = False, - purr: bool = False, + unresr: bool = True, + purr: bool = True, # ERRORR options - iwt: int = 2, + iwt: int = 6, spectrum: Optional[Sequence[float]] = None, relative: bool = True, irespr: int = 1, @@ -350,6 +364,12 @@ def generate_errorr_mf33( if mat is None: mat = _read_mat_from_endf(endf_path) + if not _endf_has_mf33(endf_path, mat): + raise ValueError( + f"ENDF file {endf_path.name} (MAT={mat}) contains no MF=33 " + f"covariance data; nothing for ERRORR to process." + ) + if minimal_processing: thermr = unresr = purr = False diff --git a/openmc/data/xs_covariance_njoy.py b/openmc/data/xs_covariance_njoy.py index 55078a272a..60f9d4243f 100644 --- a/openmc/data/xs_covariance_njoy.py +++ b/openmc/data/xs_covariance_njoy.py @@ -562,16 +562,16 @@ class NeutronXSCovariances: else: n_cross += 1 cross_pairs.append((int(mt_key), int(mt1_key))) - log.debug( + log.info( "ERRORR tape33 parsed: %d MT section(s), " "%d self-covariance block(s), %d cross-covariance block(s)", len(reactions), n_self, n_cross, ) if cross_pairs: for mt_a, mt1_a in cross_pairs: - log.debug(" cross-covariance: MT %d <-> MT %d", mt_a, mt1_a) + log.info(" cross-covariance: MT %d <-> MT %d", mt_a, mt1_a) else: - log.debug( + log.info( " No explicit cross-covariance blocks in ERRORR output. " "Cross-reaction correlations (if any) are handled implicitly " "via NC-type derivation relations in the evaluation." @@ -589,7 +589,7 @@ class NeutronXSCovariances: ) elif qa.status == "warn": n_warnings += 1 - log.debug( + log.info( "Stage-1 MF=33 warning for MT %s -> MT1 %s: %s", mt, mt1, "; ".join(qa.messages) ) @@ -602,7 +602,7 @@ class NeutronXSCovariances: fcache[mt_key] = {} for mt1, M in sec.get("COVS", {}).items(): if int(mt_key) != int(mt1): - log.debug( + log.info( " MT %s -> MT1 %s: cross-block (%d x %d), " "stored raw (no factorization)", mt_key, mt1, @@ -616,7 +616,7 @@ class NeutronXSCovariances: fcache[mt_key][mt1] = result if result.method == "eigen_qr": n_eigen_qr += 1 - log.debug( + log.info( " MT %s -> MT1 %s: method=%-9s rank=%d/%d ", mt_key, mt1, result.method,