fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <mpi.h>
  5.  
  6. // Conversion from degrees to radians
  7. double degtorad(double degang) {
  8. return ((M_PI * degang) / 180.0);
  9. }
  10.  
  11. // Function to be integrated (replace with your actual function)
  12. double func(double x) {
  13. return tan(x); // Example function
  14. }
  15.  
  16. // Trapezoidal rule function with OpenMP parallelization
  17. double trap(int n, double h, double *fx) {
  18. double area = 0.0;
  19.  
  20. #pragma omp parallel for reduction(+:area) private(i)
  21. for (int i = 0; i < n; i++) {
  22. area += h * func(a + i * h); // Use actual function here
  23. }
  24.  
  25. return area;
  26. }
  27.  
  28. int main() {
  29. int rank, size, n_local, n_global = 2; // Initial guess for global n
  30. double a, b, h, area, local_area;
  31. double *x, *fx;
  32. double diff, tol = 1.0e-6;
  33. MPI_Status status;
  34.  
  35. MPI_Init(&argc, &argv);
  36. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  37. MPI_Comm_size(MPI_COMM_WORLD, &size);
  38.  
  39. // Enter a and b in process 0
  40. if (rank == 0) {
  41. printf("Enter a and b\n");
  42. scanf("%lf %lf", &a, &b);
  43. }
  44.  
  45. // Broadcast a and b to all processes
  46. MPI_Bcast(&a, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  47. MPI_Bcast(&b, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  48.  
  49. // Find optimal n in parallel using a doubling strategy
  50. while (1) {
  51. // Calculate local sub-interval size on each process
  52. h = (b - a) / (n_global - 1);
  53. n_local = n_global / size + (rank < n_global % size); // Account for uneven distribution
  54.  
  55. // Allocate memory for x and fx on each process
  56. x = (double*)malloc(n_local * sizeof(double));
  57. fx = (double*)malloc(n_local * sizeof(double));
  58.  
  59. // Calculate x and fx values (can be parallelized within each process)
  60. for (int i = 0; i < n_local; i++) {
  61. x[i] = a + rank * (b - a) / size + i * h;
  62. fx[i] = func(degtorad(x[i])); // Convert to radians before function call
  63. }
  64.  
  65. // Call trap function (parallelized) to find local area
  66. local_area = trap(n_local, h, fx);
  67.  
  68. // Free memory for x and fx
  69. free(x);
  70. free(fx);
  71.  
  72. // Gather local areas from all processes and sum on process 0
  73. MPI_Reduce(&local_area, &area, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
  74.  
  75. if (rank == 0) {
  76. diff = fabs(area - log(2.0));
  77. printf("n = %d, Area = %lf, Difference = %lf\n", n_global, area, diff);
  78. if (diff < tol) {
  79. break;
  80. }
  81. }
  82.  
  83. // Double the global number of intervals for the next iteration
  84. n_global *= 2;
  85.  
  86. // Check for potential overflow of n_global
  87. int ret = MPI_Bcast(&n_global, 1, MPI_INT, 0, MPI_COMM_WORLD);
  88. if (ret != MPI_SUCCESS) {
  89. printf("Error: MPI_Bcast failed (%d)\n", ret);
  90. MPI_Finalize();
  91. return 1;
  92. }
  93. }
  94.  
  95. MPI_Finalize();
  96. return 0;
  97. }
  98.  
Success #stdin #stdout #stderr 0.3s 40768KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Error: unexpected '/' in "/"
Execution halted