Advertisement
Guest User

Untitled

a guest
Dec 9th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.63 KB | None | 0 0
  1. void GetBorders(const Matrix& m,
  2.     V& border_x0,
  3.     V& border_x1,
  4.     V& border_y0,
  5.     V& border_y1
  6.     ) {
  7.         for (int j = 0; j < m.M; ++j) {
  8.             border_x0[j] = m.cat(0, j);
  9.         }      
  10.  
  11.         for (int j = 0; j < m.M; ++j) {
  12.             border_x1[j] = m.cat(m.N - 1, j);
  13.         }      
  14.  
  15.         for (int i = 0; i < m.N; ++i) {
  16.             border_y0[i] = m.cat(i, 0);
  17.         }      
  18.  
  19.         for (int i = 0; i < m.N; ++i) {
  20.             border_y1[i] = m.cat(i, m.M - 1);
  21.         }      
  22. }
  23.  
  24.  
  25. void SyncBorder(V& s, V& r, int other_i, int other_j) {
  26.    
  27.     if (other_i < 0 || other_i >= lattice_n) {
  28.         r.resize(r.size(), 0.0);
  29.         return;
  30.     }  
  31.  
  32.     if (other_j < 0 || other_j >= lattice_m) {
  33.         r.resize(r.size(), 0.0);
  34.         return;
  35.     }  
  36.  
  37.  
  38.  
  39.     int me = world_rank;
  40.     int dst = ComputeLatticeId(other_i, other_j);
  41.    
  42.  
  43.     MPI_Send(s.data(), s.size(), MPI_DOUBLE, dst, 0, MPI_COMM_WORLD);
  44.     MPI_Status status;
  45.    
  46.         MPI_Recv(r.data(), r.size(), MPI_DOUBLE, dst, 0, MPI_COMM_WORLD, &status);
  47.    
  48. }
  49.  
  50. double SyncDouble(double value) {
  51.     double result;
  52.     MPI_Allreduce(&value, &result, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
  53.     return result;
  54. }
  55.  
  56.  
  57. Matrix Solve(LocalOperator &op, int max_iter, double eps=1e-6) {
  58.     Matrix w(op.block_h, op.block_w, 0.0);
  59.  
  60.     V border_x0_s(op.block_w, 0);
  61.     V border_x1_s(op.block_w, 0);
  62.  
  63.     V border_y0_s(op.block_h, 0);
  64.     V border_y1_s(op.block_h, 0);
  65.  
  66.     V border_x0_r(op.block_w, 0);
  67.     V border_x1_r(op.block_w, 0);
  68.  
  69.     V border_y0_r(op.block_h, 0);
  70.     V border_y1_r(op.block_h, 0);
  71.    
  72.     for (int iter = 0; iter < max_iter; ++iter) {
  73.         GetBorders(w, border_x0_s, border_x1_s, border_y0_s, border_y1_s);
  74.    
  75.         SyncBorder(border_x0_s, border_x0_r, my_i - 1, my_j);
  76.         SyncBorder(border_x1_s, border_x1_r, my_i + 1, my_j);
  77.         SyncBorder(border_y0_s, border_y0_r, my_i, my_j - 1);
  78.         SyncBorder(border_y1_s, border_y1_r, my_i, my_j + 1);
  79.        
  80.  
  81.         Matrix Aw = op.Call(w, border_x0_r, border_x1_r, border_y0_r, border_y1_r);
  82.        
  83.        
  84.    
  85.         Matrix r = Aw - op.rhs;
  86.         GetBorders(r, border_x0_s, border_x1_s, border_y0_s, border_y1_s);
  87.    
  88.         SyncBorder(border_x0_s, border_x0_r, my_i - 1, my_j);
  89.         SyncBorder(border_x1_s, border_x1_r, my_i + 1, my_j);
  90.         SyncBorder(border_y0_s, border_y0_r, my_i, my_j - 1);
  91.         SyncBorder(border_y1_s, border_y1_r, my_i, my_j + 1);
  92.         Matrix Ar = op.Call(r, border_x0_r, border_x1_r, border_y0_r, border_y1_r);
  93.  
  94.        
  95.        
  96.        
  97.         double rAr = SyncDouble(op.Dot(r, Ar));
  98.         double ArAr = SyncDouble(op.Dot(Ar, Ar));
  99.         double rr = SyncDouble(op.Dot(r, r));
  100.        
  101.         double tau = rAr/ArAr;
  102.        
  103.        
  104.         w = w - r * tau;
  105.         double d = sqrt(rr) * tau;
  106.         double delta = SyncDouble(op.Norm2(w - op.phi));
  107.  
  108.  
  109.         if (d  < eps) {
  110.             break;
  111.         }
  112.  
  113.        
  114.        
  115.     }
  116.     MPI_Barrier(MPI_COMM_WORLD);
  117.  
  118.     return w;
  119. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement