Опубликован: 18.05.2011 | Доступ: свободный | Студентов: 965 / 104 | Оценка: 4.40 / 4.20 | Длительность: 12:30:00
Лекция 18:

Эволюционные уравнения в частных производных

< Лекция 17 || Лекция 18: 12345 || Лекция 19 >

Сейчас мы рассмотрим нелинейное уравнения переноса

u_t(t,x)=u(t,x)u_x(t,x)
также с периодическим краевыми условиями. Для этого уравнения характерен эффект обрушения волны. Действительно, в этом уравнении скорость переноса пропорциональна амплитуде. Поэтому "верхушка" волны движется быстрее основания, и в определенный момент производная решения будет стремится к бесконечности. Мы приведем приближенное решение уравнения нелинейного переноса. Для этого мы также будем использовать аналико-численные методы. Для этого нам нужно реализовать операцию произведения рядов Фурье, что вполне возможно. Приведем код этого класса.

\begin{verbatim}
class TUU : TRungeKutta
{
    double h;

    public TUU(int N)
        : base(N)
    {
        h = 2.0 * Math.PI / N;
    }

    public double GetY(double x)
    {
        double res = 0;
        int i;

        double di;
        for (i = 1; i < (N - 1) / 2; i++)
        {
            di = (double)i;

            res += Math.Sin(di * x) * Y[i - 1];
            res += Math.Cos(di * x) * Y[N - i];
        }

        res += Y[(N - 1) / 2];

        return res;

    }
\end{verbatim}
\begin{verbatim}
    public override void F(double t, double[] Y, ref double[] FY)
    {
        double[] DU = new double[N];

        Diff(Y, ref DU);

        Mult(Y, DU, ref FY);
    }

    int kSin(int k)
    {
        return k - 1;
    }

    int kCos(int k)
    {
        return N - k;
    }
\end{verbatim}
\begin{verbatim}
    void Mult(double[] U, double[] DU, ref double[] UDU)
    {
        int i;
        for (i = 0; i < N; i++)
        {
            UDU[i] = 0;
        }

        int N2 = (N - 1)/2;

        int k, m;
        for (k = 1; k < (N - 1) / 2; k++)
        {
            for (m = 1; m < (N - 1) / 2; m++)
            {
                // sin kx * sin mx
                if (k != m)
                {
                    UDU[kCos(Math.Abs(k - m))] +=
                    0.5 * U[kSin(k)] * DU[kSin(m)];
                }
                if (k + m < N2)
                {
                    UDU[kCos(k + m)] +=
                    -0.5 * U[kSin(k)] * DU[kSin(m)];
                }
\end{verbatim}
\begin{verbatim}
                // sin kx * cos mx
                if (k + m < N2)
                {
                    UDU[kSin(k + m)] +=
                    0.5 * U[kSin(k)] * DU[kCos(m)];
                }
                if (k > m)
                {
                    UDU[kSin(k - m)] +=
                    0.5 * U[kSin(k)] * DU[kCos(m)];
                }
                if (k < m)
                {
                    UDU[kSin(m - k)] +=
                    -0.5 * U[kSin(k)] * DU[kCos(m)];
                }
\end{verbatim}
\begin{verbatim}
                // cos kx * sin km
                if (k + m < N2)
                {
                    UDU[kSin(k + m)] +=
                    0.5 * U[kCos(k)] * DU[kSin(m)];
                }
                if (m > k)
                {
                    UDU[kSin(m - k)] +=
                    0.5 * U[kCos(k)] * DU[kSin(m)];
                }
                if (m < k)
                {
                    UDU[kSin(k - m)] +=
                    -0.5 * U[kCos(k)] * DU[kSin(m)];
                }

                // cos kx * cos mx
                if (k + m < N2)
                {
                    UDU[kCos(k + m)] +=
                    0.5 * U[kCos(k)] * DU[kSin(m)];
                }
                if (k != m)
                {
                    UDU[kCos(Math.Abs(k - m))] +=
                    0.5 * U[kCos(k)] * DU[kSin(m)];
                }
            }
        }
    }
\end{verbatim}
\begin{verbatim}
    void Diff(double[] Y, ref double[] DY)
    {
        int i;
        double di;
        for (i = 1; i < (N - 1) / 2; i++)
        {
            di = (double)i;
            DY[i - 1] = -di * Y[N - i];
            DY[N - i] = di * Y[i - 1];
        }
        DY[(N - 1) / 2] = 0;
    }
}
\end{verbatim}

Теперь испытаем этот класс.

\begin{verbatim}
int N = 257;
double h = 0.001;

double[] Y0 = new double[N];

TUU UU = new TUU(N);

for (i = 0; i < N; i++)
{
    Y0[i] = 0;
}

Y0[1] = 1;

UU.SetInit(0, Y0);

t = 0;
while (UU.GetCurrent() < (0.3 + h / 2.0))
{
    t = UU.GetCurrent();

    UU.NextStep(h);
}

Fout = File.CreateText("uu.txt");

for (i = 0; i < N; i++)
{
    x = (double)i * (2.0 * Math.PI) / (double)N;
    Fout.WriteLine("{0}\t{1}", x, UU.GetY(x));

}

Fout.Close();
\end{verbatim}

На графике 17.4 мы приведем график приближенного решения при t=0.3. К сожалению мы не имеем точного решения нелинейного уравнения, поэтому мы не приводим графика погрешности приближенного решения. Видно, что волна "пытается" обрушится.

Приближенное решение уравнения нелинейного переноса при t = 0.3

Рис. 17.4. Приближенное решение уравнения нелинейного переноса при t = 0.3

Ключевые термины

Распределенные системы - бесконечно мерные системы дифференциальных уравнений.

Начальное условие - функция, которой равно решение в начальный момент.

Абстрактная задача Коши - дифференциальное уравнение для функций со значениями в банаховом пространстве с заданным начальным условием.

Проекционный метод - метод аппроксимации эволюционных уравнений в частных производных системами обыкновенных дифференциальных уравнений.

Аналитико-числовые методы - численные методы которые содержат операции, выполняемые с использованием аналитического представления математических объектов.

Краткие итоги: Рассмотрены проекционные методы решения эволюционных уравнений в частных производных. Показано, что использование аналитико-числовых методов позволяет существенно улучшить точность расчетов.

< Лекция 17 || Лекция 18: 12345 || Лекция 19 >