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判断收敛,确实是可以的。

 

 

 

电子时钟设计是一个基于单片机的综合性电子项目,涵盖硬件设计、软件设计、模块代码编写以及运行展示等多个环节。以下是该项目的详细分析与知识点总结: 电子时钟设计是一项课程设计任务,目标是开发一个功能完善的电子时钟系统。该系统以单片机为核心控制器,具备时间显示、设置控制等功能,旨在满足用户的日常使用需求。 硬件设计的核心是系统方案原理图,它明确了系统的整体架构以及各组件之间的连接关系。外设设计方面,键盘输入模块数码管显示模块是关键部分。键盘输入模块的工作原理包括键盘扫描、按键识别以及状态机控制等环节;数码管显示模块的工作原理则涉及数码管的驱动、显示控制状态机控制等内容。 软件设计的核心是项目软件系统总架构图,它详细介绍了系统的软件框架,涵盖单片机编程、键盘输入模块流程图与代码、数码管显示模块流程图与代码等方面。顺序图则展示了软件的运行流程,包括系统初始化、键盘输入处理、显示控制状态机控制等环节。 模块代码是系统各模块功能的具体实现。例如,键盘输入模块的代码实现了键盘扫描、按键识别状态机控制等功能;数码管显示模块的代码实现了数码管驱动、显示控制状态机控制等功能。 运行展示是项目的最终成果呈现环节,展示了电子时钟的实际运行效果,包括时间的准确显示、便捷的设置操作以及稳定的控制功能等。 单片机原理:掌握单片机的架构、指令系统编程方法。 Proteus仿真:熟悉Proteus仿真原理、仿真环境及仿真操作。 C语言编程:理解C语言的语法、数据类型、控制结构、函数数组等基础知识。 电子时钟设计:了解电子时钟的工作原理、设计方法实现技术。 硬件设计:掌握硬件设计的基本原理、方法工具。 软件设计:熟悉软件设计的基本原理、方法工具。 模块代码实现:掌握模块代码的设计、编程调试技巧。 电子时钟设计项目融合了硬件与软件设计,通过模块代码实现功能,并通过运行展示呈现最终效果。掌握
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值