Нелинейная краевая задача#

Формулировка. Виды краевых условий.#

Всё, о чём будем здесь говорить, применимо и к линейным задачам, но сами понимаете, это как из пушки по воробьям.

Определение. Краевая задача

\[\begin{split} \begin{aligned} & y^{\prime \prime}=f\left(x, y, y^{\prime}\right), \quad 0<x \leq 1, \\ & y(0)=Y_0, \quad y(1)=Y_1 \end{aligned} \end{split}\]

является нелинейной краевой задачей, если функция \(f\left(x, y, y^{\prime}\right)\) нелинейна хотя бы по одному из аргументов \(y\) или \(y^{\prime}\).

Виды граничных условий.

  • Тип 1 - условия разделены на левые и правые и не используются производные.

  • Тип 2 - есть условия на производные, но левая и правая части разделены.

  • Тип 3 - условия смешанные.

Методы решения нелинейной краевой задачи#

Метод стрельбы 🏹#

Хотим решить краевую задачу

\[\begin{split} \begin{aligned} & y^{\prime \prime}=f\left(x, y, y^{\prime}\right), \quad 0<x \leq 1, \\ & y(0)=Y_0, \quad y(1)=Y_1 \end{aligned} \end{split}\]

Пусть умеем решать задачу Коши для произвольного пристрелочного параметра \(\alpha\):

\[\begin{split} \begin{aligned} & y^{\prime \prime}=f\left(x, y, y^{\prime}\right), \quad 0<x \leq 1, \\ & y(0)=Y_0, \quad y^{\prime}(0)=\alpha \end{aligned} \end{split}\]

Обозначим решение этой задачи Коши как \(y_\alpha(x)\)

Наша цель - найти такой \(\alpha = \alpha^*\), что полученное решение удовлетворяет изначальным краевым условиям. Иначе, хотим найти ноль следующей функции:

\[ F(\alpha)=y_\alpha(1)-Y_1 \]
\[ F(\alpha^*)=0 \]

Это можно делать с помощью любого алгоритма поиска нуля численно заданной функции (см. решение нелинейных уравнений), например, дихотомией или итерацией по Ньютону:

\[ \alpha_{n+1}=\alpha_n-\frac{F\left(\alpha_n\right)}{F^{\prime}\left(\alpha_n\right)} \]
\[ F^{\prime}\left(\alpha_n\right)\approx\frac{F\left(\alpha_n+h\right)-F\left(\alpha_n\right)}{h} \]

Метод Ньютона#

Метод Ньютона сводит решение нелинейной краевой задачи к решению серии линейных краевых задач и состоит в следующем.

Пусть для нелинейной краевой задачи известна функция \(y_0(x)\), удовлетворяющая граничным условиям и грубо равная искомому \(y(x)\). Положим

\[ y(x)=y_0(x)+v(x) \]

где \(v(x)\) - поправка к нулевому приближению \(y_0(x)\).

В предположении о малости поправки имеем:

\[\begin{split} \begin{aligned} y^{\prime \prime}(x)=y_0^{\prime \prime}(x)+v^{\prime \prime}(x) \\ f\left(x, y_0+v, y_0^{\prime}+v^{\prime}\right)= &f\left(x, y_0, y_0^{\prime}\right) +\frac{\partial f\left(x, y_0, y_0^{\prime}\right)}{\partial v} v+ \\&+\frac{\partial f\left(x, y_0, y_0^{\prime}\right)}{\partial v^{\prime}} v^{\prime}+O\left(v^2+\left|v^{\prime}\right|^2\right) \end{aligned} \end{split}\]

Отбрасывая остаточный член \(\mathrm{O}\left(v^2+\left|v^{\prime}\right|^2\right)\), получим линейную краевую задачу для нахождения поправки \(\tilde{v}(x)\) с нулевыми краевыми условиями:

