program2——跑模型遇到数组分配问题

问题一:见代码

 integer:: icel,ic1,ic2,ic3
    real(kind = RK):: Pos0(3), cell_width
    integer, allocatable , save :: np_ic(:) 
    integer , save :: nc1, nc2,nc3,non_conode
    integer , save :: ncel
     type(cell_info),save,allocatable::cell_nodes_temp2(:)  

      nc1 = ceiling((xyzmax(1)-xyzmin(1))/cell_width)+1
      nc2 = ceiling((xyzmax(2)-xyzmin(2))/cell_width)+1
      nc3 = ceiling((xyzmax(3)-xyzmin(3))/cell_width)+1
      ncel= nc1*nc2*nc3

如果nc1是200,nc2是4000,nc3是5000,ncel理论值应该是4000000000,但为什么计算机计算出的数值是-4812365230?

>>>> 有可能是由于nc2和nc3的数值过大,导致ncel的计算出现了数字溢出。当nc2和nc3的值与nc1相乘时,会产生一个非常大的数字,可能会超过32位整数所能代表的最大值。

在Fortran中,32位整数可表示的最大值为2,147,483,647。如果ncel的值超过这个值,就会因为整数溢出而绕成一个负值。这可能是ncel被计算为负值的原因。

一个可能的解决方案是使用64位整数来表示ncel,它可以处理比32位整数大得多的值。这可以通过将ncel声明为int64而不是整数来实现。另外,你也可以尝试使用kind参数来指定一个更大的整数类型,比如integer(kind=8),它指定了一个64位整数。

问题二:见代码

为数组np_ic和cell_nodes_temp临时分配485244501的维度,


    integer(kind=8):: icel,ic1,ic2,ic3
    real(kind = RK):: Pos0(3), cell_width
    integer, allocatable , save :: np_ic(:) 
    integer , save :: nc1, nc2,nc3,non_conode
    integer(kind=8) , save :: ncel
    type(cell_info),save,allocatable::cell_nodes_temp2(:)  
     
      cell_width = 0.5 * element_length
      nc1 = ceiling((xyzmax(1)-xyzmin(1))/cell_width)+1
      nc2 = ceiling((xyzmax(2)-xyzmin(2))/cell_width)+1
      nc3 = ceiling((xyzmax(3)-xyzmin(3))/cell_width)+1
      ncel= nc1*nc2*nc3
       if(ncel<=0) goto 444
  
  allocate  ( np_ic(ncel) ,stat=iost);if(iost/=0) goto 333
  allocate  (cell_nodes_temp(ncel),stat=iost);if(iost/=0) goto 333

iost变量用于捕获分配操作的状态,值为0表示分配成功,任何非零值表示错误。iost的值为41,表示在使用allocate语句为数组np_ic和cell_nodes_temp分配内存的过程中出现了错误。

主要是和内存有关: 内存不足: 如果系统没有足够的可用内存为np_ic和cell_nodes_temp分配所要求的内存量,分配将失败,iost被设置为非零值。

>>> 尝试将stack reserve size, stack commit size 设置为100000000,还是错。

解释:将堆栈保留大小和堆栈提交大小设置为一个大值,不一定能保证你的程序有足够的内存用于使用分配语句的动态内存分配。堆栈是计算机内存的一部分,用于存储局部变量和函数调用信息,它的大小是有限的。Fortran中的allocate语句通常在堆上分配内存,这是一个与堆不同的内存区域。堆用于动态内存分配,通常比堆栈大。因此,增加堆栈大小可能不会直接影响分配语句的可用内存。

写程序测试当前的编译环境、电脑可用内存容量,究竟能分配多大的数组。

program test_dynamic_array
  implicit none
  integer n,i,k
  integer, allocatable :: my_array(:)
  integer :: array_size
  
  ! Set the desired size of the dynamic array in bytes
  array_size = 4_000_000_000 ! 4 GB
  
  ! Dynamically allocate the array
  allocate(my_array(array_size), stat = iostat)


n=100000000  

k=10000000  

do i=1,50

    array_size=n+i*5   !每次增加5千万

    allocate(my_array(array_size), stat = iostat)
  if (iostat /= 0) then
    print *, "Failed to allocate dynamic array"
  else
    print *, "Dynamic array allocated successfully"
    end if

    
    ! Deallocate the array when done
    deallocate(my_array)

end do

  
end program test_dynamic_array

检查出最大的约为460000000< 485244501。已更新在try_Lplate 子程序中。