Download data/Run 1/RESULT Run 1/analysis/load_sharing.py from lamm-mit/MetaMaterialsDiscovery: direct link, hf CLI and curl.
- Browser
- Download file 3.65 kB
-
https://huggingface.co/lamm-mit/MetaMaterialsDiscovery/resolve/main/data/Run%201/RESULT%20Run%201/analysis/load_sharing.py
- Command line
-
hf download 'hf://lamm-mit/MetaMaterialsDiscovery/data/Run 1/RESULT Run 1/analysis/load_sharing.py'
-
curl -L -o load_sharing.py https://huggingface.co/lamm-mit/MetaMaterialsDiscovery/resolve/main/data/Run%201/RESULT%20Run%201/analysis/load_sharing.py
3.65 kB
| #!/usr/bin/env python3 | |
| """Mechanistic load-sharing statistics at the first failure event, computed from the exported per-member data | |
| (utilisation per unit displacement of the intact structure x displacement at first failure).""" | |
| import os, json, sys | |
| import numpy as np, pandas as pd | |
| from hfx_analysis import load_log, ROOT, PROC | |
| def stats_for_run(dir_rel, dFirst, **kwargs): | |
| m = pd.read_csv(os.path.join(ROOT, dir_rel, 'members.csv')) | |
| m = m[m.absent == 0] | |
| w = m['utilInitial_perUnitDisp'].values * dFirst # utilisation of every member at the first failure event | |
| w = np.clip(w, 0, None) | |
| N = len(w); wmax = w.max() if N else np.nan | |
| out = {} | |
| out['ls_mean_over_max'] = w.mean() / wmax if wmax > 0 else np.nan | |
| out['ls_participation'] = (w.sum() ** 2) / (N * (w ** 2).sum()) if (w ** 2).sum() > 0 else np.nan | |
| out['ls_frac_ge0.5'] = float((w >= 0.5 * wmax).mean()) | |
| out['ls_frac_ge0.8'] = float((w >= 0.8 * wmax).mean()) | |
| out['ls_cv'] = w.std() / w.mean() if w.mean() > 0 else np.nan | |
| out['ls_gini'] = gini(w) | |
| # dominant load path: largest single-member share of the reaction force (axial force per unit displacement / K0) | |
| Nax = m['NInitial_perUnitDisp'].values | |
| K0 = kwargs.get('K0', np.nan) | |
| out['lp_max_share'] = float(np.abs(Nax).max() / K0) if K0 > 0 else np.nan | |
| # share of the reaction carried by level-0 members crossing the mid-height line y = H/2 | |
| y1, y2 = m['y1'].values, m['y2'].values | |
| yc = 15.0 / 32.0 # cut line between grid lines of the 16x16-equivalent ordered designs | |
| cross = ((y1 - yc) * (y2 - yc) < 0) | |
| lvl = m['level'].values | |
| tot = np.abs(Nax[cross]).sum() | |
| out['lp_level0_share'] = float(np.abs(Nax[cross & (lvl == 0)]).sum() / tot) if tot > 0 else np.nan | |
| out['lp_top3_share'] = float(np.sort(np.abs(Nax[cross]))[-3:].sum() / tot) if tot > 0 else np.nan | |
| out['ls_frac_tension'] = float((Nax > 1e-3 * np.abs(Nax).max()).mean()) if np.abs(Nax).max() > 0 else np.nan | |
| # bending share of the fibre strain at the most utilised member: util - axial strain / eps_c | |
| return out | |
| def gini(x): | |
| x = np.sort(np.asarray(x, dtype=float)); n = len(x) | |
| if n == 0 or x.sum() == 0: return np.nan | |
| return (2 * np.sum(np.arange(1, n + 1) * x) / (n * x.sum())) - (n + 1) / n | |
| if __name__ == '__main__': | |
| df = load_log() | |
| rows = [] | |
| for _, r in df[df.status == 'ok'].iterrows(): | |
| try: | |
| s = stats_for_run(r['dir'], r['dFirst'], K0=r['K0']); s['runId'] = r['runId']; rows.append(s) | |
| except Exception as e: | |
| print('skip', r['runId'], e) | |
| ls = pd.DataFrame(rows).set_index('runId') | |
| ls.to_csv(os.path.join(PROC, 'load_sharing.csv')) | |
| d = df.set_index('runId').join(ls) | |
| from scipy.stats import spearmanr, pearsonr | |
| print('n =', len(d)) | |
| for k in ['ls_mean_over_max', 'ls_participation', 'ls_frac_ge0.5', 'ls_frac_ge0.8', 'ls_cv', 'ls_gini', 'ls_frac_tension', 'lp_max_share', 'lp_level0_share', 'lp_top3_share']: | |
| ok = d[[k, 'abruptness']].dropna() | |
| print('%-20s Spearman rho vs abruptness = %+.3f (p=%.1e), vs prePeakFailures = %+.3f, vs Wf = %+.3f' % (k, spearmanr(ok[k], ok['abruptness'])[0], spearmanr(ok[k], ok['abruptness'])[1], spearmanr(d[[k,'prePeakFailures']].dropna()[k], d[[k,'prePeakFailures']].dropna()['prePeakFailures'])[0], spearmanr(d[[k,'Wf']].dropna()[k], d[[k,'Wf']].dropna()['Wf'])[0])) | |
| g = d.groupby('designId')[['ls_frac_ge0.8', 'lp_max_share', 'lp_top3_share', 'abruptness', 'prePeakFailures', 'Wf']].mean().sort_values('abruptness') | |
| pd.set_option('display.width', 200); pd.set_option('display.max_rows', 200) | |
| print(g.round(3).to_string()) | |