将截断的大小数组传递给子例程

时间:2018-06-13 21:35:16

标签: arrays fortran

我正在尝试使用ghost单元在PDE上实现周期性边界条件。我已经用更详细的示例代码更新了帖子。

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

因此'ghost cells'是数组元素-nx-1-ny-1。我使用这些点来连接以强加周期性。

我遇到的问题是当我使用这个函数func传递给我的子程序时。 解决微分方程的子程序仅对物理系统大小起作用,

 (-nx:nx,-ny:ny)

所以当我调用函数func传递给我的子程序时,

我收到以下警告和错误消息:

 Actual argument contains too few elements for dummy argument
 Different shape for array assignment

有没有办法通过截断数组元素func将函数(-nx-1,-ny-1)调用到子例程中?我想只将函数数组func(-nx:nx,-ny:ny)的一部分传递给子例程,而不是调用包含产生此警告/错误消息的鬼点的整个函数数组。但是,我不确定如何调用截断的数组。

2 个答案:

答案 0 :(得分:2)

到目前为止,您的代码似乎没有意义......而且您仍然不清楚您想要实现的目标。

在主程序中,声明一个形状为func的数组(-11:10, -11:10) - 即22x22个元素 - 并将其作为实际参数传递给子例程Subrt,该子例程声明了一个虚拟参数也命名为func,但具有明确的形状(-10:10, -10:10) - 即21x21元素。

到目前为止,只有func数组的第一个21x21元素才真正传递给子例程,并且反弹使得实际参数的索引(-11, -11)元素被映射到元素伪参数的(-10, -10),依此类推,直到实际参数的元素(9, 9)映射到伪参数的最后一个元素(10, 10)

  

有没有办法通过截断数组元素(-nx-1,-ny-1)将函数func调用到子例程中?我想只将我的函数数组func,( - nx:nx,-ny:ny)的一部分传递给子例程(...)

传递数组的一部分非常简单。以下内容仅将(-nx:nx,-ny:ny) - 一个21x21元素子集 - 传递给子例程:

call Subrt(func(-nx:nx, -ny:ny))

映射将是伪参数的(-10, 10)的实际参数的(-10, 10),依此类推。

但这对以下问题没有帮助...在Subrt内,您尝试将此数组作为实际参数传递给Deriv函数,即期望{{1} } shape array - 即22x22个元素。错误来自这里。

  

实际参数包含的伪元素元素太少。阵列分配的形状不同

过程(-11:10, -11:10)期望一个数组大于你传递的数组。

答案 1 :(得分:1)

正如Rodrigo Rodrigues指出的那样,数组的维度操纵了我的主程序,SubrtDeriv不一致。

一个简单的解决方法是更改​​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

现在代码编译并运行。

在我看来,更容易在程序的不同元素中一致地传递完整数组(并忽略一些元素),而不是作为可变大小的参数数组传递。 (特别是,如果您只截断一行或一列,我看不到任何可以补偿切片生成的簿记的好处。)