Примеры

На этой странице мы делаем include примеров, которые лежат в корневом каталоге пакета в папке "examples/".

Literate.jl включает текст этих примеров и в md файл.

Пример №1, подробный, статическая сетка

В этом примере:

  • вручную задаются входные параметры,
  • решается прямая задача,
  • генерируются экспериментальные данные.

Решение прямой задачи

# Здесь мы зададим параметры вручную, дав комментарии о них.
# После, во всех следующих примерах,
# будем задавать параметры с помощью стандартной функции [`NonLinearReactionAdvectionDiffusionWithFrontData.dparams`](@ref)

using NonLinearReactionAdvectionDiffusionWithFrontData

u_l(t) = -8 + sin(2*π / T * t); # Прямая задача может быть с неоднородными ГУ
u_r(t) =  4 +4sin(-2*π / T * t);# Но в дальнейшем, будем использовать только однородные.
qf(x) = 4*sin(3 * π * x);       # Коэффициент линейного усиления, который в обратной
                                # задаче необходимо определить, но при генерации априорной
                                # информации мы задаем некоторый известный коэффициент, который
                                # и будем определять имея априорную информацию.
ε = 0.2;                        # Малый параметр при старшей производной
a, b = 0, 1;                    # Область по X
t₀, T = 0, 0.28;                # Область по T
N, M = 50, 80;                  # Кол-во разбиений по X, T
h = (b-a)/N;                    # шаг по X
τ = (T-t₀)/M;                   # шаг по T
Xₙ = [a  + n*h for n in 0:N];   # Сетка по Х
Tₘ = [t₀ + m*τ for m in 0:M];   # Сетка по Т
qₙ =     qf.(Xₙ);               # Сеточные значения коэффициента линейного усиления
ulₘ=    u_l.(Tₘ);               # Сеточные значения левого  ГУ
urₘ=    u_r.(Tₘ);               # Сеточные значения правого ГУ
u₀ = u_init.(Xₙ);               # Начальные условия

Все массивы передаются внутрь функции solve полностью, вместе с граничными точками. Внутри, они локально модифицируются, и на вход NonLinearReactionAdvectionDiffusionWithFrontData.directRP, NonLinearReactionAdvectionDiffusionWithFrontData.∂directRP_∂y подаются без граничных точек.

u, XX, TP = solve(u₀, Xₙ, N, Tₘ, M, ε, ulₘ, urₘ, qₙ);

Генерация априорной информации

# Здесь у нас все просто, сетка статическая, жизнь прекрасна.
ϕl      = phidetermination(qₙ, ulₘ, Xₙ, N, Tₘ, M);                      # Левый вырожденный корень
ϕr      = phidetermination(qₙ, urₘ, Xₙ, N, Tₘ, M, reverseX = true);     # Нужно сигнализировать, о интегрировании в
                                                                        # обратном направлении вдоль оси ``X``.
                                                                        # Ответ нам вернут в обычном направлении.
ϕ       = Φ(ϕl, ϕr, N, M);                                              # Полуразность вырожденных корней
f1_data = f1(ϕ, u, Xₙ, N, M);                                           # Положение переходного слоя
f2_data = f2(f1_data, u, Xₙ, N, M);                                     # Значение функции на переходном слое

Визуализация

Мы не можем строить большие анимации на стороне Travis-a. Если мы на CI, то будем рисовать только 10 кадров. Если мы генерируем документацию локально, то рисуем 80 кадров.

isTravis = in("Travis", keys(ENV))
ftw = isTravis ? range(1, stop = M+1, length=9) : [1; 2:div(M+1, 80):M+1];

# Запись gif одного только решения
make_gif(u, XX, Tₘ; name="solution_direct_ex1.gif", frames_to_write = ftw)

# Запись **только** mp4 вместе с вырожденными корнями и переходным слоем.
make_gif(u, XX, Tₘ, ϕl, ϕr, ϕ, f1_data, f2_data;
         name="solution_direct_ex11.mp4", frames_to_write = ftw)

Пример №2, краткий, стандартные параметры

В этом примере:

  • получаем стандартные входные параметры,
  • решается прямая задача,
  • генерируются экспериментальные данные.

Только в отличии от Подробного примера №1 будем пользоваться функциями-сокращениями.

Этот файл будет использоваться в тестировании.

Задаем параметры с помощью стандартной функции NonLinearReactionAdvectionDiffusionWithFrontData.dparams

using NonLinearReactionAdvectionDiffusionWithFrontData

a, b, t₀, T, N, M, ε, Xₙ, Tₘ, qₙ, ulₘ, urₘ, u₀ = NonLinearReactionAdvectionDiffusionWithFrontData.dparams();
#
u, XX, TP = solve(u₀, Xₙ, N, Tₘ, M, ε, ulₘ, urₘ, qₙ);

Генерируем экспериментальные данные функцией NonLinearReactionAdvectionDiffusionWithFrontData.generate_obs_data.

ϕl, ϕr, ϕ, f1_data, f2_data = generate_obs_data(u, Xₙ, N, Tₘ, M, qₙ, ulₘ, urₘ);

Визуализация

Так выглядит решение для стандартных данных.

make_gif(u, XX, Tₘ, ϕl, ϕr, ϕ, f1_data, f2_data; name="solution_direct_ex2.gif", frames_to_write = ftw)

Пример №3, развернуты, динамическая сетка

В этом примере:

  • вручную задаём параметры для динамической сетки,
  • решается прямая задача,
  • генерируются экспериментальные данные на динамической сетке.
