Advertisement
Archangelpl

Untitled

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