Files
Calculators-for-University-…/Young's modulus.py
T
2026-06-28 11:22:35 +08:00

151 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import math
from decimal import Decimal
"""
Young's Modulus Calculator (Optical Lever & Successive Difference Method)
杨氏模量计算器 (光杠杆 & 逐差法)
不确定度传递公式:
1. 杨氏模量公式:
E = (32 * m * g * L * D) / (π * d^2 * b * Δn_avg)
其中 Δn_avg 是 4 个砝码对应的平均刻度位移(由 8 个刻度值通过逐差法求得)。
2. 相对不确定度传递公式:
u_r(E) = u_E / E = sqrt( (u_L/L)^2 + (u_D/D)^2 + (2 * u_d/d)^2 + (u_b/b)^2 + (u_Δn/Δn_avg)^2 )
3. 合成不确定度:
u_E = E * u_r(E)
其中各物理量 X 的不确定度 u_X = sqrt( u_A,X^2 + u_B,X^2 )
u_A,X = s_X / sqrt(n)
u_B,X = Δ_inst / sqrt(3)
"""
from utils import (
scientific_round,
calculate_stats,
input_data_group
)
def main():
# --- 1. 常量设置 ---
M_WEIGHT = Decimal("0.350") # 单个砝码质量 350g = 0.350kg
G = Decimal("9.80") # 重力加速度
PI = Decimal(str(math.pi))
print("========================================")
print(" 杨氏模量计算 (光杠杆 & 逐差法) ")
print("========================================")
print(f"单个砝码质量 m = {M_WEIGHT} kg")
print(f"重力加速度 g = {G} m/s^2")
# --- 2. 几何长度输入 (各6次测量) ---
# L: 钢丝长度, D: 镜面到刻度尺距离, d: 钢丝直径, b: 光杠杆臂长
L_vals = input_data_group("钢丝长度 L", 6, "mm")
D_vals = input_data_group("镜面到尺距离 D", 6, "mm")
d_vals = input_data_group("钢丝直径 d", 6, "mm")
b_vals = input_data_group("光杠杆臂长 b", 6, "mm")
print("\n--- 输入仪器误差 Δ_inst ---")
delta_L = Decimal(input("L 的仪器误差 (mm, 默认 1.0): ").strip() or "1.0")
delta_D = Decimal(input("D 的仪器误差 (mm, 默认 1.0): ").strip() or "1.0")
delta_d = Decimal(input("d 的仪器误差 (mm, 默认 0.005): ").strip() or "0.005")
delta_b = Decimal(input("b 的仪器误差 (mm, 默认 0.02): ").strip() or "0.02")
L_mean, L_u = calculate_stats(L_vals, delta_L)[:2]
D_mean, D_u = calculate_stats(D_vals, delta_D)[:2]
d_mean, d_u = calculate_stats(d_vals, delta_d)[:2]
b_mean, b_u = calculate_stats(b_vals, delta_b)[:2]
# --- 3. 刻度值输入 (0-7个砝码, 加重+减重) ---
print("\n--- 输入刻度尺读数 n (单位: mm) ---")
n_up = []
n_down = []
for i in range(8):
while True:
try:
line = input(f"砝码数量 {i} (加重, 减重): ").replace(',', ' ').split()
if len(line) != 2:
print("请输入两个数值(空格或逗号隔开)")
continue
n_up.append(Decimal(line[0]))
n_down.append(Decimal(line[1]))
break
except Exception:
print("输入无效!")
delta_n_inst = Decimal(input("刻度尺仪器误差 (mm, 默认 0.5): ").strip() or "0.5")
# 计算平均读数 n_i
n_means = [(u + d) / 2 for u, d in zip(n_up, n_down)]
print("\n--- 中间量 (加重与减重的平均值 n_i) ---")
for i, val in enumerate(n_means):
print(f"n_{i} = {val} mm")
# 逐差法计算 Δn (隔 4 项相减)
# Δn_j = n_{j+4} - n_j, j = 0,1,2,3
dn_list = []
print("\n--- 逐差计算过程 ---")
for j in range(4):
diff = n_means[j+4] - n_means[j]
dn_list.append(diff)
print(f"Δn_{j} = n_{j+4} - n_{j} = {diff} mm")
# Δn 的平均值及不确定度
dn_mean = sum(dn_list) / Decimal("4")
# A类: 针对这 4 个差值
variance_dn = sum((x - dn_mean)**2 for x in dn_list) / Decimal("3")
s_dn = Decimal(str(math.sqrt(float(variance_dn))))
u_a_dn = s_dn / Decimal(str(math.sqrt(4)))
# B类: 刻度尺误差
# 因为 n_i = (n_up + n_down)/2, Δn = n_high - n_low
# 传播得 u_B(Δn) = Δ_inst / sqrt(3)
u_b_dn = delta_n_inst / Decimal(str(math.sqrt(3)))
dn_u = Decimal(str(math.sqrt(float(u_a_dn**2 + u_b_dn**2))))
# --- 4. 杨氏模量计算 ---
# 全部转为标准单位 (m)
L_m = L_mean / 1000
D_m = D_mean / 1000
d_m = d_mean / 1000
b_m = b_mean / 1000
dn_m = dn_mean / 1000
# E = (32 * m * g * L * D) / (pi * d^2 * b * Δn)
# 这里的 Δn 对应 4 个砝码的位移
numerator = Decimal("32") * M_WEIGHT * G * L_m * D_m
denominator = PI * (d_m**2) * b_m * dn_m
E_val = numerator / denominator
# --- 5. 不确定度传播 ---
# rel_u = sqrt( (uL/L)^2 + (uD/D)^2 + (2*ud/d)^2 + (ub/b)^2 + (udn/dn)^2 )
rel_u_sq = (L_u/L_mean)**2 + (D_u/D_mean)**2 + (Decimal("2")*d_u/d_mean)**2 + (b_u/b_mean)**2 + (dn_u/dn_mean)**2
rel_u = Decimal(str(math.sqrt(float(rel_u_sq))))
E_u = E_val * rel_u
# --- 6. 修约与输出 ---
# 通常用 10^11 Pa 表示
E_11 = E_val / Decimal("1e11")
E_u_11 = E_u / Decimal("1e11")
E_final, u_final = scientific_round(E_11, E_u_11)
print("\n" + "="*40)
print(" 计算结果")
print("="*40)
print(f"L = {L_mean:.2f} ± {L_u:.2f} mm")
print(f"D = {D_mean:.2f} ± {D_u:.2f} mm")
print(f"d = {d_mean:.4f} ± {d_u:.4f} mm")
print(f"b = {b_mean:.3f} ± {b_u:.3f} mm")
print(f"Δn = {dn_mean:.3f} ± {dn_u:.3f} mm (4个砝码位移)")
print("-" * 40)
print(f"杨氏模量 E (原始): {E_val:.4e} Pa")
print(f"相对不确定度 u_r: {rel_u*100:.2f}%")
print("-" * 40)
print(f"最终结果: E = {E_final} ± {u_final} × 10^11 Pa")
print("="*40)
if __name__ == "__main__":
main()