delta-theory 6.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
apps/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ """
2
+ δ-Theory Applications
3
+ ====================
4
+
5
+ Web applications and tools for δ-theory.
6
+ """
@@ -0,0 +1,337 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ δ理論 疲労予測 Web App (Streamlit)
4
+ v6.8 Structure Presets + A_int/A_ext 分離
5
+
6
+ デモURL: streamlit run delta_fatigue_app.py
7
+ """
8
+
9
+ import streamlit as st
10
+ import numpy as np
11
+ import pandas as pd
12
+ import matplotlib.pyplot as plt
13
+
14
+ # ===============================
15
+ # v6.8 Core (embedded)
16
+ # ===============================
17
+ eV_to_J = 1.602176634e-19
18
+ k_B = 1.380649e-23
19
+ PI = np.pi
20
+
21
+ STRUCTURE_PRESETS = {
22
+ "BCC": {"r_th": 0.65, "n_cl": 10, "desc": "Body-Centered Cubic (Fe, W) - 明確な疲労限度"},
23
+ "FCC": {"r_th": 0.02, "n_cl": 7, "desc": "Face-Centered Cubic (Cu, Al, Ni) - 疲労限度なし"},
24
+ "HCP": {"r_th": 0.40, "n_cl": 8, "desc": "Hexagonal Close-Packed (Ti, Mg) - 中間的挙動"},
25
+ }
26
+
27
+ MATERIAL_DB = {
28
+ "Fe": {"structure": "BCC", "E_bond_eV": 4.28, "f_d": 1.5, "a_lat_m": 2.92e-10,
29
+ "alpha0": 0.289, "T_m_K": 1811, "delta_L": 0.18, "M_taylor": 3.0,
30
+ "tau_sigma_ratio": 0.565, "color": "#1f77b4"},
31
+ "W": {"structure": "BCC", "E_bond_eV": 8.90, "f_d": 1.3, "a_lat_m": 3.16e-10,
32
+ "alpha0": 0.289, "T_m_K": 3695, "delta_L": 0.18, "M_taylor": 3.0,
33
+ "tau_sigma_ratio": 0.565, "color": "#17becf"},
34
+ "Cu": {"structure": "FCC", "E_bond_eV": 3.49, "f_d": 2.0, "a_lat_m": 3.61e-10,
35
+ "alpha0": 0.289, "T_m_K": 1358, "delta_L": 0.18, "M_taylor": 3.06,
36
+ "tau_sigma_ratio": 0.565, "color": "#d62728"},
37
+ "Al": {"structure": "FCC", "E_bond_eV": 3.39, "f_d": 1.0, "a_lat_m": 4.05e-10,
38
+ "alpha0": 0.289, "T_m_K": 933, "delta_L": 0.18, "M_taylor": 3.06,
39
+ "tau_sigma_ratio": 0.565, "color": "#2ca02c"},
40
+ "Ni": {"structure": "FCC", "E_bond_eV": 4.44, "f_d": 1.8, "a_lat_m": 3.52e-10,
41
+ "alpha0": 0.289, "T_m_K": 1728, "delta_L": 0.18, "M_taylor": 3.06,
42
+ "tau_sigma_ratio": 0.565, "color": "#ff7f0e"},
43
+ "Ti": {"structure": "HCP", "E_bond_eV": 4.85, "f_d": 1.2, "a_lat_m": 2.95e-10,
44
+ "alpha0": 0.289, "T_m_K": 1941, "delta_L": 0.18, "M_taylor": 4.0,
45
+ "tau_sigma_ratio": 0.50, "color": "#9467bd"},
46
+ }
47
+
48
+ def get_burgers(mat):
49
+ struct, a = mat["structure"], mat["a_lat_m"]
50
+ if struct == "BCC": return a * np.sqrt(3) / 2
51
+ elif struct == "FCC": return a / np.sqrt(2)
52
+ else: return a
53
+
54
+ def get_V_act(mat):
55
+ return get_burgers(mat) ** 3
56
+
57
+ def calc_A_int(mat, T_K=300.0):
58
+ E_bond = mat["E_bond_eV"] * eV_to_J
59
+ E_eff = E_bond * mat["alpha0"] * mat["f_d"]
60
+ V_act = get_V_act(mat)
61
+ T_m = mat["T_m_K"]
62
+ tau_sigma = mat["tau_sigma_ratio"]
63
+ A_raw = tau_sigma * E_eff / (V_act * k_B * T_m)
64
+ # Normalize to Fe
65
+ Fe = MATERIAL_DB["Fe"]
66
+ E_Fe = Fe["E_bond_eV"] * eV_to_J * Fe["alpha0"] * Fe["f_d"]
67
+ V_Fe = get_V_act(Fe)
68
+ A_Fe = Fe["tau_sigma_ratio"] * E_Fe / (V_Fe * k_B * Fe["T_m_K"])
69
+ return A_raw / A_Fe
70
+
71
+ def sigma_yield(mat, T_K, d_m, beta_hp=3.5e-3):
72
+ E_bond = mat["E_bond_eV"] * eV_to_J
73
+ E_eff = E_bond * mat["alpha0"] * mat["f_d"]
74
+ V_act = get_V_act(mat)
75
+ delta_L = mat["delta_L"]
76
+ M = mat["M_taylor"]
77
+ T_m = mat["T_m_K"]
78
+ HP = max(1e-9, 1.0 - T_K / T_m)
79
+ A0 = (E_eff / V_act) * delta_L / (2 * PI * M)
80
+ sigma0 = A0 * HP
81
+ R_block = 1.0 + beta_hp / np.sqrt(d_m)
82
+ return sigma0 * R_block
83
+
84
+ def N_fail_CL(sigma_max, R_ratio, T_K, d_m, mat, A_ext, D_req=0.78):
85
+ struct = mat["structure"]
86
+ preset = STRUCTURE_PRESETS[struct]
87
+ r_th, n_cl = preset["r_th"], preset["n_cl"]
88
+ A_int = calc_A_int(mat, T_K)
89
+ A_total = A_int * A_ext
90
+
91
+ sigma_amp = 0.5 * sigma_max * (1 - R_ratio)
92
+ sigma_y = sigma_yield(mat, T_K, d_m)
93
+ r = sigma_amp / sigma_y
94
+
95
+ if r <= r_th:
96
+ return float("inf"), r, r_th, n_cl, A_int, sigma_y
97
+
98
+ k = A_total * (r - r_th) ** n_cl
99
+ if k <= 0:
100
+ return float("inf"), r, r_th, n_cl, A_int, sigma_y
101
+
102
+ N_fail = D_req / k
103
+ return N_fail, r, r_th, n_cl, A_int, sigma_y
104
+
105
+ def calibrate_A_ext(sigma_max, R_ratio, N_target, T_K, d_m, mat, D_req=0.78):
106
+ struct = mat["structure"]
107
+ preset = STRUCTURE_PRESETS[struct]
108
+ r_th, n_cl = preset["r_th"], preset["n_cl"]
109
+ A_int = calc_A_int(mat, T_K)
110
+
111
+ sigma_amp = 0.5 * sigma_max * (1 - R_ratio)
112
+ sigma_y = sigma_yield(mat, T_K, d_m)
113
+ r = sigma_amp / sigma_y
114
+
115
+ if r <= r_th:
116
+ return None, r, r_th, n_cl, A_int, sigma_y, "Error: r ≤ r_th (疲労限度以下)"
117
+
118
+ A_total_need = D_req / (N_target * (r - r_th) ** n_cl)
119
+ A_ext = A_total_need / A_int
120
+ return A_ext, r, r_th, n_cl, A_int, sigma_y, "OK"
121
+
122
+ # ===============================
123
+ # Streamlit App
124
+ # ===============================
125
+
126
+ st.set_page_config(
127
+ page_title="δ理論 疲労予測 v6.8",
128
+ page_icon="🔬",
129
+ layout="wide"
130
+ )
131
+
132
+ st.title("🔬 δ理論 疲労予測システム v6.8")
133
+ st.markdown("""
134
+ **結晶構造から疲労限度を予測** | フィッティングパラメータ: **0.5個**(1点校正のみ)
135
+ """)
136
+
137
+ # Sidebar
138
+ st.sidebar.header("⚙️ 設定")
139
+
140
+ tab1, tab2, tab3 = st.tabs(["📊 S-N曲線予測", "🎯 A_ext キャリブレーション", "📚 理論説明"])
141
+
142
+ # ========== Tab 1: S-N Prediction ==========
143
+ with tab1:
144
+ col1, col2 = st.columns([1, 2])
145
+
146
+ with col1:
147
+ st.subheader("パラメータ設定")
148
+
149
+ materials = st.multiselect(
150
+ "材料選択",
151
+ options=list(MATERIAL_DB.keys()),
152
+ default=["Fe", "Cu", "Al", "Ni"]
153
+ )
154
+
155
+ T_K = st.slider("温度 T [K]", 200, 800, 300)
156
+ d_um = st.slider("粒径 d [μm]", 1, 100, 30)
157
+ A_ext = st.number_input("A_ext (校正値)", value=2.46e-4, format="%.2e")
158
+ R_ratio = st.slider("応力比 R", -1.0, 0.5, -1.0, 0.1)
159
+
160
+ st.divider()
161
+ sigma_min = st.slider("σ_min [MPa]", 10, 200, 30)
162
+ sigma_max = st.slider("σ_max [MPa]", 100, 500, 300)
163
+ n_points = st.slider("計算点数", 10, 50, 25)
164
+
165
+ with col2:
166
+ if st.button("🚀 S-N曲線を計算", type="primary"):
167
+ d_m = d_um * 1e-6
168
+ sigma_list = np.linspace(sigma_min * 1e6, sigma_max * 1e6, n_points)
169
+
170
+ fig, ax = plt.subplots(figsize=(10, 7))
171
+
172
+ results_data = []
173
+
174
+ for mat_name in materials:
175
+ mat = MATERIAL_DB.get(mat_name)
176
+ if mat is None:
177
+ continue
178
+
179
+ N_list = []
180
+ for sig in sigma_list:
181
+ N, r, r_th, n_cl, A_int, sigma_y = N_fail_CL(sig, R_ratio, T_K, d_m, mat, A_ext)
182
+ N_list.append(N)
183
+
184
+ # Filter finite values
185
+ valid = [(s, N) for s, N in zip(sigma_list, N_list) if N < 1e20]
186
+
187
+ if valid:
188
+ x = [s/1e6 for s, N in valid]
189
+ y = [N for s, N in valid]
190
+ ax.loglog(x, y, 'o-', color=mat.get("color", "black"),
191
+ linewidth=2.5, markersize=6,
192
+ label=f'{mat_name} ({mat["structure"]}, r_th={STRUCTURE_PRESETS[mat["structure"]]["r_th"]:.2f})')
193
+
194
+ struct = mat["structure"]
195
+ A_int_val = calc_A_int(mat, T_K)
196
+ results_data.append({
197
+ "材料": mat_name,
198
+ "構造": struct,
199
+ "r_th": STRUCTURE_PRESETS[struct]["r_th"],
200
+ "n_cl": STRUCTURE_PRESETS[struct]["n_cl"],
201
+ "A_int": f"{A_int_val:.3f}",
202
+ "有限寿命点": f"{len(valid)}/{n_points}",
203
+ "疲労限度": "✅ あり" if STRUCTURE_PRESETS[struct]["r_th"] > 0.1 else "❌ なし"
204
+ })
205
+
206
+ ax.set_xlabel('Maximum Stress σ_max [MPa]', fontsize=12)
207
+ ax.set_ylabel('Cycles to Failure N_f', fontsize=12)
208
+ ax.set_title(f'δ理論 S-N曲線予測 (v6.8)\nT={T_K}K, d={d_um}μm, R={R_ratio}', fontsize=14)
209
+ ax.legend(loc='upper right', fontsize=10)
210
+ ax.grid(True, which='both', alpha=0.3)
211
+ ax.set_ylim(1e2, 1e15)
212
+
213
+ st.pyplot(fig)
214
+
215
+ st.subheader("予測結果サマリー")
216
+ st.dataframe(pd.DataFrame(results_data), use_container_width=True)
217
+
218
+ st.success(f"""
219
+ **計算完了!**
220
+ - 材料数: {len(materials)}
221
+ - A_ext: {A_ext:.2e}(1点校正パラメータ)
222
+ - r_th, n_cl は構造プリセットから自動設定(フィッティングなし)
223
+ """)
224
+
225
+ # ========== Tab 2: Calibration ==========
226
+ with tab2:
227
+ st.subheader("A_ext の1点校正")
228
+ st.markdown("""
229
+ 実験データ1点から **A_ext** を逆算します。
230
+ この値を使って他の材料・条件の S-N 曲線を予測できます。
231
+ """)
232
+
233
+ col1, col2 = st.columns(2)
234
+
235
+ with col1:
236
+ cal_material = st.selectbox("材料", list(MATERIAL_DB.keys()), index=0)
237
+ cal_T_K = st.slider("温度 T [K]", 200, 800, 300, key="cal_T")
238
+ cal_d_um = st.slider("粒径 d [μm]", 1, 100, 30, key="cal_d")
239
+
240
+ with col2:
241
+ cal_sigma_max = st.number_input("σ_max [MPa]", value=244.0)
242
+ cal_R_ratio = st.slider("応力比 R", -1.0, 0.5, -1.0, 0.1, key="cal_R")
243
+ cal_N_target = st.number_input("N_target [cycles]", value=7.25e7, format="%.2e")
244
+
245
+ if st.button("🔧 A_ext を計算", type="primary"):
246
+ mat = MATERIAL_DB[cal_material].copy()
247
+ d_m = cal_d_um * 1e-6
248
+
249
+ A_ext_cal, r, r_th, n_cl, A_int, sigma_y, status = calibrate_A_ext(
250
+ cal_sigma_max * 1e6, cal_R_ratio, cal_N_target, cal_T_K, d_m, mat
251
+ )
252
+
253
+ if status == "OK":
254
+ st.success(f"### A_ext = {A_ext_cal:.6e}")
255
+
256
+ col1, col2, col3 = st.columns(3)
257
+ with col1:
258
+ st.metric("σ_y (δ理論)", f"{sigma_y/1e6:.1f} MPa")
259
+ st.metric("r = σ_a/σ_y", f"{r:.4f}")
260
+ with col2:
261
+ st.metric("r_th (プリセット)", f"{r_th:.2f}")
262
+ st.metric("n_cl (プリセット)", f"{n_cl}")
263
+ with col3:
264
+ st.metric("A_int (δスケール)", f"{A_int:.4f}")
265
+ st.metric("A_total", f"{A_int * A_ext_cal:.6e}")
266
+ else:
267
+ st.error(status)
268
+
269
+ # ========== Tab 3: Theory ==========
270
+ with tab3:
271
+ st.subheader("δ理論とは")
272
+
273
+ st.markdown("""
274
+ ### 核心方程式
275
+ """)
276
+
277
+ st.latex(r"\Lambda = \frac{K}{|V|_{\text{eff}}}")
278
+
279
+ st.markdown("""
280
+ - **K**: 破壊駆動エネルギー(外力)
281
+ - **|V|_eff**: 有効凝集エネルギー(材料抵抗)
282
+ - **Λ = 1**: 臨界条件(破壊発生)
283
+
284
+ ---
285
+
286
+ ### v6.8 疲労モデルの特徴
287
+
288
+ **ダメージ蓄積(非マルコフ的):**
289
+ """)
290
+
291
+ st.latex(r"\frac{dD}{dN} = A_{\text{cl}} \times (r - r_{th})^{n_{cl}} \times (1-D)^{m_{cl}}")
292
+
293
+ st.markdown("""
294
+ - **r = σ_a / σ_y**: 正規化応力振幅
295
+ - **r_th**: 疲労限度閾値(構造依存)
296
+ - **r ≤ r_th → dD/dN = 0**: 疲労限度が自然に出る!
297
+
298
+ ---
299
+
300
+ ### 構造プリセット
301
+ """)
302
+
303
+ preset_df = pd.DataFrame([
304
+ {"構造": "BCC", "r_th": 0.65, "n_cl": 10, "疲労限度": "✅ 明確にあり", "例": "Fe, W, Mo"},
305
+ {"構造": "FCC", "r_th": 0.02, "n_cl": 7, "疲労限度": "❌ なし/曖昧", "例": "Cu, Al, Ni, Au"},
306
+ {"構造": "HCP", "r_th": 0.40, "n_cl": 8, "疲労限度": "△ 中間的", "例": "Ti, Mg, Zn"},
307
+ ])
308
+ st.dataframe(preset_df, use_container_width=True)
309
+
310
+ st.markdown("""
311
+ ---
312
+
313
+ ### A_int / A_ext 分離
314
+
315
+ | パラメータ | 意味 | 導出方法 |
316
+ |-----------|------|---------|
317
+ | **r_th** | 疲労限度閾値 | 構造プリセット(BCC/FCC/HCP) |
318
+ | **n_cl** | Basquin指数 | 構造プリセット |
319
+ | **A_int** | 内部スケール | δパラメータから計算 |
320
+ | **A_ext** | 外部要因 | **1点校正のみ** |
321
+
322
+ **結果: フィッティングパラメータ = 0.5個(A_ext の1点校正だけ)**
323
+
324
+ ---
325
+
326
+ ### Author
327
+ **飯泉真道 & 環**
328
+ Version 6.8 | 2026-01-31
329
+ """)
330
+
331
+ # Footer
332
+ st.divider()
333
+ st.markdown("""
334
+ <div style='text-align: center; color: gray;'>
335
+ δ理論 疲労予測システム v6.8 | Masamichi Iizumi & Tamaki | 2026
336
+ </div>
337
+ """, unsafe_allow_html=True)