Gauss-Seidel迭代,OpenMP并行化本质上和串行不一样,但是是收敛的

1)代码

      PROGRAM OPENMP_GZ
      INCLUDE 'omp_lib.h'
      INTEGER, PARAMETER :: N = 101
      INTEGER I,J,L,MAXIT,T,S
      REAL(8), ALLOCATABLE, DIMENSION(:,:):: W,X,Y
      REAL(8) ERROR, EPS, T1, T2, dX, dY, C
      MAXIT = 100000 !最大迭代次数
      EPS = 1E-6 !收敛精度
      ERROR = 1E6 !初始误差
      L = 1
      ALLOCATE (W(N,N),X(N,N),Y(N,N))

      OPEN(1, FILE='101.msh')!从文件读取网格数据
      DO J=1,N
          DO I=1,N
              READ(1,*) X(I,J), Y(I,J)
          ENDDO
      ENDDO
      CLOSE(1)

      W(2:N-1,2:N-1) = 0.0! 设置边界条件
      DO J=1,N
         W(1,J) = EXP(-1.5*(X(1,J))**2 + 2*(Y(1,J))**2)
         W(N,J) = EXP(-1.5*(X(N,J))**2 + 2*(Y(N,J))**2)
      ENDDO
      DO I=1,N
         W(I,1) = EXP(-1.5*(X(I,1))**2 + 2*(Y(I,1))**2)
         W(I,N) = EXP(-1.5*(X(I,N))**2 + 2*(Y(I,N))**2)
      ENDDO

      T1 = OMP_GET_WTIME()
      DO S=1,100000000
      DO WHILE (L .LE. MAXIT .AND. ERROR .GT. EPS)
        ERROR = 0.0
!$OMP PARALLEL PRIVATE(I,J,dX,dY,C)  ! PARALLEL DO 指令允许指定哪些循环应由编译器并行化
!$OMP DO REDUCTION(MAX:ERROR)        ! DO 循环,通过 REDUCTION 计算最大误差
        DO J = 2, N-1
          DO I = 2, N-1
            dY = Y(I,J+1) - Y(I,J)
            dX = X(I+1,J) - X(I,J)
            C = W(I,J)
            W(I,J) = 0.5 * (dY*(W(I-1,J) + W(I+1,J)) + dX*(W(I,J-1) + W(I,J+1)) - 0.2*dX*dY)/(                                                         dX + dY)
            ERROR = MAX(ERROR, ABS(W(I,J) - C))
          END DO
        ENDDO
!$OMP END DO    !END PARALLEL DO 指令标记在 PARALLEL DO 指令中指定的 DO 循环的结束
!$OMP END PARALLEL
        L = L + 1
      END DO
      END DO
      T2 = OMP_GET_WTIME()
      PRINT *, 'computational time: ', T2-T1, 's'
      PRINT *, L

      OPEN(2,FILE='Res.dat')  ! 输出数据到文件
      DO J=1,N
        DO I=1,N
            WRITE(2,*) X(I,J), Y(I,J), W(I,J)
        END DO
      END DO
      CLOSE(2)

      DEALLOCATE (W,X,Y)
      END PROGRAM

2)编译命令

gfortran -fopenmp   -o pa.exe Gauss–Seidel_parallel.f90

3)输入数据

见附件

3)运行结果

3000-3100行的数据:

串行:

  0.40000000000000002      -0.41999999999999998       0.94283719429734447     
  0.41999999999999998      -0.41999999999999998       0.91517049547914420     
  0.44000000000000000      -0.41999999999999998       0.88692669347676489     
  0.46000000000000002      -0.41999999999999998       0.85820552287434693     
  0.47999999999999998      -0.41999999999999998       0.82910918519491994     
  0.50000000000000000      -0.41999999999999998       0.79974214641266483     
  0.52000000000000002      -0.41999999999999998       0.77021094585209326     
  0.54000000000000004      -0.41999999999999998       0.74062401904255837     
  0.56000000000000005      -0.41999999999999998       0.71109153718516127     
  0.57999999999999996      -0.41999999999999998       0.68172526596580540     
  0.59999999999999998      -0.41999999999999998       0.65263844650670655     

并行:

   
  0.40000000000000002      -0.41999999999999998       0.94283837147741767     
  0.41999999999999998      -0.41999999999999998       0.91517164464449596     
  0.44000000000000000      -0.41999999999999998       0.88692781352135375     
  0.46000000000000002      -0.41999999999999998       0.85820661272195631     
  0.47999999999999998      -0.41999999999999998       0.82911024380019038     
  0.50000000000000000      -0.41999999999999998       0.79974317276209350     
  0.52000000000000002      -0.41999999999999998       0.77021193896500240     
  0.54000000000000004      -0.41999999999999998       0.74062497797203064     
  0.56000000000000005      -0.41999999999999998       0.71109246101893997     
  0.57999999999999996      -0.41999999999999998       0.68172615382715873     
  0.59999999999999998      -0.41999999999999998       0.65263929755525862     

 

串行:

10000-10010

    
  -1.0000000000000000       0.97999999999999998        1.5231796120207264     
 -0.97999999999999998       0.97999999999999998        1.6350407390271877     
 -0.95999999999999996       0.97999999999999998        1.7454097502627000     
 -0.93999999999999995       0.97999999999999998        1.8566927732738419     
 -0.92000000000000004       0.97999999999999998        1.9699458586500573     
 -0.90000000000000002       0.97999999999999998        2.0856822347163213     
 -0.88000000000000000       0.97999999999999998        2.2041598308409540     
 -0.85999999999999999       0.97999999999999998        2.3254975194154395     
 -0.83999999999999997       0.97999999999999998        2.4497279948182107     
 -0.81999999999999995       0.97999999999999998        2.5768244045233648     
 -0.80000000000000004       0.97999999999999998        2.7067149417711622     

并行:

   
  -1.0000000000000000       0.97999999999999998        1.5231796120207264     
 -0.97999999999999998       0.97999999999999998        1.6350407359076693     
 -0.95999999999999996       0.97999999999999998        1.7454097440298204     
 -0.93999999999999995       0.97999999999999998        1.8566927639368240     
 -0.92000000000000004       0.97999999999999998        1.9699458462211767     
 -0.90000000000000002       0.97999999999999998        2.0856822192108919     
 -0.88000000000000000       0.97999999999999998        2.2041598122773096     
 -0.85999999999999999       0.97999999999999998        2.3254974978149128     
 -0.83999999999999997       0.97999999999999998        2.4497279702051098     
 -0.81999999999999995       0.97999999999999998        2.5768243769249448     
 -0.80000000000000004       0.97999999999999998        2.7067149112175963  

5)分析

数据类型是双精度的,

REAL(8), ALLOCATABLE, DIMENSION(:,:):: W,X,Y

下面的代码存在强依赖,就是W(I,J)依赖于W(I-1,J)和W(I,J-1)

W(I,J) = 0.5 * (dY*(W(I-1,J) + W(I+1,J)) + dX*(W(I,J-1) + W(I,J+1)) - 0.2*dX*dY)/(dX + dY)

尽管迭代会逐步减少误差到满足收敛要求

 DO WHILE (L .LE. MAXIT .AND. ERROR .GT. EPS)

6)

确实也是可以并行,但是只是结果不一样

根据EP判断收敛,确实是可以的。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值