using NonLinearReactionAdvectionDiffusionWithFrontData
using NonLinearReactionAdvectionDiffusionWithFrontData: shishkin_mesh;

Заданием параметров для динамической сетки

u_l(t) = -8;                    # ГУ
u_r(t) =  4;                    #
qf(x) = 4*sin(3 * π * x);       # Коэффициент линейного усиления, который в обратной
                                # задаче необходимо определить, но при генерации априорной
                                # информации мы задаем некоторый коэффициент, который,
                                # собственно, после имея априорную информацию и будем определять.
ε = 0.01;                       # Малый параметр при старшей производной
a, b = 0, 1;                    # Область по X
t₀, T = 0, 0.42;                # Область по T
x_tp = 0.12;                    # Положение переходного слоя
M = 500;                        # Кол-во разбиений по X, T
τ = (T-t₀)/M;                   # шаг по T
Tₘ = [t₀ + m*τ for m in 0:M];   # Сетка по Т
ulₘ=    u_l.(Tₘ);               # Сеточные значения левого  ГУ
urₘ=    u_r.(Tₘ);               # Сеточные значения правого ГУ

Создание и решение в случае динамической сетки

Новое поведение будет реализоваться с помощью передачи функции создания сетки внутрь solve в качестве аргумента. Эта функция должна принимать только один аргумент — положение переходного слоя и формировать соответствующую сетку. В пакете есть формирование кусочно-равномерной сетки со сгущениями на границе и на переходном слое. Создадим замыкание этой функции, которое будет иметь нужную сигнатуру.

mshfrm(x_tp) = shishkin_mesh(a, b, x_tp, ε, 40, 0.5, 1.0, 1.0, 0.25);
Xₙ = mshfrm(x_tp); ;                            # Сетка по Х
N  = length(Xₙ) - 1                             # Примем за N длину сетки, что получилась в итоге.
qₙ =    qf.(Xₙ);                                # Сеточные значения коэффициента линейного усиления
u₀ = u_init.(Xₙ, ε=ε, x_tp = x_tp);             # Начальные условия

u, XX, TP = solve(u₀, Xₙ, N, Tₘ, M, ε, ulₘ, urₘ, qₙ, create_mesh = mshfrm);

Генерация априорной информации

ϕl      = phidetermination(qₙ, ulₘ, Xₙ, N, Tₘ, M);                  # Левый вырожденный корень
ϕr      = phidetermination(qₙ, urₘ, Xₙ, N, Tₘ, M, reverseX = true); # Правый вырожденный корень
ϕ       = Φ(ϕl, ϕr, N, M);                                          # Полуразность вырожденных корней
ϕ       = apply_on_dynamic_mesh(ϕ, XX, N, M);                       # Аппроксимация на переменную сетку
ϕl      = apply_on_dynamic_mesh(ϕl, XX, N, M);                      # Аппроксимация на переменную сетку
ϕr      = apply_on_dynamic_mesh(ϕr, XX, N, M);                      # Аппроксимация на переменную сетку
f1_data = f1(ϕ, u, XX, N, M);                                       # Положение переходного слоя
f2_data = f2(f1_data, u, XX, N, M);                                 # Значение функции на переходном слое

Визуализация

Так выглядит решение для динамической сетке

ftw = isTravis ? range(1, stop = M+1, length=15) : [1; 2:div(M+1, 80):M+1];
make_gif(u, XX, Tₘ, ϕl, ϕr, ϕ, f1_data, f2_data; name="solution_direct_ex3.gif", frames_to_write = ftw)

Пример №4, краткий, динамическая сетка

Делаем тоже самое, что в развернутом примере №3, только с использованием функций сокращений и стандартных параметров.

using NonLinearReactionAdvectionDiffusionWithFrontData
using NonLinearReactionAdvectionDiffusionWithFrontData: shishkin_mesh;

# Задача параметров и решение в коротком виде
a, b, t₀, T, N, M, ε, Xₙ, Tₘ, qₙ, ulₘ, urₘ, u₀, mshfrm_std = NonLinearReactionAdvectionDiffusionWithFrontData.dparams_nonuniform();
u, XX, TP = solve(u₀, Xₙ, N, Tₘ, M, ε, ulₘ, urₘ, qₙ, create_mesh = mshfrm_std);


# Генерация априорной информации
ϕl      = phidetermination(qₙ, ulₘ, Xₙ, N, Tₘ, M);                  # Левый вырожденный корень
ϕr      = phidetermination(qₙ, urₘ, Xₙ, N, Tₘ, M, reverseX = true); # Правый вырожденный корень
ϕ       = Φ(ϕl, ϕr, N, M);                                          # Полуразность вырожденных корней
ϕ       = apply_on_dynamic_mesh(ϕ, XX, N, M);                       # Аппроксимация на переменную сетку
ϕl      = apply_on_dynamic_mesh(ϕl, XX, N, M);                      # Аппроксимация на переменную сетку
ϕr      = apply_on_dynamic_mesh(ϕr, XX, N, M);                      # Аппроксимация на переменную сетку
f1_data = f1(ϕ, u, XX, N, M);                                       # Положение переходного слоя
f2_data = f2(f1_data, u, XX, N, M);                                 # Значение функции на переходном слое

Визуализация

Так выглядит решение для стандартных данных динамической сетке.

ftw = [1; 2:div(M+1, 80):M+1];
make_gif(u, XX, Tₘ, ϕl, ϕr, ϕ, f1_data, f2_data; name="solution_direct_ex4.gif", frames_to_write = ftw)

This page was generated using Literate.jl.