1

感谢您查看此问题。

问题: 段。在生成正确的计算结果,从包含 KINSOL 求解过程的 f90 子程序返回时出错。相同的求解过程在主程序中没有问题。

环境: linux、gcc、日晷静态库

如何启动问题:

获取随附的 REDUCED 测试代码

module moduleNonlinearSolve
  integer,save::nEq
contains
  subroutine solveNonlinear(u)
    double precision::u(*)
    integer iout(15),ier
    double precision rout(2),koefScal(nEq)
    koefScal(:)=1d0
    call fnvinits(3,nEq,ier)
    call fkinmalloc(iout,rout,ier)
    call fkinspgmr(50,10,ier)
    call fkinsol(u,1,koefScal,koefScal,ier)
    call fkinfree()
    do i=1,nEq
      write(*,*),i,u(i)
    end do
  end subroutine
end module

subroutine fkfun(u,fval,ier)
  use moduleNonlinearSolve
  double precision::u(*)
  double precision::fval(*)
  integer::ier
  forall(i=2:nEq-1)
    fval(i)=-u(i-1)+2d0*u(i)-u(i+1)-1d0
  end forall
  fval(1)=u(1)+2d0*u(1)-u(2)-1d0
  fval(nEq)=-u(nEq-1)+2d0*u(nEq)+u(nEq)-1d0
  ier=0
end subroutine

program test
  use moduleNonLinearSolve
  double precision u(10)
  nEq=size(u)
  u(:)=10d0
  call solveNonlinear(u)
end program``

编译

$ gfortran -c -Wall -g test.f90
$ gfortran -Wall -g -o test test.o -lsundials_fkinsol -lsundials_fnvecserial -lsundials_kinsol -lsundials_nvecserial -llapack -lblas

$ ./test

注意:如果将所有 SUNDIALS 程序放在主程序中,它将完美运行。

非常感谢您的任何意见。

绵至

4

1 回答 1

1

根据KINSOL文档, 的第一个参数fkinmalloc必须与 type 的整数类型C相同long int。在您的情况下,long int长度为 8 个字节,但您传入的是一个由 4 个字节整数组成的数组。这将导致fkinmalloc尝试写入超出数组的范围,并写入其他内存。这通常会导致内存损坏,其症状就像您所观察到的一样:在稍后的某个随机点崩溃,例如从函数返回时。您应该能够通过 valgrind 运行程序来确认这一点,这可能会报告大小为 8 的无效写入。无论如何,替换

integer :: iout(15)

integer*8 :: iout(15)

应该解决问题。

于 2012-11-01T12:42:40.407 回答