Моделирование насос-форсунки EUI
Автор
# =============================================================================
# simulation_plots.jl — Запуск расчетов и построение графиков
# =============================================================================
using Plots
using DataFrames
using Engee
function run_simulations_and_plot(modelName::String, rpm_vectors::Vector{Float64}, voa_vectors::Vector{Float64})
# Проверка наличия модели и её загрузка
if !(modelName in [m.name for m in engee.get_all_models()])
engee.load("$(@__DIR__)/$(modelName).engee");
end
# Вспомогательная функция для безопасного извлечения времени и значений с прореживанием
function get_data(path, max_points=1000)
wa = WorkspaceArray{Float64}("$modelName/$path")
df = collect(wa)
t = df.time
y = df.value
n = length(t)
if n > max_points
# Берем ровно max_points точек, равномерно распределенных по всей длине
idx = round.(Int, range(1, n, length=max_points))
return t[idx], y[idx]
else
return t, y
end
end
sim_results = Dict()
# Цикл расчетов
for i in 1:6
global rpm = rpm_vectors[i]
global VOA = voa_vectors[i]
println("Расчет $i/6: Переданы параметры rpm = $rpm, VOA = $VOA")
engee.run(modelName)
# Считываем данные (каждый сигнал получает свой вектор времени)
local t_ctrl, y_ctrl = get_data("Ctrl_Output")
local t_valve, y_valve = get_data("Управляющий_клапан/Pos_Control_Valve")
local t_press, y_press = get_data("Форсунка/P_Needle")
local t_flow, y_flow = get_data("Расходомер_Форсунки/Q_Needle")
local t_vel, y_vel = get_data("Преобразователь_1/Кулачок_толкатель/Vel_Follower")
sim_results[i] = (
t_ctrl = t_ctrl, y_ctrl = y_ctrl,
t_valve = t_valve, y_valve = y_valve .* 1e3, # мм
t_press = t_press, y_press = y_press .* 1e-06, # МПа
t_flow = t_flow, y_flow = y_flow,
t_vel = t_vel, y_vel = y_vel,
rpm_val = rpm,
voa_val = VOA
)
end
# --- ОТРИСОВКА ГРАФИКОВ ---
# 1. ПОЛЕ 1: Зависимость от VOA (Расчеты 1, 2, 3)
g1_p1 = plot(title="Сигнал контроллера", ylabel="Уровень сигнала")
g1_p2 = plot(title="Перемещение клапана", ylabel="Перемещение, мм")
g1_p3 = plot(title="Давление впрыска", ylabel="Давление, МПа", xlabel="Время, с")
g1_p4 = plot(title="Расход через форсунку", ylabel="Расход, л/мин", xlabel="Время, с")
for i in 1:3
res = sim_results[i]
lbl = "VOA = $(res.voa_val)"
plot!(g1_p1, res.t_ctrl, res.y_ctrl, label=lbl)
plot!(g1_p2, res.t_valve, res.y_valve, label="")
plot!(g1_p3, res.t_press, res.y_press, label="")
plot!(g1_p4, res.t_flow, res.y_flow, label="")
end
field_voa = plot(g1_p1, g1_p2, g1_p3, g1_p4, layout=(2,2), size=(1200,680),
titlefont=font(10), plot_title="Зависимость от угла окончания впрыска (VOA)", plot_titlefontsize=14)
# 2. ПОЛЕ 2: Зависимость от оборотов rpm (Расчеты 4, 5, 6)
g2_p1 = plot(title="Сигнал контроллера", ylabel="Уровень сигнала")
g2_p2 = plot(title="Перемещение клапана", ylabel="Перемещение, мм")
g2_p3 = plot(title="Давление впрыска", ylabel="Давление, МПа", xlabel="Время, с")
g2_p4 = plot(title="Расход через форсунку", ylabel="Расход, л/мин", xlabel="Время, с")
for i in 4:6
res = sim_results[i]
lbl = "rpm = $(Int(res.rpm_val))"
plot!(g2_p1, res.t_ctrl, res.y_ctrl, label=lbl)
plot!(g2_p2, res.t_valve, res.y_valve, label="")
plot!(g2_p3, res.t_press, res.y_press, label="")
plot!(g2_p4, res.t_flow, res.y_flow, label="")
end
field_rpm = plot(g2_p1, g2_p2, g2_p3, g2_p4, layout=(2,2), size=(1200,680),
titlefont=font(10), plot_title="Зависимость от оборотов (rpm)", plot_titlefontsize=14)
# 3. САМОСТОЯТЕЛЬНЫЕ ФИГУРЫ (Базовый режим: Индекс 3)
res_single = sim_results[3]
lbl_single = "rpm=1000, VOA=12.5"
fig_velocity = plot(res_single.t_vel, res_single.y_vel, label=lbl_single,
title="Скорость толкателя", ylabel="Скорость, м/с", xlabel="Время, с", size=(800, 450))
fig_characteristic = plot(res_single.y_press, res_single.y_flow, label=lbl_single,
title="Характеристика форсунки", ylabel="Расход Q, л/мин", xlabel="Давление P, МПа", size=(800, 450))
# Возвращаем готовые объекты графиков
return field_voa, field_rpm, fig_velocity, fig_characteristic
end