Загрузка данных


kill(all)$
numer : true$

/* --- БЛОК 1: МЕТОД БИСЕКЦИИ --- */
sign_change(expr, int) := block(
    [var, a, b],
    [var, a, b]: int,
    is(subst(a, var, expr) * subst(b, var, expr) < 0)
)$

bisect(expr, int, eps, imax) := block(
    [var, beg, end, xold, xnew, cnv, fxnew, i],
    if not(sign_change(expr, int)) then return(false),
    [var, beg, end]: int, 
    i: 0, [xold, xnew]: [beg, end],
    cnv: abs(xnew - xold),
    while cnv > eps do (
        i: i + 1, xold: xnew, xnew: (beg + end) / 2.0,
        cnv: abs(xnew - xold),
        fxnew: subst(xnew, var, expr),
        if fxnew = 0.0 then return([xnew, i, cnv]),
        if i > imax then return([xnew, i, cnv]),
        if sign_change(expr, [var, beg, xnew]) then end: xnew else beg: xnew
    ),
    [xnew, i, cnv]
)$

sign_change_ints(expr, int, dvar) := block(
    [var, vmin, vmax, a, b, out],
    [var, vmin, vmax]: int,
    [a, b]: [vmin, vmin + dvar], out: [],
    while b < vmax do (
        if sign_change(expr, [var, a, b]) then out: cons([a, b], out),
        a: b, b: b + dvar
    ),
    if sign_change(expr, [var, a, vmax]) then out: cons([a, vmax], out),
    reverse(out)
)$

roots_bisect(expr, int, dvar, eps, imax) := block(
    [len, ints, res, tmp],
    ints: sign_change_ints(expr, int, dvar),
    len: length(ints),
    if len = 0 then return([]),
    res: [],
    for i:1 thru len do (
        tmp: bisect(expr, cons(first(int), ints[i]), eps, imax),
        if tmp # false then res: endcons(first(tmp), res)
    ),
    res
)$

/* --- БЛОК 2: ДИСПЕРСИОННОЕ УРАВНЕНИЕ (Вар. 6) --- */
F(G, V, prms) := block(
    [m, ep1, mu1, ep2, mu2, B1, B2, c1_sq, c2_sq, ry1_sq, ry2_sq, k1, k2, sn1, cs1, sn2, cs2, res],
    [m, ep1, mu1, ep2, mu2, B1, B2] : prms,
    
    c1_sq : 1 - (m/V)^2,
    ry1_sq : %pi^2 * c1_sq * (1 - G),
    c2_sq : 1 - (ep1*mu1/(ep2*mu2)) * (m/V)^2,
    ry2_sq : %pi^2 * (ep2*mu2/(ep1*mu1)) * c2_sq - %pi^2 * c1_sq * G,
    
    k1 : sqrt(abs(ry1_sq)), k2 : sqrt(abs(ry2_sq)),
    
    if ry1_sq >= 0 then (sn1: sin(B1*V*k1), cs1: cos(B1*V*k1))
    else (sn1: sinh(B1*V*k1), cs1: cosh(B1*V*k1)),
    
    if ry2_sq >= 0 then (sn2: sin(B2*V*k2), cs2: cos(B2*V*k2))
    else (sn2: sinh(B2*V*k2), cs2: cosh(B2*V*k2)),
    
    res : k1 * mu2 * cs1 * sn2 + k2 * mu1 * cs2 * sn1,
    return(res)
)$

/* --- БЛОК 3: СБОР ТОЧЕК ДХ --- */
eval_dsp(prms, NG, GMap, Vmin, Vmax, dV, eps, imax) := block(
    [V, %V, %%G, %G, g_val, n, num_modes],
    num_modes : 4, 
    %%G : makelist([], n, 1, num_modes),
    
    %G : float(makelist(i / NG, i, 0, NG - 1)),
    %G : map(lambda([val], subst(val, 'x, GMap)), %G),
    
    for i:1 thru length(%G) do (
        g_val : %G[i],
        %V : roots_bisect(F(g_val, V, prms), [V, Vmin, Vmax], dV, eps, imax),
        if length(%V) > 0 then (
            %V : sort(%V), 
            for n:1 thru min(length(%V), num_modes) do (
                %%G[n] : endcons([%V[n], g_val], %%G[n])
            )
        )
    ),
    %%G
)$

/* --- БЛОК 4: РАСЧЕТ И ВЫВОД РЕЗУЛЬТАТОВ --- */
prms : [0, 15.0, 1.0, 9.0, 1.0, 1/3, 2/3]$

%%G0 : block([%p],
    %p: cons(0, rest(prms)),
    eval_dsp(%p, 40, 1 - (x - 1)^2, 0.01, 14.0, 0.15, 1E-6, 100)
)$

%%G1 : block([%p],
    %p: cons(1, rest(prms)),
    eval_dsp(%p, 40, 1 - (x - 1)^2, 1.01, 14.0, 0.15, 1E-6, 100)
)$

/* Печать точных значений частот отсечки */
print("--------------------------------------------------")$
print("ЗНАЧЕНИЯ НОРМИРОВАННЫХ ЧАСТОТ ОТСЕЧКИ (при G -> 0):")$
for idx:1 thru 4 do (
    if length(%%G0[idx]) > 0 then print("Мода LE0", idx, ": V =", %%G0[idx][1][1]),
    if length(%%G1[idx]) > 0 then print("Мода LE1", idx, ": V =", %%G1[idx][1][1])
                             else print("Мода LE1", idx, ": Вне диапазона расчёта (V > 14)")
)$
print("--------------------------------------------------")$

/* Рисуем Окно 1: Дисперсионные характеристики */
load(draw)$
draw2d(
    terminal = wxt,
    title = "Дисперсионные характеристики LE-волн (Вар. 6)",
    points_joined = true, grid = true,
    xlabel = "V (Нормированная частота)",
    ylabel = "G (Норм. пост. распространения)",
    
    /* m=0 */
    key = "LE01", color = red, points(%%G0[1]),
    key = "LE02", color = orange, points(%%G0[2]),
    key = "LE03", color = dark_yellow, points(%%G0[3]),
    key = "LE04", color = dark_green, points(%%G0[4]),
    
    /* m=1 */
    points_joined = false, point_size = 1,
    key = "LE11", color = red, point_type = 3, points(%%G1[1]),
    key = "LE12", color = orange, point_type = 4, points(%%G1[2]),
    key = "LE13", color = dark_yellow, point_type = 5, points(%%G1[3]),
    key = "LE14", color = dark_green, point_type = 6, points(%%G1[4])
)$

/* --- БЛОК 5: СТРОИТЕЛЬСТВО ЭПЮРЫ ПОЛЯ Ez --- */
ezy(m, Y, G, V, prms) := block(
    [ep1, mu1, ep2, mu2, B1, B2, c1_sq, c2_sq, ry1_sq, ry2_sq, k1, k2, A, B],
    [m, ep1, mu1, ep2, mu2, B1, B2]: prms,
    c1_sq : 1 - (m/V)^2,
    ry1_sq : %pi^2 * c1_sq * (1 - G),
    c2_sq : 1 - (ep1*mu1/(ep2*mu2)) * (m/V)^2,
    ry2_sq : %pi^2 * (ep2*mu2/(ep1*mu1)) * c2_sq - %pi^2 * c1_sq * G,
    
    k1 : sqrt(abs(ry1_sq)), k2 : sqrt(abs(ry2_sq)),
    
    if Y >= 0 then (
        if ry1_sq >= 0 then A : sin(V * k1 * (B1 - Y)) else A : sinh(V * k1 * (B1 - Y)),
        return(A)
    ) else (
        if ry2_sq >= 0 then B : (sin(V * k1 * B1) / sin(V * k2 * B2)) * sin(V * k2 * (B2 + Y))
        else B : (sinh(V * k1 * B1) / sinh(V * k2 * B2)) * sinh(V * k2 * (B2 + Y)),
        return(B)
    )
)$

/* Берем стабильную точку из середины графика моды LE01 */
_pt : %%G0[1][fix(length(%%G0[1])/2)]$
_V : _pt[1]$
_G : _pt[2]$
[ B1, B2 ] : rest(prms, 5)$

/* Рисуем Окно 2: Эпюра поля Ez */
draw2d(
    terminal = wxt,
    title = concat("Распределение поля Ez вдоль слоев (LE01) при V=", string(_V)),
    xlabel = "Y (Ось поперек слоев)",
    ylabel = "Ez (относ. единицы)",
    grid = true,
    color = blue,
    explicit(ezy(0, Y, _G, _V, prms), Y, -B2, B1)
)$