C内核流量计算方法优化,前端文件名称读取优化

This commit is contained in:
lujingze committed 2026-09-11 08:48:56 +00:00
1 parent 5d5a2e1843
commit 808c484f5b
94 files changed
+20163 -4418

No files matched your search

+92
View File
@@ -0,0 +1,92 @@
"""Compare real native/browser results to the frozen 72-curve Amesim reference.
Run with Python + NumPy. --plot additionally requires Matplotlib, available in
this workstation's system Python. Outputs stay in the requested artifact folder.
"""
from __future__ import annotations
import argparse
import csv
import hashlib
import json
from pathlib import Path
import numpy as np
ROOT = Path(__file__).resolve().parents[2]
LIMITS = {'pressure': 250., 'temperature': .015, 'displacement': 2e-6,
'velocity': 1e-5, 'mass_flow': 3e-5}
UNITS = {'pressure': 'Pa', 'temperature': 'K', 'displacement': 'm',
'velocity': 'm/s', 'mass_flow': 'kg/s'}
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('result', type=Path)
parser.add_argument('--reference', type=Path, default=ROOT/'tests/baselines/simulation/test_mql_4/test-mql-4-amesim-reference.json')
parser.add_argument('--output-dir', type=Path, required=True)
parser.add_argument('--plot', action='store_true')
args = parser.parse_args()
ref = json.loads(args.reference.read_text())
data = json.loads(args.result.read_text())
if 'snapshot' in data:
data = data['snapshot']['result']
series = data['series']; times = np.array(series['time']); ref_times = np.array(ref['times'])
if not data['success'] or times[-1] < ref_times[-1] or times[0] > ref_times[0]:
raise ValueError('A completed result covering all reference times is required.')
if np.any(np.diff(times) < 0):
raise ValueError('Native sample times are not ordered.')
finite = all(np.all(np.isfinite(values)) for values in series.values())
rows = []; grouped = {}
for key, curve in ref['series'].items():
actual = np.interp(ref_times, times, series[key]); error = actual - curve['values']
worst = int(np.argmax(abs(error))); quantity = curve['quantity']
row = {'key': key, 'quantity': quantity, 'unit': UNITS[quantity],
'maxAbsoluteError': float(abs(error[worst])), 'rmsError': float(np.sqrt(np.mean(error**2))),
'worstTime': float(ref_times[worst]), 'limit': LIMITS[quantity],
'passed': bool(np.max(abs(error)) <= LIMITS[quantity])}
rows.append(row)
if quantity not in grouped or row['maxAbsoluteError'] > grouped[quantity]['maxAbsoluteError']:
grouped[quantity] = row
masses = np.array([v for k, v in series.items() if k.rsplit('.', 1)[-1] in ('m', 'm1', 'm2')])
total = np.sum(masses, axis=0)
mass_drift = float(np.max(abs(total-total[0])))
force_peaks = sorted(({'key': k, 'peakAbsolute': max(map(abs, v))} for k, v in series.items()
if k.startswith('amesim_lstp00a_') and k.endswith('.f')),
key=lambda row: row['peakAbsolute'], reverse=True)
summary = {'resultPath': str(args.result.resolve()),
'resultSha256': hashlib.sha256(args.result.read_bytes()).hexdigest(),
'referencePath': str(args.reference.resolve()),
'referenceSha256': hashlib.sha256(args.reference.read_bytes()).hexdigest(),
'referenceSource': ref['source'], 'freshAmesimRun': False,
'referenceCurveCount': len(rows), 'referenceTimeCount': len(ref_times),
'nativeSampleCount': len(times), 'allSamplesFinite': bool(finite),
'massStateCount': len(masses), 'maxTotalMassDriftKg': mass_drift,
'groupedWorstErrors': grouped, 'curves': rows, 'contactForcePeaksOutsideReferenceScope': force_peaks,
'passed': bool(finite and mass_drift <= 1e-10 and all(row['passed'] for row in rows))}
args.output_dir.mkdir(parents=True, exist_ok=True)
(args.output_dir/'comparison.json').write_text(json.dumps(summary, ensure_ascii=False, indent=2)+'\n')
with (args.output_dir/'curve-errors.csv').open('w', newline='') as output:
writer = csv.DictWriter(output, fieldnames=list(rows[0])); writer.writeheader(); writer.writerows(rows)
if args.plot:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
fig, axes = plt.subplots(5, 2, figsize=(13, 15), constrained_layout=True)
for (quantity, row), (left, right) in zip(grouped.items(), axes):
key = row['key']; values = ref['series'][key]['values']
actual = np.interp(ref_times, times, series[key])
left.plot(times, series[key], linewidth=1, label='Native, rtol=1e-8')
left.plot(ref_times, values, '.', markersize=3, label='Saved Amesim reference')
left.set_title(key, fontsize=9); left.set_ylabel(UNITS[quantity]); left.legend(fontsize=7)
right.plot(ref_times, actual-values, '.-', linewidth=.8, markersize=3)
right.axhline(row['limit'], color='gray', linestyle='--', linewidth=.6)
right.axhline(-row['limit'], color='gray', linestyle='--', linewidth=.6)
right.set_title(f'{quantity}: sampled difference and acceptance limits', fontsize=9)
right.set_ylabel(UNITS[quantity])
for ax in (left, right): ax.grid(alpha=.2); ax.set_xlabel('Time [s]')
fig.suptitle('Four-branch model: 72 curves checked at 57 stored Amesim times\nWorst curve per quantity; contact force is outside this reference', fontsize=12)
fig.savefig(args.output_dir/'comparison.svg'); fig.savefig(args.output_dir/'comparison.png', dpi=140)
print(json.dumps({k: summary[k] for k in ('passed', 'nativeSampleCount', 'maxTotalMassDriftKg', 'groupedWorstErrors')}, indent=2))
if not summary['passed']: raise SystemExit(1)
if __name__ == '__main__': main()