我正在尝试使用METIS库进行网格划分,这是我为有限元计算编写的Fortran程序的一部分。 METIS是用C语言编写的,但它应该可以和Fortran 90一起使用。但是我一直都遇到了seg错误。
一个潜在的打嗝是有几个参数我要给出空指针。其他一些人无法从fortran调用C函数来识别空指针对象。这是here解决的问题,我认为这不是我遇到的问题。
我认为问题是让METIS改变起始数组索引;在C中它是0,在Fortran中它是1.有一个options
数组传递给每个函数,如果你想要Fortran约定,它应该有一个字段METIS_OPTION_NUMBERING
,你可以改为1
。如果不这样做,将导致C程序尝试访问索引0,从而为您提供seg错误。
edunlop1 here的帖子表明我只是创建一个数组options
,并且METIS的一些约定的约定确定该数组的哪个元素应该被设置为1以便重新编号。 。但是,这取决于您正在使用的例程,以及数组长度。
无论如何,这是我的代码:
integer :: ndomains,ncommon,objval
integer :: options(0:40)
integer, dimension(:), allocatable :: eptr,eind
integer, pointer :: vwgt(:)=>null(), vsize(:)=>null(), opts(:)=>null()
real(kind=8), pointer :: tpwgts(:)=>null()
! Read in the mesh data
call getarg(1,meshname)
call readmesh(meshname)
allocate(color(ne),domain(nn))
allocate(eind(3*ne),eptr(ne+1))
do n=1,ne
eptr(n) = 1+3*(n-1)
do i=1,3
eind( eptr(n)+i-1 ) = elem(i,n)
enddo
enddo
! Try and call METIS
ncommon = 2
ndomains = 2
options = 0
options(0) = 1
options(8) = 1
call METIS_PartMeshDual(ne,nn,eptr,eind,vwgt,vsize, &
& ncommon,ndomains,tpwgts,options,objval,color,domain)
METIS中用于更改编号的相关代码位于文件libmetis / meshpart.c中:
/* renumber the mesh */
if (options && options[METIS_OPTION_NUMBERING] == 1) {
ChangeMesh2CNumbering(*ne, eptr, eind);
renumber = 1;
}
有什么想法?如果有帮助,我可以发布Valgrind输出。
答案 0 :(得分:3)
可能没有任何内容,但问题第二段中的链接帖子或许仍然是相关的。
Fortran中的POINTER和C中的指针概念不完全相同,特别是如果Fortran指针指向数组。在Fortran中实现指向数组的指针需要存储除C指针(只是数据地址)之外的其他信息(数组边界或等价物)。
(从技术上讲,除非METIS_PartMeshDual的相关伪参数定义具有可选或指针属性(如果它是一个被调用的C函数且语言标准是< = F2008,则不可能),那么对调用中的分离指针的引用在Fortran中是非法的。再次 - 实现取决于将要发生的事情 - 我可以想象它将起作用的实现选项以及它不会发生的地方。)
请注意,在链接到空指针声明的帖子中,作为解决方案的一部分,从数组变为标量(列表中的第一个回复 - 检查帖子的时间)。在作为问题的一部分发布的示例代码中,“null”事物的声明仍然显示数组。我怀疑声明中的更改会更改调用C api的“设置”和/或编译器的分离指针。
现在,当从Fortran调用C API时,我更喜欢(尽可能)使用Fortran 2003的C互操作性功能(BIND(C)和朋友)为C API编写接口块。这更加强大,并避免了这种依赖于平台的问题。它确实需要一次性的前期工作以及支持F2003这方面的Fortran编译器。为他们的Fortran用户提供这种接口块的麻烦的图书馆供应商得到了很大的好处和许多善意的想法。
答案 1 :(得分:2)
Fortran数组大小比C更灵活。您可以使Fortran数组为0索引,或任何您想要的起始索引。
real, dimension (0:N-1) :: array
real, dimension (:), allocatable :: group
allocate (group (0:N-1))
如果在某种程度上对起始索引的分歧是问题,也许这会有所帮助。
答案 2 :(得分:2)
使用:
vwgt=>null()
而不是
vwgt(:)=>null()
表示所有空值(即vwgt,vsize,opts,tpwgts等)。问题是vwgt(:)并不是真正定义的,而只是vwgt或vwgt(1)。如果仍有问题,请使用调试器检查所有值。
我是第2段中提到的线程中的OP。不幸的是,最终的解决方案位于回复的顶部(参见时间戳)。希望有所帮助。