Advertisement
Archangelpl

Untitled

Jun 18th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.26 KB | None | 0 0
  1. #define _USE_MATH_DEFINES
  2.  
  3. #include <iostream>
  4. #include <cmath>
  5. #include <fstream>
  6. #include "calerf.h"
  7.  
  8. const double D = 1.0;
  9. const double tMax = 2.0;
  10. const double a = 6.0 * sqrt(D * tMax);
  11. const double LAMBDA = 1.0;
  12. const double h = 0.1;
  13. const double dt = (LAMBDA * (h*h) / D);
  14. const int N = (int)((tMax / dt) + 2);
  15. const int M = (int)((a / h) + 1);
  16.  
  17. double *newWektor(int n);
  18. double **newMacierz(int n, int m);
  19. void deleteWektor(double* x);
  20. void deleteMacierz(double** x, int n);
  21.  
  22. void Wypelnij(double* x, double delta, int k);
  23.  
  24. void ZapiszPlik(const char* fileName, double** macierz, int r, int c);
  25. void ZapiszPLik2(char *filename, double **macierz, int r, int c, double *hPoziom);
  26.  
  27. void RozwiazanieAnalityczne(double** analit, int N, int M, double* dtPoziom, double* hPoziom, double dt, double h);
  28. void CrankNicolsonGS(double** U, int N, int M, double* dtPoziom, double* hPoziom, double dt, double h, double LAMBDA);
  29. void CrankNicolsonLU(double** U, int N, int M, double* dtPoziom, double* hPoziom, double dt, double h, double LAMBDA);
  30. void GS(double* L, double* D, double* U, double* b, double* x, int n);
  31. void LU(double* L, double* D, double* U, double* b, double* x, int n);
  32.  
  33. void BladGS(double **err, double **Analityczne, double **U, int N, int M, double *dt_kroki, double *h_kroki);
  34. void BladLU(double **err, double **Analityczne, double **U, int N, int M, double *dt_kroki, double *h_kroki);
  35.  
  36. int main()
  37. {
  38. double* dtPoziom = newWektor(N);
  39. double* hPoziom = newWektor(M);
  40.  
  41. std::cout << "Zapisanie do pliku." << std::endl;
  42.  
  43. Wypelnij(dtPoziom, dt, N);
  44. Wypelnij(hPoziom, h, M);
  45.  
  46. std::ofstream file("dt.txt");
  47. file.setf(std::ios::fixed, std::ios::floatfield);
  48. file.precision(4);
  49. for (int i = 0; i < N; i++)
  50. {
  51. file << dtPoziom[i] << std::endl;
  52. }
  53.  
  54. file.close();
  55.  
  56. std::ofstream file2("h.txt");
  57. file2.setf(std::ios::fixed, std::ios::floatfield);
  58. file2.precision(4);
  59. for (int i = 0; i < M; i++)
  60. {
  61. file2 << hPoziom[i] << std::endl;
  62. }
  63.  
  64. file2.close();
  65.  
  66. double** A = newMacierz(N, M);
  67. RozwiazanieAnalityczne(A, N, M, dtPoziom, hPoziom, dt, h);
  68.  
  69. double** Err = newMacierz(N, M);
  70.  
  71. double** U = newMacierz(N, M);
  72. CrankNicolsonGS(U, N, M, dtPoziom, hPoziom, dt, h, LAMBDA);
  73. ZapiszPLik2("Crank+GS.txt", U, N, M, hPoziom);
  74. BladGS(Err, A, U, N, M, dtPoziom, hPoziom);
  75. deleteMacierz(U, N);
  76.  
  77. U = newMacierz(N, M);
  78. CrankNicolsonLU(U, N, M, dtPoziom, hPoziom, dt, h, LAMBDA);
  79. ZapiszPLik2("Crank+LU.txt", U, N, M, hPoziom);
  80. BladLU(Err, A, U, N, M, dtPoziom, hPoziom);
  81.  
  82. system("pause");
  83. return 0;
  84. }
  85.  
  86. double *newWektor(int n)
  87. {
  88. return new double[n];
  89. }
  90.  
  91. double **newMacierz(int n, int m)
  92. {
  93. double** macierz = new double*[n];
  94.  
  95. for (int i = 0; i < n; i++)
  96. {
  97. macierz[i] = new double[m];
  98. }
  99.  
  100. return macierz;
  101. }
  102.  
  103. void deleteWektor(double* x)
  104. {
  105. delete[] x;
  106. }
  107.  
  108. void deleteMacierz(double** x, int n)
  109. {
  110. for (int i = 0; i < n; i++)
  111. {
  112. delete[] x[i];
  113. }
  114. delete[] x;
  115. }
  116.  
  117. void Wypelnij(double* x, double delta, int k)
  118. {
  119. x[0] = 0.0;
  120. for (int i = 1; i<k; i++)
  121. x[i] = x[i - 1] + delta;
  122. }
  123.  
  124. void RozwiazanieAnalityczne(double** analit, int N, int M, double* dtPoziom, double* hPoziom, double dt, double h)
  125. {
  126. for (int i = 0; i < N; i++)
  127. {
  128. analit[i][0] = 0.0;
  129. }
  130. for (int i = 0; i < N; i++)
  131. {
  132. analit[i][M - 1] = 1.0;
  133. }
  134.  
  135. for (int i = 0; i < M; i++)
  136. {
  137. analit[0][i] = 1.0;
  138. }
  139.  
  140. for (int i = 1; i < N; i++)
  141. {
  142. for (int j = 1; j < M - 1; j++)
  143. {
  144. analit[i][j] = erf(hPoziom[j] / (2 * sqrt(D * dtPoziom[i])));
  145. }
  146. }
  147.  
  148. ZapiszPLik2("RozwiazanieAnalityczne.txt", analit, N, M, hPoziom);
  149. }
  150.  
  151. void CrankNicolsonGS(double** U, int N, int M, double* dtPoziom, double* hPoziom, double dt, double h, double LAMBDA)
  152. {
  153. double* L = newWektor(M);
  154. double* Up = newWektor(M);
  155. double* D = newWektor(M);
  156. double* b = newWektor(M);
  157. double* u = newWektor(M);
  158.  
  159. for (int i = 0; i < N; i++)
  160. {
  161. U[i][0] = 0.0; //Warunek brzegowy U(0, t) = 0.0.
  162. }
  163. for (int i = 0; i < N; i++)
  164. {
  165. U[i][M - 1] = 1.0; //Warunek brzegowy U(INF, t) = 1.0.
  166. }
  167.  
  168. for (int i = 0; i < M; i++)
  169. {
  170. U[0][i] = 1.0; //Warunek poczatkowy U(X, 0) = 1.0.
  171. }
  172.  
  173. for (int k = 1; k < N; k++)
  174. {
  175. L[0] = LAMBDA / 2.0;
  176. D[0] = 1.0;
  177. Up[0] = 0.0;
  178. b[0] = 0.0;
  179.  
  180. for (int i = 1; i < M - 1; i++)
  181. {
  182. L[i] = LAMBDA / 2.0;
  183. D[i] = -(1 + LAMBDA);
  184. Up[i] = LAMBDA / 2.0;
  185. b[i] = -(LAMBDA / 2.0 * U[k - 1][i - 1] + (1.0 - LAMBDA) * U[k - 1][i] + (LAMBDA / 2.0) * U[k - 1][i + 1]);
  186. }
  187.  
  188. L[M - 1] = 0.0;
  189. D[M - 1] = 1.0;
  190. Up[M - 1] = 0.0;
  191. b[M - 1] = 1.0;
  192.  
  193. GS(L, D, Up, b, u, M);
  194.  
  195. for (int i = 1; i < M - 1; i++)
  196. {
  197. U[k][i] = u[i];
  198. }
  199. }
  200. }
  201.  
  202. void CrankNicolsonLU(double** U, int N, int M, double* dtPoziom, double* hPoziom, double dt, double h, double LAMBDA)
  203. {
  204. double* L = newWektor(M);
  205. double* Up = newWektor(M);
  206. double* D = newWektor(M);
  207. double* b = newWektor(M);
  208. double* u = newWektor(M);
  209.  
  210. for (int i = 0; i < N; i++)
  211. {
  212. U[i][0] = 0.0; //Warunek brzegowy U(0, t) = 0.0.
  213. }
  214. for (int i = 0; i < N; i++)
  215. {
  216. U[i][M - 1] = 1.0; //Warunek brzegowy U(INF, t) = 1.0.
  217. }
  218.  
  219. for (int i = 0; i < M; i++)
  220. {
  221. U[0][i] = 1.0; //Warunek początkowy U(X, 0) = 1.0.
  222. }
  223.  
  224. for (int k = 1; k < N; k++)
  225. {
  226. L[0] = LAMBDA / 2.0;
  227. D[0] = 1.0;
  228. Up[0] = 0.0;
  229. b[0] = 0.0;
  230.  
  231. for (int i = 1; i < M - 1; i++)
  232. {
  233. L[i] = LAMBDA / 2.0;
  234. D[i] = -(1 + LAMBDA);
  235. Up[i] = LAMBDA / 2.0;
  236. b[i] = -(LAMBDA / 2.0 * U[k - 1][i - 1] + (1.0 - LAMBDA) * U[k - 1][i] + (LAMBDA / 2.0) * U[k - 1][i + 1]);
  237. }
  238.  
  239. L[M - 1] = 0.0;
  240. D[M - 1] = 1.0;
  241. Up[M - 2] = 0.0;
  242. b[M - 1] = U[k-1][M-1];
  243.  
  244. LU(L, D, Up, b, u, M);
  245.  
  246. for (int i = 1; i < M - 1; i++)
  247. {
  248. U[k][i] = u[i];
  249. }
  250. }
  251. }
  252.  
  253. void GS(double* L, double* D, double* U, double* b, double* x, int n)
  254. {
  255. double** A = newMacierz(n, n);
  256.  
  257. for (int i = 0; i < n; i++)
  258. {
  259. for (int j = 0; j < n; j++)
  260. {
  261. A[i][j] = 0.0;
  262. }
  263. }
  264. for (int i = 0; i < n - 1; i++)
  265. {
  266. A[i][i] = D[i];
  267. A[i + 1][i] = U[i];
  268. A[i][i + 1] = L[i];
  269. }
  270. A[n - 1][n - 1] = D[n - 1];
  271.  
  272. double x1;
  273. for (int k = 0; k<M - 1; k++)
  274. {
  275. for (int i = k + 1; i<M; i++)
  276. {
  277. x1 = A[i][k] / A[k][k];
  278. A[i][k] = x1;
  279. for (int j = k + 1; j<M; j++)
  280. {
  281. A[i][j] = A[i][j] - (x1*A[k][j]);
  282. }
  283. }
  284. }
  285. double suma;
  286. double *z = new double[M];
  287.  
  288. for (int i = 0; i<M; i++)
  289. {
  290. suma = 0.0;
  291. for (int j = 0; j <= i - 1; j++)
  292. {
  293. suma += A[i][j] * z[j];
  294. }
  295.  
  296. z[i] = b[i] - suma;
  297. }
  298.  
  299. for (int i = M - 1; i >= 0; i--)
  300. {
  301. suma = 0.0;
  302. for (int j = i + 1; j<M; j++)
  303. {
  304. suma += A[i][j] * x[j];
  305. }
  306.  
  307. x[i] = (z[i] - suma) / A[i][i];
  308. }
  309. }
  310.  
  311. void LU(double* L, double* D, double* U, double* b, double* x, int n)
  312. {
  313. double** A = newMacierz(n, n);
  314.  
  315. for (int i = 0; i < n; i++)
  316. {
  317. for (int j = 0; j < n; j++)
  318. {
  319. A[i][j] = 0.0;
  320. }
  321. }
  322. for (int i = 0; i < n - 1; i++)
  323. {
  324. A[i][i] = D[i];
  325. A[i + 1][i] = U[i];
  326. A[i][i + 1] = L[i];
  327. }
  328. A[n - 1][n - 1] = D[n - 1];
  329.  
  330. //Dekompozycja LU, metoda eliminacji Gaussa
  331. double x1;
  332. for (int k = 0; k<M - 1; k++)
  333. {
  334. for (int i = k + 1; i<M; i++)
  335. {
  336. x1 = A[i][k] / A[k][k];
  337. A[i][k] = x1;
  338. for (int j = k + 1; j<M; j++)
  339. {
  340. A[i][j] = A[i][j] - (x1*A[k][j]);
  341. }
  342. }
  343. }
  344.  
  345. //Rozwiązywanie układu równań
  346. double suma;
  347. double *z = new double[M];
  348.  
  349. //Ly=b => y=...
  350. for (int i = 0; i<M; i++)
  351. {
  352. suma = 0.0;
  353. for (int j = 0; j <= i - 1; j++)
  354. {
  355. suma += A[i][j] * z[j];
  356. }
  357.  
  358. z[i] = b[i] - suma;
  359. }
  360.  
  361. //Ux=y => x=...
  362. for (int i = M - 1; i >= 0; i--)
  363. {
  364. suma = 0.0;
  365. for (int j = i + 1; j<M; j++)
  366. {
  367. suma += A[i][j] * x[j];
  368. }
  369.  
  370. x[i] = (z[i] - suma) / A[i][i];
  371. }
  372. }
  373.  
  374. void BladGS(double **err, double **Analityczne, double **U, int N, int M, double *dt_kroki, double *h_kroki)
  375. {
  376. std::ofstream file1;
  377. std::ofstream file2;
  378.  
  379. file1.open("Blad_max_co_krok_t_GS.txt");
  380. file2.open("Blad_max_od_kroku_h_GS.txt", std::ios::app);
  381.  
  382. file1.setf(std::ios::fixed, std::ios::floatfield);
  383. file2.setf(std::ios::fixed, std::ios::floatfield);
  384.  
  385. file1.precision(15);
  386. file2.precision(15);
  387.  
  388. double max = 0.0;
  389.  
  390. for (int i = 0; i < N; i++)
  391. {
  392. max = 0.0;
  393. for (int j = 0; j < M; j++)
  394. {
  395. err[i][j] = fabs(U[i][j] - Analityczne[i][j]);
  396.  
  397. if (err[i][j] > max)
  398. max = err[i][j];
  399. }
  400. if (i == (N - 1))
  401. {
  402. file2 << log10(h) << "\t" << log10(max) << std::endl;
  403. }
  404. if (dt_kroki[i] != 0.0)
  405. {
  406. file1 << dt_kroki[i] << "\t";
  407. file1 << max << std::endl;
  408. }
  409.  
  410. }
  411.  
  412. ZapiszPlik("BladGS.txt", err, N, M);
  413. }
  414.  
  415. //Obliczanie bledu dla CN+LU.
  416. void BladLU(double **err, double **Analityczne, double **U, int N, int M, double *dt_kroki, double *h_kroki)
  417. {
  418. std::ofstream file1;
  419. std::ofstream file2;
  420.  
  421. file1.open("Blad_max_co_krok_t_LU.txt");
  422. file2.open("Blad_max_od_kroku_h_LU.txt", std::ios::app);
  423.  
  424. file1.setf(std::ios::fixed, std::ios::floatfield);
  425. file2.setf(std::ios::fixed, std::ios::floatfield);
  426.  
  427. file1.precision(15);
  428. file2.precision(15);
  429.  
  430. double max = 0.0;
  431.  
  432. for (int i = 0; i < N; i++)
  433. {
  434. max = 0.0;
  435. for (int j = 0; j < M; j++)
  436. {
  437. err[i][j] = fabs(U[i][j] - Analityczne[i][j]);
  438.  
  439. if (err[i][j] > max)
  440. max = err[i][j];
  441. }
  442. if (i == (N - 1))
  443. {
  444. file2 << (log10(h)) << "\t" << (log10(max)) << std::endl;
  445. }
  446.  
  447.  
  448. if (dt_kroki[i] != 0.0)
  449. {
  450. file1 << dt_kroki[i] << "\t";
  451. file1 << max << std::endl;
  452. }
  453. }
  454.  
  455. ZapiszPlik("BladLU.txt", err, N, M);
  456. }
  457.  
  458. void ZapiszPlik(const char* fileName, double** macierz, int r, int c)
  459. {
  460. std::ofstream file(fileName);
  461.  
  462. file.setf(std::ios::scientific, std::ios::floatfield);
  463. file.precision(4);
  464.  
  465. for (int i = 0; i < r; i++)
  466. {
  467. for (int j = 0; j < c; j++)
  468. {
  469. file << macierz[i][j] << "\t";
  470. }
  471. file << std::endl;
  472. }
  473.  
  474. file.close();
  475. }
  476.  
  477. void ZapiszPLik2(char *filename, double **macierz, int r, int c, double *hPoziom)
  478. {
  479. std::ofstream file(filename);
  480.  
  481. file.setf(std::ios::scientific, std::ios::floatfield);
  482. file.precision(4);
  483. file << std::endl;
  484. for (int i = 0; i < c; i++)
  485. {
  486. file << std::endl;
  487. file << hPoziom[i] << "\t";
  488. for (int j = 0; j < c; j++)
  489. {
  490. file << macierz[j][i] << "\t";
  491. }
  492. }
  493. file.close();
  494. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement