Я новичок в openmp. Я пытаюсь распараллелить цикл do в подпрограмме GAUSSLEG. Переменные Xg, Wg и Ng берутся из матрицы модуля. Я получаю неожиданные результаты. Я запутался в правильном назначении переменных (частных и общих). Кто-нибудь может мне помочь?
SUBROUTINE GAUSSLEG(f,a,b,s)
USE OMP_LIB
USE MATRIC , ONLY : XG ,WG , NG
IMPLICIT DOUBLE PRECISION(A-H,O-Z)
external f
xm = 0.5d0*(b+a)
xl = 0.5d0*(b-a)
s = 0.d0
!$omp parallel do reduction ( + : s) default(none)
!$omp private(j) shared(xm,xl,wg,xg,ng,dx)
do j=1,ng
dx = xl*xg(j)
s = s + wg(j)*(func(xm+dx)+func(xm-dx))
end do
!$omp end parallel do
s = xl*s/2.0
return
END
Привет, я использовал подпрограмму gaussleg для вычисления интегрирования sin(x) от 0 до pi, я получаю тот же результат (2,5464790894), независимо от того, делаю ли я dx частным или общим, но точный результат равен 2,0. Я также пытался поставить xl*xg(j) напрямую и удалить dx, все равно получая тот же результат, что и выше. Без опции -openmp в компиляции я получаю точный результат 2.0. Это целая программа.
MODULE MATRIC
IMPLICIT NONE
INTEGER , PARAMETER :: NG = 40
DOUBLE PRECISION , PARAMETER :: PI=2.0D0*ACOS(0.0D0)
DOUBLE PRECISION :: XG(60) , WG(60)
END MODULE MATRIC
program gauss
use matric, only : xg,wg,pi
implicit none
double precision :: x1,x2,a,b,ans
external :: f
x1 = -1.0d0 ; x2 = 1.0d0
a = 0.0 ; b = PI
call gauleg(x1,x2)
call gaussleg(f,a,b,ans)
write(*,*)ans
end program gauss
!function to be integrated
double precision function f(x)
implicit none
double precision, intent(in) :: x
f = sin(x)
end function f
SUBROUTINE GAUSSLEG(func,a,b,ss)
USE OMP_LIB
USE MATRIC , ONLY : XG ,WG , NG
double precision,intent(in) :: a , b
double precision,intent(out)::ss
double precision :: xm , xl , dx
integer :: j
double precision,external::func
xm = 0.5d0*(b+a)
xl = 0.5d0*(b-a)
ss = 0.d0
!$OMP PARALLEL DO REDUCTION( + : ss) default(none) &
!$OMP PRIVATE(j,dx) SHARED(xm,xl,xg,wg)
do j=1,ng
dx = xl*xg(j)
ss = ss + wg(j)*(func(xm+dx)+func(xm-dx))
end do
!$OMP END PARALLEL DO
ss = xl*ss/2.0
return
END