Reputation: 413
I am trying to implement periodic boundary conditions on a PDE using ghost cells. I've updated the post with a more detailed sample code.
module Example
integer, parameter :: nx = 10, ny = 10
contains
subroutine Subrt(func)
implicit none
real, dimension(-nx:nx, -ny:ny), intent(inout) :: func
real, dimension(-nx:nx, -ny:ny) :: func1
real, dimension(-nx:nx, -ny:ny) :: Gfunc0, Gfunc1
Gfunc0 = Deriv(func)
func1 = func + Gfunc0
Gfunc1 = Deriv(func1)
end subroutine Subrt
function Deriv(func)
implicit none
integer :: i,j
real, dimension(-nx-1:nx,-ny-1:ny) :: func, Deriv
do j = -ny,ny-1
do i = -nx,nx-1
deriv(i,j) = func(i+1,j) + func(i-1,j)
end do
end do
!imposing periodicity on the gradient
deriv(-nx-1,:) = deriv(nx-1,:)
deriv(nx,:) = deriv(-nx,:)
deriv(:,-ny-1) = deriv(:,ny-1)
deriv(:,ny) = deriv(:,-ny)
end function Deriv
end module Example
!I now define the function func, initial and boundary conditions and run the code:
program MyTest
use Example
implicit none
real, dimension(-nx-1:nx,-ny-1:ny) :: func
integer :: i,j
do i = -nx,nx-1
do j = -ny,ny-1
func(i,j) = ...
end do
end do
!Impose periodicity
func(-nx-1,:) = func(nx-1,:)
func(nx,:) = func(-nx,:)
func(:,-ny-1) = func(:,ny-1)
func(:,ny) = func(:,-ny)
call Subrt(func) !problem arises when I call subroutine here
end program
So the 'ghost cells' are the array elements -nx-1
, -ny-1
. I use these points to connect to impose periodicity.
The problem I have is when I use this function func
to pass into my subroutine.
My subroutine that solves the differential equation only acts on the physical system size, from
(-nx:nx,-ny:ny)
so when I call the function func
to pass into my subroutine,
I am getting the follow warning and error message:
Actual argument contains too few elements for dummy argument
Different shape for array assignment
Is there a way to call the function func
into the subroutine by truncating the array elements (-nx-1,-ny-1)
? I want to pass only a part of my function array func
, (-nx:nx,-ny:ny)
into the subroutine, instead of calling the whole function array which includes the ghost points that yields this warning/error message. However, I'm unsure of how to call the truncated array.
Upvotes: 1
Views: 204
Reputation: 336
As pointed by Rodrigo Rodrigues, the dimensions of the array manipulated my the main program, Subrt
and Deriv
are inconsistent.
An easy fix is to change variable declaration in Subrt
:
subroutine Subrt(func)
implicit none
real, dimension(-nx-1:nx, -ny-1:ny), intent(inout) :: func
real, dimension(-nx-1:nx, -ny-1:ny) :: func1
real, dimension(-nx-1:nx, -ny-1:ny) :: Gfunc0, Gfunc1
The code now compiles and runs.
It seems to me easier to consistently pass the full array within the different elements of the program (and to ignore some elements), rather than passing as arguments arrays of variable size. (In particular, if you truncate only one row or one column, I don't see any benefit that would compensate the book-keeping generated by slicing.)
Upvotes: 1
Reputation: 8576
Your code doesn't seem to make sense so far... and it still not clear what are you trying to achieve.
In the main program, you declare an array func
with shape (-11:10, -11:10)
- that are 22x22 elements - and pass it as an actual argument to the subroutine Subrt
, which declares a dummy argument also named func
, but with an explicit shape (-10:10, -10:10)
- that is 21x21 elements.
So far so good, only the first 21x21 elements of your func
array are really passed to the subroutine, and rebounded such that the element of index (-11, -11)
of the actual argument is mapped to the element (-10, -10)
of the dummy argument, and so on, until the element (9, 9)
of the actual argument is mapped to the last element (10, 10)
of the dummy argument.
Is there a way to call the function func into the subroutine by truncating the array elements (-nx-1,-ny-1)? I want to pass only a part of my function array, func, (-nx:nx,-ny:ny) into the subroutine (...)
Passing a section of an array is really easy. The following will pass only (-nx:nx,-ny:ny)
- a 21x21 elements subset - to the subroutine:
call Subrt(func(-nx:nx, -ny:ny))
And the mapping will be (-10, 10)
of the actual argument to the (-10, 10)
of the dummy argument, and so on.
But this will not help you with the following problem... Inside Subrt
, you try to pass this array as an actual argument to the Deriv
function, that is expecting a (-11:10, -11:10)
shape array - that is 22x22 elements. The error comes from here.
Actual argument contains too few elements for dummy argument. Different shape for array assignment
The procedure Subrt
expects an array larger than the one you are passing.
Upvotes: 2