Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program Helmholtz
- ! PARA
- use mpi
- ! PARA
- implicit none
- ! PARA
- integer, parameter :: master_id = 0
- integer :: id, tag, numprocs
- integer :: mpi_error_code
- integer, dimension(MPI_STATUS_SIZE) :: status
- ! PARA
- real(kind=8), parameter :: ystar(2) = (0,0), kappa=2, eta=kappa, &
- eulerconst = 0.5772156649, pi = 4.D0*DATAN(1.D0)
- integer :: n = 1, k, j
- real(kind=8) :: testpoint(2) = (3,3)
- real(kind=8) , allocatable :: matrix(:,:), rightpart (:), density(:)
- ! PARA
- call MPI_init(mpi_error_code)
- call MPI_comm_rank(MPI_COMM_WORLD, id, mpi_error_code)
- call MPI_comm_size(MPI_COMM_WORLD, numprocs, mpi_error_code)
- !if (id == 0) then
- ! PARA
- do while (n<=20)
- ALLOCATE (matrix(4*n,4*n), rightpart(4*n), density(4*n))
- if (id /= master_id) then
- do k = id - 1, 2*n-1, numprocs - 1 !myid, 2*n-1, numprocs
- do j = 0, 2*n-1
- Matrix(k + 1, j+1) = Lre(k, j);
- Matrix(k + 1, j + 2 * n+1) = -Lim(k, j);
- Matrix(k + 2 * n+1, j+1) = Lim(k, j);
- Matrix(k + 2 * n+1, j + 2 * n+1) = Lre(k, j);
- if (k == j) then
- Matrix(k+1, j + 2 * n+1) = Matrix(k+1, j + 2 * n+1) - aim(t(k));
- Matrix(k + 2 * n+1, j+1) = Matrix(k + 2 * n+1, j+1) + aim(t(k));
- endif
- end do
- tag = 0
- call MPI_send(Matrix(k + 1, :), 4*n, MPI_DOUBLE_PRECISION, &
- master_id, tag, &
- MPI_COMM_WORLD, mpi_error_code)
- tag = 1
- call MPI_send(Matrix(k + 2 * n+1, :), 4*n, MPI_DOUBLE_PRECISION, &
- master_id, tag, &
- MPI_COMM_WORLD, mpi_error_code)
- end do
- else
- do k = 0, 2*n-1 !myid, 2*n-1, numprocs
- tag = 0
- call MPI_recv(Matrix(k + 1, :), 4*n, MPI_DOUBLE_PRECISION, &
- mod(k, numprocs - 1) + 1, tag, &
- MPI_COMM_WORLD, status, mpi_error_code)
- tag = 1
- call MPI_recv(Matrix(k + 2 * n+1, :), 4*n, MPI_DOUBLE_PRECISION, &
- mod(k, numprocs - 1) + 1, tag, &
- MPI_COMM_WORLD, status, mpi_error_code)
- rightPart(k+1) = fre(t(k));
- rightPart(k + 2 * n+1) = fim(t(k));
- end do
- end if
- density = solve(Matrix,rightPart)
- if (id == master_id) then
- write(*, *) Matrix
- write(*, *) rightPart
- write(*, *) sum(Matrix(:, 1) * rightPart)
- write(*, *) density
- write(*,*) "n = ", n, " ", &
- Abs(resultRe(testPoint, density) - exactRe(testPoint)), " ", &
- Abs(resultIm(testPoint, density) - exactIm(testPoint))
- end if
- DEALLOCATE (matrix, rightpart, density)
- n = n*2
- end do
- ! PARA
- !endif
- call MPI_FINALIZE(mpi_error_code)
- ! PARA
- contains
- real(kind=8) function x1(t)
- real(kind=8) t
- x1 = 2.*cos(t)
- return
- end
- real(kind=8) function x2(t)
- real(kind=8) t
- x2 = 2.*sin(t)
- return
- end
- real(kind=8) function x1d(t)
- real(kind=8) t
- x1d = -2.*sin(t)
- return
- end
- real(kind=8) function x2d(t)
- real(kind=8) t
- x2d = 2.*cos(t)
- return
- end
- real(kind=8) function x1dd(t)
- real(kind=8) t
- x1dd = -2.*cos(t)
- return
- end
- real(kind=8) function x2dd(t)
- real(kind=8) t
- x2dd = -2.*sin(t)
- return
- end
- real(kind=8) function x1ddd(t)
- real(kind=8) t
- x1ddd = 2.*sin(t)
- return
- end
- real(kind=8) function x2ddd(t)
- real(kind=8) t
- x2ddd = -2.*cos(t)
- return
- end
- real(kind=8) function diffmodule(t, tau)
- real(kind=8) t, tau
- diffmodule = SQRT((x1(t) - x1(tau)) * (x1(t) - x1(tau)) + (x2(t) - x2(tau)) * (x2(t) - x2(tau)))
- return
- end
- real(kind=8) function dermodule(t)
- real(kind=8) t
- dermodule = SQRT(x1d(t) * x1d(t) + x2d(t) * x2d(t))
- return
- end
- real(kind=8) function doubledermodule(t)
- real(kind=8) t
- doubledermodule = SQRT(x1dd(t) * x1dd(t) + x2dd(t) * x2dd(t))
- return
- end
- real(kind=8) function h(t, tau)
- real(kind=8) t, tau, numerator, denominator
- numerator = ((x1(tau) - x1(t)) * x2d(t) - (x2(tau) - x2(t)) * x1d(t))
- denominator = diffModule(t, tau)
- h = numerator / denominator
- return
- end
- real(kind=8) function him(t, tau)
- real(kind=8) t, tau
- him = kappa * h(t, tau) * BESSEL_J1(kappa * diffModule(t, tau)) * derModule(tau) / 2.0
- return
- end
- real(kind=8) function hre(t, tau)
- real(kind=8) t, tau
- hre = -kappa * h(t, tau) * BESSEL_Y1(kappa * diffModule(t, tau)) * derModule(tau) / 2.0;
- return
- end
- real(kind=8) function h1(t, tau)
- real(kind=8) t, tau
- if (t /= tau) then
- h1 = -kappa * h(t, tau) * BESSEL_J1(kappa * diffModule(t, tau)) * derModule(tau) / (2.0 * pi)
- return
- else
- h1 = 0.0
- return
- end if
- end
- real(kind=8) function h2re(t, tau)
- real(kind=8) t, tau
- if (t /= tau) then
- h2re = hre(t, tau) - h1(t, tau) * log(4.0 * sin((t - tau) / 2.0) * sin((t - tau) / 2.0))
- return
- else
- h2re = (x2d(t) * x1dd(t) - x1d(t) * x2dd(t)) / (2.0 * pi * derModule(t))
- return
- end if
- end
- real(kind=8) function h2im(t, tau)
- real(kind=8) t, tau
- if (t /= tau) then
- h2im = him(t, tau)
- return
- else
- h2im = 0.0
- return
- end if
- end
- real(kind=8) function mim(t, tau)
- real(kind=8) t, tau
- mim = BESSEL_J0(kappa * diffModule(t, tau)) / 2.0
- return
- end
- real(kind=8) function mre(t, tau)
- real(kind=8) t, tau
- mre = -BESSEL_Y0(kappa * diffModule(t, tau)) / 2.0
- return
- end
- real(kind=8) function m1(t, tau)
- real(kind=8) t, tau
- if (t /= tau) then
- m1 = -BESSEL_J0(kappa * diffModule(t, tau)) / (2.0 * pi)
- return
- else
- m1 = -1 / (2.0 * pi)
- return
- end if
- end
- real(kind=8) function m2re(t, tau)
- real(kind=8) t, tau
- if (t /= tau) then
- m2re = mre(t, tau) - m1(t, tau) * log(4.0 * sin((t - tau) / 2.0) * sin((t - tau) / 2.0))
- return
- else
- m2re = -(eulerconst + log(kappa * derModule(t) / 2.0)) / pi
- return
- end if
- end
- real(kind=8) function m2im(t, tau)
- real(kind=8) t, tau
- if (t /= tau) then
- m2im = mim(t, tau)
- return
- else
- m2im = 1.0 / 2.0
- return
- end if
- end
- real(kind=8) function tildan(t, tau)
- real(kind=8) t, tau, numerator, denominator
- numerator = ((x1(t) - x1(tau)) * x1d(t) + (x2(t) - x2(tau)) * x2d(t)) * &
- ((x1(t) - x1(tau)) * x1d(tau) + (x2(t) - x2(tau)) * x2d(tau))
- denominator = diffModule(t, tau) * diffModule(t, tau)
- tildan = numerator / denominator
- return
- end
- real(kind=8) function nre(t, tau)
- real(kind=8) t, tau
- nre = 1.0 / (4.0 * pi * sin((t - tau) / 2.0) * sin((t - tau) / 2.0)) + tildan(t, tau) * &
- (-kappa * kappa * BESSEL_Y0(kappa * diffModule(t, tau)) + &
- 2.0 * kappa * BESSEL_Y1(kappa * diffModule(t, tau)) / diffModule(t, tau)) / 2.0 &
- - kappa * (x1d(t) * x1d(tau) + x2d(t) * x2d(tau)) * BESSEL_Y1(kappa * diffModule(t, tau)) / (2.0 * diffModule(t, tau))
- return
- end
- real(kind=8) function nim(t, tau)
- real(kind=8) t, tau
- nim = tildan(t, tau) * (kappa * kappa * BESSEL_J0(kappa * diffModule(t, tau)) - &
- 2 * kappa * BESSEL_J1(kappa * diffModule(t, tau)) / diffModule(t, tau)) / 2.0 + &
- kappa * (x1d(t) * x1d(tau) + x2d(t) * x2d(tau)) * BESSEL_J1(kappa * diffModule(t, tau)) / (2.0 * diffModule(t, tau))
- return
- end
- real(kind=8) function n1(t, tau)
- real(kind=8) t, tau
- if (t /= tau) then
- n1 = -tildaN(t, tau) * (kappa * kappa * BESSEL_J0(kappa * diffModule(t, tau)) - 2 * kappa * BESSEL_J1(kappa * &
- diffModule(t, tau)) / diffModule(t, tau)) / (2.0 * pi) - &
- kappa * BESSEL_J1(kappa * diffModule(t, tau)) * (x1d(t) * x1d(tau) + x2d(t) * x2d(tau)) / &
- (2.0 * pi * diffModule(t, tau))
- return
- else
- n1 = -kappa * kappa * derModule(t) * derModule(t) / (4.0 * pi)
- return
- end if
- end
- real(kind=8) function n2re(t, tau)
- real(kind=8) t, tau
- if (t /= tau) then
- n2re = Nre(t, tau) - N1(t, tau) * log(4.0 * sin((t - tau) / 2.0) * sin((t - tau) / 2.0))
- return
- else
- n2re = -kappa * kappa * derModule(t) * derModule(t) / (4.0 * pi) - eulerconst * kappa * kappa * derModule(t) &
- * derModule(t) / (2.0 * pi) - kappa * kappa * derModule(t) * derModule(t) * &
- log(kappa * derModule(t) / 2.0) / (2.0 * pi) + 1 / (12.0 * pi) &
- + (x1d(t) * x1dd(t) + x2d(t) * x2dd(t)) * (x1d(t) * x1dd(t) + x2d(t) * x2dd(t)) / &
- (2.0 * pi * derModule(t)*derModule(t)*derModule(t)*derModule(t)) &
- - doubleDerModule(t) * doubleDerModule(t) / (4.0 * pi * derModule(t) * derModule(t)) &
- - (x1d(t) * x1ddd(t) + x2d(t) * x2ddd(t)) / (6.0 * pi * derModule(t) * derModule(t))
- return
- end if
- end
- real(kind=8) function n2im(t, tau)
- real(kind=8) t, tau
- if (t /= tau) then
- n2im = Nim(t, tau)
- return
- else
- n2im = kappa * kappa * derModule(t) * derModule(t) / 4.0
- return
- end if
- end
- real(kind=8) function k1re(t, tau)
- real(kind=8) t, tau
- k1re = kappa * kappa * (x1d(t) * x1d(tau) + x2d(t) * x2d(tau)) * M1(t, tau) - N1(t, tau)
- return
- end
- real(kind=8) function k1im(t, tau)
- real(kind=8) t, tau
- k1im = -eta * H1(t, tau)
- return
- end
- real(kind=8) function k2re(t, tau)
- real(kind=8) t, tau
- k2re = kappa * kappa * (x1d(t) * x1d(tau) + x2d(t) * x2d(tau)) * M2re(t, tau) - N2re(t, tau) + eta * H2im(t, tau)
- return
- end
- real(kind=8) function k2im(t, tau)
- real(kind=8) t, tau
- k2im = kappa * kappa * (x1d(t) * x1d(tau) + x2d(t) * x2d(tau)) * M2im(t, tau) - N2im(t, tau) - eta * H2re(t, tau)
- return
- end
- real(kind=8) function tcapital(j)
- integer j
- if (j == 0) then
- tcapital = -n / 2.0
- return
- else if (mod(j,2) == 0) then
- tcapital = 0.0
- return
- else
- tcapital = 1 / (2.0 * n * sin(t(j) / 2.0) * sin(t(j) / 2.0))
- return
- end if
- end
- real(kind=8) function t(j)
- integer j
- t = j * pi / n
- end
- real(kind=8) function r(j)
- integer j, m
- real(kind=8) sum
- sum = 0.0
- do m = 1, n-1
- sum = sum + cos(m * j * pi / n) / m
- end do
- r = -2 * pi * sum / n + (-1)**j * pi / (n * n)
- end
- real(kind=8) function aim(t)
- real(kind=8) t
- aim = eta * derModule(t)
- return
- end
- real(kind=8) function lre(k, j)
- integer k, j
- lre = tcapital(abs(k - j)) + r(abs(k - j)) * K1re(t(k), t(j)) + pi * K2re(t(k), t(j)) / n
- return
- end
- real(kind=8) function lim(k, j)
- integer k, j
- lim = r(abs(k - j)) * K1im(t(k), t(j)) + pi * K2im(t(k), t(j)) / n
- return
- end
- real(kind=8) function uinfre(xhat, density)
- real(kind=8), dimension(:) :: xhat, density
- real(kind=8) :: sum = 0.0
- integer j
- do j = 0, 2 * n - 1
- sum = sum + (kappa * (xHat(1) * x2d(t(j)) - xHat(2) * x1d(t(j))) + eta) * derModule(t(j)) * &
- Ere(xHat, j, density)/(derModule(t(j))* derModule(t(j)))
- end do
- uinfre = pi * sum / (n * SQRT(8 * pi * kappa))
- return
- end
- real(kind=8) function ere(xhat, j, density)
- real(kind=8), dimension(:) :: xhat, density
- real(kind=8) scalarprod
- integer j
- scalarprod = (xHat(1) * x1(t(j)) + xHat(2) * x2(t(j))) / SQRT(xHat(1) * xHat(1) + xHat(2) * xHat(2))
- ere = cos(kappa * scalarprod + pi / 4.0) * density(j+1) + sin(kappa * scalarprod + pi / 4.0) * density(j + 2 * n+1)
- return
- end
- real(kind=8) function uinfim(xhat, density)
- real(kind=8), dimension(:) :: xhat, density
- real(kind=8) :: sum = 0.0
- integer j
- do j = 0, 2 * n - 1
- sum = sum + (kappa * (xHat(1) * x2d(t(j)) - xHat(2) * x1d(t(j))) + eta) * (derModule(t(j))) * Eim(xHat, j, density)
- end do
- uinfim = pi * sum / (n * SQRT(8 * pi * kappa))
- return
- end
- real(kind=8) function eim(xhat, j, density)
- real(kind=8), dimension(:) :: xhat, density
- real(kind=8) scalarprod
- integer j
- scalarprod = (xHat(1) * x1(t(j)) + xHat(2) * x2(t(j))) / SQRT(xHat(1) * xHat(1) + xHat(2) * xHat(2))
- eim = -sin(kappa * scalarprod + pi / 4.0) * density(j+1) + cos(kappa * scalarprod + pi / 4.0) * density(j + 2 * n + 1)
- return
- end
- real(kind=8) function fre(t)
- real(kind=8) t
- real(kind=8), dimension(2) :: x
- x(1) = x1(t)
- x(2) = x2(t)
- fre = kappa * BESSEL_Y1(kappa * module(x, yStar)) * ((x1(t) - yStar(1)) * x2d(t) - (x2(t) - yStar(2)) * x1d(t)) / &
- (2 * module(x, yStar));
- end
- real(kind=8) function fim(t)
- real(kind=8) t
- real(kind=8), dimension(2) :: x
- x(1) = x1(t)
- x(2) = x2(t)
- fim = -kappa * BESSEL_J1(kappa * module(x, yStar)) * ((x1(t) - yStar(1)) * x2d(t) - (x2(t) - yStar(2)) * x1d(t)) / &
- (2 * module(x, yStar));
- end
- real(kind=8) function module(x, y)
- real(kind=8), dimension(:) :: x,y
- module = Sqrt((x(1) - y(1)) * (x(1) - y(1)) + (x(2) - y(2)) * (x(2) - y(2)))
- return
- end
- real(kind=8) function resultRe(x, density)
- real(kind=8), dimension(:) :: x,density
- real(kind=8), dimension(2) :: temp
- real(kind=8) sum ,h
- integer j
- sum = 0
- do j=0,2*n-1
- temp(1) = x1(t(j))
- temp(2) = x2(t(j))
- h = ((x1(t(j)) - x(1)) * x2d(t(j)) - (x2(t(j)) - x(2)) * x1d(t(j))) / (module(x, temp) * derModule(t(j)));
- sum = sum + (density(j+1) * (kappa * BESSEL_Y1(kappa * module(x, temp)) * h + eta * BESSEL_J0(kappa * &
- module(x, temp))) - density(j + 2 * n+1) * (eta * BESSEL_Y0(kappa * module(x, temp)) - &
- kappa * BESSEL_J1(kappa * module(x, temp)) * h)) * derModule(t(j))
- end do
- resultRe = pi * sum / (4 * n)
- return
- end
- real(kind=8) function exactRe(x)
- real(kind=8), dimension(:) :: x
- exactRe =-BESSEL_Y0(kappa*module(x, yStar))/4
- return
- end
- real(kind=8) function resultIm(x, density)
- real(kind=8), dimension(:) :: x,density
- real(kind=8), dimension(2) :: temp
- real(kind=8) sum ,h
- integer j
- sum = 0
- do j=0,2*n-1
- temp(1) = x1(t(j))
- temp(2) = x2(t(j))
- h = ((x1(t(j)) - x(1)) * x2d(t(j)) - (x2(t(j)) - x(2)) * x1d(t(j))) / (module(x, temp) * derModule(t(j)));
- sum = sum + (density(j+1) * (eta * BESSEL_Y0(kappa * module(x, temp)) - &
- kappa * BESSEL_J1(kappa * module(x, temp)) * h) &
- + density(j + 2*n + 1) * (kappa * BESSEL_Y1(kappa * module(x, temp)) * h + &
- eta * BESSEL_J0(k * module(x, temp)))) * derModule(t(j))
- end do
- resultIm = pi * sum / (4 * n)
- return
- end
- real(kind=8) function exactIm(x)
- real(kind=8), dimension(:) :: x
- exactIm = BESSEL_J0(kappa*module(x, yStar))/4
- return
- end
- ! PARA
- function solve(A, b) result(x)
- integer, parameter :: master_id = 0
- integer :: id, tag, numprocs
- integer :: mpi_error_code
- integer, dimension(MPI_STATUS_SIZE) :: status
- real(kind=8), dimension(:, :) :: A
- real(kind=8), dimension(:) :: b
- real(kind=8), dimension(:), allocatable :: x
- real(kind=8) :: upi
- integer :: i,j,n,p
- real(kind=8), dimension(:, :), allocatable :: u(:,:)
- n = size(A, 1)
- u = reshape( [A, b], [n,n+1] )
- do j = 1, n
- if (id == master_id) then
- p = maxloc(abs(u(j:n, j)),1) + j - 1 ! maxloc returns indices between (1,n-j+1)
- if (p /= j) u([p, j],j) = u([j, p],j)
- u(j + 1:,j) = u(j + 1:,j)/u(j, j)
- end if
- !call MPI_comm_rank(MPI_COMM_WORLD, id, mpi_error_code)
- !call MPI_comm_size(MPI_COMM_WORLD, numprocs, mpi_error_code)
- !call MPI_bcast (u(j + 1:n, j), n - j, MPI_DOUBLE_PRECISION, master_id, &
- ! MPI_COMM_WORLD, mpi_error_code)
- !if (id == master_id) then
- !do i = j + 1, n
- !tag = i
- !call MPI_send(u(j + 1:n, i), n - j, MPI_DOUBLE_PRECISION, &
- ! mod(i - j, numprocs - 1) + 1, tag, &
- ! MPI_COMM_WORLD, mpi_error_code)
- !write(*, *) "SENT", id, u(j + 1:n, i)
- !tag = i + n
- !call MPI_recv(u(j + 1:n, i), n - j, MPI_DOUBLE_PRECISION, &
- ! mod(i - j, numprocs - 1) + 1, tag, &
- ! MPI_COMM_WORLD, status, mpi_error_code)
- !write(*, *) "RECV", id, u(j + 1:n, i)
- !end do
- !else
- do i = j + 1, n !j + id, n, numprocs - 1
- !tag = i
- !call MPI_recv(u(j + 1:n, i), n - j, MPI_DOUBLE_PRECISION, master_id, tag, &
- ! MPI_COMM_WORLD, status, mpi_error_code)
- !write(*, *) "RECV", id, u(j + 1:n, i)
- upi = u(p, i)
- if (p /= j) u([p, j],i) = u([j, p],i)
- u(j + 1:n,i) = u(j + 1:n, i) - upi * u(j + 1:n, j)
- !tag = i + n
- !call MPI_send(u(j + 1:n, i), n - j, MPI_DOUBLE_PRECISION, master_id, tag, &
- ! MPI_COMM_WORLD, mpi_error_code)
- !write(*, *) "SENT", id, u(j + 1:n, i)
- end do
- !end if
- end do
- allocate(x(n))
- !if (id == master_id) then
- do i = n, 1, -1
- x(i) = (u(i,n+1) - sum(u(i,i+1:n)*x(i+1:n))) / u(i,i)
- end do ! i
- !end if
- !call MPI_bcast (x, n, MPI_DOUBLE_PRECISION, master_id, &
- ! MPI_COMM_WORLD, mpi_error_code)
- end
- ! PARA
- end program Helmholtz
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement