vatman

mmn_test_final

May 29th, 2024
760
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.06 KB | None | 0 0
  1. #include <cmath>
  2. #include <fstream>
  3. #include <iomanip>
  4. #include <iostream>
  5. #include <vector>
  6.  
  7. double f(double x, double y) {
  8.   double T = M_PI * x * y;
  9.   double sin2T = std::pow(std::sin(T), 2);
  10.   double cos2T = std::pow(std::cos(T), 2);
  11.   double y2_x2 = y * y + x * x;
  12.   return -2 * M_PI * std::exp(std::pow(std::sin(T), 2)) *
  13.          (2 * M_PI * y2_x2 * cos2T * sin2T - M_PI * y2_x2 * sin2T +
  14.           M_PI * y2_x2 * cos2T);
  15. }
  16.  
  17. double u(double x, double y) {
  18.   return std::exp(std::pow(std::sin(M_PI * x * y), 2));
  19. }
  20.  
  21. std::vector<std::vector<double>> MinimalResiduals(const int nmax = 1000,
  22.                                                   const double _eps = 0.0000001,
  23.                                                   const int _n = 3,
  24.                                                   const int _m = 3) {
  25.   int Nmax = nmax; // максимальное число итераций (не менее 1)
  26.   std::vector<std::vector<double>> v; // сеточная функция ѵ (x, y)
  27.   v.resize(_n + 1);
  28.   for (size_t i = 0; i < _n + 1; i++) {
  29.     v[i].resize(_m + 1);
  30.     for (size_t j = 0; j < _m + 1; j++) {
  31.       v[i][j] = 0;
  32.     }
  33.   }
  34.   std::vector<std::vector<double>> r_vec; // вектор невязки
  35.   r_vec.resize(_n + 1);
  36.   for (size_t i = 0; i < _n + 1; i++) {
  37.     r_vec[i].resize(_m + 1);
  38.     for (size_t j = 0; j < _m + 1; j++) {
  39.       r_vec[i][j] = 0;
  40.     }
  41.   }
  42.   std::vector<std::vector<double>> ar; // вектор невязки
  43.   ar.resize(_n + 1);
  44.   for (size_t i = 0; i < _n + 1; i++) {
  45.     ar[i].resize(_m + 1);
  46.     for (size_t j = 0; j < _m + 1; j++) {
  47.       ar[i][j] = 0;
  48.     }
  49.   }
  50.   double r1 = 0;
  51.   int S = 0;         // счетчик итераций
  52.   double eps = _eps; // заданная точность
  53.   double eps_max = 0; // точность, достигнутая на текущей итерации
  54.   double eps_cur = 0; // для подсчета точности на текущей итерации
  55.   double a2, k2, h2; // ненулевые элементы матрицы (-А)
  56.   const int n = _n, m = _m; // размерность сетки
  57.   double r_max = 0;
  58.   double a = 0;
  59.   double b = 1;
  60.   double c = 0;
  61.   double d = 1; // границы области определения уравнения
  62.   int i, j; // индексы
  63.   double r = 0;
  64.   double v_old; // старое значение преобразуемой компоненты вектора
  65.   double v_new; // новое значение преобразуемой компоненты вектора и
  66.   bool flag = false; // условие остановки
  67.   double h = ((b - a) / n);
  68.   double k = ((d - c) / m);
  69.   double z = 0;
  70.   double z_max = 0;
  71.   double tau_s = 0;
  72.   double num = 0; // tau=num/denominator
  73.   double denominator = 1;
  74.   double x, y;
  75.   h2 = -std::pow((n / (b - a)), 2);
  76.   k2 = -std::pow((m / (d - c)), 2);
  77.   a2 = -2 * (h2 + k2);
  78.   for (int i = 0; i < n + 1; i++) {
  79.     v[i][0] = u(a + i * h, a);
  80.     v[i][m] = u(a + i * h, b);
  81.   }
  82.   for (int j = 0; j < m + 1; j++) {
  83.     v[0][j] = u(c, c + j * k);
  84.     v[n][j] = u(d, c + j * k);
  85.   }
  86.   do {
  87.     z = 0;
  88.     z_max = 0;
  89.     eps_max = 0;
  90.     r_max = -20;
  91.     num = 0;
  92.     denominator = 0;
  93.     for (j = 1; j < m; j++) {
  94.       for (i = n - 1; i > 0; i--) {
  95.         r_vec[i][j] = f(a + i * h, c + j * k) -
  96.                       (h2 * (v[i + 1][j] + v[i - 1][j]) +
  97.                        k2 * (v[i][j + 1] + v[i][j - 1]) + v[i][j] * a2);
  98.       }
  99.     }
  100.     for (j = 1; j < m; j++) {
  101.       for (i = n - 1; i > 0; i--) {
  102.         ar[i][j] =
  103.             (h2 * (r_vec[i + 1][j] + r_vec[i - 1][j]) +
  104.              k2 * (r_vec[i][j + 1] + r_vec[i][j - 1]) + r_vec[i][j] * a2);
  105.         num += ar[i][j] * r_vec[i][j];
  106.         denominator += ar[i][j] * ar[i][j];
  107.       }
  108.     }
  109.     tau_s = num / denominator;
  110.     for (j = 1; j < m; j++) {
  111.       for (i = n - 1; i > 0; i--) {
  112.         v_old = v[i][j];
  113.         v_new = v_old + tau_s * r_vec[i][j];
  114.         eps_cur = std::fabs(v_old - v_new);
  115.         if (eps_cur > eps_max) {
  116.           eps_max = eps_cur;
  117.         }
  118.         v[i][j] = v_new;
  119.         r = fabs(f(a + i * h, c + j * k) -
  120.                  (h2 * (v[i + 1][j] + v[i - 1][j]) +
  121.                   k2 * (v[i][j + 1] + v[i][j - 1]) + v_old * a2));
  122.         if (r > r_max)
  123.           r_max = r;
  124.         z = u(a + i * h, c + j * k) - v[i][j];
  125.         if (z > z_max) {
  126.           z_max = z;
  127.           x = i;
  128.           y = j;
  129.         }
  130.       }
  131.     }
  132.  
  133.     S = S + 1;
  134.     if ((eps_max <= eps) or (S >= Nmax) or (z_max < 0.0000005)) {
  135.       flag = true;
  136.     }
  137.   } while (!flag);
  138.  
  139.   std::ofstream in("./"
  140.                    "param_test.txt"); // подключение текстового файла для записи
  141.   in << "\nСПРАВКА:" << std::endl;
  142.  
  143.   in << "Количество выполненных итераций = " << S << std::endl;
  144.   in << "Точность на выходе = " << eps_max << std::endl;
  145.   in << "Невязка = " << r_max << std::endl;
  146.   in << "Норма общей погрешности = " << z_max << std::endl;
  147.   in << "Максимальное отклонение в узле x= " << x << ", y= " << y;
  148.   return v;
  149. }
  150.  
  151. int main() {
  152.   int n = 800;
  153.   int m = 800;
  154.   std::vector<std::vector<double>> v(n, std::vector<double>(m, 0));
  155.   v = MinimalResiduals(100, 0.000000001, n, m);
  156.   n++;
  157.   m++;
  158.   std::ofstream in("./"
  159.                    "data_test.txt"); // подключение текстового файла для записи
  160.   in << "Результат:" << std::endl;
  161.   for (int i = n - 1; i >= 0; i--) {
  162.     for (int j = 0; j < m; j++)
  163.       in << std::left << std::setw(10) << v[i][j];
  164.     in << "\n";
  165.   }
  166.   std::ofstream in2(
  167.       "./"
  168.       "data_test_u_v.txt"); // подключение текстового файла для записи
  169.   in2 << "Результат:" << std::endl;
  170.   for (int i = n - 1; i >= 0; i--) {
  171.     for (int j = 0; j < m; j++)
  172.       in2 << std::left << std::setw(15)
  173.           << std::fabs(u(double(i) / n, double(j) / m) - v[i][j]);
  174.  
  175.     in2 << "\n";
  176.   }
  177.   return 0;
  178. }
  179.  
Advertisement
Add Comment
Please, Sign In to add comment