Advertisement
Guest User

Untitled

a guest
Oct 14th, 2019
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.92 KB | None | 0 0
  1. #include <iostream>
  2. #include <mpi.h>
  3. #include <stdlib.h>
  4. #include <iomanip>
  5. #include <math.h>
  6.  
  7.  
  8. int main(int argc, char *argv[]) {
  9.         double k, timeIteration;
  10.         double h, dt;
  11.         const double T = 0.0001; //Last moment of time
  12.  
  13.         int myrank, size; // MPI Initializings
  14.         MPI_Status Status;
  15.  
  16.         double begin,end;
  17.  
  18.         MPI_Init(&argc, &argv);
  19.         begin = MPI_Wtime();
  20.  
  21.         MPI_Comm_size(MPI_COMM_WORLD, &size);
  22.         MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
  23.  
  24.         int pointsCount;
  25.         int partSize;
  26.         int lastPart;
  27.  
  28.         if (myrank == 0) {
  29.                 pointsCount = 50000;
  30.         }
  31.  
  32.         MPI_Bcast(&pointsCount, 1, MPI_INT, 0, MPI_COMM_WORLD);
  33.  
  34.         k = 1;
  35.         h = 1 / double(pointsCount);
  36.         dt = h * h / (2 * k);
  37.         partSize = pointsCount / size;
  38.         lastPart = pointsCount % size;
  39.         if (lastPart != 0 && myrank < lastPart) {
  40.                 ++partSize;
  41.         }
  42.    
  43.         double temperatureArray[partSize];
  44.         for (int i = 0; i < partSize; ++i) {
  45.                 temperatureArray[i] = 1;
  46.         }
  47.         if (myrank == 0) {
  48.                 temperatureArray[0] = 0;
  49.         }
  50.         if (myrank == size - 1) {
  51.                 temperatureArray[partSize - 1] = 0;
  52.         }
  53.  
  54.         double leftElement = 0;
  55.         double rightElement = 0;
  56.         timeIteration = dt;
  57.  
  58.         while (timeIteration <= T) {
  59.         double newTemperatureArray[partSize];  
  60.         newTemperatureArray[0] = 0;
  61.         newTemperatureArray[partSize - 1] = 0; 
  62.                 if (myrank != size - 1) {
  63.                         MPI_Sendrecv(&temperatureArray[partSize - 1], 1, MPI_DOUBLE, myrank + 1, myrank, // передача
  64.                                 &rightElement, 1, MPI_DOUBLE, myrank + 1, MPI_ANY_TAG, // прием
  65.                                 MPI_COMM_WORLD, &Status);
  66.                 }
  67.    
  68.                 if (myrank != 0) {
  69.                         MPI_Sendrecv(&temperatureArray[0], 1, MPI_DOUBLE, myrank - 1, myrank, // передача
  70.                                 &leftElement, 1, MPI_DOUBLE, myrank - 1, MPI_ANY_TAG, // прием
  71.                                 MPI_COMM_WORLD, &Status);
  72.                 }
  73.  
  74.         if (myrank != 0) {
  75.                     newTemperatureArray[0] = k * (temperatureArray[1] - 2 * temperatureArray[0] + leftElement) / (h * h) * dt + temperatureArray[0];
  76.         }
  77.                 for (int i = 1; i < partSize - 1; ++i) {
  78.                         newTemperatureArray[i] = k * (temperatureArray[i + 1] - 2 * temperatureArray[i] + temperatureArray[i - 1]) / (h * h) * dt + temperatureArray[i];
  79.                 }
  80.         if (myrank != size - 1) {
  81.                     newTemperatureArray[partSize - 1] = k * (rightElement - 2 * temperatureArray[partSize - 1] + temperatureArray[partSize - 2]) / (h * h) * dt + temperatureArray[partSize - 1];
  82.         }
  83.  
  84.         for (int i = 0; i < partSize; ++i) {
  85.             temperatureArray[i] = newTemperatureArray[i];
  86.         }
  87.                 timeIteration += dt;
  88.         }
  89.  
  90.         MPI_Barrier (MPI_COMM_WORLD);
  91.  
  92.         if (myrank == 0) {
  93.                 int offset = 0;
  94.                 double resultArray[pointsCount];
  95.                 for (int i = 0; i < partSize; ++i) {
  96.                         resultArray[i] = temperatureArray[i];
  97.                 }
  98.                 offset += partSize;
  99.                 for (int i = 1; i < size; ++i) {
  100.                         MPI_Probe(i, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
  101.                         MPI_Get_count(&Status, MPI_DOUBLE, &partSize);
  102.  
  103.                         MPI_Recv(&resultArray[offset], partSize, MPI_DOUBLE, i, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
  104.                         offset += partSize;
  105.                 }
  106.  
  107.                 end = MPI_Wtime();
  108.  
  109.                 //Counting by formula
  110.                 const double precision = 1e-12;
  111.                 double prevIteration = 0;
  112.                 double currentIteration = 0;
  113.                 double difference = 0;
  114.                 double formulaResultArray[11];
  115.                 formulaResultArray[0] = 0;
  116.                 formulaResultArray[10] = 0;
  117.  
  118.                 //Так как sin(0) = 0 и sin(Pi * (2m + 1)) = 0 о считать значение
  119.                 //в начальной и конечной точках не имеет смысла
  120.                 for (int i = 1; i < 10; ++i) {
  121.                         double point = (pointsCount / 10 * i) * h;
  122.                         currentIteration = 0;
  123.                         prevIteration = 0;
  124.                         difference = 1e-5;
  125.                         double iteration = 0;
  126.  
  127.                         while (difference > precision) {
  128.                                 prevIteration = currentIteration;
  129.                                 difference = exp(-1 * k * M_PI * M_PI * (2 * iteration + 1) * (2 * iteration + 1) * T / (1 * 1)) / (2 * iteration + 1) * sin(M_PI * (2 * iteration + 1) * point / 1);
  130.  
  131.                                 currentIteration = prevIteration + difference;
  132.                                 ++iteration;
  133.                         }
  134.                         formulaResultArray[i] = 4 * currentIteration / M_PI;
  135.                 }
  136.  
  137.  
  138.                 std::cout <<  "1 point: " << resultArray[pointsCount - 1] << "    formula: 0" << std::endl;
  139.                 for (int i = 1; i < 10; ++i) {
  140.                         int number = pointsCount / 10 * i - 1;
  141.                         std::cout << i << " point: " << resultArray[number] << "    formula: " << formulaResultArray[i] << std::endl;
  142.                 }
  143.         std::cout <<  "11 point: " << resultArray[pointsCount - 1] << "    formula: 0"<< std::endl;
  144.  
  145.                 double time = end - begin;
  146.                 std::cout <<  std::setprecision(3) << "Program worked: " << time << " seconds" << std::endl;
  147.  
  148.  
  149.         }
  150.         else {
  151.                 MPI_Send(temperatureArray, partSize, MPI_DOUBLE, 0, myrank, MPI_COMM_WORLD);
  152.         }
  153.  
  154.     MPI_Finalize();
  155.         return 0;
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement