Метод Эйлера для моделирования движения сферического тела в воде¶
Моделирование движения тел в жидкостях – важная часть проектов в различных областях науки и техники, включая гидродинамику, океанографию и инженерную механику. В данном примере рассматривается применение численного метода Эйлера для моделирования движения сферического тела в воде.
Этот метод позволяет учитывать влияние гравитации, плотности среды и тела, а также сопротивление жидкости. Для решения задачи используется явный метод Эйлера первого порядка. Это один из наиболее простых методов численного интегрирования обыкновенных дифференциальных уравнений (ОДУ), позволяющий аппроксимировать решение ОДУ на каждом временном шаге. Основная идея метода заключается в следующем: текущее значение функции приближается через её производную, умноженную на малый временной интервал.
Мы поставили цель разработать программу на языке Julia и MATLAB, которая моделирует движение тела и визуализирует результаты в виде графиков изменения глубины погружения и скорости тела во времени.
Также мы сравним скорость работы идентичных скриптов в этих двух языках и разберём синтаксические различия.
Далее для сравнения опишем код на MATLAB и Julia в отдельных функциях с выводом результатов замеров затраченного времени на инициализацию, расчёты в цикле и вывод графиков.
using MATLAB
using Images
function test_MATLAB()
mat"""
tic
rho_w = 1000; % Плотность воды (кг/м^3)
rho = 800; % Плотность тела (кг/м^3)
g = 9.81; % Ускорение свободного падения (м/с^2)
dt = 0.01; % Шаг по времени (с)
T = 5; % Общее время моделирования (с)
% Количество шагов
N = round(T / dt);
% Массивы для хранения результатов
z = 0; % Начальная глубина (м)
v = 0; % Начальная скорость (м/с)
time = 0; % Время
T = toc;
disp("Время инициализации: " + string(T))
tic
% Моделирование
for n = 1:N-1
time(n+1) = dt * n;
z(n+1) = z(n) + v(n) * dt;
v(n+1) = v(n) + g * (rho_w - rho) / rho * dt;
end
T = toc;
disp("Время цикла: " + string(T))
tic
% Построение графиков
figure;
% Глубина от времени
subplot(1, 2, 1);
plot(time, z);
xlabel('Время (с)');
ylabel('Глубина (м)');
grid on;
% Скорость от времени
subplot(1, 2, 2);
plot(time, v);
xlabel('Время (с)');
ylabel('Скорость (м/с)');
grid on;
saveas(gcf, 'mat_plot.png');
T = toc;
disp("Время отображения графиков:" + string(T))
"""
end
using TickTock
function test_Julia()
start_time = time()
rho_w = 1000.0 # Плотность воды (кг/м³)
rho = 800.0 # Плотность тела (кг/м³)
g = 9.81 # Ускорение свободного падения (м/с²)
dt = 0.01 # Шаг по времени (с)
T = 5.0 # Общее время моделирования (с)
N = floor(Int, T / dt) + 1 # Расчёт количества шагов
t = zeros(N) # Время
t[1] = 0.0 # Начальное время
z = zeros(N) # Позиция (глубина)
z[1] = 0.0 # Начальная позиция (м)
v = zeros(N) # Скорость
v[1] = 0.0 # Начальная скорость (м/с)
println("Время инициализации: " * string(time() - start_time))
start_time = time()
# Моделирование движения
for n in 1:N-1
t[n+1] = dt * n
z[n+1] = z[n] + v[n] * dt
v[n+1] = v[n] + g * (rho_w - rho) / rho * dt
end
println("Время цикла: " * string(time() - start_time))
start_time = time()
# Глубина от времени
A = plot(t, z,
xlabel="Время (с)",
ylabel="Глубина (м)")
# Скорость от времени
B = plot(t, v,
xlabel="Время (с)",
ylabel="Скорость (м/с)")
fig = plot(A, B, legend=false)
savefig(fig, "jl_plot.png")
println("Время отображения графиков:" * string(time() - start_time))
end
Давайте рассмотрим основные различия этих реализаций.
- Типы переменных
MATLAB: динамическая типизация, типы переменных не объявляются явно.
Julia: статическая типизация, часто требуется указывать типы переменных для повышения производительности.
- Индексирование массивов
MATLAB: начинается с единицы и в круглых скобках ().
Julia: начинается с единицы, но в квадратных скобках [].
- Печать значений
MATLAB: используется функция disp.
Julia: используется функция println.
- Комментарии
MATLAB: однострочные комментарии начинаются с %.
Julia: однострочные комментарии начинаются с #.
- Графики
MATLAB: функции изменения разбиты на множество отдельных команд.
Julia: все изменения с графиками представленны как параметры plot.
Теперь выполним сравнение скорости работы и результов работы алгоритмов.
test_MATLAB()
test_Julia()
Судя по представленным результатам, Julia значительно превосходит MATLAB по скорости выполнения каждого этапа процесса. Ниже краткий разбор по каждому этапу.
Инициализация в Julia происходит примерно в 120 раз быстрее.
Время обработки цикла в Julia примерно в 1300 раз короче.
Отображение графиков в Julia происходит примерно в 21 раз быстрее.
# Загружаем изображения
jl_plot = load("$(@__DIR__)/jl_plot.png")
mat_plot = load("$(@__DIR__)/mat_plot.png")
# Объединяем изображения
print("jl_plot, mat_plot")
hcat(jl_plot, imresize(mat_plot, size(jl_plot)))
Видно, что графики в обоих языках однотипные. То же самое касается и точности расчётов.
Вывод¶
Синтаксис языков – это дело вкуса, вопрос чисто субъективной оценки. А вот скорость можно замерить и оценить объективно. И оказывается, что Julia работает гораздо быстрее на всех ключевых этапах выполнения кода — от инициализации до построения графиков. Эти преимущества могут быть обусловлены более строгой статической типизацией, JIT-компиляцией и тщательной оптимизацией языка. MATLAB, хотя и остается мощным инструментом для научных расчетов, уступает Julia в плане быстродействия, особенно когда речь идет о высокоуровневых вычислительных задачах, где критична производительность.