数组的导数

计算科学 pde 有限差分 正则
2021-12-22 18:01:23

嗨,我正在尝试对数组进行导数,但遇到了麻烦。该数组是二维的,方向。我想使用中心差分离散化该数组具有随机数字值,没有值是 NaN。我将提供下面代码的基本部分来说明我的观点(假设数组已定义并且已经输入了一些初始值)xyxyu

integer :: i,j
integer, parameter :: nx=10, ny=10
real, dimension(-nx:nx, -ny:ny) :: u,v,w
real, parameter :: h

do i=-nx,nx
    do j=-ny,ny

        v = (u(i+1,j)-u(i-1,j))/(2*h)
        w = (u(i,j+1)-u(i,j-1))/(2*h)

    end do 
end do

请注意,假设数组之前已定义并填充 ,应该是数组分别沿的导数。这是获取数组导数的正确方法吗?uvwvwuxy

2个回答

纯粹就术语而言,最好谈论对存储在数组中的变量字段进行离散偏导,而不是对数组本身进行微分。

关于代码本身,您似乎已经在循环中删除了元素分配,

v(i,j) = (u(i+1,j)-u(i-1,j))/(2*h)
w(i,j) = (u(i,j+1)-u (i,j-1))/(2*h)

虽然这可能是一个错字。您的版本在范围的端点(即i=-nx, i=nx, j=ny, j=-ny)也存在错误和不安全,因为在这些地方您正在访问不存在的 u 数组的元素。在这些位置,您要么需要使用非中心导数,例如 v(-nx,j) = (u(-nx+1,j) - u(-nx,j)/h,要么使用边界条件的任何知识。

附带说明一下,如果您经常编写 Fortran 代码,那么就代码优化而言,记住最右边的索引应该在循环中最外层是很有用的,这样代码才能有最好的机会快速运行,这意味着交换你的 i 和 j 循环。在许多简单的情况下,编译器可能会为您解决这个问题,而且它肯定不如拥有有效的代码重要,但这可能是一个好习惯。

由于 Fortran 数组模型,它被称为列专业。简单地说一下:让a是一个大小矩阵m×n. aij成为元素a为了i=1,m¯j=1,n¯, 然后aij存储在(i+(j1)m)-一维存储的位置A(:), IEaij=A(i+(j1)m). 将循环写为原始帖子,存储A(:)被处理m-增量。但是,交换循环顺序,存储A(:)被连续处理。因此,这种方法比第一种方法执行得更快。