我正在尝试编写一个程序来解决我设计的泵系统的管道直径。我已经在纸上完成了这项工作并理解了方程式的机制。我很感激任何指导。
编辑:我已经使用用户的一些建议更新了代码,但仍然看到快速分歧。那里的猜测太高了。如果我弄清楚这一点,我会将其更新为工作。#!/bin/bash
array=({a..z} {A..Z})
while read -r a b c d e; do
# additional part
if [[ $a == "map:" ]]; then
echo "$a $b $c $d $e"
continue
fi
echo -n "$a $b $c "
for ((i=0;i<${#d};i++)); do
if [[ ${d:$i:1} =~ [a-zA-Z] ]]; then
printf "%s" ${array[RANDOM % 51]}
else
printf "%s" ${d:$i:1}
fi
done
echo " $e"
done < file
答案 0 :(得分:1)
您非常清楚地将接口(和实现)中的函数声明为
FUNCTION f(L,D,Q,hf,rho,mu,rough)
IMPLICIT NONE
INTEGER,PARAMETER::DP=selected_real_kind(15)
REAL(DP), PARAMETER::pi=3.14159265, g=9.81
REAL(DP), INTENT(IN)::L,Q,rough,rho,mu,hf,D
REAL(DP)::fx
END FUNCTION
所以你需要传递7个参数。并且它们都不是可选的。
但是当你打电话时,你称之为
xnew=xold-fx(xold)*((xolder-xold)/(fx(xolder)-fx(xold))
为它提供一个参数。例如,当您尝试使用gfortran
编译它时,编译器会抱怨没有为D
(第二个伪参数)获取任何参数,因为它会因第一个错误而停止。
答案 1 :(得分:0)
似乎xold
和xolder
的初始值离解决方案太远了。如果我们将它们改为
xold = 3.0d-5
xolder = 9.0d-5
并更紧密地改变收敛的门槛
IF (ABS(fx(xnew,L,Q,hf,rho,mu,rough)) <= 1.0d-10) THEN
然后我们得到
...
Diameter = 7.8306011049894322E-005
Diameter = 7.4533171406818087E-005
Diameter = 7.2580746283970710E-005
Diameter = 7.2653611474296094E-005
Diameter = 7.2652684750264582E-005
Diameter = 7.2652684291155581E-005
在这里,我们注意到函数f(x)
被定义为
FUNCTION f(D,L,Q,hf,rho,mu,rough)
...
f = (1/(hf/((L/D)*((4*Q)/pi*D)))) !! (1)
+ 2.0 * log( (rough/(3.7*D)) + (2.51/(((rho*((4*Q)/pi*D))/mu) !! (2)
* (hf/((L/D)*((4*Q)/pi*D))))) !! (3)
)
END FUNCTION
其中第(1)行和第(3)行中的项都是常数,而第(2)行中的项是D
上的某些常数。因此,我们看到f(D) = c1 - 2.0 * log( D / c2 )
,因此我们可以解析地获得解决方案D = c2 * exp(c1/2.0) = 7.26526809959e-5
,这与上面的数值解决方案很吻合。为了大致了解解决方案的位置,将f(D)
绘制为D
的函数非常有用,例如使用Gnuplot。
但我担心f(D)
本身的表达式(在Fortran代码中给出)可能包含一些由于许多括号引起的拼写错误。为避免此类问题,在制作程序之前,首先尽可能简单地安排f(D)
的表达式始终是有用的。
(一个提示是在外部提取常数因子并预先计算它们。)
此外,出于调试目的,检查各种术语的物理尺寸和物理单位的一致性有时很有用。实际上,如果获得的解决方案的幅度太大或太小,例如,物理单位的转换因子可能存在一些问题。