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仅保留循环结束后的单一最终值,同时修正代码中的潜在问题,可按以下方式修改:
关键修改点
- 修复命名冲突:代码中同时定义了标量
T和数组T(5),这会导致编译错误,需重命名其中一个避免冲突。 - 优化V的计算:
A和X数组在循环中未被修改,V的积分结果固定,无需在循环内重复计算,提前到循环外计算一次即可。 - 延迟H、D的计算:先在循环内完成
HH、DD数组的所有元素赋值,循环结束后再调用积分函数计算整体积分,得到单一的H、D结果。 - 调整输出位置:将V的打印移到循环结束后,仅输出最终值。
- 修正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
相关产品推荐
相关产品推荐

