【发布时间】:2021-11-25 10:01:06
【问题描述】:
我正在使用 Sympy nsolve 来求解非线性方程组。 求解器运行良好,但我需要初始猜测的灵活性,因此我希望可以插入变量作为初始猜测。
例如,对于固定的初始猜测,一切正常:
import numpy as np
from sympy import Symbol, nsolve, cos, sin, asin, acos, S
# Definition of parameters #
tracking_angle_deg = 55
pv_area = 2.174 # pv panel area in m^2
mirror_area = pv_area / cos(0.25 * np.pi) # mirrors area in m^2
pv_length = 1 # pv panel length in m
mirror_length = pv_length / cos(0.25 * np.pi) # mirror length in m\
k = 0.027 # thermal conduction of air
pv_eps = 0.9 # pv emissivity
mirror_eps = 0.8 # mirrors emissivity
gravity = 9.81
sigma = 5.67e-8 # boltzman constant
nu = 15.69e-6 # kinematic viscosity of air
alpha = 22.9e-6 # thermal diffusivity of air
Pr = nu / alpha # Prandtl of air
F_m_sky = 0.5 # shape factor mirror-sky
F_pv_sky = 1 - ((2 ** 0.5) / 2) # shape factor pv-sky
F_pv_m = 1 - F_pv_sky # shape factor mirror-pv
e1 = (1 - pv_eps) / (pv_eps * pv_area)
e2 = (1 - mirror_eps) / (mirror_eps * mirror_area)
f12 = 1 / (pv_area * F_pv_m)
f13 = 1 / (pv_area * F_pv_sky)
f23 = 1 / (mirror_area * F_m_sky)
Epower = 240 # electric power output from PV
Ta_kelvin = 297
Tsky = Ta_kelvin - 5
PV_flux = 535.5
m1_flux = 86.1 # absorbed flux on left/west mirror
m2_flux = 86.1 # absorbed flux on right/east mirror
teta_deg = 23
teta_rad = (teta_deg / 180) * np.pi
# angles of mirrors
phi1_rad = ((teta_deg + 45) / 180) * np.pi
phi2_rad = ((abs(teta_deg - 45)) / 180) * np.pi
J_PV_1 = Symbol('J_PV_1', real=True)
J_PV_2 = Symbol('J_PV_2', real=True)
J_m1 = Symbol('J_m1', real=True)
J_m2 = Symbol('J_m2', real=True)
Tm1 = Symbol('Tm1', real=True)
Tm2 = Symbol('Tm2', real=True)
Tpv = Symbol('Tpv', real=True)
E1 = sigma * (Tpv ** 4)
Em1 = sigma * (Tm1 ** 4)
Em2 = sigma * (Tm2 ** 4)
E3 = sigma * (Tsky ** 4)
J3 = E3
# Natural convection PV #
beta_pv = 1 / ((Tpv + Ta_kelvin) / 2)
Ra_pv = (gravity * beta_pv * (Tpv - Ta_kelvin) * (pv_length ** 3)) / (nu * alpha)
Ra_pv_crit = (2e9) / np.exp(2.94 * abs(teta_rad))
Nusselt_pv_down = 0.59 * ((Ra_pv * cos(teta_rad)) ** 0.25)
h_pv_down = (Nusselt_pv_down * k) / pv_length
Nusselt_pv_up = (0.1 + ((0.05 * abs(teta_rad)) / np.pi)) * (Ra_pv ** (1 / 3)) # turbulent flow correlation
h_pv_up = (Nusselt_pv_up * k) / pv_length
# mirror1 left west #
beta_m1 = 1 / ((Tm1 + Ta_kelvin) / 2)
Ra_m1 = abs((gravity * beta_m1 * (Tm1 - Ta_kelvin) * (mirror_length ** 3)) / (nu * alpha))
Nusselt_m1_down = 0.59 * ((Ra_m1 * cos(phi1_rad)) ** 0.25)
Nusselt_m1_up = (0.1 + ((0.05 * abs(phi1_rad)) / np.pi)) * (Ra_m1 ** (1 / 3))
h_m1_down = (Nusselt_m1_down * k) / mirror_length
h_m1_up = (Nusselt_m1_up * k) / mirror_length
h_m1 = h_m1_down + h_m1_up
# mirror2 right east #
beta_m2 = 1 / ((Tm2 + Ta_kelvin) / 2)
Ra_m2 = abs((gravity * beta_m2 * (Tm2 - Ta_kelvin) * (mirror_length ** 3)) / (nu * alpha))
Nusselt_m2_down = 0.59 * ((Ra_m2 * cos(phi2_rad)) ** 0.25)
Nusselt_m2_up = (0.1 + ((0.05 * abs(phi2_rad)) / np.pi)) * (Ra_m2 ** (1 / 3))
h_m2_down = (Nusselt_m2_down * k) / mirror_length
h_m2_up = (Nusselt_m2_up * k) / mirror_length
h_m2 = h_m2_down + h_m2_up
# equations #
eq1 = ((E1 - J_PV_1) / e1) + ((J_m1 - J_PV_1) / f12) + ((J3 - J_PV_1) / f13)
eq2 = ((E1 - J_PV_2) / e1) + ((J_m2 - J_PV_2) / f12) + ((J3 - J_PV_2) / f13)
eq3 = ((Em1 - J_m1) / e2) + ((J_PV_1 - J_m1) / f12) + ((J3 - J_m1) / f23)
eq4 = ((Em2 - J_m2) / e2) + ((J_PV_2 - J_m2) / f12) + ((J3 - J_m2) / f23)
eq5 = (PV_flux * pv_area) - Epower - (h_pv_up * pv_area * (Tpv - Ta_kelvin)) - (
h_pv_down * pv_area * (Tpv - Ta_kelvin)) - ((E1 - J_PV_1) / e1) - ((E1 - J_PV_2) / e1)
eq6 = (m1_flux * mirror_area) - (h_m1 * mirror_area * (Tm1 - Ta_kelvin)) - (
mirror_eps * sigma * mirror_area * ((Tm1 ** 4) - (Tsky ** 4))) - ((Em1 - J_m1) / e2)
eq7 = (m2_flux * mirror_area) - (h_m2 * mirror_area * (Tm2 - Ta_kelvin)) - (
mirror_eps * sigma * mirror_area * ((Tm2 ** 4) - (Tsky ** 4))) - ((Em2 - J_m2) / e2)
initial_guess = [PV_flux, PV_flux, PV_flux, PV_flux, Ta_kelvin, Ta_kelvin, Ta_kelvin + 15]
print(nsolve([eq1, eq2, eq3, eq4, eq5, eq6, eq7], [J_PV_1, J_PV_2, J_m1, J_m2, Tm1, Tm2, Tpv],
[500, 500, 500, 500, 293, 293, 310], domain=S.Reals))
输出:
Matrix([[593.171007328550], [593.142501153849], [491.462389303786], [491.059251115046], [304.687760815851], [304.609734541627], [321.670012318818]])
但是我不能以任何我尝试的方式在初始猜测中使用变量(有限数字),例如: 对于变量:
print([PV_flux, Ta_kelvin])
[535.5, 297]
当我在 nsolve 中使用它们时:
print(nsolve([eq1, eq2, eq3, eq4, eq5, eq6, eq7], [J_PV_1, J_PV_2, J_m1, J_m2, Tm1, Tm2, Tpv],
[PV_flux, PV_flux, PV_flux, PV_flux, Ta_kelvin, Ta_kelvin, Ta_kelvin], domain=S.Reals))
加注:
Traceback (most recent call last):
File "C:/Users/", line 154, in <module>
a=temp(535.5,240.1,86.1, 86.1,23,24)
File "C:/Users/", line 105, in temp
return(nsolve([eq1,eq2,eq3,eq4,eq5,eq6,eq7], [J_PV_1,J_PV_2,J_m1,J_m2,Tm1,Tm2,Tpv], [PV_flux,PV_flux,PV_flux,PV_flux,Ta_kelvin,Ta_kelvin,Ta_kelvin], domain = S.Reals))
File "C:\Users\\anaconda3\envs\ben\lib\site-packages\sympy\utilities\decorator.py", line 92, in func_wrapper
return func(*args, **kwargs)
File "C:\Users\\anaconda3\envs\ben\lib\site-packages\sympy\solvers\solvers.py", line 3026, in nsolve
x = findroot(f, x0, J=J, **kwargs)
File "C:\Users\\anaconda3\envs\ben\lib\site-packages\mpmath\calculus\optimization.py", line 960, in findroot
for x, error in iterations:
File "C:\Users\\anaconda3\envs\ben\lib\site-packages\mpmath\calculus\optimization.py", line 658, in __iter__
s = self.ctx.lu_solve(Jx, fxn)
File "C:\Users\\anaconda3\envs\ben\lib\site-packages\mpmath\matrices\linalg.py", line 227, in lu_solve
A, p = ctx.LU_decomp(A)
File "C:\Users\\anaconda3\envs\ben\lib\site-packages\mpmath\matrices\linalg.py", line 143, in LU_decomp
ctx.swap_row(A, j, p[j])
File "C:\Users\bents\anaconda3\envs\ben\lib\site-packages\mpmath\matrices\matrices.py", line 868, in swap_row
A[i,k], A[j,k] = A[j,k], A[i,k]
File "C:\Users\\anaconda3\envs\ben\lib\site-packages\mpmath\matrices\matrices.py", line 491, in __getitem__
if key[0] >= self.__rows or key[1] >= self.__cols:
TypeError: '>=' not supported between instances of 'NoneType' and 'int'
谢谢
【问题讨论】:
-
这些变量是什么类型的?它们都必须是有限数。你试过
print([PV_flux,PV_flux,PV_flux,PV_flux,Ta_kelvin,Ta_kelvin,Ta_kelvin])来检查它们吗? -
它们是有限数。 nsolve 命令在函数内部,这些变量是函数的输入。
-
@JohanC 已编辑。谢谢
-
你能展示实际的可运行代码吗?
-
@OscarBenjamin 我编辑了这篇文章。参数多,有点长
标签: sympy