\[\begin{split} \left \{\begin{aligned} & \tilde{v}^{\prime \prime}=p(x) \cdot \tilde{v}^{\prime}+g(x) \cdot \tilde{v}+r(x), \\ & \tilde{v}(0)=0, \quad \tilde{v}(1)=0 \end{aligned} \right . \end{split}\]

где

\[\begin{split} \begin{aligned} & p(x)=\frac{\partial f\left(x, y_0, y_0^{\prime}\right)}{\partial y^{\prime}}, \quad q(x)=\frac{\partial f\left(x, y_0, y_0^{\prime}\right)}{\partial y}, \\ & r(x)=f\left(x, y_0, y_0^{\prime}\right)-y_0^{\prime \prime} \end{aligned} \end{split}\]

Решая эту линейную краевую задачу каким-либо численным методом, найдем поправку \(\widetilde{v}\) и примем за первое приближение

\[ y_1(x) \equiv y_0(x)+\tilde{v} . \]

Осталось только продолжить этот процесс до тех пор, пока не будут выполнено неравенство на норму ошибки

\[ \max |\tilde{v}(x)| \leq \varepsilon, \quad x \in[0,1] \]

где \(\varepsilon\) - требуемая точность.

Метод Фурье 🌊#

В предыдущем методе Ньютона краевая задача на поправку достаточно «хорошая» и её можно решать т.н. проекционными методами (а можно решать и любым упомянутым ранее методом ;)).

Представим решаемую задачу в следующем виде (Извините за совпадение обозначений - внимательно посмотрите на разницу предыдущей формы записи краевой задачи на поправку и той, которую я сейчас напишу - буковки с предыдущим пунктом не равны):

\[\begin{split} \left\{\begin{gathered} p(x) \cdot \tilde{v}^{\prime \prime}+q(x) \cdot {\tilde{v}}^\prime+r(x) \cdot \tilde{v}=g(x) \\ \tilde{v}(a)=0, \quad \tilde{v}(b)=0 \end{gathered} \right . \end{split}\]

Иначе говоря, выбирается некоторый базис \(\{e_k\}_k^\infty\) на отрезке, по которому мы раскладываем нашу искомую поправку:

\[ \tilde{v}(x)=\sum_{k=1}^N a_k \cdot e_k(x), \]

Возможные базисы:

  • Любые, удовлетворяющие граничным условиям \(\tilde{v}(0)=0, \quad \tilde{v}(1)=0\)

  • Например, синусы: \(e_k(x)=\sin \pi k(x-a) /(b-a), \; k=0,1, \ldots\)

  • Многочлены: \(e_k(x)=(x-a)(b-x) P_{k-1}(x), \; k=0,1, \ldots\), где \(P_k-\) алгебраический полином степени \(k\)

Далее возникает вопрос, как определить коэффициенты \(a_k\)?

Стандартно, можно использовать метод наименьших квадратов:

\[\begin{split} \begin{gathered} \sum_{k=1}^N a_k \int_a^b\left[p(t) \ddot{e}_k(t)+q(t) \dot{e}_k(t)+r(t) e_k(t)\right]\left[p(t) \ddot{e}_j(t)+q(t) \dot{e}_j(t)+r(t) e_j(t)\right] d t= \\ \int_a^b g_n(t)\left[p(t) \ddot{e}_j(t)+q(t) \dot{e}_j(t)+r(t) e_j(t)\right] d t, \quad j=1, \ldots, N \end{gathered} \end{split}\]

Все интегралы взять численно или аналитически (если получится). Таким образом имеем систему на коэффициенты \(a_k\), которая также решается численно.

Метод Галёркина#

В методе Галёркина всё как в Фурье, только систему составляем по другому правилу:

\[\begin{split} \begin{gathered} \sum_{k=1}^N a_k \int_a^b\left[p(t) \ddot{e}_k(t)+q(t) \dot{e}_k(t)+r(t) e_k(t)\right] e_j(t) d t=\int_a^b g_n(t) e_j(t) d t \\ j=1, \ldots, N . \end{gathered} \end{split}\]

Метод конечных элементов 😱#

Помимо рассмотренных существуют также вариационные методы (например, метод Ритца) и метод конечных элементов, основанный на них.

Метод конечных элементов очень сложен для реализации вручную и для его освоения нужен отдельный учебный курс. Тем не менее это самое лучшее, что вы можете использовать.

Во многих пакетах моделирования он уже встроен. Кроме того, существует открытый проект, позволяющий решать с его помощью на Python и C++ произвольные собственные задачи https://fenicsproject.org/