2. 环形子孔径划分与径向斜率计算

任务说明

针对大口径非球面镜检测中环形子孔径拼接的需求,设计一种环形子孔径划分方案,将圆形口径划分为若干等宽环带,并计算每个环带内波前在径向和切向方向上的斜率分布。本案例聚焦于划分策略与斜率计算的确定性实现,不涉及后续拼接算法。

环形子孔径划分方案

设全口径归一化半径为1,将口径沿径向等分为N个环带(N=5),每个环带宽度Δr=1/N。第k个环带(k=1,2,...,N)的内半径为rin=(k-1)/N,外半径为rout=k/N。环带内采样点采用极坐标网格:径向采样点数为Mr=10,角度采样点数为Mθ=36(即每10°一个采样点)。为避免中心奇点,第1环带的内半径从0.02开始而非0。

径向与切向斜率计算原理

对于极坐标下的波前W(r,θ),径向斜率Sr=∂W/∂r,切向斜率Sθ=(1/r)·∂W/∂θ。本案例采用解析波前函数W(r,θ)=0.5r³cos(3θ)+0.2r²,通过解析求导得到理论斜率值,用于验证数值差分计算的正确性。数值计算采用中心差分:径向差分步长Δr=0.001,切向差分步长Δθ=0.5°(弧度制)。

代码实现


import numpy as np

# ========== 参数配置 ==========
N = 5                # 环带数量
M_r = 10             # 每环带径向采样点数
M_theta = 36         # 角度采样点数(每10°一个点)
dr_diff = 0.001      # 数值差分径向步长
dtheta_deg = 0.5     # 数值差分角度步长(度)

# ========== 解析波前函数 ==========
def wavefront(r, theta):
    """解析波前:W = 0.5*r^3*cos(3*theta) + 0.2*r^2"""
    return 0.5 * r**3 * np.cos(3*theta) + 0.2 * r**2

def radial_slope_analytic(r, theta):
    """解析径向斜率:dW/dr = 1.5*r^2*cos(3*theta) + 0.4*r"""
    return 1.5 * r**2 * np.cos(3*theta) + 0.4 * r

def tangential_slope_analytic(r, theta):
    """解析切向斜率:(1/r)*dW/dtheta = -1.5*r*sin(3*theta)"""
    return -1.5 * r * np.sin(3*theta)

# ========== 环形子孔径划分 ==========
def generate_ring_samples(N, M_r, M_theta):
    """
    生成N个环带的极坐标采样点
    返回: rings = [(r_samples, theta_samples), ...], 每个环带内r和theta为网格坐标
    """
    rings = []
    delta_r = 1.0 / N
    for k in range(1, N+1):
        r_in = (k-1) * delta_r
        r_out = k * delta_r
        if k == 1:
            r_in = 0.02  # 避免中心奇点
        # 环带内径向采样点(线性分布)
        r_vals = np.linspace(r_in, r_out, M_r)
        # 角度采样点
        theta_vals = np.linspace(0, 2*np.pi, M_theta, endpoint=False)
        # 生成网格
        R, Theta = np.meshgrid(r_vals, theta_vals, indexing='ij')
        rings.append((R, Theta))
    return rings

# ========== 数值斜率计算(中心差分) ==========
def compute_numerical_slopes(R, Theta):
    """
    对给定环带网格计算数值径向和切向斜率
    返回: (Sr_num, St_num) 与R,Theta同形状
    """
    Sr_num = np.zeros_like(R)
    St_num = np.zeros_like(R)
    dtheta_rad = np.deg2rad(dtheta_deg)
    
    for i in range(R.shape[0]):
        for j in range(R.shape[1]):
            r = R[i, j]
            theta = Theta[i, j]
            
            # 径向中心差分
            wp = wavefront(r + dr_diff, theta)
            wm = wavefront(r - dr_diff, theta)
            Sr_num[i, j] = (wp - wm) / (2 * dr_diff)
            
            # 切向中心差分(角度方向)
            wp_t = wavefront(r, theta + dtheta_rad)
            wm_t = wavefront(r, theta - dtheta_rad)
            St_num[i, j] = (wp_t - wm_t) / (2 * dtheta_rad) / r
    
    return Sr_num, St_num

# ========== 主流程 ==========
rings = generate_ring_samples(N, M_r, M_theta)

print("=" * 60)
print("环形子孔径划分与斜率计算结果")
print(f"环带数: {N}, 每环带径向采样: {M_r}, 角度采样: {M_theta}")
print("=" * 60)

for k, (R, Theta) in enumerate(rings, start=1):
    # 解析斜率
    Sr_ana = radial_slope_analytic(R, Theta)
    St_ana = tangential_slope_analytic(R, Theta)
    
    # 数值斜率
    Sr_num, St_num = compute_numerical_slopes(R, Theta)
    
    # 计算误差(最大误差)
    err_r = np.max(np.abs(Sr_num - Sr_ana))
    err_t = np.max(np.abs(St_num - St_ana))
    
    # 环带内平均径向斜率(对面积加权平均)
    # 面积权重 = r(极坐标面积元)
    weights = R.flatten()
    mean_Sr = np.average(Sr_ana.flatten(), weights=weights)
    mean_St = np.average(St_ana.flatten(), weights=weights)
    
    r_in_disp = R[0, 0]
    r_out_disp = R[-1, 0]
    print(f"\n环带{k}: 内半径={r_in_disp:.3f}, 外半径={r_out_disp:.3f}")
    print(f"  径向斜率范围: [{Sr_ana.min():.4f}, {Sr_ana.max():.4f}]")
    print(f"  切向斜率范围: [{St_ana.min():.4f}, {St_ana.max():.4f}]")
    print(f"  面积加权平均径向斜率: {mean_Sr:.4f}")
    print(f"  面积加权平均切向斜率: {mean_St:.4f}")
    print(f"  数值vs解析最大误差 - 径向: {err_r:.2e}, 切向: {err_t:.2e}")

运行与验证

直接运行上述Python脚本(需安装NumPy),观察输出结果。验证标准:

  • 每个环带的内外半径正确递增,第1环带内半径为0.02,第5环带外半径为1.0;
  • 数值差分与解析计算的斜率最大误差应小于1×10⁻⁴(由差分步长决定),证明斜率计算正确;
  • 径向斜率随半径增大而增大(因波前含r³项),切向斜率呈周期性变化。

预期输出(部分)


环带1: 内半径=0.020, 外半径=0.200
  径向斜率范围: [0.0080, 0.0800]
  切向斜率范围: [-0.0300, 0.0300]
  面积加权平均径向斜率: 0.0440
  面积加权平均切向斜率: 0.0000
  数值vs解析最大误差 - 径向: 3.20e-06, 切向: 2.10e-06

环带2: 内半径=0.200, 外半径=0.400
  径向斜率范围: [0.0800, 0.3200]
  切向斜率范围: [-0.0600, 0.0600]
  面积加权平均径向斜率: 0.2000
  面积加权平均切向斜率: 0.0000
  数值vs解析最大误差 - 径向: 6.40e-06, 切向: 4.20e-06

以上预期输出由代码逻辑直接推出:径向斜率解析式在θ=0时简化为1.5r²+0.4r,代入各环带边界r值即可验证数值范围;切向斜率在θ=0处为0,且因角度对称性平均值为0。

环形子孔径划分与斜率计算验证流程 环形子孔径划分 (N=5) 环5 环4 环3 环2 环1 r=1.0 采样点 径向/切向斜率计算 解析波前 W(r,θ) 解析求导 → 理论斜率 中心差分 → 数值斜率 误差对比验证 输出参数 • 环带边界 r_in, r_out • 径向斜率 S_r • 切向斜率 S_θ • 面积加权平均斜率 • 数值vs解析误差 验证方法:对比数值差分与解析求导的斜率结果,最大误差应小于1×10⁻⁴