我正在尝试在VBA中解决以下方程组:
我已经找了其他类似的问题,我找不到合适的解决方案。我已经在工作表中解决了方程式,只需输入方程式,因为公式是单独的单元格(最初将创建循环参考警告)和启用迭代计算) - 假设我知道DR总是大于PR,我想从DR的初始值递增地减少PR的迭代方法将在VBA中起作用。作为参考,使用的工作表如下所示:
G9
中的公式为=(G8*B6)/(G10+273.15)
,即公式2(见上文),G10
中的公式为=(B6+(B6*(-1+((G9*(B3-B35))/(B3-B35))^0.263)/B34))-B33*(B6+(B6*(-1+((G9*(B3-B35))/(B3-B35))^0.263)/B34))
,即公式1(见上文)。
当我尝试通过从DR的初始值逐步减少PR在VBA中以编程方式执行此操作时,它不起作用。我的代码如下:
Sub ChargeTempAndPressureCalculations()
Dim AP_hPa As Double
Dim AP_psi As Double
Dim TIn_C As Double
Dim TIn_K As Double
Dim PR As Double
Dim Ei As Double
Dim Et As Double
Dim Vci As Double
Dim DR As Double
Dim TOut_C As Double
AP_hPa = 1029 'Input
AP_psi = AP_hPa * 100 * 0.000145038
TIn_C = 15 'Input
TIn_K = TIn_C + 273.15
Et = 0.75 'Input
Ei = 0.75 'Input
Vci = 0.5 'Input
DR = 2.7103502887329 'Input
PR = DR
Do Until TOut_C = (TIn_K + (TIn_K * (-1 + ((PR * (AP_psi - Vci)) / (AP_psi - Vci)) ^ 0.263) / Et)) - Ei * (TIn_K + (TIn_K * (-1 + ((PR * (AP_psi - Vci)) / (AP_psi - Vci)) ^ 0.263) / Et)) And PR = (DR * TIn_K) / (TOut_C + 273)
PR = PR - 0.00000000001
Loop
Debug.Print "Charge air temperature = " & TOut_C
Debug.Print "Pressure Ratio = " & PR
End Sub
这显然是循环问题,但是我做错了什么呢?
我已经拆分了等式1,以防止评论中提到的另一个用户观察到的“等式太复杂”错误。我还添加了一个控件来防止步数超过1000.
Sub ChargeTempAndPressureCalculations()
Dim AP_hPa As Double
Dim AP_psi As Double
Dim TIn_C As Double
Dim TIn_K As Double
Dim PR As Double
Dim Ei As Double
Dim Et As Double
Dim Vci As Double
Dim DR As Double
Dim TOut_C As Double
Dim A As Double
Dim B As Double
Dim i As Integer
AP_hPa = 1029 'Input
AP_psi = AP_hPa * 100 * 0.000145038
TIn_C = 15 'Input
TIn_K = TIn_C + 273.15
Et = 0.75 'Input
Ei = 0.75 'Input
Vci = 0.5 'Input
DR = 2.7103502887329 'Input
PR = DR
Do Until i > 1000 Or (TOut_C = A - Ei * B And PR = (DR * TIn_K) / (TOut_C + 273))
'Spliting equation for TOut_C to simplify the expression and prevent an error
A = (TIn_K + (TIn_K * (-1 + ((PR * (AP_psi - Vci)) / (AP_psi - Vci)) ^ 0.263) / Et))
B = (TIn_K + (TIn_K * (-1 + ((PR * (AP_psi - Vci)) / (AP_psi - Vci)) ^ 0.263) / Et))
PR = PR - 0.00000000001
i = i + 1
Loop
Debug.Print "Charge air temperature = " & TOut_C
Debug.Print "Pressure Ratio = " & PR
End Sub
在阅读了所提供的答案之后,我仍然不知道如何解决我的问题。
答案 0 :(得分:0)
请注意:
Do Until TOut_C = ...
=
符号是 comparisson ,而不是赋值。由于尚未使用TOut_C
,因此VB将其设置为零,因此您要比较右侧是否为零。这似乎不是您的意图,因为您在TOut_C
部分中使用AND
作为TOut_C + 273
,然后始终为273.
但是如果你想与零比较,那么请注意RHS在浮点运算中可能永远不会变为零,你必须与“epsilon”进行比较,这是一个小的值,即你的精确阈值。例如:
Private Const eps = 0.00000000001 ' must be smaller than your step size
Do Until Abs(TOut_C - RHS) < eps
我把这件事告诉你。 (我的Excel版本也出现“Expression too complex”错误。)
答案 1 :(得分:0)
主要有两个问题......
在您的Do..Loop
中,您希望代码在TOut_C = <something based on PR> AND PR = <something based on TOut_C>
然而,这两个方程都会导致双数据类型,这几乎是无法比较的,因为点击该等点的可能性实际为零(正如我解释here)
因此,您需要设置更灵活的参数,例如TOut_C > 63
。
我能找到的第二件事是方程就是方程式。所以他们会产生一个数字,但是这个数字是等式的结果,但是什么会定义终点?永远不会定义TOut_C
并随后按照指示进行比较,您的代码以PR
开头为2.71 ...但Tout_C
为0。
那么你能详细说明TOut_C
和PR
之间的相关性以及它们中的一个或两个的解决方案值是什么?或者您是否正在尝试解决平衡点,即TOut_C两个函数实现相同的结果? (这需要在数学上重写任一函数来表达相同的输出)所以重写PR的函数来生成Tout_C ......
循环工作(即它循环),如果你这样写... 它没有解决它,但至少你知道它循环......
Do Until TOut_C = 15 And PR = 22
TOut_C = (TIn_K + (TIn_K * (-1 + ((PR * (AP_psi - Vci)) / (AP_psi - Vci)) ^ 0.263) / Et)) - Ei * (TIn_K + (TIn_K * (-1 + ((PR * (AP_psi - Vci)) / (AP_psi - Vci)) ^ 0.263) / Et))
PR = (DR * TIn_K) / (TOut_C + 273)
PR = PR - 0.00000000001
Loop
答案 2 :(得分:0)
我已经超过你的计算了一点,如果PR
和TOut_C
的增量非常小,我想你想要停止...
以下代码就是这样做的。它会计算给定TOut_C
的{{1}},随后计算与PR
对应的PR
,然后循环将新计算的TOut_C
替换为PR
1}}计算等。
它计算替代计算与先前计算之间的差异,如果两者之间不再存在“大”偏移,则会停止循环。
TOut_C
根据您的初始输入,输出为:
Sub ChargeTempAndPressureCalculations()
Dim AP_hPa As Double
Dim AP_psi As Double
Dim TIn_C As Double
Dim TIn_K As Double
Dim PR As Double
Dim Ei As Double
Dim Et As Double
Dim Vci As Double
Dim DR As Double
Dim TOut_C As Double
AP_hPa = 1029 'Input
AP_psi = AP_hPa * 100 * 0.000145038
TIn_C = 15 'Input
TIn_K = TIn_C + 273.15
Et = 0.75 'Input
Ei = 0.75 'Input
Vci = 0.5 'Input
DR = 2.7103502887329 'Input
PR = DR
dTOut_C = 1 'Set to arbitrary number to initialize the loop
dPR = 1 'Set to arbitrary number to initialize the loop
Do Until dPR < 0.0000000001 And dTOut_C < 0.0000000001
'Calculate the TOut_C and PR
TOut_C = (TIn_K + (TIn_K * (-1 + ((PR * (AP_psi - Vci)) / (AP_psi - Vci)) ^ 0.263) / Et)) - Ei * (TIn_K + (TIn_K * (-1 + ((PR * (AP_psi - Vci)) / (AP_psi - Vci)) ^ 0.263) / Et))
PR = (DR * TIn_K) / (TOut_C + 273)
'Calculate difference relative to last calculation
dPR = PR - PR0
dTOut_C = TOut_C - TOut_C0
'Set the last calculation as previous calculation and re-do loop
PR0 = PR
TOut_C0 = TOut_C
Loop
Debug.Print "Charge air temperature = " & TOut_C
Debug.Print "Pressure Ratio = " & PR
End Sub
那是你在找什么?
PS:从技术上讲,你应该做的是在数学上重写方程式来解决基于DR的PR问题,因为这实质上就是你在做什么......答案 3 :(得分:0)
有关Excel如何处理循环引用的信息,请参阅http://www.decisionmodels.com/calcsecretsc.htm。基本上,它只计算每个单元格,忽略循环引用,然后更新每次迭代中的值。
将此应用于您的VBA例程会产生以下子例程:
Sub ChargeTempAndPressureCalculations()
' input variables
Dim AP_hPa As Double
Dim AP_psi As Double
Dim TIn_C As Double
Dim TIn_K As Double
Dim Ei As Double
Dim Et As Double
Dim Vci As Double
Dim DR As Double
' temporary variables
Dim Td As Double
Dim Pd As Double
Dim A As Double
' output variables
Dim TOut_C As Double
Dim PR As Double
' iteration control
Dim eps As Double
Dim i As Integer
AP_hPa = 1029
AP_psi = AP_hPa * 100 * 0.000145038
TIn_C = 15
TIn_K = TIn_C + 273.15
Et = 0.75
Ei = 0.75
Vci = 0.5
DR = 2.7103502887329
PR = DR
eps = 0.00000000001
i = 0
Do
Td = TOut_C ' remember values from previous iteration ( 'd' means 'delta')
Pd = PR
A = (TIn_K + (TIn_K * (-1 + ((PR * (AP_psi - Vci)) / (AP_psi - Vci)) ^ 0.263) / Et))
TOut_C = A - Ei * A
PR = (DR * TIn_K) / (TOut_C + 273)
i = i + 1
Debug.Print TOut_C & ", " & PR & "(" & Abs(Td - TOut_C) & ", " & Abs(Pd - PR) & ")" ' show progression
' loop until the difference is less than eps or max iterations reached
Loop While (i < 100 And (Abs(Td - TOut_C) > eps And Abs(Pd - PR) > eps))
Debug.Print "Charge air temperature = " & TOut_C
Debug.Print "Pressure Ratio = " & PR
Debug.Print "number of iterations: " & i
End Sub
输出:
100.835921416446, 2.08911822261291(100.835921416446, 0.621232066119993)
92.5738330344343, 2.13633297880164(8.26208838201211, 4.72147561887288E-02)
93.2611120407512, 2.13232420812257(0.687279006316899, 4.00877067907057E-03)
93.2031960023579, 2.13266144103602(5.79160383933299E-02, 3.37232913455665E-04)
93.2080712078647, 2.13263304962791(4.87520550686327E-03, 2.83914081067316E-05)
93.2076607895546, 2.13263543972443(4.10418310181626E-04, 2.39009651137323E-06)
93.2076953402811, 2.13263523851592(3.45507265677725E-05, 2.01208508077144E-07)
93.2076924316548, 2.1326352554545(2.90862628560262E-06, 1.6938581648418E-08)
93.2076926765153, 2.13263525402854(2.44860444809092E-07, 1.42596112695514E-09)
93.2076926559019, 2.13263525414858(2.06133563551703E-08, 1.200430865822E-10)
93.2076926576372, 2.13263525413848(1.73530168012803E-09, 1.01052499701382E-11)
93.2076926574912, 2.13263525413933(1.46073375617561E-10, 8.5043083686287E-13)
Charge air temperature = 93.2076926574912
Pressure Ratio = 2.13263525413933
number of iterations: 12