mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
128 lines
4.9 KiB
Fortran
128 lines
4.9 KiB
Fortran
module PoissonDiscretization
|
|
implicit none
|
|
public :: fillmatrixandrhs
|
|
|
|
contains
|
|
subroutine fillmatrixandrhs(sm, rhs, ownedbox, dimensions)
|
|
use SparseMatrix
|
|
implicit none
|
|
real(kind=8), intent(out) :: rhs(:)
|
|
type(SparseMatrixData), intent(inout) :: sm
|
|
integer, intent(in) :: ownedbox(6), dimensions(3)
|
|
integer :: i,j,k
|
|
real(kind=8) :: dxsqinverse, dysqinverse, dzsqinverse, value
|
|
logical :: negativex, negativey, negativez, positivex, positivey, positivez, interior
|
|
integer :: numx, numy, numz, row
|
|
|
|
! construct the matrix
|
|
numx = ownedbox(2)-ownedbox(1)+1
|
|
if(numx < 1) numx = 1
|
|
numy = ownedbox(4)-ownedbox(3)+1
|
|
if(numy < 1) numy = 1
|
|
numz = ownedbox(6)-ownedbox(5)+1
|
|
|
|
rhs(:) = 0.0
|
|
|
|
dxsqinverse = 1.d0/((dimensions(1)-1)*(dimensions(1)-1))
|
|
dysqinverse = 1.d0/((dimensions(2)-1)*(dimensions(2)-1))
|
|
dzsqinverse = 1.d0/((dimensions(3)-1)*(dimensions(3)-1))
|
|
|
|
do k=1, numz
|
|
negativez = .TRUE.
|
|
if(k .eq. 1 .and. ownedbox(5) .eq. 1) negativez = .FALSE.
|
|
positivez = .TRUE.
|
|
if(k .eq. numz .and. ownedbox(6) .eq. dimensions(3)) positivez = .FALSE.
|
|
do j=1, numy
|
|
negativey = .TRUE.
|
|
if(j .eq. 1 .and. ownedbox(3) .eq. 1) negativey = .FALSE.
|
|
positivey = .TRUE.
|
|
if(j .eq. numy .and. ownedbox(4) .eq. dimensions(2)) positivey = .FALSE.
|
|
do i=1, numx
|
|
negativex = .TRUE.
|
|
if(i .eq. 1 .and. ownedbox(1) .eq. 1) negativex = .FALSE.
|
|
positivex = .TRUE.
|
|
if(i .eq. numx .and. ownedbox(2) .eq. dimensions(1)) positivex = .FALSE.
|
|
interior = negativex .and. negativey .and. negativez .and. positivex .and. positivey .and. positivez
|
|
row = i+ownedbox(1)-1+(j+ownedbox(3)-2)*dimensions(1)+(k+ownedbox(5)-2)*dimensions(1)*dimensions(2)
|
|
if(.NOT. interior) then
|
|
call insert(sm, row, row, 1.d0)
|
|
if(.NOT. positivez) rhs(row) = 1.d0
|
|
else
|
|
call insert(sm, row, row-1, dxsqinverse)
|
|
call insert(sm, row, row+1, dxsqinverse)
|
|
call insert(sm, row, row-dimensions(1), dysqinverse)
|
|
call insert(sm, row, row+dimensions(1), dysqinverse)
|
|
call insert(sm, row, row-dimensions(1)*dimensions(2), dzsqinverse)
|
|
call insert(sm, row, row+dimensions(1)*dimensions(2), dzsqinverse)
|
|
call insert(sm, row, row, -2.d0*dxsqinverse-2.d0*dysqinverse-2.d0*dzsqinverse)
|
|
endif
|
|
end do
|
|
end do
|
|
end do
|
|
|
|
! now we need to diagonalize the matrix based on boundary conditions
|
|
! do the non-homogeneous bcs on the z=1 plane first
|
|
if(ownedbox(5) .le. dimensions(3)-1 .and. ownedbox(6) .ge. dimensions(3)-1) then
|
|
do i=ownedbox(1), ownedbox(2)
|
|
do j=ownedbox(3), ownedbox(4)
|
|
row = i+(j-1)*dimensions(1)+dimensions(1)*dimensions(2)*(dimensions(3)-2)
|
|
call get(sm, row, row+dimensions(1)*dimensions(2), value)
|
|
rhs(row) = rhs(row) - value*1.d0
|
|
call insert(sm, row, row+dimensions(1)*dimensions(2), 0.d0)
|
|
enddo
|
|
enddo
|
|
endif
|
|
! the homogeneous bcs
|
|
! the z=0 plane
|
|
if(ownedbox(5) .le. 2 .and. ownedbox(6) .ge. 2) then
|
|
do i=ownedbox(1), ownedbox(2)
|
|
do j=ownedbox(3), ownedbox(4)
|
|
row = i+(j-1)*dimensions(1)+dimensions(1)*dimensions(2)
|
|
call insert(sm, row, row-dimensions(1)*dimensions(2), 0.d0)
|
|
enddo
|
|
enddo
|
|
endif
|
|
! the x=0 plane
|
|
if(ownedbox(1) .le. 2 .and. ownedbox(2) .ge. 2) then
|
|
do i=ownedbox(3), ownedbox(4)
|
|
do j=ownedbox(5), ownedbox(6)
|
|
row = 2+(i-1)*dimensions(1)+(j-1)*dimensions(1)*dimensions(2)
|
|
call insert(sm, row, row-1, 0.d0)
|
|
enddo
|
|
enddo
|
|
endif
|
|
! the x=1 plane
|
|
if(ownedbox(1) .le. dimensions(1)-1 .and. ownedbox(2) .ge. dimensions(1)-1) then
|
|
do i=ownedbox(3), ownedbox(4)
|
|
do j=ownedbox(5), ownedbox(6)
|
|
row = dimensions(1)-1+(i-1)*dimensions(1)+(j-1)*dimensions(1)*dimensions(2)
|
|
call insert(sm, row, row+1, 0.d0)
|
|
enddo
|
|
enddo
|
|
endif
|
|
! the y=0 plane
|
|
if(ownedbox(3) .le. 2 .and. ownedbox(4) .ge. 2) then
|
|
do i=ownedbox(1), ownedbox(2)
|
|
do j=ownedbox(5), ownedbox(6)
|
|
row = i+dimensions(1)+(j-1)*dimensions(1)*dimensions(2)
|
|
call insert(sm, row, row-dimensions(1), 0.d0)
|
|
enddo
|
|
enddo
|
|
endif
|
|
! the y=1 plane
|
|
if(ownedbox(3) .le. dimensions(2)-1 .and. ownedbox(4) .ge. dimensions(2)-1) then
|
|
do i=ownedbox(1), ownedbox(2)
|
|
do j=ownedbox(5), ownedbox(6)
|
|
row = i+dimensions(1)*(dimensions(2)-2)+(j-1)*dimensions(1)*dimensions(2)
|
|
call insert(sm, row, row+dimensions(1), 0.d0)
|
|
enddo
|
|
enddo
|
|
endif
|
|
|
|
! now do an mpi_allreduce on the rhs
|
|
call allreducevector(sm%globalsize, rhs)
|
|
|
|
end subroutine fillmatrixandrhs
|
|
|
|
end module PoissonDiscretization
|