Примечание | от автора: Программа окончательно написана и проверена счетом 30 июня 2011; от редактора: приведен только текст, формулы и графики статьи находятся в архивном файле |
Загрузить архив: | |
Файл: ref-31702.zip (271kb [zip], Скачиваний: 1) скачать |
06 сентября 2011 (расчет ЦИЛИНДРИЧЕСКОЙ ОБОЛОЧКИ)
Алексей Юрьевич Виноградов
Кандидат физико-математических наук (1996 года защиты)
Дата рождения: 12 апреля 1970 (а то в интернете много моих полных тезок)
Мои сайты по методам решения краевых задач в интернете:
СОДЕРЖАНИЕ:
//from_A_Yu_Vinogradov.cpp: главный файл проекта.
//Решение краевой задачи - цилиндрической оболочки.
//Интервал интегрирования разбит на 100 участков: левый край - точка 0 и правый край - точка 100
#include "stdafx.h"
#include
#include
using namespace std;
//Скалярное произведение векторов - i-й строки матрицы А и j-й строки матрицы С.
double mult(double A[8][8], int i, double C[8][8], int j){
double result=0.0;
for(int k=0;k<8;k++){
result+=A[i][k]*C[j][k];
}
return result;
}
//Вычисление нормы вектора, где вектор это i-я строка матрицы А.
double norma(double A[8][8], int i){
double norma_=0.0;
for(int k=0;k<8;k++){
norma_+=A[i][k]*A[i][k];
}
norma_=sqrt(norma_);
return norma_;
}
//Выполнение ортонормирования. Исходная система A*x=b размерности 8х8 приводиться к системе C*x=d, где строки матрицы С ортонормированы.
void orto_norm_8x8(double A[8][8], double b[8], double C[8][8], double d[8]){
double NORM;
double mult0,mult1,mult2,mult3,mult4,mult5,mult6,mult7;
//Получаем 1-ю строку уравнения C*x=d:
NORM=norma(A,0);
for(int k=0;k<8;k++){
C[0][k]=A[0][k]/NORM;
}
d[0]=b[0]/NORM;
//Получаем 2-ю строку уравнения C*x=d:
mult0=mult(A,1,C,0);
for(int k=0;k<8;k++){
C[1][k]=A[1][k]-mult0*C[0][k];
}
NORM=norma(C,1);
for(int k=0;k<8;k++){
C[1][k]/=NORM;
}
d[1]=(b[1]-mult0*d[0])/NORM;
//Получаем 3-ю строку уравнения C*x=d:
mult0=mult(A,2,C,0); mult1=mult(A,2,C,1);
for(int k=0;k<8;k++){
C[2][k]=A[2][k]-mult0*C[0][k]-mult1*C[1][k];
}
NORM=norma(C,2);
for(int k=0;k<8;k++){
C[2][k]/=NORM;
}
d[2]=(b[2]-mult0*d[0]-mult1*d[1])/NORM;
//Получаем 4-ю строку уравнения C*x=d:
mult0=mult(A,3,C,0); mult1=mult(A,3,C,1); mult2=mult(A,3,C,2);
for(int k=0;k<8;k++){
C[3][k]=A[3][k]-mult0*C[0][k]-mult1*C[1][k]-mult2*C[2][k];
}
NORM=norma(C,3);
for(int k=0;k<8;k++){
C[3][k]/=NORM;
}
d[3]=(b[3]-mult0*d[0]-mult1*d[1]-mult2*d[2])/NORM;
//Получаем 5-ю строку уравнения C*x=d:
mult0=mult(A,4,C,0); mult1=mult(A,4,C,1); mult2=mult(A,4,C,2); mult3=mult(A,4,C,3);
for(int k=0;k<8;k++){
C[4][k]=A[4][k]-mult0*C[0][k]-mult1*C[1][k]-mult2*C[2][k]-
mult3*C[3][k];
}
NORM=norma(C,4);
for(int k=0;k<8;k++){
C[4][k]/=NORM;
}
d[4]=(b[4]-mult0*d[0]-mult1*d[1]-mult2*d[2]-mult3*d[3])/NORM;
//Получаем 6-ю строку уравнения C*x=d:
mult0=mult(A,5,C,0); mult1=mult(A,5,C,1); mult2=mult(A,5,C,2); mult3=mult(A,5,C,3); mult4=mult(A,5,C,4);
for(int k=0;k<8;k++){
C[5][k]=A[5][k]-mult0*C[0][k]-mult1*C[1][k]-mult2*C[2][k]-
mult3*C[3][k]-mult4*C[4][k];
}
NORM=norma(C,5);
for(int k=0;k<8;k++){
C[5][k]/=NORM;
}
d[5]=(b[5]-mult0*d[0]-mult1*d[1]-mult2*d[2]-mult3*d[3]-mult4*d[4])/NORM;
//Получаем 7-ю строку уравнения C*x=d:
mult0=mult(A,6,C,0); mult1=mult(A,6,C,1); mult2=mult(A,6,C,2); mult3=mult(A,6,C,3); mult4=mult(A,6,C,4); mult5=mult(A,6,C,5);
for(int k=0;k<8;k++){
C[6][k]=A[6][k]-mult0*C[0][k]-mult1*C[1][k]-mult2*C[2][k]-
mult3*C[3][k]-mult4*C[4][k]-mult5*C[5][k];
}
NORM=norma(C,6);
for(int k=0;k<8;k++){
C[6][k]/=NORM;
}
d[6]=(b[6]-mult0*d[0]-mult1*d[1]-mult2*d[2]-mult3*d[3]-mult4*d[4]-
mult5*d[5])/NORM;
//Получаем 8-ю строку уравнения C*x=d:
mult0=mult(A,7,C,0); mult1=mult(A,7,C,1); mult2=mult(A,7,C,2); mult3=mult(A,7,C,3); mult4=mult(A,7,C,4); mult5=mult(A,7,C,5);
mult6=mult(A,7,C,6);
for(int k=0;k<8;k++){
C[7][k]=A[7][k]-mult0*C[0][k]-mult1*C[1][k]-mult2*C[2][k]-
mult3*C[3][k]-mult4*C[4][k]-mult5*C[5][k]-mult6*C[6][k];
}
NORM=norma(C,7);
for(int k=0;k<8;k++){
C[7][k]/=NORM;
}
d[7]=(b[7]-mult0*d[0]-mult1*d[1]-mult2*d[2]-mult3*d[3]-mult4*d[4]-
mult5*d[5]-mult6*d[6])/NORM;
}
//Выполнение ортонормирования системы A*x=b с прямоугольной матрицей A коэффициентов размерности 4х8.
void orto_norm_4x8(double A[4][8], double b[4], double C[4][8], double d[4]){
double NORM;
double mult0,mult1,mult2,mult3,mult4,mult5,mult6,mult7;
//Получаем 1-ю строку уравнения C*x=d:
NORM=norma(A,0);
for(int k=0;k<8;k++){
C[0][k]=A[0][k]/NORM;
}
d[0]=b[0]/NORM;
//Получаем 2-ю строку уравнения C*x=d:
mult0=mult(A,1,C,0);
for(int k=0;k<8;k++){
C[1][k]=A[1][k]-mult0*C[0][k];
}
NORM=norma(C,1);
for(int k=0;k<8;k++){
C[1][k]/=NORM;
}
d[1]=(b[1]-mult0*d[0])/NORM;
//Получаем 3-ю строку уравнения C*x=d:
mult0=mult(A,2,C,0); mult1=mult(A,2,C,1);
for(int k=0;k<8;k++){
C[2][k]=A[2][k]-mult0*C[0][k]-mult1*C[1][k];
}
NORM=norma(C,2);
for(int k=0;k<8;k++){
C[2][k]/=NORM;
}
d[2]=(b[2]-mult0*d[0]-mult1*d[1])/NORM;
//Получаем 4-ю строку уравнения C*x=d:
mult0=mult(A,3,C,0); mult1=mult(A,3,C,1); mult2=mult(A,3,C,2);
for(int k=0;k<8;k++){
C[3][k]=A[3][k]-mult0*C[0][k]-mult1*C[1][k]-mult2*C[2][k];
}
NORM=norma(C,3);
for(int k=0;k<8;k++){
C[3][k]/=NORM;
}
d[3]=(b[3]-mult0*d[0]-mult1*d[1]-mult2*d[2])/NORM;
}
//Произведение матрицы A1 размерности 4х8 на матрицу А2 размерности 8х8. Получаемматрицу rezult размерности 4х8:
void mat_4x8_on_mat_8x8(double A1[4][8], double A2[8][8], double rezult[4][8]){
for(int i=0;i<4;i++){
for(int j=0;j<8;j++){
rezult[i][j]=0.0;
for(int k=0;k<8;k++){
rezult[i][j]+=A1[i][k]*A2[k][j];
}
}
}
}
//Умножение матрицы A на вектор b и получаем rezult.
void mat_on_vect(double A[8][8], double b[8], double rezult[8]){
for(int i=0;i<8;i++){
rezult[i]=0.0;
for(int k=0;k<8;k++){
rezult[i]+=A[i][k]*b[k];
}
}
}
//Умножение матрицы A размерности 4х8 на вектор b размерности 8 и получаем rezult размерности 4.
void mat_4x8_on_vect_8(double A[4][8], double b[8], double rezult[4]){
for(int i=0;i<4;i++){
rezult[i]=0.0;
for(int k=0;k<8;k++){
rezult[i]+=A[i][k]*b[k];
}
}
}
//Вычитание из вектора u1 вектора u2 и получение вектора rez=u1-u2. Всевектораразмерности 4.
void minus(double u1[4], double u2[4], double rez[4]){
for(int i=0;i<4;i++){
rez[i]=u1[i]-u2[i];
}
}
//Вычисление матричной экспоненты EXP=exp(A*delta_x)
void exponent(double A[8][8], double delta_x, double EXP[8][8]) {
//n - количество членов ряда в экспоненте, m - счетчик членов ряда (m<=n)
int n=100, m;
double E[8][8]={0}, TMP1[8][8], TMP2[8][8];
int i,j,k;
//E - единичная матрица - первый член ряда экспоненты
E[0][0]=1.0; E[1][1]=1.0; E[2][2]=1.0; E[3][3]=1.0;
E[4][4]=1.0; E[5][5]=1.0; E[6][6]=1.0; E[7][7]=1.0;
//первоначальное заполнение вспомогательного массива TMP1 - предыдущего члена ряда для следующего перемножения
//и первоначальное заполнение экспоненты первым членом ряда
for(i=0;i<8;i++) {
for(j=0;j<8;j++) {
TMP1[i][j]=E[i][j];
EXP[i][j]=E[i][j];
}
}
//ряд вычисления экспоненты EXP, начиная со 2-го члена ряда (m=2;m<=n)
for(m=2;m<=n;m++) {
for(i=0;i<8;i++) {
for(j=0;j<8;j++) {
TMP2[i][j]=0;
for(k=0;k<8;k++) {
//TMP2[i][j]+=TMP1[i][k]*A[k][j]*delta_x/(m-1);
TMP2[i][j]+=TMP1[i][k]*A[k][j];
}
TMP2[i][j]*=delta_x;//вынесено за цикл произведения строки на столбец
TMP2[i][j]/=(m-1);//вынесено за цикл произведения строки на столбец
EXP[i][j]+=TMP2[i][j];
}
}
//заполнение вспомогательного массива TMP1 для вычисления следующего члена ряда - TMP2 в следующем шаге цикла по m
if (m for(i=0;i<8;i++) { for(j=0;j<8;j++) { TMP1[i][j]=TMP2[i][j]; } } } } } //Вычисление матрицы MAT_ROW в виде матричного ряда для последующего использования //при вычислении вектора partial_vector - вектора частного решения неоднородной системы ОДУ на шаге delta_x void mat_row_for_partial_vector(double A[8][8], double delta_x, double MAT_ROW[8][8]) { //n - количество членов ряда в MAT_ROW, m - счетчик членов ряда (m<=n) int n=100, m; double E[8][8]={0}, TMP1[8][8], TMP2[8][8]; int i,j,k; //E - единичная матрица - первый член ряда MAT_ROW E[0][0]=1.0; E[1][1]=1.0; E[2][2]=1.0; E[3][3]=1.0; E[4][4]=1.0; E[5][5]=1.0; E[6][6]=1.0; E[7][7]=1.0; //первоначальное заполнение вспомогательного массива TMP1 - предыдущего члена ряда для следующего перемножения //и первоначальное заполнение MAT_ROW первым членом ряда for(i=0;i<8;i++) { for(j=0;j<8;j++) { TMP1[i][j]=E[i][j]; MAT_ROW[i][j]=E[i][j]; } } //ряд вычисления MAT_ROW, начиная со 2-го члена ряда (m=2;m<=n) for(m=2;m<=n;m++) { for(i=0;i<8;i++) { for(j=0;j<8;j++) { TMP2[i][j]=0; for(k=0;k<8;k++) { TMP2[i][j]+=TMP1[i][k]*A[k][j]; } TMP2[i][j]*=delta_x; TMP2[i][j]/=m; MAT_ROW[i][j]+=TMP2[i][j]; } } //заполнение вспомогательного массива TMP1 для вычисления следующего члена ряда - TMP2 в следующем шаге цикла по m if (m for(i=0;i<8;i++) { for(j=0;j<8;j++) { TMP1[i][j]=TMP2[i][j]; } } } } } //Задание вектора внешних воздействий в системе ОДУ - вектора POWER: Y'(x)=A*Y(x)+POWER(x): void power_vector_for_partial_vector(double x, double POWER[8]){ POWER[0]=0.0; POWER[1]=0.0; POWER[2]=0.0; POWER[3]=0.0; POWER[4]=0.0; POWER[5]=0.0; POWER[6]=0.0; POWER[7]=0.0; } //Вычисление vector - НУЛЕВОГО (частный случай) вектора частного решения //неоднородной системы дифференциальных уравнений на рассматриваемом участке: void partial_vector(double vector[8]){ for(int i=0;i<8;i++){ vector[i]=0.0; } } //Вычисление vector - вектора частного решения неоднородной системы дифференциальных уравнений на рассматриваемом участке delta_x: void partial_vector_real(double expo_[8][8], double mat_row[8][8], double x_, double delta_x, double vector[8]){ double POWER_[8]={0};//Вектор внешней нагрузки на оболочку double REZ[8]={0}; double REZ_2[8]={0}; power_vector_for_partial_vector(x_, POWER_);//Расчитываем POWER_ прикоординате x_ mat_on_vect(mat_row, POWER_, REZ);//Умножениематрицы mat_row навектор POWER_ иполучаемвектор REZ mat_on_vect(expo_, REZ, REZ_2);//Умножение матрицы expo_ на вектор REZ и получаем вектор REZ_2 for(int i=0;i<8;i++){ vector[i]=REZ_2[i]*delta_x; } } //Решение СЛАУ размерности 8 методом Гаусса с выделением главного элемента int GAUSS(double AA[8][8], double bb[8], double x[8]){ double A[8][8]; double b[8]; for(int i=0;i<8;i++){ b[i]=bb[i];//Работать будем с вектором правых частей b, чтобы исходный вектор bb не изменялся при выходе из подпрограммы for(int j=0;j<8;j++){ A[i][j]=AA[i][j];//Работать будем с матрицей А, чтобы исходная матрица АА не менялась при выходе из подпрограммы } } int e;//номер строки, где обнаруживается главный (максимальный) коэффициент в столбце jj double s, t, main;//Вспомогательная величина for(int jj=0;jj<(8-1);jj++){//Цикл по столбцам jj преобразования матрицы А в верхнетреугольную e=-1; s=0.0; main=A[jj][jj]; for(int i=jj;i<8;i++){//Находится номер е строки, где лежит главный (максимальный) элемент в столбце jj и делается взаимозамена строк if ((A[i][jj]*A[i][jj])>s) {//Вместо перемножения (удаляется возможный знак минуса) можно было бы использовать функцию по модулю abs() e=i; s=A[i][jj]*A[i][jj]; } } if (e<0) { cout<<"Mistake "< } if (e>jj) {//Если главный элемент не в строке с номером jj. а в строке с номером е main=A[e][jj]; for(int j=0;j<8;j++){//Взаимная замена двух строк - с номерами e и jj t=A[jj][j]; A[jj][j]=A[e][j]; A[e][j]=t; } t=b[jj]; b[jj]=b[e]; b[e]=t; } for(int i=(jj+1);i<8;i++){//Приведение к верхнетреугольной матрице for(int j=(jj+1);j<8;j++){ A[i][j]=A[i][j]-(1/main)*A[jj][j]*A[i][jj];//Перерасчеткоэффициентовстроки i>(jj+1) } b[i]=b[i]-(1/main)*b[jj]*A[i][jj]; A[i][jj]=0.0;//Обнуляемые элементы столбца под диагональным элементом матрицы А } }//Цикл по столбцам jj преобразования матрицы А в верхнетреугольную x[8-1]=b[8-1]/A[8-1][8-1];//Первоначальное определение последнего элемента искомого решения х (7-го) for(int i=(8-2);i>=0;i--){//Вычисление елементов решения x[i] от 6-го до 0-го t=0; for(int j=1;j<(8-i);j++){ t=t+A[i][i+j]*x[i+j]; } x[i]=(1/A[i][i])*(b[i]-t); } return 0; } int main() { int nn;//Номер гармоники, начиная с 1-й (без нулевой) int nn_last=50;//Номер последней гармоники double Moment[100+1]={0};//Массив физического параметра (момента), что рассчитывается в каждой точке между краями double step=0.02; //step=(L/R)/100 - величина шага расчета оболочки - шага интервала интегрирования (должна быть больше нуля, т.е. положительная) double h_div_R;//Величина h/R h_div_R=1.0/100; double c2; c2=h_div_R*h_div_R/12;//Величина h*h/R/R/12 double nju; nju=0.3; double gamma; gamma=3.14159265359/4;//Угол распределения силы по левому краю //распечатка в файлы: FILE *fp; // Open for write if( (fp = fopen( "C:/test.txt", "w" )) == NULL ) // C4996 printf( "The file 'C:/test.txt' was not openedn" ); else printf( "The file 'C:/test.txt' was openedn" ); for(nn=1;nn<=nn_last;nn++){ //ЦИКЛ ПО ГАРМОНИКАМ, НАЧИНАЯ С 1-ОЙ ГАРМОНИКИ (БЕЗ НУЛЕВОЙ ГАРМОНИКИ) double x=0.0;//Координата от левого края - нужна для случая неоднородной системы ОДУ для вычисления частного вектора FF double expo_from_minus_step[8][8]={0};//Матрица для расположения в ней экспоненты на шаге типа (0-x1) double expo_from_plus_step[8][8]={0};//Матрица для расположения в ней экспоненты на шаге типа (x1-0) double mat_row_for_minus_expo[8][8]={0};//вспомогательная матрица для расчета частного вектора при движении на шаге типа (0-x1) double mat_row_for_plus_expo[8][8]={0};//вспомогательная матрица для расчета частного вектора при движении на шаге типа (x1-0) double MATRIXS[100+1][8][8]={0};//Массив из матриц размерности 8x8 для решения СЛАУ в каждой точке интервала интегрирования double VECTORS[100+1][8]={0};//Массив векторов правых частей размерности 8 соответствующих СЛАУ double U[4][8]={0};//Матрица краевых условий левого края размерности 4х8 double u_[4]={0};//Вектор размерности 4 внешнего воздействия для краевых условий левого края double V[4][8]={0};//Матрица краевых условий правого края размерности 4х8 double v_[4]={0};//Вектор размерности 4 внешнего воздействия для краевых условий правого края double Y[100+1][8]={0};//Массив векторов-решений соответствующих СЛАУ (в каждой точке интервала между краями): MATRIXS*Y=VECTORS double A[8][8]={0};//Матрица коэффициентов системы ОДУ double FF[8]={0};//Вектор частного решения неоднородной ОДУ на участке интервала интегрирования double Ui[4][8]={0};//Вспомогательная матрица коэффициентов переносимых краевых условий с левого края double ui_[4]={0};//Правые части переносимых краевых условий с левого края double ui_2[4]={0};//вспомогательный вектор (промежуточный) double UiORTO[4][8]={0};//Ортонормированная переносимая матрица с левого края double ui_ORTO[4]={0};//Соответственно правые части ортонормированного переносимого уравнения с левого края double Vj[4][8]={0};//Вспомогательная матрица коэффициентов переносимых краевых условий с правого края double vj_[4]={0};//Правые части переносимых краевых условий с правого края double vj_2[4]={0};//Вспомогательный вектор (промежуточный) double VjORTO[4][8]={0};//Ортонормированная переносимая матрица с правого края double vj_ORTO[4]={0};//Соответственно правые части ортонормированного переносимого уравнения с правого края double MATRIX_2[8][8]={0};//Вспомогательная матрица double VECTOR_2[8]={0};//Вспомогательный вектор double Y_2[8]={0};//Вспомогательный вектор double nn2,nn3,nn4,nn5,nn6,nn7,nn8;//Возведенный в соответствующие степени номер гармоники nn nn2=nn*nn; nn3=nn2*nn; nn4=nn2*nn2; nn5=nn4*nn; nn6=nn4*nn2; nn7=nn6*nn; nn8=nn4*nn4; //Заполнение ненулевых элементов матрицы А коэффициентов системы ОДУ A[0][1]=1.0; A[1][0]=(1-nju)/2*nn2; A[1][3]=-(1+nju)/2*nn; A[1][5]=-nju; A[2][3]=1.0; A[3][1]=(1+nju)/(1-nju)*nn; A[3][2]=2*nn2/(1-nju); A[3][4]=2*nn/(1-nju); A[4][5]=1.0; A[5][6]=1.0; A[6][7]=1.0; A[7][1]=-nju/c2; A[7][2]=-nn/c2; A[7][4]=-(nn4+1/c2); A[7][6]=2*nn2; //Здесь надо первоначально заполнить ненулевыми значениями матрицы и вектора краевых условий U*Y[0]=u_ (слева) и V*Y[100]=v_ (справа) : U[0][1]=1.0; U[0][2]=nn*nju; U[0][4]=nju; u_[0]=0.0;//Сила T1 на левом крае равна нулю U[1][0]=-(1-nju)/2*nn; U[1][3]=(1-nju)/2; U[1][5]=(1-nju)*nn*c2; u_[1]=0.0;//Сила S* на левом краю равна нулю U[2][4]=-nju*nn2; U[2][6]=1.0; u_[2]=0;//Момент M1 на левом краю равен нулю U[3][5]=(2-nju)*nn2; U[3][7]=-1.0; u_[3]=-sin(nn*gamma)/(nn*gamma);//Сила Q1* на левом крае распределена на угол -gamma +gamma V[0][0]=1.0; v_[0]=0.0;//Перемещение u на правом крае равно нулю V[1][2]=1.0; v_[1]=0.0;//Перемещение v на правом крае равно нулю V[2][4]=1.0; v_[2]=0.0;//Перемещение w на правом крае равно нулю V[3][5]=1.0; v_[3]=0.0;//Угол поворота на правом крае равен нулю //Здесь заканчивается первоначальное заполнение U*Y[0]=u_ и V*Y[100]=v_ orto_norm_4x8(U, u_, UiORTO, ui_ORTO);//Первоначальное ортонормирование краевых условий orto_norm_4x8(V, v_, VjORTO, vj_ORTO); //Первоначальное заполнение MATRIXS и VECTORS матричными уравнениями краевых условий соответственно //UiORTO*Y[0]=ui_ORTOиVjORTO*Y[100]=vj_ORTO: for(int i=0;i<4;i++){ for(int j=0;j<8;j++){ MATRIXS[0][i][j]=UiORTO[i][j];//Левый край; верхнее матричное уравнение MATRIXS[100][i+4][j]=VjORTO[i][j];//Правый край (точка номер 101 с индексом 100 - отсчет идет с нуля); нижнее матричное уравнение } VECTORS[0][i]=ui_ORTO[i];//Левый край; верхнее матричное уравнение VECTORS[100][i+4]=vj_ORTO[i];//Правый край (точка номер 101 с индексом 100 - отсчет идет с нуля); нижнее матричное уравнение } //Цикл по точкам ii интервала интегрирования заполнения ВЕРХНИХ частей матричных уравнений MATRIXS[ii]*Y[ii]=VECTORS[ii], //начиная со второй точки - точки с индексом ii=1 exponent(A,(-step),expo_from_minus_step);//Шаг отрицательный (значение шага меньше нуля из-за направления вычисления матричной экспоненты) x=0.0;//начальное значение координаты - для расчета частного вектора mat_row_for_partial_vector(A, step, mat_row_for_minus_expo); for(int ii=1;ii<=100;ii++){ x+=step;//Координата для расчета частного вектора на шаге mat_4x8_on_mat_8x8(UiORTO,expo_from_minus_step,Ui);//Вычислениематрицы Ui=UiORTO*expo_from_minus_step //partial_vector(FF);//Вычисление НУЛЕВОГО вектора частного решения системы ОДУ на шаге partial_vector_real(expo_from_minus_step, mat_row_for_minus_expo, x, (-step),FF);// - длядвиженияслеванаправо mat_4x8_on_vect_8(UiORTO,FF,ui_2);//Вычислениевектора ui_2=UiORTO*FF minus(ui_ORTO, ui_2, ui_);//Вычислениевектора ui_=ui_ORTO-ui_2 orto_norm_4x8(Ui, ui_, UiORTO, ui_ORTO);//Ортонормирование для текущего шага по ii for(int i=0;i<4;i++){ for(int j=0;j<8;j++){ MATRIXS[ii][i][j]=UiORTO[i][j]; } VECTORS[ii][i]=ui_ORTO[i]; } }//Цикл по шагам ii (ВЕРХНЕЕ заполнение) //Цикл по точкам ii интервала интегрирования заполнения НИЖНИХ частей матричных уравнений MATRIXS[ii]*Y[ii]=VECTORS[ii], //начиная с предпоследней точки - точки с индексом ii=(100-1) используем ii-- (уменьшение индекса точки) exponent(A,step,expo_from_plus_step);//Шаг положительный (значение шага больше нуля из-за направления вычисления матричной экспоненты) x=step*100;//Координатаправогокрая mat_row_for_partial_vector(A, (-step), mat_row_for_plus_expo); for(int ii=(100-1);ii>=0;ii--){ x-=step;//Движение справа на лево - для расчета частного вектора mat_4x8_on_mat_8x8(VjORTO,expo_from_plus_step,Vj);//Вычислениематрицы Vj=VjORTO*expo_from_plus_step //partial_vector(FF);//Вычисление НУЛЕВОГО вектора частного решения системы ОДУ на шаге partial_vector_real(expo_from_plus_step,mat_row_for_plus_expo, x,step,FF);// - длядвижениясправаналево mat_4x8_on_vect_8(VjORTO,FF,vj_2);//Вычислениевектора vj_2=VjORTO*FF minus(vj_ORTO, vj_2, vj_);//Вычислениевектора vj_=vj_ORTO-vj_2 orto_norm_4x8(Vj, vj_, VjORTO, vj_ORTO);//Ортонормирование для текущего шага по ii for(int i=0;i<4;i++){ for(int j=0;j<8;j++){ MATRIXS[ii][i+4][j]=VjORTO[i][j]; } VECTORS[ii][i+4]=vj_ORTO[i]; } }//Цикл по шагам ii (НИЖНЕЕ заполнение) //Решение систем линейных алгебраических уравнений for(int ii=0;ii<=100;ii++){ for(int i=0;i<8;i++){ for(int j=0;j<8;j++){ MATRIX_2[i][j]=MATRIXS[ii][i][j];//Вспомогательное присвоение для соответствия типов в вызывающей функции GAUSS } VECTOR_2[i]=VECTORS[ii][i];//Вспомогательное присвоение для соответствия типов в вызывающей функции GAUSS } GAUSS(MATRIX_2,VECTOR_2,Y_2); for(int i=0;i<8;i++){ Y[ii][i]=Y_2[i]; } } //Вычисление момента во всех точках между краями for(int ii=0;ii<=100;ii++){ Moment[ii]+=Y[ii][4]*(-nju*nn2)+Y[ii][6]*1.0;//Момент M1 в точке [ii] //U[2][4]=-nju*nn2; U[2][6]=1.0; u_[2]=0;//Момент M1 } }//ЦИКЛ ПО ГАРМОНИКАМ ЗДЕСЬ ЗАКАНЧИВАЕТСЯ for(int ii=0;ii<=100;ii++){ fprintf(fp,"%fn",Moment[ii]); } fclose(fp); printf( "PRESS any key to continue...n" ); _getch(); return 0; } Метод Алексея Юрьевича Виноградова «переноса краевых условий» для решения краевых задач, включая «жесткие» краевые задачи. 1. Введение. Метод проверен и его эффективность выше, чем эффективность (скорость счета) метода ортогональной прогонки С.К.Годунова - до 2 порядков (в 100 раз). Для разных типов задач преимущество по скорости разное. А для некоторых типов задач метод А.Ю.Виноградова не требует применять ортонормирование вовсе. Рассмотрим метод на примере системы дифференциальных уравнений цилиндрической оболочки ракеты – системы обыкновенных дифференциальных уравнений 8-го порядка (после разделения частных производных). Система линейных обыкновенных дифференциальных уравнений имеет вид: , где – искомая вектор-функция задачи размерности 8х1, – производная искомой вектор-функции размерности 8х1, – квадратная матрица коэффициентов дифференциального уравнения размерности 8х8, – вектор-функция внешнего воздействия на систему размерности 8х1. Здесь и далее вектора обозначаем жирным шрифтом вместо черточек над буквами Краевые условия имеют вид: где – значение искомой вектор-функции на левом крае х=0 размерности 8х1, – прямоугольная горизонтальная матрица коэффициентов краевых условий левого края размерности 4х8, – вектор внешних воздействий на левый край размерности 4х1, – значение искомой вектор-функции на правом крае х=1 размерности 8х1, – прямоугольная горизонтальная матрица коэффициентов краевых условий правого края размерности 4х8, – вектор внешних воздействий на правый край размерности 4х1. В случае, когда система дифференциальных уравнений имеет матрицу с постоянными коэффициентами =const, решение задачи Коши имеет вид [1]: , где , где - это единичная матрица. Матричная экспонента ещё может называться матрицей Коши или матрициантом и может обозначаться в виде: . Тогда решение задачи Коши может быть записано в виде: , где это вектор частного решения неоднородной системы дифференциальных уравнений. 2. Случай переменных коэффициентов. Из теории матриц [1] известно свойство перемножаемости матричных экспонент (матриц Коши):
В случае, когда система дифференциальных уравнений имеет матрицу с переменными коэффициентами , решение задачи Коши предлагается искать при помощи свойства перемножаемости матриц Коши. То есть интервал интегрирования разбивается на малые участки и на малых участках матрицы Коши приближенно вычисляются по формуле для постоянной матрицы в экспоненте. А затем матрицы Коши, вычисленные на малых участках, перемножаются: , где матрицы Коши приближенно вычисляются по формуле: , где . 3. Вычисление вектора частного решения неоднородной системы дифференциальных уравнений. Вместо формулы для вычисления вектора частного решения неоднородной системы дифференциальных уравнений в виде [1]: предлагается использовать следующую формулу для каждого отдельного участка интервала интегрирования: . Правильность приведенной формулы подтверждается следующим: , , , , , , что и требовалось подтвердить. Вычисление вектора частного решения неоднородной системы дифференциальных уравнений производиться при помощи представления матрицы Коши под знаком интеграла в виде ряда и интегрирования этого ряда поэлементно: Эта формула справедлива для случая системы дифференциальных уравнений с постоянной матрицей коэффициентов =const. Вектор может рассматриваться на участке приближенно в виде постоянной величины , что позволяет вынести его из под знака интеграла, что приводит к совсем простому ряду для вычислений на рассматриваемом участке. Для случая дифференциальных уравнений с переменными коэффициентами в приведенной выше формуле для каждого участка может использоваться осредненная матрица коэффициентов системы дифференциальных уравнений. Рассмотрим вариант, когда шаги интервала интегрирования выбираются достаточно малыми, что позволяет рассматривать вектор на участке приближенно в виде постоянной величины , что позволяет вынести этот вектор из под знаков интегралов: Известно, что при T=(at+b) имеем В нашем случае имеем Тогда получаем . Тогда получаем ряд для вычисления вектора частного решения неоднородной системы дифференциальных уравнений на малом участке : Приведем формулы вычисления вектора частного решения, например, на рассматриваемом участке через вектора частного решения , , соответствующих подучастков , , . Имеем . Также имеем формулу для отдельного подучастка: . Можем записать: , . Подставим в и получим: . Сравним полученное выражение с формулой: и получим, очевидно, что: и для частного вектора получаем формулу: . То есть вектора подучастков не просто складываются друг с другом, а с участием матрицы Коши подучастка. Аналогично запишем и подставим сюда формулу для и получим: Сравнив полученное выражение с формулой: очевидно, получаем, что: и вместе с этим получаем формулу для частного вектора: То есть именно так и вычисляется частный вектор – вектор частного решения неоднородной системы дифференциальных уравнений, то есть так вычисляется, например, частный вектор на рассматриваемом участке через вычисленные частные вектора , , соответствующих подучастков , , . 4. Метод «переноса краевых условий» в произвольную точку интервала интегрирования. Полное решение системы дифференциальных уравнений имеет вид . Или можно записать: . Подставляем это выражение для в краевые условия левого края и получаем: , , . Или получаем краевые условия, перенесенные в точку : , где и. Далее запишем аналогично И подставим это выражение для в перенесенные краевые условия точки : , , . Или получаем краевые условия, перенесенные в точку : , гдеи. И так в точку переносим матричное краевое условие с левого края и таким же образом переносим матричное краевое условие с правого края. Покажем шаги переноса краевых условий с правого края. Можем записать: Подставляем это выражение для в краевые условия правого края и получаем: , , Или получаем краевые условия правого края, перенесенные в точку : , гдеи. Далее запишем аналогично И подставим это выражение для в перенесенные краевые условия точки : , , . Или получаем краевые условия, перенесенные в точку : , гдеи. И так во внутреннюю точку интервала интегрирования переносим матричное краевое условие, как показано, и с левого края и таким же образом переносим матричное краевое условие с правого края и получаем: , . Из этих двух матричных уравнений с прямоугольными горизонтальными матрицами коэффициентов очевидно получаем одну систему линейных алгебраических уравнений с квадратной матрицей коэффициентов: . 5. Случай «жестких» дифференциальных уравнений. В случае «жестких» дифференциальных уравнений предлагается применять построчное ортонормирование матричных краевых условий в процессе их переноса в рассматриваемую точку. Для этого формулы ортонормирования систем линейных алгебраических уравнений можно взять в [2]. То есть, получив применяем к этой группе линейных алгебраических уравнений построчное ортонормирование и получаем эквивалентное матричное краевое условие: . И теперь уже в это проортонормированное построчно уравнение подставляем . И получаем , . Или получаем краевые условия, перенесенные в точку : , гдеи. Теперь уже к этой группе линейных алгебраических уравнений применяем построчное ортонормирование и получаем эквивалентное матричное краевое условие: И так далее. И аналогично поступаем с промежуточными матричными краевыми условиями, переносимыми с правого края в рассматриваемую точку. В итоге получаем систему линейных алгебраических уравнений с квадратной матрицей коэффициентов, состоящую из двух независимо друг от друга поэтапно проортонормированных матричных краевых условий. Эта система решается методом Гаусса с выделением главного элемента для получения решения в рассматриваемой точке : . 6. Контроль точности вычислений. Для однородной системы дифференциальных уравнений имеем: . Можем записать: и Подставляем одну формулу в другую и получаем: , то есть получаем: , но последнее возможно только когда - единичная матрица, то есть матрицы и взаимообратны. То есть доказано, что , то есть . Таким образом, получаем, что точность вычислений можно контролировать при помощи определения точности вычисления матричных экспонент (или иначе говоря - матриц Коши или матрициантов), что можно проверять, удостоверяясь, что на участках интегрирования выполняется условие взаимной обратности соответствующих матричных экспонент: . 7. Применяемые формулы ортонормирования. Взято из [2]. Пусть дана система линейных алгебраических уравнений порядка n: =. Здесь над векторами поставим черточки вместо их обозначения жирным шрифтом. Будем рассматривать строки матрицы системы как векторы: =(,,…,). Ортонормируем эту систему векторов. Первое уравнение системы =делим на . При этом получим: ++…+=,=(,,…,), где =, =, =1. Второе уравнение системы заменяется на: ++…+=,=(,,…,), где =, =, =-(,),=-(,). Аналогично поступаем дальше. Уравнение с номером i примет вид: ++…+=,=(,,…,), где =, =, =-(,)-(,)-…-(,), =-(,)-(,)-…-(,). Здесь (,) – это скалярное произведение вектора на вектор и т.п. Процесс будет осуществим, если система линейных алгебраических уравнений линейно независима. В результате мы придем к новой системе , где матрица будет с ортонормированными строками, то есть обладает свойством , где - это единичная матрица. 8. Вычислительные эксперименты. В качестве проверочных задач использовалась схема консольно закрепленных цилиндрической и сферической оболочек с параметрами R/h=50, 100, 200. Длина цилиндрической оболочки рассматривалась L/R=2, а угловые координаты сферической оболочки рассматривались от p/4 до 3p/4. На свободном крае рассматривалось нормальное к поверхности оболочек погонное усилие, равномерно распределенное в интервале [-p/4, p/4]. В качестве среды программирования использовалась система MicrosoftVisualStudio 2010 (VisualC++). Первоначально метод был предложен и обсчитывался в кандидатской диссертации А.Ю.Виноградова в 1993-1995 годах. Тогда оказалось, что без использования ортонормирования в рамках метода успешно решаются задачи осесимметрично нагруженных оболочек вращения. Расчеты тогда выполнялись на компьютере поколения 286. Задачи же неосесимметричного нагружения оболочек вращения можно было решать на компьютерах поколения 286 только с применением процедур построчного ортонормирования - как это и предлагалось в рамках метода. Без процедур ортонормирования в неосесимметричных случаях выдавались только ошибочные графики, представлявшие собой хаотично скачущие большие отрицательные и большие положительные значения, например, изгибающего обезразмеренного момента М1. Современные компьютеры имеют значительно более совершенное внутреннее устройство и более точные внутренние операции с числами, чем это было в 1993-1995 годах. Поэтому было интересно рассмотреть возможность расчета неосесимметрично нагруженных оболочек, например, цилиндров, на современном аппаратном и программном обеспечении в рамках предложенного метода «переноса краевых условий» совсем без использования процедур построчного ортонормирования. Оказалось, что неосесимметрично нагруженные цилиндры при некоторых параметрах на современных компьютерах уже можно решать в рамках предложенного метода «переноса краевых условий» совсем без применения операций построчного ортонормирования. Это, например, при параметрах цилиндра L/R=2 и R/h=100. При параметрах цилиндра L/R=2 и R/h=200 все же оказываются необходимыми процедуры ортонормирования. Но на современных персональных компьютерах уже не наблюдаются сплошные скачки значений от больших отрицательных до больших положительных по всему интервалу между краями цилиндра - как это было на компьютерах поколения 286. В частном случае L/R=2 и R/h=200 наблюдаются лишь незначительные скачки в районе максимума изгибающего обезразмеренного момента М1 на левом крае и небольшой скачек обезразмеренного момента М1 на правом крае. Приводятся графики изгибающего обезразмеренного момента М1: - слева приводятся графики, полученные при использовании операций построчного ортонормирования на каждом из 100 шагов, на которые разделялся участок между краями цилиндра, - справа приводятся графики, полученные совсем без применения операций построчного ортонормирования. Следует сказать, что в качестве расчетной среды использовалась 32-х битная операционная система WindowsXP и среда программирования MicrosoftVisualStudio 2010 (VisualC++) использовалась в тех же рамках 32-х битной организации операций с числами. Параметры компьютера такие: ноутбук ASUSM51V (CPUDuoT5800). Компьютеры будут и дальше развиваться такими же темпами как сейчас и это означает, что в самое ближайшее время для подобных расчетов типа расчета неосесимметрично нагруженных оболочек вращения совсем не потребуется применять ортонормирование в рамках предложенного метода «переноса краевых условий», что существенно упрощает программирование метода и увеличивает скорость расчетов не только по сравнению с другими известными методами, но и по сравнению с собственными характеристиками метода «переноса краевых условий» предыдущих лет.
СПИСОК ЛИТЕРАТУРЫ P.S. Метод Алексея Юрьевича Виноградова «переноса краевых условий» первоначально был опубликован в Межвузовском сборнике МИРЭА (кажется в 1995 году). МИРЭА это Московский институт радиотехники, электроники и автоматики. Точное название и год выхода стать можно посмотреть в Ленинской библиотеке в списке литературы моей диссертации. Там у меня только одна статья в МИРЭА. К сожалению, на руках у меня нет экземпляра моей кандидатской диссертации, поэтому не могу привести точное название статьи, но называется она, кажется, что-то вроде «Метод приведения краевых задач к задаче Коши».