/project/curs/curs/parabolicVector_solver.cpp

http://cm-kp-406.googlecode.com/ · C++ · 215 lines · 176 code · 33 blank · 6 comment · 19 complexity · 2fd548983dc11855ae524fbf7104b588 MD5 · raw file

  1. #include "parabolicVector_solver.h"
  2. CParabolicVector_solver::CParabolicVector_solver()
  3. {
  4. q_arr = NULL;
  5. }
  6. CParabolicVector_solver::~CParabolicVector_solver()
  7. {
  8. if (pTable != NULL)
  9. {
  10. for (int i = 0; i < K; ++i)
  11. {
  12. delete [] pTable[i];
  13. }
  14. delete [] pTable;
  15. pTable = NULL;
  16. }
  17. delete[] q_arr;
  18. q_arr = NULL;
  19. }
  20. double **CParabolicVector_solver:: getTable()
  21. {
  22. return pTable;
  23. }
  24. int CParabolicVector_solver::getK()
  25. {
  26. return K;
  27. }
  28. int CParabolicVector_solver::getN()
  29. {
  30. return N;
  31. }
  32. double * CParabolicVector_solver::getLeftBorder()
  33. {
  34. double *temp_arr = new double[K];
  35. for (int k = 0; k < K; k++)
  36. {
  37. temp_arr[k] = pTable[k][0];
  38. }
  39. return temp_arr;
  40. }
  41. double * CParabolicVector_solver::getRightBorder()
  42. {
  43. double *temp_arr = new double[K];
  44. for (int k = 0; k < K; k++)
  45. {
  46. temp_arr[k] = pTable[k][N-1];
  47. }
  48. return temp_arr;
  49. }
  50. void CParabolicVector_solver::setGrid(int _N, int _K, double _xb, double _xe, double _maxT)
  51. {
  52. stepT = _maxT / _K;
  53. stepX = (_xe - _xb) / _N;
  54. if (pTable != NULL)
  55. {
  56. for (int i = 0; i < K; ++i)
  57. {
  58. delete [] pTable[i];
  59. }
  60. delete [] pTable;
  61. pTable = NULL;
  62. }
  63. if (q_arr != NULL)
  64. {
  65. delete [] q_arr;
  66. q_arr = NULL;
  67. }
  68. N = _N + 1;
  69. K = _K + 1;
  70. xb = _xb;
  71. xe = _xe;
  72. maxT = _maxT;
  73. //
  74. pTable = new double* [K];
  75. q_arr = new double[K];
  76. for (int i = 0; i < K; ++i)
  77. {
  78. pTable[i] = new double[N];
  79. q_arr[i] = 0.0;
  80. }
  81. }
  82. void CParabolicVector_solver::setTask( double _a, double _b, double _c, double(*_f)(double, double),
  83. double _alpha1, double _betta1, double _alpha2, double _betta2,
  84. double * _left_border, double (*_phi2)(double, double),
  85. double (*_psi)(double, double)) // Only after setGrid;
  86. {
  87. a = _a;
  88. b = _b;
  89. c = _c;
  90. f = _f;
  91. alpha1 = _alpha1;
  92. alpha2 = _alpha2;
  93. betta1 = _betta1;
  94. betta2 = _betta2;
  95. phi2 = _phi2;
  96. psi = _psi;
  97. setBorder(_left_border);
  98. }
  99. void CParabolicVector_solver::solve_implicit()
  100. {
  101. double sigma = (a * a * stepT) / (stepX * stepX);
  102. //????????? ?????? ?????? ?? ??????? psi(x, 0) = sin(x)
  103. for (int i = 0; i < N; ++i)
  104. {
  105. pTable[0][i] = psi(xb + i * stepX, 0.0);
  106. }
  107. //??????? ??? ?????? ????????
  108. double* A = new double[N];
  109. double* B = new double[N];
  110. double* C = new double[N];
  111. double* D = new double[N];
  112. double* P = new double[N];
  113. double* Q = new double[N];
  114. double* x = new double[N];
  115. double csigma = a * a * stepT / (stepX * stepX); // only constant, don't want to copy-paste
  116. double csigma1 = 2.0 * a * a * alpha1 / (2.0 * a * a * stepX - b * stepX * stepX); // only constant, don't want to copy-paste
  117. double csigma2 = 2.0 * a * a * alpha2 / (2.0 * a * a * stepX + b * stepX * stepX); // only constant, don't want to copy-paste
  118. for (int i = 1; i < K; ++i)
  119. {
  120. A[0] = 0.0;
  121. B[0] = csigma1 * ( ((c * stepX * stepX) / (2.0 * a * a)) - 1.0 - ((stepX * stepX) / (2.0 * a * a * stepT))) + betta1;
  122. C[0] = csigma1;
  123. D[0] = phi0(xb, i ) - pTable[i-1][0] * (csigma1 * ((stepX * stepX) / (2.0 * a * a * stepT))) - csigma1 * ((stepX * stepX) / (2.0 * a * a)) * f(xb, i * stepT);
  124. // ??? ? ?????? ???? - ??????????? i -?? ??????? ?? ???????.
  125. for (int j = 1; j < N - 1; ++j)
  126. {
  127. A[j] = csigma - ((b * stepT) / (2.0 * stepX));
  128. B[j] = (-2.0 * csigma) - 1.0 + c * stepT;
  129. C[j] = csigma + ((b * stepT) / (2.0 * stepX));
  130. D[j] = -pTable[i-1][j] - f(xb + j * stepX, i * stepT) * stepT;
  131. if (fabs(B[i]) < fabs(A[i]) + fabs(C[i]))
  132. {
  133. printf("error in coeff\n");
  134. }
  135. }
  136. A[N - 1] = -csigma2;
  137. B[N - 1] = csigma2 * (1.0 + ((stepX * stepX) / (2.0 * a * a * stepT)) - ((c * stepX * stepX) / (2.0 * a * a))) + betta2;
  138. C[N - 1] = 0.0;
  139. D[N - 1] = phi2(xe, i * stepT) + pTable[i-1][N - 1] * (csigma2 * stepX * stepX / (2.0 * a * a * stepT)) + f(xe, i * stepT) * csigma2 * stepX * stepX / (2.0 * a * a);
  140. // ?????? ????????
  141. double aa, bb, cc;
  142. bb = B[0];
  143. cc = C[0];
  144. P[0] = -cc / bb;
  145. Q[0] = D[0] / bb;
  146. for (int k = 1; k < N - 1; ++k)
  147. {
  148. aa = A[k];
  149. bb = B[k];
  150. cc = C[k];
  151. P[k] = -cc / (bb + aa*P[k-1]);
  152. Q[k] = (D[k] - aa*Q[k-1]) / (bb + aa*P[k-1]);
  153. }
  154. aa = A[N - 1];
  155. bb = B[N - 1];
  156. P[N - 1] = 0;
  157. Q[N - 1] = (D[N - 1] - aa * Q[N - 2]) / (bb + aa * P[N - 2]);
  158. x[N - 1] = Q[N - 1];
  159. for (int k = N - 2; k >= 0; k--)
  160. {
  161. x[k] = P[k] * x[k+1] + Q[k];
  162. }
  163. //????? ????????
  164. for (int j = 0; j < N; ++j)
  165. pTable[i][j] = x[j];
  166. }
  167. delete [] A;
  168. delete [] B;
  169. delete [] C;
  170. delete [] D;
  171. delete [] P;
  172. delete [] Q;
  173. delete [] x;
  174. }
  175. double CParabolicVector_solver::phi0(double x, int i){
  176. return -q_arr[i];
  177. }
  178. void CParabolicVector_solver::setBorder(double *_arr){
  179. for (int i = 0; i < K; i++){
  180. q_arr[i] = _arr[i];
  181. }
  182. }