Опытный
 
Профиль
Группа: Участник
Сообщений: 290
Регистрация: 9.6.2006
Где: Москва
Репутация: нет Всего: 6
|
Вот рабочая программа решения ОДУ прогонкой. Там прогоночные коэффициенты из дифура берутся. А так - всё то же самое Код | ! Решение ОДУ прогонкой program Progonka
implicit none;
! Точность real(8), parameter :: eps = 0.00005; ! Мин. и макс. аргументы real(8), parameter :: x_min = 0.0, x_max = 0.5;
! Кол-во точек integer(4), parameter :: N = 11000, N2 = 2*N;
! Переменные ! Параметр задачи real(8) :: p_alpha; ! Шаг real(8) :: h; ! Счетчик integer(4) :: i;
! Файл вывода integer(4),parameter :: id = 1000; character(80) :: f_name; logical :: RungeRule;
! Прогоночные коэффициенты real(8), allocatable, dimension(:) :: y, alpha, beta; real(8), allocatable, dimension(:) :: y2, alpha2, beta2; ! Вспом. переменные real(8) :: A, B, C, mu1, mu2, xi1, xi2;
!======================================================================= ! С А М А П Р О Г Р А М М А p_alpha = 0.5;
main_loop: do
! Вычисляем шаг h = (x_max - x_min)/dble(N); ! Выделяем память под массивы allocate( y(0:N), alpha(1:N), beta(1:N) ); ! Начальные Условия xi1 = 1.0; mu1 = -h;
alpha(1) = xi1; beta(1) = mu1;
write(*,*) write(*,"(a10,F10.5)") 'Alpha = ', p_alpha; write(*,"(a10,F10.5)") 'h = ',h;
write(*,"(a10,F10.5)") 'xi1 = ',xi1; write(*,"(a10,F10.5)") 'mu1 = ',mu1;
! Прямой ход do i = 1,N-1
A = 1.0 + (0.5*h*(p_alpha - 1.0)/(i*h + 1)); B = 1.0 - (0.5*h*(p_alpha - 1.0)/(i*h + 1)); C = 2.0 + p_alpha*h*h; ! Находим прогоночные коэффициенты alpha(i+1) = B/( C - A*alpha(i) ); beta(i+1) = ( A*beta(i) + F(i) )/( C - A*alpha(i) ); end do;
! Обратный ход mu2 = 2*h*((1.5)**p_alpha)/(p_alpha*h + 1.5); xi2 = 1.5/(p_alpha*h + 1.5);
write(*,"(a10,F10.5)") 'xi2 = ',xi2; write(*,"(a10,F10.5)") 'mu2 = ',mu2;
y(N) = (mu2 + xi2*beta(N))/(1 - xi2*alpha(N));
do i = N-1,0,-1 y(i) = alpha(i+1)*y(i+1) + beta(i+1); end do;
! Повторяем прогонку с уменьшенным в 2 раза шагом ! Вычисляем шаг h = h/2.0; ! Выделяем память под массивы allocate( y2(0:N2), alpha2(1:N2), beta2(1:N2) ); ! Начальные Условия xi1 = 1.0; mu1 = -h;
alpha2(1) = xi1; beta2(1) = mu1;
! Прямой ход do i = 1,N2-1
A = 1.0 + (0.5*h*(p_alpha - 1.0)/(i*h + 1)); B = 1.0 - (0.5*h*(p_alpha - 1.0)/(i*h + 1)); C = 2.0 + p_alpha*h*h; ! Находим прогоночные коэффициенты alpha2(i+1) = B/( C - A*alpha2(i) ); beta2(i+1) = ( A*beta2(i) + F(i) )/( C - A*alpha2(i) ); end do;
! Обратный ход mu2 = 2*h*((1.5)**p_alpha)/(p_alpha*h + 1.5); xi2 = 1.5/(p_alpha*h + 1.5);
y2(N2) = (mu2 + xi2*beta2(N2))/(1 - xi2*alpha2(N2));
do i = N2-1,0,-1 y2(i) = alpha2(i+1)*y2(i+1) + beta2(i+1); end do;
! Проверка Правила Рунге RungeRule = .true.; do i = 0,N if( abs(y2(2*i) - y(i)) >= eps) then write(*,*) 'Runge Rule is wrong'; RungeRule = .false.; exit; end if; end do;
if( RungeRule) then
! Выводим в файл write(f_name, "('Out_Alpha=',F3.1,'.csv')") p_alpha;
open(id, file = f_name, status = 'replace'); write(id,*) 'i; x; y; alpha; beta'; write(id, "(1x,i4,';',F15.7,';',F15.7,';;')") 0, 0.0, y2(0); do i = 1,N2 write(id, "(1x, i4, ';' ,F15.7, ';' ,F15.7, ';' ,F15.7 ,';', F15.7)") i, i*h, y2(i), alpha2(i), beta2(i); end do; close(id, status = 'keep');
end if;
! Освобождаем память deallocate( y, alpha, beta ); deallocate( y2, alpha2, beta2 );
! Меняем параметр alpha p_alpha = p_alpha + 0.5;
if(p_alpha > 5.0) exit main_loop;
end do main_loop;
write(*,*) 'Press enter'; read(*,*);
contains
! Правая часть real(8) function F(i) ! На входе integer(4), intent(in) :: i; F = (1.0 + i*h)**p_alpha * h*h; end function F;
end program Progonka;
|
--------------------
С уважением, Попов Д.А.
|