- •Решение краевой задачи для обыкновенного дифференциального уравнения.
- •Содержание:
- •3.2. Описание результатов...................................................................................................11
- •4.2. Описание результатов...................................................................................................15
- •1. Постановка задачи
- •2. Метод сведения краевой задачи к задаче Коши
- •2.1. Описание метода
- •2.2. Описание результатов
- •3. Метод конечных разностей
- •3.1. Описание метода
- •3.2. Описание результатов
- •4. Метод Галёркина
- •4.1. Описание метода
- •4.2. Описание результатов
- •5. Выводы
- •Приложение 1. Листинг программы «Метод сведения краевой задачи к задаче Коши»
- •Приложение 2. Листинг программы «Метод конечных разностей»
- •Приложение 3. Листинг программы «Метод Галёркина»
Приложение 2. Листинг программы «Метод конечных разностей»
#include "stdafx.h"
#include "math.h"
const int N_max=200;
const double epsel=0.00001;
const double a=1.3, b=1.8, A=2.2, B=-1.4;
double F(double x)
{ return 1.8/(x*x)-4;}
double Q(double x)
{ return 2.3/x;}
double P(double x)
{ return 0.9*x;}
void Metod_K_R(double y[],double h,int n )
{int i;
double x,m,k,f;
static double c[N_max],d[N_max];
c[0]=0;
d[0]=A;
for( i=1;i<n;i++)
{
x=a+i*h;
m=(Q(x) - 2/(h*h)) / (1/(h*h) + P(x)/(2*h));
k= (1/(h*h) - P(x)/(2*h)) / (1/(h*h) + P(x)/(2*h));
f=F(x) / (1/(h*h) + P(x)/(2*h));
c[i]=1/(m-k*c[i-1]);
d[i]=c[i]*(f-k*d[i-1]);
}
y[n]=B;
for(i=n-1;i>=0;i--)
y[i]=d[i]-c[i]*y[i+1];
}
double Prov_toch(double y[],double y_tochnoe[],int n,double delta,double eps[])
{
int i;
delta=0;
for(i=0;i<=n/2;i++)
{
eps[i]=fabs(y[2*i]-y_tochnoe[i]);
if(eps[i]>delta)
delta=eps[i];
}
return delta;
}
void Pechat(double y_vivodimoe[],double a,double eps[],int n,int N,double delta)
{
int i,j=1,k;
double h,x=a;
k=n/N;
h=(b-a)/n;
printf("n = %d\nh = %1.2f\nMax_Delta = %1.2e\n\n",n,h,delta);
printf("\tx\ty\t\tE\n");
for(i=0;i<=n;i+=k)
{
printf("%d)\t%1.2f\t%f\t%1.2e\n",j++,x,y_vivodimoe[i],eps[i]);
x=x+k*h;
}
}
main()
{
int i,N=25,n;
double y[N_max],y_tochnoe[N_max],eps[N_max],y_vivodimoe[N_max];
double h,delta;
n=N;
do
{
if(n>=N_max)
{
printf("Vihod za predeli masiva ");
return 0;
}
h=(b-a)/n;
Metod_K_R(y,h,n);
delta=Prov_toch(y,y_tochnoe,n,delta,eps);
for(i=0;i<=n;i++){
y_vivodimoe[i]=y_tochnoe[i];
y_tochnoe[i] = y[i];}
n=2*n;
}
while(delta>epsel);
Pechat(y_vivodimoe,a,eps,n/4,N,delta);
printf("n = %d\nh = %1.2f\nMax_Delta = %1.2e\n\n",n,h,delta);
return 0;}
Приложение 3. Листинг программы «Метод Галёркина»
#include "stdafx.h"
#include "math.h"
#include "process.h"
const double epsel=0.00001;
const double h=0.02;
const double a=1.3;
const double b=1.8;
const double A=2.2;
const double B=-1.4;
const int M=10, N_max=26, E=8;
double F(double x)
{ return 1.8/(x*x)-4;}
double Q(double x)
{ return 2.3/x;}
double P(double x)
{ return 0.9*x;}
void Resheniya(double D[],double C[],int n)
{
double U,L,matrix[N_max][N_max];
double x,sum1,sum2,h=(b-a)/E,koef;
int k,i,j,t;
for(k=1;k<=n;k++){
for(i=1;i<=n;i++)
{sum1=0;sum2=0;
for(j=1;j<E;j++)
{
x=a+j*h;
U=pow(x-a,i)*(x-b);
L=k*pow(x-a,k-2)*((k-1)*(x-b)+2*(x-a))+P(x)*(k*pow(x-a,k-1)*(x-b)+pow(x-a,k))+Q(x)*pow(x-a,k)*(x-b);
if(j%2) sum1+=U*L;
else sum2+=U*L;
}
matrix[i-1][k-1]=h/3*(4*sum1+2*sum2);
}
}
for(i=1;i<=n;i++)
{sum1=0;sum2=0;
for(j=1;j<E;j++)
{
x=a+j*h;
U=pow(x-a,i)*(x-b);
L=P(x)*(B-A)/(b-a)+Q(x)*((A*b-B*a)/(b-a)+(B-A)/(b-a)*x);
if(j%2) sum1+=U*(F(x)-L);
else sum2+=U*(F(x)-L);
}
D[i-1]=h/3*(4*sum1+2*sum2);
}
// Metod Gausa
for(t=0;t<n-1;t++)
{
for( i=t+1;i<n;i++){
koef=matrix[i][t]/matrix[t][t];
D[i]=D[i]-D[t]*koef;
for( j=t+1;j<n;j++){
matrix[i][j]=matrix[i][j]-matrix[t][j]*koef;
}
}
}
for(i=n-1;i>=0;i--){
C[i]=D[i];
for(j=i+1;j<n;j++)
{C[i]=C[i]- matrix[i][j]*C[j];}
C[i]=C[i]/matrix[i][i];}
}
void Nahozdenie_y(double y[],double C[],int n)
{
int i,j;
double x,m=(A*b-B*a)/(b-a),g=(B-A)/(b-a);
for(j=0;j<N_max;j++){
x=a+j*h;
y[j]=m+g*x;
for(i=1;i<=n;i++)
{y[j]+=C[i-1]*pow(x-a,i)*(x-b);}
}
}
double Proverka(double y[],double y_tekushee[],int n,double eps[])
{
int i;
double delta;
for(i=0;i<N_max;i++)
{eps[i]=fabs(y[i]-y_tekushee[i]);
if(eps[i]>delta)delta=eps[i]; }
return delta;
}
void Prisvoenie_y_tekushee(double y[],double y_tekushee[],double y_vivodimoe[],int n)
{
int i;
for(i=0;i<N_max;i++)
{y_vivodimoe[i]=y_tekushee[i];
y_tekushee[i] = y[i];}
}
void Pechat_rez(double y_vivodimoe[],double eps[], int n,double delta)
{ int i;
double x;
printf("Bazis = %d\n",n);
printf("Razbienij v metode Simpsona = %d \n",E);
printf("Max_Delta = %1.2e\n\n",delta);
printf("\t X\t Y(X)\t\t Delta\n");
for(i=0;i<N_max;i++)
{
x=a+i*h;
printf("\t %1.2f \t %lf \t %1.2e\n",x,y_vivodimoe[i],eps[i]);
}
}
main()
{
int n=0;
double y[N_max],y_tekushee[N_max],y_vivodimoe[N_max],eps[N_max],B[N_max],C[N_max];
double delta;
do
{
n++;
if(n>=M)
{
printf("Error!!! Vihod za predeli\n\n");
return 0;
}
Resheniya(B,C,n);
Nahozdenie_y(y,C,n);
delta=Proverka(y,y_tekushee,n,eps);
Prisvoenie_y_tekushee(y,y_tekushee,y_vivodimoe,n);
}while(delta>epsel);
Pechat_rez(y_vivodimoe,eps,n,delta);
return 0;
}