2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 Решение краевой задачи
Сообщение26.10.2021, 01:29 


17/03/20
183
Добрый вечер, уважаемые форумчане! Прошу помощи с решением проблемы: необходимо решить волновое уравнение с помощью явной разнотстной схемы типа "крестик":

$\frac{\partial^2u(x,t)}{\partial t^{2}} = a^{2}\frac{\partial^2u(x,t)}{\partial x^{2}}$


при следующих начальных и граиничных условиях:
$   U(x,0)=0.2(1-x)\sin(\pi x) \\ 
           \frac{\partial U(x,0)}{\partial t} = 0 
           \\U(0,t) = 0 
            \\U(1,t) = 0$


Выкладываю полный код программы и тип ошибки ( уже и так исправил кучу, а все равно не могу получить работоспособную программу) :facepalm: :-( :-(


код: [ скачать ] [ спрятать ]
Используется синтаксис Python
# Author: Alm99-collab
# Date: 25/10/2021 2:00
# Description: MSUT STANKIN Μyagkov Alexandr IDM - 21 - 03


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

Общий вид волнового уравнения:
u_tt = a**2*u_xx + f(x,t) (0,L) где u=0 на диапазоне x=0,L, for t in (0,T].
Начальные условия в общем случае: u=I(x), u_t=V(x).
В случае неоднородного уравнения задается функция f(x,t).

Синтакис основной функции решателя:
u, x, t = sol(I, V, f, a, L, dt, C, T, user_func) где:
I = I(x) - функция.
V = V(x) - функция.
f = f(x,t) - функция.
U_0, U_L, - условия на границе.
C - число Куранта (=c*dt/dx), зависящее от шага dx. Является криетрием
стабильности численных расчето, если соблюдено условие (<=1)
dt - шаг по времени.
dx - шаг по координате.
T - конечное время симуляции волнового процесса.
user_func - функция (u, x, t, n) для вызова пользовательских сценариев,
таких как анимация или вывод графика, запси данных в текстовый файл,
расчет ошибки (в случае если известно точное решение) и.т.д.
"""


import numpy as np
import math
import matplotlib.pyplot as plt
import os
import time
import glob


def sol(I, V, f, a, L, C, T, U_0, U_L, dt, user_func = None):
    """
    Функция решатель волнового 1-D волнового уравнения
    u_tt = a**2*u_xx + f(x,t) (0,L) где u=0 на диапазоне
    x=0,L, for t in (0,T].
    :param I:
    :param V:
    :param f:
    :param a:
    :param L:
    :param C:
    :param T:
    :param U_0:
    :param U_L:
    :param dt:
    :param user_func:
    :return:
    """


    nt = int(round(T / dt))
    t = np.linspace(0, nt * dt, nt + 1)  # Массив точек для сетки времени
    dx = dt * a / float(C)
    nx = int(round(L / dx))
    x = np.linspace(0, L, nx + 1)  # Массив точек для сетки координат
    q = a ** 2
    C2 = (dt / dx) ** 2
    dt2 = dt * dt

    #  --- Проверка размерностей массивов сетки и шага между двумя точками сетки ---
    dx = x[1] - x[0]
    dt = t[1] - t[0]

    # --- Условие для проверки в качестве входного аргумента однородной функии ---
    if f is None or f == 0:
        f = lambda x, t: 0  # без использования векторизации используем лямбда- функцию

    # --- Условие для проверки в качестве входного аргумента начального условия dU(x,0)/dt ---
    if V is None or V == 0:
        V = lambda x: 0

    # Граничные условия для заданного волнового уравнения
    if U_0 is not None:
        if isinstance(U_0, (float, int)) and U_0 == 0:
            U_0 = lambda t: 0
    if U_L is not None:
        if isinstance(U_L, (float, int)) and U_L == 0:
            U_L = lambda t: 0

    # ---  Выделяем память под значения решений  ---
    u = np.zeros(nx + 1)  # Массив решений в узлах сетки на  временном шаге u(i,n+1)
    u_n = np.zeros(nx + 1)  # Массив решений в узлах сетки на  временном шаге u(i,n)
    u_nm = np.zeros(nx + 1)  # Массив решений в узлах сетки на  временном шаге u(i,n-1)

    # --- Проверка индексов для соблюдения размерностей массивов ---
    Ix = range(0, Nx + 1)
    It = range(0, Nt + 1)

    # --- Запись начальных условий ---
    for i in range(0, Nx + 1):
        u_n[i] = I(x[i])

    if user_func is not None:
        user_action(u_n, x, t, 0)

    # --- Разностная формулма явной схемы "типа крест" на первом шаге ---
    for i in Ix[1:-1]:
        u[i] = u_n[i] + dt * V(x[i]) + 0.5 * C2 * (0.5 * (q[i] + q[i + 1]) * (u_n[i + 1] - u_n[i]) -
                                                   0.5 * (q[i] + q[i - 1]) * (u_n[i] - u_n[i - 1])) + 0.5 * dt2 * f(
                x[i], t[0])

    i = Ix[0]
    if U_0 is None:
        # Запись граничных условий (x=0: i-1 -> i+1  u[i-1]=u[i+1]
        # где du/dn = 0, on x=L: i+1 -> i-1  u[i+1]=u[i-1])
        ip1 = i + 1
        im1 = ip1  # i-1 -> i+1
        u[i] = u_n[i] + dt * V(x[i]) + \
               0.5 * C2 * (0.5 * (q[i] + q[ip1]) * (u_n[ip1] - u_n[i]) - 0.5 * (q[i] + q[im1])
                           * (u_n[i] - u_n[im1])) + 0.5 * dt2 * f(x[i], t[0])
    else:
        u[i] = U_0(dt)

    i = Ix[-1]
    if U_L is None:
        im1 = i - 1
        ip1 = im1  # i+1 -> i-1
        u[i] = u_n[i] + dt * V(x[i]) + \
               0.5 * C2 * (0.5 * (q[i] + q[ip1]) * (u_n[ip1] - u_n[i]) - 0.5 * (q[i] + q[im1]) * (u_n[i] - u_n[im1])) + \
               0.5 * dt2 * f(x[i], t[0])
    else:
        u[i] = U_L(dt)

    if user_action is not None:
        user_func(u, x, t, 1)

    # Обновление данных и подготовка к новому шагу
    u_nm, u_n, u = u_n, u, u_nm

    # --- Симуляция (цикл прохода по времени) ---
    for n in It[1:-1]:
        # Обновление значений во внутренних узлах сетки
        for i in Ix[1:-1]:
            u[i] = - u_nm[i] + 2 * u_n[i] + \
                   C2 * (0.5 * (q[i] + q[i + 1]) * (u_n[i + 1] - u_n[i]) -
                         0.5 * (q[i] + q[i - 1]) * (u_n[i] - u_n[i - 1])) + dt2 * f(x[i], t[n])

        #  --- Запись граничных условий ---
        i = Ix[0]
        if U_0 is None:
            # Установка значений граничных условий
            # x=0: i-1 -> i+1  u[i-1]=u[i+1] где du/dn=0
            # x=L: i+1 -> i-1  u[i+1]=u[i-1] где du/dn=0
            ip1 = i + 1
            im1 = ip1
            u[i] = - u_nm[i] + 2 * u_n[i] + \
                   C2 * (0.5 * (q[i] + q[ip1]) * (u_n[ip1] - u_n[i]) - 0.5 * (q[i] + q[im1]) * (u_n[i] - u_n[im1])) + \
                   dt2 * f(x[i], t[n])
        else:
            u[i] = U_0(t[n + 1])

        i = Ix[-1]
        if U_L is None:
            im1 = i - 1
            ip1 = im1
            u[i] = - u_nm[i] + 2 * u_n[i] + \
                   C2 * (0.5 * (q[i] + q[ip1]) * (u_n[ip1] - u_n[i]) - 0.5 * (q[i] + q[im1]) * (u_n[i] - u_n[im1])) + \
                   dt2 * f(x[i], t[n])
        else:
            u[i] = U_L(t[n + 1])

        if user_action is not None:
            if user_action(u, x, t, n + 1):
                break

        u_nm, u_n, u = u_n, u, u_nm

    return u, x, t


# Функция формирования I(x)
def I(x):
    """
    Задается выражение для начального условия
    :param x:
    :return:
    """


    return 0.2 * (1 - x) * sin(math.pi * x)


# Функция формирования  V(x)
def V(x):
    """
    Задачется выражение для начальной производной
    :param x:
    :return:
    """


    return 0  # задается необходимое выражение


# Функция формирования  f(x,t)
def f(x, t):
    """
    Задается функция f(x,t), если данное уравнение не является однородным
    :param x:
    :param t:
    :return:
    """


    return 0  # задается необходимое выражение


# Функция для задания граничных условий
def U_0( ):
    """
    Задается граничное значение или функция (условие слева)
    :return:
    """


    return 0  # задается необходимое выражение


# Функция для задания граничных условий
def U_L( ):
    """
    Задается граничное значение или функция (условие справа)
    :return:
    """


    return 0  # задается необходимое выражение


# Функция запуска процесса симуляции
def simulate(
        I, V, f, c, L, U_0, U_L, dt, C, T,  # Параметры модели (уравнения)
        umin, umax,  # Интервал амплитуды колебаний
        animate = True,  # Выбор опции визуализации (с анимацией или нет)
        solver_func = sol,  # Вызов решателя
        mode = 'plotter',  # Выбор режима работы: вывод графика или сохранение данных в файл
):
    """
    Функция запуска процесса симуляции и вывода графика численного решения
    волнового уравнения, а также записи результатов в файл.
    :param I:
    :param V:
    :param f:
    :param c:
    :param L:
    :param dt:
    :param C:
    :param T:
    :param umin:
    :param umax:
    :param U_0:
    :param U_L:
    :param animate:
    :param solver_func:
    :param mode:
    :return:
    """


    class PlotMatplotlib:
        def __call__(self, u, x, t, n):
            """
            Функция типа user_func для визуализации
            :param u:
            :param x:
            :param t:
            :param n:
            :return:
            """

            if n == 0:
                plt.ion()
                self.lines = plt.plot(x, u, 'r-')
                plt.xlabel('x')
                plt.ylabel('u')
                plt.axis([0, L, umin, umax])
                plt.legend(['t=%f' % t[n]], loc = 'lower left')
            else:
                self.lines[0].set_ydata(u)
                plt.legend(['t=%f' % t[n]], loc = 'lower left')
                plt.draw()

            # Начало формирования кадров (первый кадр)
            time.sleep(2) if t[n] == 0 else time.sleep(0.2)
            plt.savefig('tmp_%04d.png' % n)  # для создания анимации

    if mode == 'plotter':
        plot_u = PlotMatplotlib()
    elif mode == 'logger':
        ff = file_save()

    # Очистка фреймов для визуализации
    for filename in glob.glob('tmp_*.png'):
        os.remove(filename)

    # Вызов функции решателя и начало симуляции
    user_func = plot_u if animate else None
    u, x, t = solver_function(
            I, V, f, c, L, dt, U_0, U_L, C, T, user_func)

    # Создание видеофайла анимации
    fps = 5

    # перечень поддерживаемых видеокодеков
    codec2ext = {'flv': 'flv', 'libx264': 'mp4', 'libvpx': 'webm', 'libtheora': 'ogg'}
    filespec = 'tmp_%04d.png'
    movie_program = 'ffmpeg'  # или 'avconv'
    for codec in codec2ext:
        ext = codec2ext[codec]
        cmd = '{movie_program} -r {fps:d} -i {filespec} ' \
              '-vcodec {codec} movie.{ext}'.format(**vars())
        os.system(cmd)

    # Запись данных симуляции в файл
    def file_save( ):
        """
        Сохранение данных расечтов  в файл
        :return:
        """


        sys.stdout = open('data.txt', 'w')
        u, x, t = solver_func(
                I, V, f, c, L, U_0, U_L, dt, C, T)
        print(x, u, t)
        sys.stdout.close()
        return print('writing data is success')

    return 0


def task( ):
    '''
    Постановка задачи
    :return:
    '''


    L = 1
    a = 1
    C = 0.75
    T = 1
    U_0(), U_L(), V, f, I
    umax = 2
    umin = -umax

    simulate(I, V, f, a, L, dt, U_0, U_L, C, T, umax, umin, user_func,
             animate = True, mode = 'plotter', solver_func = 'sol')
 



Выдаваемая ошибка:

Используется синтаксис Text
Выдаваемая ошибка:

Traceback (most recent call last):
File "C:\\LR2-rep\wave_eq_1d.py", line 350, in <module>
task()
File "C:\\LR2-rep\wave_eq_1d.py", line 346, in task
simulate(I, V, f, a, L, dt, U_0, U_L, C, T, umax, umin, animate = True, mode = 'plotter', solver_func = 'sol')
File "C:\\LR2-rep\wave_eq_1d.py", line 299, in simulate
solver_func(I, V, f, a, L, dt, U_0, U_L, C, T, user_func)
TypeError: 'str' object is not callable
 



Заранее благодарю!

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение26.10.2021, 07:04 


27/08/14
207
Что такое solver_function на 299 строке? Скорее всего тут должно быть просто sol, объявленный на 40.

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение26.10.2021, 07:58 


21/05/16
4292
Аделаида
Уберите на самой последней строке программы кавычки возле sol.

-- 26 окт 2021, 14:29 --

Ну и на 299 строке должно быть solver_func вместо solver_function.

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение26.10.2021, 09:12 


17/03/20
183
Progger в сообщении #1536383 писал(а):
Что такое solver_function на 299 строке? Скорее всего тут должно быть просто sol, объявленный на 40.


Это функция решатель, там просто надо кавычик убрать, и тогда будет все работать!

-- 26.10.2021, 09:14 --

kotenok gav

Да, помогло! Но теперь ошибка получилась еще более прозаичная... Честно говоря, не понимаю, что не нравится...


Используется синтаксис Text
 File "C:\\LR2-rep\wave_eq_1d.py", line 126, in sol
    u[i] = U_L(dt)
TypeError: 'float' object is not callable

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение26.10.2021, 20:45 


21/05/16
4292
Аделаида
А сейчас дело в том, что вы перепутали порядок аргументов при вызове функции simulate.

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение27.10.2021, 10:37 


17/03/20
183
kotenok gav
Да, это уже тоже исправил, но появилась ошибка float object not callable

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение27.10.2021, 12:08 


21/05/16
4292
Аделаида
Покажите тогда новый код, пожалуйста. И используйте параметр start в теге syntax, чтобы можно было легко строку нужную искать.

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение27.10.2021, 12:45 


17/03/20
183
kotenok gav

Вот исправленный код:

код: [ скачать ] [ спрятать ]
Используется синтаксис Python
  1.  
  2. # Author: Alm99-collab
  3. # Date: 25/10/2021 2:00
  4. # Description: MSUT STANKIN Μyagkov Alexandr IDM - 21 - 03
  5.  
  6.  
  7. """
  8. Программа для численного решения волнового уравнения в одномерном случае,
  9. при разлинчых начальных и граничных условий, с помощью явной разностной
  10. схемы типа "крест".
  11.  
  12. Общий вид волнового уравнения:
  13. u_tt = a**2*u_xx + f(x,t) (0,L) где u=0 на диапазоне x=0,L, for t in (0,T].
  14. Начальные условия в общем случае: u=I(x), u_t=V(x).
  15. В случае неоднородного уравнения задается функция f(x,t).
  16.  
  17. Синтакис основной функции решателя:
  18. u, x, t = sol(I, V, f, a, L, dt, C, T, user_func) где:
  19. I = I(x) - функция.
  20. V = V(x) - функция.
  21. f = f(x,t) - функция.
  22. U_0, U_L, - условия на границе.
  23. C - число Куранта (=c*dt/dx), зависящее от шага dx. Является криетрием
  24. стабильности численных расчето, если соблюдено условие (<=1)
  25. dt - шаг по времени.
  26. dx - шаг по координате.
  27. T - конечное время симуляции волнового процесса.
  28. user_func - функция (u, x, t, n) для вызова пользовательских сценариев,
  29. таких как анимация или вывод графика, запси данных в текстовый файл,
  30. расчет ошибки (в случае если известно точное решение) и.т.д.
  31. """
  32.  
  33. import numpy as np
  34. import math
  35. import matplotlib.pyplot as plt
  36. import os
  37. import time
  38. import glob
  39.  
  40.  
  41. def sol(I, V, f, a, L, C, T, U_0, U_L, dt, user_func = None):
  42.     """
  43.    Функция решатель волнового 1-D волнового уравнения
  44.    u_tt = a**2*u_xx + f(x,t) (0,L) где u=0 на диапазоне
  45.    x=0,L, for t in (0,T].
  46.    :param I:
  47.    :param V:
  48.    :param f:
  49.    :param a:
  50.    :param L:
  51.    :param C:
  52.    :param T:
  53.    :param U_0:
  54.    :param U_L:
  55.    :param dt:
  56.    :param user_func:
  57.    :return:
  58.    """
  59.  
  60.     nt = int(round(T / dt))
  61.     t = np.linspace(0, nt * dt, nt + 1)  # Массив точек для сетки времени
  62.     dx = dt * a / float(C)
  63.     nx = int(round(L / dx))
  64.     x = np.linspace(0, L, nx + 1)  # Массив точек для сетки координат
  65.     q = a ** 2
  66.     C2 = (dt / dx) ** 2
  67.     dt2 = dt * dt
  68.  
  69.     # --- Условие для проверки в качестве входного аргумента однородной функии ---
  70.     if f is None or f == 0:
  71.         f = lambda x, t: 0  # без использования векторизации используем лямбда- функцию
  72.  
  73.     # --- Условие для проверки в качестве входного аргумента начального условия dU(x,0)/dt ---
  74.     if V is None or V == 0:
  75.         V = lambda x: 0
  76.  
  77.     # Граничные условия для заданного волнового уравнения
  78.     if U_0 is not None:
  79.         if isinstance(U_0, (float, int)) and U_0 == 0:
  80.             U_0 = lambda t: 0
  81.     if U_L is not None:
  82.         if isinstance(U_L, (float, int)) and U_L == 0:
  83.             U_L = lambda t: 0
  84.  
  85.     # ---  Выделяем память под значения решений  ---
  86.     u = np.zeros(nx + 1)  # Массив решений в узлах сетки на  временном шаге u(i,n+1)
  87.     u_n = np.zeros(nx + 1)  # Массив решений в узлах сетки на  временном шаге u(i,n)
  88.     u_nm = np.zeros(nx + 1)  # Массив решений в узлах сетки на  временном шаге u(i,n-1)
  89.  
  90.     # --- Проверка индексов для соблюдения размерностей массивов ---
  91.     Ix = range(0, nx + 1)
  92.     It = range(0, nt + 1)
  93.  
  94.     # --- Запись начальных условий ---
  95.     for i in range(0, nx + 1):
  96.         u_n[i] = I(x[i])
  97.  
  98.     if user_func is not None:
  99.         user_func(u_n, x, t, 0)
  100.  
  101.     # --- Разностная формулма явной схемы "типа крест" на первом шаге ---
  102.     for i in Ix[1:-1]:
  103.         u[i] = u_n[i] + dt * V(x[i]) + 0.5 * C2 * (0.5 * (q[i] + q[i + 1]) * (u_n[i + 1] - u_n[i]) -
  104.                0.5 * (q[i] + q[i - 1]) * (u_n[i] - u_n[i - 1])) + 0.5 * dt2 * f(x[i], t[0])
  105.  
  106.     i = Ix[0]
  107.     if U_0 is None:
  108.         # Запись граничных условий (x=0: i-1 -> i+1  u[i-1]=u[i+1]
  109.         # где du/dn = 0, on x=L: i+1 -> i-1  u[i+1]=u[i-1])
  110.         ip1 = i + 1
  111.         im1 = ip1  # i-1 -> i+1
  112.         u[i] = u_n[i] + dt * V(x[i]) + \
  113.                0.5 * C2 * (0.5 * (q[i] + q[ip1]) * (u_n[ip1] - u_n[i]) - 0.5 * (q[i] + q[im1])
  114.                            * (u_n[i] - u_n[im1])) + 0.5 * dt2 * f(x[i], t[0])
  115.     else:
  116.         u[i] = U_0(dt)
  117.  
  118.     i = Ix[-1]
  119.     if U_L is None:
  120.         im1 = i - 1
  121.         ip1 = im1  # i+1 -> i-1
  122.         u[i] = u_n[i] + dt * V(x[i]) + \
  123.                0.5 * C2 * (0.5 * (q[i] + q[ip1]) * (u_n[ip1] - u_n[i]) - 0.5 * (q[i] + q[im1]) * (u_n[i] - u_n[im1])) + \
  124.                0.5 * dt2 * f(x[i], t[0])
  125.     else:
  126.         u[i] = U_L(dt)
  127.  
  128.     if user_func is not None:
  129.         user_func(u, x, t, 1)
  130.  
  131.     # Обновление данных и подготовка к новому шагу
  132.     u_nm, u_n, u = u_n, u, u_nm
  133.  
  134.     # --- Симуляция (цикл прохода по времени) ---
  135.     for n in It[1:-1]:
  136.         # Обновление значений во внутренних узлах сетки
  137.         for i in Ix[1:-1]:
  138.             u[i] = - u_nm[i] + 2 * u_n[i] + \
  139.                    C2 * (0.5 * (q[i] + q[i + 1]) * (u_n[i + 1] - u_n[i]) -
  140.                          0.5 * (q[i] + q[i - 1]) * (u_n[i] - u_n[i - 1])) + dt2 * f(x[i], t[n])
  141.  
  142.         #  --- Запись граничных условий ---
  143.         i = Ix[0]
  144.         if U_0 is None:
  145.             # Установка значений граничных условий
  146.             # x=0: i-1 -> i+1  u[i-1]=u[i+1] где du/dn=0
  147.             # x=L: i+1 -> i-1  u[i+1]=u[i-1] где du/dn=0
  148.             ip1 = i + 1
  149.             im1 = ip1
  150.             u[i] = - u_nm[i] + 2 * u_n[i] + \
  151.                    C2 * (0.5 * (q[i] + q[ip1]) * (u_n[ip1] - u_n[i]) - 0.5 * (q[i] + q[im1]) * (u_n[i] - u_n[im1])) + \
  152.                    dt2 * f(x[i], t[n])
  153.         else:
  154.             u[i] = U_0(t[n + 1])
  155.  
  156.         i = Ix[-1]
  157.         if U_L is None:
  158.             im1 = i - 1
  159.             ip1 = im1
  160.             u[i] = - u_nm[i] + 2 * u_n[i] + \
  161.                    C2 * (0.5 * (q[i] + q[ip1]) * (u_n[ip1] - u_n[i]) - 0.5 * (q[i] + q[im1]) * (u_n[i] - u_n[im1])) + \
  162.                    dt2 * f(x[i], t[n])
  163.         else:
  164.             u[i] = U_L(t[n + 1])
  165.  
  166.         if user_func is not None:
  167.             if user_func(u, x, t, n + 1):
  168.                 break
  169.  
  170.         u_nm, u_n, u = u_n, u, u_nm
  171.  
  172.     return u, x, t
  173.  
  174.  
  175. # Функция формирования I(x)
  176. def I(x):
  177.     """
  178.    Задается выражение для начального условия
  179.    :param x:
  180.    :return:
  181.    """
  182.  
  183.     return 0.2 * (1 - x) * math.sin(math.pi * x)
  184.  
  185.  
  186. # Функция формирования  V(x)
  187. def V(x):
  188.     """
  189.    Задачется выражение для начальной производной
  190.    :param x:
  191.    :return:
  192.    """
  193.  
  194.     return 0  # задается необходимое выражение
  195.  
  196.  
  197. # Функция формирования  f(x,t)
  198. def f(x, t):
  199.     """
  200.    Задается функция f(x,t), если данное уравнение не является однородным
  201.    :param x:
  202.    :param t:
  203.    :return:
  204.    """
  205.  
  206.     return 0  # задается необходимое выражение
  207.  
  208.  
  209. # Функция для задания граничных условий
  210. def U_0( ):
  211.     """
  212.    Задается граничное значение или функция (условие слева)
  213.    :return:
  214.    """
  215.  
  216.     return 0  # задается необходимое выражение
  217.  
  218.  
  219. # Функция для задания граничных условий
  220. def U_L( ):
  221.     """
  222.    Задается граничное значение или функция (условие справа)
  223.    :return:
  224.    """
  225.  
  226.     return 0  # задается необходимое выражение
  227.  
  228.  
  229. # Функция запуска процесса симуляции
  230. def simulate(
  231.         I, V, f, a, L, C, T, U_0, U_L, dt,  # Параметры модели (уравнения)
  232.         umin, umax,  # Интервал амплитуды колебаний
  233.         animate = True,  # Выбор опции визуализации (с анимацией или нет)
  234.         solver_func = sol,  # Вызов решателя
  235.         mode = 'plotter',  # Выбор режима работы: вывод графика или сохранение данных в файл
  236. ):
  237.     """
  238.    Функция запуска процесса симуляции и вывода графика численного решения
  239.    волнового уравнения, а также записи результатов в файл.
  240.    :param I:
  241.    :param V:
  242.    :param f:
  243.    :param a:
  244.    :param L:
  245.    :param dt:
  246.    :param C:
  247.    :param T:
  248.    :param umin:
  249.    :param umax:
  250.    :param U_0:
  251.    :param U_L:
  252.    :param animate:
  253.    :param solver_func:
  254.    :param mode:
  255.    :return:
  256.    """
  257.  
  258.     class PlotMatplotlib:
  259.         def __call__(self, u, x, t, n):
  260.             """
  261.            Функция типа user_func для визуализации
  262.            :param u:
  263.            :param x:
  264.            :param t:
  265.            :param n:
  266.            :return:
  267.            """
  268.             if n == 0:
  269.                 plt.ion()
  270.                 self.lines = plt.plot(x, u, 'r-')
  271.                 plt.xlabel('x')
  272.                 plt.ylabel('u')
  273.                 plt.axis([0, L, umin, umax])
  274.                 plt.legend(['t=%f' % t[n]], loc = 'lower left')
  275.             else:
  276.                 self.lines[0].set_ydata(u)
  277.                 plt.legend(['t=%f' % t[n]], loc = 'lower left')
  278.                 plt.draw()
  279.  
  280.             # Начало формирования кадров (первый кадр)
  281.             time.sleep(2) if t[n] == 0 else time.sleep(0.2)
  282.             plt.savefig('tmp_%04d.png' % n)  # для создания анимации
  283.  
  284.     if mode == 'plotter':
  285.         plot_u = PlotMatplotlib()
  286.     elif mode == 'logger':
  287.         ff = file_save()
  288.  
  289.     # Очистка фреймов для визуализации
  290.     for filename in glob.glob('tmp_*.png'):
  291.         os.remove(filename)
  292.  
  293.     # Вызов функции решателя и начало симуляции
  294.     user_func = plot_u if animate else None
  295.     solver_func(I, V, f, a, L, C, T, U_0, U_L, dt, user_func)
  296.  
  297.     # Создание видеофайла анимации
  298.     fps = 5
  299.  
  300.     # перечень поддерживаемых видеокодеков
  301.     codec2ext = {'flv': 'flv', 'libx264': 'mp4', 'libvpx': 'webm', 'libtheora': 'ogg'}
  302.     filespec = 'tmp_%04d.png'
  303.     movie_program = 'ffmpeg'  # или 'avconv'
  304.     for codec in codec2ext:
  305.         ext = codec2ext[codec]
  306.         cmd = '{movie_program} -r {fps:d} -i {filespec} ' \
  307.               '-vcodec {codec} movie.{ext}'.format(**vars())
  308.         os.system(cmd)
  309.  
  310.     # Запись данных симуляции в файл
  311.     def file_save( ):
  312.         """
  313.        Сохранение данных расечтов  в файл
  314.        :return:
  315.        """
  316.  
  317.         sys.stdout = open('data.txt', 'w')
  318.         u, x, t = solver_func(
  319.                 I, V, f, a, L, C, T, U_0, U_L, dt)
  320.         print(x, u, t)
  321.         sys.stdout.close()
  322.         return print('writing data is success')
  323.  
  324.     return 0
  325.  
  326.  
  327. def task( ):
  328.     '''
  329.    Постановка задачи
  330.    :return:
  331.    '''
  332.  
  333.     I
  334.     L = 1
  335.     a = 1
  336.     C = 0.85
  337.     T = 1
  338.     dt = 0.05
  339.     U_0, U_L, V, f = 0, 0, 0, 0
  340.     umax = 2
  341.     umin = -umax
  342.  
  343.     simulate(I, V, f, a, L, C, T, U_0, U_L, dt, umax, umin, animate = True, solver_func = sol, mode = 'plotter')
  344.  
  345.  
  346. if __name__ == '__main__':
  347.     task()
  348.  

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение27.10.2021, 12:53 


21/05/16
4292
Аделаида
Вы не изменили порядок аргументов simulate.

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение27.10.2021, 13:19 


17/03/20
183
kotenok gav

Да, прошу прощения, изменил порядок аргументов!

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение27.10.2021, 13:29 


21/05/16
4292
Аделаида
Ошибка на строке 338, там вы зачем-то переопределяете U_0 и U_L как числа, хотя они у вас должны быть функциями.

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение27.10.2021, 13:44 


17/03/20
183
kotenok gav


В данной постановке, граничные условия должны быть равны нулю, но в задании также сказано провести расчеты при произвольных параметрах также, т.е. исследовать влияние граничных и начальных условий, в том числе если они будут заданы в виде функций... Или мне тогда просто лучше в самой функции task посредством лямбда-выражений определять их и передавать?

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

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение27.10.2021, 14:22 


21/05/16
4292
Аделаида
Alm99 в сообщении #1536540 писал(а):
Или мне тогда просто лучше в самой функции task посредством лямбда-выражений определять их и передавать?

Да, лучше. Но у вас они же уже и так определены - на 209-й и 219-й строках.

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение27.10.2021, 18:43 


17/03/20
183
kotenok gav

Я переписал функцию task():

код: [ скачать ] [ спрятать ]
Используется синтаксис Python
def task( ):
    '''
    Постановка задачи
    :return:
    '''


    I
    L = 1
    a = 1
    C = 0.85
    T = 1
    dt = 0.05
    U_0, U_L, V, f
    umax = 2
    umin = -umax

    simulate(I, V, f, a, L, C, T, U_0, U_L, dt, umax, umin, animate = True, solver_func = sol, mode = 'plotter',)


if __name__ == '__main__':
    task()
 


И получил ошибку следующего типа:

Код:
   
  File "C:\\LR2-rep\wave_eq_1d.py", line 102, in sol
    u[i] = u_n[i] + dt * V(x[i]) + 0.5 * C2 * (0.5 * (q[i] + q[i + 1]) * (u_n[i + 1] - u_n[i]) -
TypeError: 'int' object is not subscriptable


Ошибка в принципе мне сама понятна, что я пытаюсь рассматривать объекти типа int как например объект типов list,str, map... Меня просто интересует, ведь в принципе я просто писал шаблон для разностной схемы для элментов , которые индексируеются, как например в matlab, и вроде бы правильно делаю, но получается, что мне придется задавать u_nm, u как элменты например list? Почему-то считает, что это объект целочисленный, и не поддается подписи... Когда мы пытаемся объединить строковые и целочисленные значения, это сообщение говорит нам, что мы рассматриваем целое число как подписываемый объект. Целое число не является подписываемым объектом, но как тогда еще исправлять подобное?

 Профиль  
                  
 
 Re: Решение краевой задачи
Сообщение28.10.2021, 07:23 


21/05/16
4292
Аделаида
У вас же q - число.
Alm99 в сообщении #1536569 писал(а):
Когда мы пытаемся объединить строковые и целочисленные значения

??? Что это значит и откуда у вас в программе взялись строки?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 22 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group