
Програмки с отчётами по числакам / 3. Краевая задача для ОДУ 2 порядка / 3. Вар 10
.docxМинистерство образования и науки Российской Федерации
Федеральное государственное бюджетное образовательное учреждение Высшего профессионального образования
НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ ЯДЕРНЫЙ УНИВЕРСИТЕТ
Отчет по лабораторной работе № 3
«ЧИСЛЕННОЕ РЕШЕНИЕ КРАЕВОЙ ЗАДАЧИ ДЛЯ ОБЫКНОВЕННОГО ДИФФЕРЕНЦИАЛЬНОГО УРАВНЕНИЯ»
Программа/ Результат |
Теоретический материал |
Оценка |
|
|
|
Группа: Ф-03
Курс: Численные методы
Выполнил:
Преподаватель: Рябов Павел Николаевич
Москва 2012 год
-
Полная постановка задачи:
-
График точного решения
-
Результаты, полученные при выполнении лабораторной работы:
Для шага h=0.05
Точное решение задачи, |
Численное
решение задачи с аппроксимацией
краевых условий с первым порядком
точности,
|
Численное решение задачи с аппроксимацией краевых условий со вторым порядком точности,
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
Модуль разности точного решения и численного в первом случае, |
Модуль разности точного решения и численного во втором случае, |
||||||||||||||||||||||||||||||||||||||||||
|
|
Для шага h=0.1 приведена только вторая таблица.
Модуль
разности точного решения и численного
в первом случае,
|
Модуль
разности точного решения и численного
во втором случае,
|
||||||||||||||||||||||
|
|
Код с 1 порядком
#include<stdio.h>
#include<math.h>
#include<conio.h>
double h= 0.10 , lbnd= 0.0, rbnd= 1.0; //шаг и границы отрезка
const int n = 10; // равно 1/h
double p(double x) {
return 2.0*x/(1.0+x*x) ;
}
double q(double x) {
return -2.0/(1.0+x*x) ;
}
double f(double x) {
return (2.0+(1.0-2.0*x-x*x)*exp(x)) / (1.0+x*x) ;
}
double u0(double x) {
return x*atan(x)-exp(x) ;
}
void Progon (double *a, double *b, double *c, double *d, double *y)
{
double A[n], B[n]; //прогоночные коэффициенты
// Прямой ход
A[0]= -c[0]/b[0] ; B[0]= d[0]/b[0] ;
for (int i=1; i< n; i++) {
A[i]= -c[i]/(b[i] + a[i]*A[i-1]) ;
B[i]= (d[i] - a[i]*B[i-1])/(b[i] + a[i]*A[i-1]) ;
}
// Обратный ход
y[n]= (d[n]-a[n]*B[n-1]) / (b[n]+a[n]*A[n-1]) ;
for (int i= n-1; i>= 0; i--) {
y[i]= A[i]*y[i+1] + B[i] ;
}
}
int main()
{
double xi, y[n], a[n], b[n], c[n], d[n] ;
//Производная во внутренних точках аппроксимирована со 2 порядком точности (не менять)
xi= lbnd + h ;
for (int i= 1; i< n; i++) {
a[i]= 1/h/h - p(xi)/2/h ;
b[i]= q(xi) - 2/h/h ;
c[i]= 1/h/h + p(xi)/2/h ;
d[i]= f(xi) ;
xi += h ;
}
//Коэффициенты для левой границы аппроксимированы с 1ой точностью, a[0]=0:
a[0]=0.0; b[0]= 1.0 ;
c[0]=-1.0; d[0]= h ;
//Коэффициенты для правой границы аппроксимированы с 1ой точностью, c[n]=0:
a[n]= 1.0; b[n]=-1.0-4.0*h ;
c[n]= 0.0; d[n]= 9.1644*h ;
Progon(a, b, c, d, y) ; //в массиве y окажутся численные значения решения
FILE *file;
file = fopen("c:/3-1Vova.txt", "w");
xi= lbnd;
printf(" x u0 y(x) |y-u0| \n\n") ;
fprintf(file, " x u0 y(x) |y-u0| \n\n") ;
for (int i= 0; i<= n; i++) {
printf("%.2f %.10f %.10f %.2e\n", xi, u0(xi), y[i], abs(y[i]-u0(xi)) ) ;
fprintf(file, "%.2f %.10f %.10f %.2e\n", xi, u0(xi), y[i], abs(y[i]-u0(xi)) ) ;
xi += h ;
}
getch();
return 0;
}
Код со 2 порядком
#include<stdio.h>
#include<math.h>
#include<conio.h>
double h= 0.10 , lbnd= 0.0, rbnd= 1.0; //шаг и границы отрезка
const int n = 10; // равно (rbnd-lbnd)/h
double p(double x) {
return 2.0*x/(1.0+x*x) ;
}
double q(double x) {
return -2.0/(1.0+x*x) ;
}
double f(double x) {
return (2.0+(1.0-2.0*x-x*x)*exp(x)) / (1.0+x*x) ;
}
double u0(double x) {
return x*atan(x)-exp(x) ;
}
void Progon (double *a, double *b, double *c, double *d, double *y)
{
double A[n], B[n]; //прогоночные коэффициенты
// Прямой ход
A[0]= -c[0]/b[0] ; B[0]= d[0]/b[0] ;
for (int i=1; i< n; i++) {
A[i]= -c[i]/(b[i] + a[i]*A[i-1]) ;
B[i]= (d[i] - a[i]*B[i-1])/(b[i] + a[i]*A[i-1]) ;
}
// Обратный ход
y[n]= (d[n]-a[n]*B[n-1]) / (b[n]+a[n]*A[n-1]) ;
for (int i= n-1; i>= 0; i--) {
y[i]= A[i]*y[i+1] + B[i] ;
}
}
int main()
{
double xi, y[n], a[n], b[n], c[n], d[n] ;
xi= lbnd + h ;
for (int i= 1; i< n; i++) {
a[i]= 1/h/h - p(xi)/2/h ;
b[i]= q(xi) - 2/h/h ;
c[i]= 1/h/h + p(xi)/2/h ;
d[i]= f(xi) ;
xi += h ;
}
//Коэффициенты для левой границы аппроксимированы с 2ой точностью, a[0]=0:
a[0]=0.0; b[0]=1.0+h*h;
c[0]=-1.0; d[0]=h-1.5*h*h;
//Коэффициенты для правой границы аппроксимированы с 2ой точностью, c[n]=0:
a[n]=1.0; b[n]=-1.0-4.0*h-2.5*h*h;
c[n]=0.0; d[n]=9.1644*h+h*h/2.0*7.4461;
Progon(a, b, c, d, y) ; //в массиве y окажутся численные значения решения
FILE *file;
file = fopen("c:/3-2Vova.txt", "w");
xi= lbnd;
printf(" x u0 y(x) |y-u0| \n\n") ;
fprintf(file, " x u0 y(x) |y-u0| \n\n") ;
for (int i= 0; i<= n; i++) {
printf("%.2f %.10f %.10f %.2e\n", xi, u0(xi), y[i], abs(y[i]-u0(xi)) ) ;
fprintf(file, "%.2f %.10f %.10f %.2e\n", xi, u0(xi), y[i], abs(y[i]-u0(xi)) ) ;
xi += h ;
}
getch();
return 0;
}