Advertisement
Archangelpl

Untitled

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