You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fortran中为积分变量V、H、D设置单一最终值的问题

问题

重写Fortran代码后,后续计算要求V、H、D仅保留单一最终值(例如V最终需为8),但当前循环中V会输出多个值(如1;2.5;4;5.5;8),重启程序时前几个值随机,但最终目标值始终为8,希望计算完成后V、H、D仅保留该最终目标值。

现有代码
dimension A1(5), B1(5),  T1(5), D(5), OOO(5), HH(5),DD(5)
    real :: T, M, L, Y, a, b, e, V, H
    real A(5) /1,2,3,2,1/
    real B(5) /1,2,3,2,1/
    real T(5) /2,2,2,2,2/
    real X(5) /-2,-1,0,1,2/
    integer :: i
    T = 2
    M = 3.0
    Y = 5
    L = (Y**2) / 9.81
    e = 2.718
    KN = 5
     do i = 1, 5

      if (A(i) > 0 .and. B(i) > 0) then 
       go to 123
      else
       A1(i) = 0
       B1(i) = 0
       T1(i) = 0
      endif
      123 if ((A(i)/B(i)) <= T(i)) then
           A1(i) = A(i)
           B1(i) = B(i)
           T1(i) = A(i)/B(i)
          else
           B1(i) = B(i)
           T1(i) = T(i)
           A1(i) = B1(i) * T1(i)
          endif
       
      !V
      call VV(X, A, OOO,V)
      print *, V
      !H
      HH(i) = (1.0/12.0)* B1(i)**3
      call VV(X, HH, OOO,HHH)
      H = HHH * (1.0/V)
   
      !D
      DD(i) = ((-T1(i))/2.0) * A1(i)
      call VV(X,A,OOO,DDD)
      D = (DDD * (1.0/V)) + T
   
   
     end do
 
    end program F
    !Integral
    subroutine VV(X, Y, IY,O)
    real, intent(in):: X(1:5), Y(1:5)
    real :: IY(1:5), S, S1, O
    integer:: i, n
      n=size(X)
      S=0.0
      do i=1, n-1
        S1=S
        S=S+0.5*(X(i+1)-X(i))*(Y(i+1)+Y(i))
        IY(i)=S1
      end do
      IY(n)=S
      O = IY(n)
      return
    end subroutine VV
解决方案

要让V、H、D仅保留循环结束后的单一最终值,同时修正代码中的潜在问题,可按以下方式修改:

关键修改点

  1. 修复命名冲突:代码中同时定义了标量T和数组T(5),这会导致编译错误,需重命名其中一个避免冲突。
  2. 优化V的计算:A和X数组在循环中未被修改,V的积分结果固定,无需在循环内重复计算,提前到循环外计算一次即可。
  3. 延迟H、D的计算:先在循环内完成HH、DD数组的所有元素赋值,循环结束后再调用积分函数计算整体积分,得到单一的H、D结果。
  4. 调整输出位置:将V的打印移到循环结束后,仅输出最终值。
  5. 修正D的计算逻辑:原代码计算D时错误传入A数组,应传入循环内赋值的DD数组。

修改后的代码

dimension A1(5), B1(5),  T1(5), D_arr(5), OOO(5), HH(5), DD(5)
    real :: T_scalar, M, L, Y, a, b, e, V, H, D
    real A(5) /1,2,3,2,1/
    real B(5) /1,2,3,2,1/
    real T_arr(5) /2,2,2,2,2/  ! 重命名数组避免与标量冲突
    real X(5) /-2,-1,0,1,2/
    integer :: i
    T_scalar = 2
    M = 3.0
    Y = 5
    L = (Y**2) / 9.81
    e = 2.718
    KN = 5

    ! 提前计算V,仅需一次
    call VV(X, A, OOO, V)

    do i = 1, 5
        if (A(i) > 0 .and. B(i) > 0) then 
            go to 123
        else
            A1(i) = 0
            B1(i) = 0
            T1(i) = 0
        endif
123     if ((A(i)/B(i)) <= T_arr(i)) then
            A1(i) = A(i)
            B1(i) = B(i)
            T1(i) = A(i)/B(i)
        else
            B1(i) = B(i)
            T1(i) = T_arr(i)
            A1(i) = B1(i) * T1(i)
        endif
       
        ! 仅在循环内赋值数组元素,不计算最终结果
        HH(i) = (1.0/12.0)* B1(i)**3
        DD(i) = ((-T1(i))/2.0) * A1(i)
    end do

    ! 循环结束后计算最终H值
    call VV(X, HH, OOO, HHH)
    H = HHH * (1.0/V)

    ! 循环结束后计算最终D值,修正传入的数组为DD
    call VV(X, DD, OOO, DDD)
    D = (DDD * (1.0/V)) + T_scalar

    ! 打印最终结果
    print *, "最终V值:", V
    print *, "最终H值:", H
    print *, "最终D值:", D
 
end program F

! 积分子程序保持不变
subroutine VV(X, Y, IY, O)
    real, intent(in):: X(1:5), Y(1:5)
    real :: IY(1:5), S, S1, O
    integer:: i, n
    n = size(X)
    S = 0.0
    do i = 1, n-1
        S1 = S
        S = S + 0.5*(X(i+1)-X(i))*(Y(i+1)+Y(i))
        IY(i) = S1
    end do
    IY(n) = S
    O = IY(n)
    return
end subroutine VV

内容的提问来源于stack exchange,提问作者Fr_RedPaw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 19:35:15