Advertisement
Archangelpl

Untitled

Jun 11th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.21 KB | None | 0 0
  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <cstdlib>
  4. #include <fstream>
  5. #include <String>
  6. #include <Math.h>
  7. #include <sys/timeb.h>
  8. using namespace std;
  9.  
  10. fstream file,file2,file3,file4,file5,file6,file7,file8,file9,file10;
  11.  
  12.  
  13.  
  14. //deklaracja stałych:
  15. const double D = 1.0;
  16. const double lambda_bez = 0.4; //dla metod bezposredniej
  17. const double lam_pos = 1.0; //dla metod posrednich
  18. const double h = 0.1; //krok dla x
  19. const double dt = (lambda_bez*h*h)/D; //krok dla t
  20. const double PI=3.1415;
  21. const double x_max=1; //maksymalny przedzial x
  22. const double x_min=0; //minimalny przedzial x
  23. const double t_max=0.5; //maksymalny przedzial x
  24. const double t_min=0; //minimalny przedzial x
  25.  
  26.  
  27. //wymiary macierzy do obliczeń numerycznych:
  28. //const int N = (int)((2*x_max/h)+1);//liczba kolumn (os x)
  29. const int N = 40; //liczba kolumn(x)
  30. const int M = (int)((t_max/dt)+1);//liczba wierszy (os t)
  31.  
  32. //const int M=(t_max-t_min)/dt;
  33. //const int N=(x_max-x_min)/h;
  34.  
  35. //**************************************************************************************************
  36. //tworzy nową macierz MxN
  37. double **macierz(int m, int n)
  38. {
  39. double **a;
  40. a=new double *[m];
  41. for(int i=0; i<m; i++)
  42. a[i]=new double[n];
  43. return a;
  44. }
  45.  
  46. //**************************************************************************************************
  47. //usuwa macierz
  48. void usun_macierz(double **a, int m)
  49. {
  50. for(int i=m-1; i>=0; i--)
  51. delete []a[i];
  52. delete []a;
  53. }
  54.  
  55. //**************************************************************************************************
  56. //zapisywanie macierzy do pliku
  57. void zapisz(double **macierz, fstream &plik)
  58. {
  59.  
  60. //plik.setf(ios::scientific, ios::floatfield);
  61. //plik.precision(4);
  62. plik << ";";
  63. for(int i = 0; i<N; i++){
  64. plik << i*h << ";";
  65. }
  66. plik << endl;
  67. for(int j = 0; j<M; j++){
  68. plik << j*dt << ";";
  69. for(int i=0;i<N;i++){
  70. plik << macierz[j][i] << ";";
  71. }
  72. plik<<"\n";
  73. }
  74.  
  75. plik.close();
  76. }
  77.  
  78. //**************************************************************************************************
  79. void zapiszW(double *wek, fstream &plik)
  80. {
  81. for(int j = 0; j<M; j++){
  82. plik << j*h << ";" << wek[j] << "\n";
  83. }
  84. plik.close();
  85. }
  86.  
  87. /*********************************************************************************************/
  88. /*metoda obliczająca czas wykonywania obliczen*/
  89.  
  90. //**************************************************************************************************
  91. //Metoda rozwiązująca analitycznie równanie rózniczkowe
  92. void analitycznie(double **A, double *x, double *t)
  93. {
  94. //warunek początkowy
  95. for(int i=0;i<N;i++){
  96. A[0][i]=sin(PI*x[i]);
  97. }
  98.  
  99. //warunek brzegowy
  100. for(int i=0;i<M;i++){
  101. A[i][N-1]=0;
  102. A[i][0]=0;
  103. }
  104.  
  105. //wypełnienie całej macierzy:
  106. for(int i =1; i<M; i++){
  107. for(int j =1; j<N-1; j++){
  108. A[i][j] = exp(-(PI*PI)*D*t[i])*sin(PI*x[j]);
  109. }
  110. }
  111.  
  112. //zapisanie rozwiązania do pliku:
  113. zapisz(A, file);
  114. }
  115.  
  116. //**************************************************************************************************
  117. //klasyczna metoda bezposrednia
  118. void klas_bezp(double **KMB, double *x, double *t, double lambda_bez)
  119. {
  120. file8.open("Czas_KMB.txt",ios::out);
  121. double start, stop;
  122. start = Czas();
  123. //warunek początkowy
  124. for(int i=0;i<N;i++){
  125. KMB[0][i]=sin(PI*x[i]);
  126. }
  127.  
  128. //warunek brzegowy:
  129. for(int i =0; i<M; i++){
  130. KMB[i][N-1] = 0;
  131. KMB[i][0] = 0;
  132.  
  133. }
  134. //wypełnienie całej macierzy:
  135. for(int k = 1; k < M; k++){
  136. for(int i = 1; i < N-1; i++){
  137. KMB[k][i]=KMB[k-1][i]+lambda_bez*(KMB[k-1][i-1]-(2*KMB[k-1][i])+KMB[k-1][i+1]);
  138. }
  139. }
  140. stop = Czas();
  141. file8 << "Czas[sek]: \t" << (stop - start )<< "\n";
  142. file8 << "H: \t"<< h << "\n";
  143. file8 << "N: \t"<< N << "\n";
  144. //zapisanie rozwiązania do pliku:
  145. zapisz(KMB, file2);
  146. }
  147.  
  148. //**************************************************************************************************
  149. void blad(double *BLAD, double **KMB, double **A, fstream &plik)
  150. {
  151. double temp;
  152. for(int i =0; i<M; i++)
  153. {
  154. double max = 0.0;
  155. for(int j =0; j<N; j++){
  156. temp = fabs(KMB[i][j] - A[i][j]);
  157. if(temp>max){
  158. max = temp;
  159. }
  160. }
  161. BLAD[i] = max;
  162. }
  163.  
  164. zapiszW(BLAD, plik);
  165.  
  166. }
  167.  
  168. //**************************************************************************************************
  169. double norma(double *dane){
  170. double w = dane[0];
  171. for( register int i = 1; i < N; i++ ){
  172. if( w < dane[i] )
  173. w = dane[i] ;
  174. }
  175. return w;
  176. }
  177.  
  178. //**************************************************************************************************
  179. //funkcja dokonująca częściowego wyboru elementów podstawowych
  180. void szukaj_zamien(double **A, int *indeksy, int start){
  181. int max = start;
  182. for(register int i = start+1; i < M; i++ )
  183. if( fabs( A[indeksy[i]][start] ) > A[indeksy[max]][start] )
  184. max = i;
  185. //sprawdzanie czy udało się znaleść odpowiedni element
  186. if( A[indeksy[max]][start] == 0 ){
  187. printf("Bladna macierz A\n");
  188. exit(1);
  189. }
  190. indeksy[start] = max;
  191. indeksy[max] = start;
  192. }
  193.  
  194. //**************************************************************************************************
  195. //funkcja dokonująca dekompozycji LU
  196. void rozklad_LU(double **LU, double **A, int *indeksy){
  197. double wsp;
  198. for(int i = 0; i < N; i++ ){
  199. for(int j = 0; j < N; j++ ){
  200. LU[indeksy[i]][j] = A[indeksy[i]][j];
  201. }
  202. }
  203. for( int i = 0; i < N; i++ ){
  204. for(int j = i+1; j < N; j++ ){
  205. if(LU[indeksy[i]][i] == 0 ) szukaj_zamien(LU,indeksy,i);
  206. wsp = LU[indeksy[j]][i]/LU[indeksy[i]][i];
  207. for(int k = i; k < M; k++ ){
  208. LU[indeksy[j]][k] = LU[indeksy[j]][k] - LU[indeksy[i]][k]*wsp;
  209. if( i < j ){
  210. LU[indeksy[j]][i] = wsp;
  211. }
  212. }
  213. }
  214. }
  215. }
  216.  
  217. //**************************************************************************************************
  218. //funkcja dokonująca obliczeń wektora y z równania Ly=b
  219. void obliczanie_y(double **LU, double *Y, double *B, int *indeksy, const int n){
  220. double S;
  221. for(register int i = 0; i < n; i++ ){
  222. S = 0;
  223. for(register int j = 0; j < i; j++ ){
  224. S += Y[j]*LU[indeksy[i]][j];
  225. }
  226. Y[i] = B[indeksy[i]] - S;
  227. }
  228. }
  229.  
  230. //**************************************************************************************************
  231. //funkcja dokonująca obliczeń wektora x z równania Ux=y
  232. void obliczanie_x(double **LU, double *X, double *Y, int *indeksy, const int n){
  233. double S;
  234. register int j;
  235. for( register int i = n-1; i >= 0; i-- ){
  236. S = 0;
  237. for( j = n-1; j > i; j-- )
  238. S += X[j]*LU[indeksy[i]][j];
  239. X[i] = (Y[i] - S)/LU[indeksy[i]][i];
  240. }
  241. }
  242.  
  243. //**************************************************************************************************
  244. //funkcja inicjalizująca tablicę indeksów potrzebna dla powyższych funkcji.
  245. void init_kolumny(int *indeksy, const int n ){
  246. for( register int i = 0; i < n; i++ )
  247. indeksy[i] = i;
  248. }
  249.  
  250. //**************************************************************************************************
  251. void crank_nicolson_LU(double **A,double *x, double *t, double lam_pos){
  252. register int i,j,k;
  253. double *b,*z;
  254.  
  255. double **LU = new double * [N];
  256. double **WSP = new double * [N];
  257. for( i = 0 ; i < N ; i++ ){
  258. LU[i] = new double [N];
  259. WSP[i] = new double [N];
  260. }
  261. double *Y = new double [N];
  262. int *indeksy = new int [N];
  263.  
  264. b=new double[N];
  265. z=new double[N];
  266.  
  267. for(j=0;j<N;j++)
  268. A[0][j]=sin(PI*x[i]);
  269.  
  270. for(i=0;i<M;i++){
  271. A[i][0]=0;
  272. A[i][N-1]=0;
  273. }
  274.  
  275. for( i = 0; i < N; i++ )
  276. for( j =0; j< N; j++ ){
  277. if( j == i-1 || j == i+1){
  278. WSP[i][j] = -lam_pos/2.0;
  279. }else if( j == i ){
  280. WSP[i][j] = 1 + lam_pos;
  281. }else{
  282. WSP[i][j] = 0;
  283. }
  284. }
  285.  
  286. init_kolumny(indeksy,N);
  287. rozklad_LU(LU,WSP,indeksy);
  288. for( i=0;i<M-1;i++){
  289. b[0]=b[N-1]=0;
  290. for(j=1;j<N-1;j++)
  291. //b[j]=(lambda/2.0)*A[i][j-1]+(1-lambda)*A[i][j]+(lambda/2.0)*A[i][j+1];
  292. b[j]=-((lam_pos/2.0)*A[i][j-1]+(1.0-lam_pos)*A[i][j]+(lam_pos/2.0)*A[i][j+1]);
  293. //for(k=0;k<m;k++)
  294. //b[k]=b[k]+D*dt;
  295.  
  296. obliczanie_y( LU,Y, b,indeksy,N);
  297. obliczanie_x( LU,z, Y,indeksy,N);
  298.  
  299. for(j=1;j<N-1;j++)
  300. A[i+1][j]=z[j];
  301. }
  302.  
  303. zapisz(A, file4);
  304. }
  305. //**************************************************************************************************
  306. //gauss Seidel
  307. void GS(double **A, double *x, double *b){
  308. double tmp;
  309. double *xp = new double[N];
  310. double *tmp_w = new double[N];
  311. for( int i = 0; i < N; i++ )
  312. xp[i] =x[i] + 1;
  313. do{
  314.  
  315. for( int i = 0; i < N; i++ ){
  316. tmp = 0;
  317. for( int j = 0; j < i-1; j++ ){
  318. tmp += A[j][i] * x[j];
  319. }
  320. for( int j = i+1; j < N; j++ ){
  321. tmp += A[j][i] * x[j];
  322. }
  323. x[i] = b[i] - tmp;
  324. x[i] /= A[i][i];
  325. }
  326. for( int i = 0; i < N; i++ ){
  327. tmp_w[i] = fabs(x[i] - xp[i]);
  328. xp[i] = x[i];
  329. }
  330. }while( norma(tmp_w) > 0.00000000001 );
  331. }
  332.  
  333.  
  334. void crank_nicolson_GS(double **A, double *x, double *t, double lam_pos){
  335. register int i,j,k;
  336. double *b,*z;
  337.  
  338. double **LU = new double * [N];
  339. double **WSP = new double * [N];
  340. for( i = 0 ; i < N ; i++ ){
  341. LU[i] = new double [N];
  342. WSP[i] = new double [N];
  343. }
  344.  
  345. b=new double[N];
  346. z=new double[N];
  347.  
  348.  
  349. for(j=0;j<N;j++){
  350. A[0][j]=sin(PI*x[i]);
  351. z[j] = 1;
  352. }
  353.  
  354. for(i=0;i<M;i++){
  355. A[i][0]=0;
  356. A[i][N-1]=0;
  357. }
  358.  
  359. for( i = 0; i < N; i++ )
  360. for( j =0; j< N; j++ ){
  361. if( j == i-1 || j == i+1){
  362. WSP[i][j] = -lam_pos/2.0;
  363. }else if( j == i ){
  364. WSP[i][j] = 1 + lam_pos;
  365. }else{
  366. WSP[i][j] = 0;
  367. }
  368. }
  369. for( i=0;i<M-1;i++){
  370. b[0]=b[N-1]=0;
  371. for(j=1;j<N-1;j++)
  372. //b[j]=(lambda/2.0)*A[i][j-1]+(1-lambda)*A[i][j]+(lambda/2.0)*A[i][j+1];
  373. b[j]=(lam_pos/2.0)*A[i][j-1]-(lam_pos-1)*A[i][j]+(lam_pos/2.0)*A[i][j+1];
  374. //for(k=0;k<m;k++)
  375. //b[k]=b[k]+D*dt;
  376.  
  377. GS(WSP,z,b);
  378.  
  379. for(j=1;j<N-1;j++)
  380. A[i+1][j]=z[j];
  381. }
  382. zapisz(A, file6);
  383. }
  384.  
  385.  
  386.  
  387. //**************************************************************************************************
  388. int main(){
  389. file.open("Analit.csv",ios::out);
  390. file2.open("BMK.csv",ios::out);
  391. file3.open("Bledy_BMK.csv",ios::out);
  392. file6.open("CN-LU.csv",ios::out);
  393. file5.open("Bledy_CN-LU.csv",ios::out);
  394. file4.open("CN-GS.txt",ios::out);
  395. file7.open("Bledy_CN-GS.txt",ios::out);
  396.  
  397.  
  398. double *x = new double[N];
  399. double *t = new double[M];
  400.  
  401.  
  402. for(int i =1; i<N; i++)
  403. x[i] = x_min + (i*h);
  404.  
  405. for(int i =1; i<M; i++)
  406. t[i] = t_min + (i*dt);
  407.  
  408. double **A = macierz(M, N); //macierz do rozwiązania analitycznego
  409. double **KMB = macierz(M,N);
  410. double *BLAD = new double[M];
  411. double **CN_LU = macierz(M,N);
  412. double **CN_GS = macierz(M,N);
  413. analitycznie(A,x,t);
  414. klas_bezp(KMB,x,t,lambda_bez);
  415. blad(BLAD,KMB,A,file3);
  416. crank_nicolson_GS(CN_GS,x,t,lambda_bez);
  417. blad(BLAD,CN_GS,A,file7);
  418. crank_nicolson_LU(CN_LU,x,t,lambda_bez);
  419. blad(BLAD,CN_LU,A,file5);
  420.  
  421. return 0;
  422. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement