1

我正在尝试将q_IN_w_sym(此处无法容纳的非常长的表达式)的 sympy 表达式转换为 python 函数,以便我可以评估它的数值。q_IN_w_sym我使用q_IN_w_sym.atoms(sym.Symbol)and检查了符号的数量q_IN_w_sym.free_symbols,两者都给出了相同数量的变量/符号(数量为 13)。之后,我尝试使用此答案中的建议将 sympy 表达式转换为 python 函数,如下所示:

q_IN_w = sym.lambdify(((r_g, r_o, R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP), ), \
    q_IN_w_sym)

但是,我收到以下错误:

(*list(__flatten_args__([_0])))
                                       ^
SyntaxError: invalid syntax

我也尝试了以下命令,但它给出了相同的错误(虽然略有不同)

q_IN_w = sym.lambdify((r_g, r_o, R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP), q_IN_w_sym)

错误:

(*list(__flatten_args__([_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12])))
                                                              ^
SyntaxError: invalid syntax

不确定上述命令有什么问题。下面,您可以找到一个最小的示例,您可以运行它来查看我面临的问题:

from __future__ import division
import numpy as np
import sympy as sym

def deg_to_rad(theta_deg):
    theta_rad = (sym.pi/180)*theta_deg
    return theta_rad


def q_IN_NS_sym():
    #======= define variables as symbols
    r, a_w, a_o, a_g, b_IN_w, b_IN_o, b_IN_g, c_IN_2w, c_IN_2o, c_IN_2g, u_IN_w, u_IN_o, u_IN_g, r_g, r_o, R, \
    sigma_dia, IFT_ow, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, mu_w, deltaP = \
    sym.symbols('r, a_w, a_o, a_g, b_IN_w, b_IN_o, b_IN_g, c_IN_2w, c_IN_2o, c_IN_2g, u_IN_w, u_IN_o, u_IN_g, r_g, r_o, R, \
    sigma_dia, IFT_ow, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, mu_w, deltaP')

    #======= 
    l_IN_slip = sigma_dia/((sym.pi - deg_to_rad(theta_IN_CA_deg))**4)
    W_IN_egy = IFT_ow*(1 + sym.cos(deg_to_rad(theta_IN_CA_deg)))
    u_IN_s = (l_IN_slip*R*nablaP)/(2*mu_w)
    u_IN_ads = (D_IN_ads_coeff/W_IN_egy)*deltaP
    u_IN_s_eff = (u_IN_s - u_IN_ads)

    #======= parameter b
    b_IN_g = 0
    b_IN_o = 2*(a_g - a_o)*(r_g**2)
    b_IN_w = b_IN_o + 2*(a_o - a_w)*(r_o**2)

    #======= parameter c
    c_IN_2w = u_IN_s_eff - a_w*(R**2) - b_IN_w*sym.log(R)
    c_IN_2o = c_IN_2w - (a_o - a_w)*(r_o**2)*(1 - 2*sym.log(r_o))
    c_IN_2g = b_IN_o*sym.log(r_g) + c_IN_2o - (a_g - a_o)*(r_g**2)

    #======= 
    u_IN_w = a_w*(r**2) + b_IN_w*sym.log(r) + c_IN_2w
    u_IN_o = a_o*(r**2) + b_IN_o*sym.log(r) + c_IN_2o
    u_IN_g = a_g*(r**2) + b_IN_g*sym.log(r) + c_IN_2g

    #======= 
    q_IN_w = sym.integrate((u_IN_w)*(2*sym.pi*r), (r, r_o, R))
    q_IN_o = sym.integrate((u_IN_o)*(2*sym.pi*r), (r, r_g, r_o))
    q_IN_g = sym.integrate((u_IN_g)*(2*sym.pi*r), (r, 0, r_g))

    return q_IN_w, q_IN_o, q_IN_g


#========= get sympy expression
q_IN_w_sym, q_IN_o_sym, q_IN_g_sym = q_IN_NS_sym()
q_IN_w_sym.atoms(sym.Symbol)

#========= change sympy expression to a python function
r_g, r_o, R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP = \
sym.symbols('r_g, r_o, R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP')
q_IN_w_fn = sym.lambdify(((r_g, r_o, R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP), ), \
q_IN_w_sym)

#======= constants
mu_w, mu_o, mu_g = 1e-3, 43-3, 2e-5
R = 10e-06 
M_g, R_gas, g = 16e-3, 8.314, 9.80
P_avg, T = 3.0e+6, 275
D_IN_m, s_IN, D_OR_m, s_OR = 1e-8, 2*R, 1e-7, 2*R
deltaP = 1.5e+6
L = 0.5
nablaP = (deltaP/L)

a_w = (-nablaP)/(4*mu_w)
a_o = (-nablaP)/(4*mu_o)
a_g = (-nablaP)/(4*mu_g)

IFT_ow = 0.05 
theta_IN_CA_deg, theta_OR_CA_deg = 15, 10
sigma_dia = 1e-9
D_IN_ads_coeff = 1e-8 
D_OR_ads_coeff = 1e-8 
tmp = np.linspace(1e-06, 1 - 0.01 - 0.2, num=50)
r_g = np.sqrt((R**2)*0.01)
r_o = np.sqrt((R**2)*(0.01 + tmp))

#========= calculate numerical value of lambdified sympy function
q_IN_w_num = q_IN_w_fn(r_g, r_o, R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP)

注意:虽然我有兴趣使用数组作为输入(r_o在本例中),但即使将其单个元素作为输入也会引发错误。另外,这里为了复现一个简单的例子,错误是不同的,但是找到数值的问题仍然存在。

4

1 回答 1

3

我不认为这是命令本身;对我来说都很好。

vars = sym.symbols("r_g, r_o, R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP")

r_g, r_o, R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP = vars

q_IN_w_sym = sum(vars)

(上面只是定义了 sympy vars,其名称取自您的帖子,并由它们制作的表达式用于演示)。

现在我运行你的线路:

q_IN_w = sym.lambdify(((r_g, r_o, R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP), ), q_IN_w_sym)
In [50]: q_IN_w([1]*13)
Out[50]: 13

或者第二个:

q_IN_w = sym.lambdify((r_g, r_o, R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP), q_IN_w_sym)

In [53]: q_IN_w(*[1]*13)
Out[53]: 13

所以它应该像你所说的那样工作,我相信。你应该能够运行我粘贴的代码,看看你是否仍然得到错误。也许问题出在您的代码中的其他地方?您是否检查过作为参数传递的所有变量是否实际上都是 sympy 符号?


编辑:运行现在粘贴的代码,对我来说运行良好,除了最后一次调用;如果我这样做:

q_IN_w_num = q_IN_w_fn(np.array([r_g, r_o[0], R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP]))

我明白了

In [18]: q_IN_w_num
Out[18]: -2.5016487930770088e-11

编辑2:

如何让您的函数使用数组r_o作为输入,并为其每个元素输出一个值:

首先,我建议稍微改变一下你的函数的步骤。而不是你有的线,使用:

q_IN_w_fn = sym.lambdify((r_g, r_o, R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP), q_IN_w_sym)

现在您设置了此函数的矢量化版本。在上一行之后添加这一行:

q_IN_w_vec = np.vectorize(q_IN_w_fn)

现在,在最后,您可以像最初打算的那样调用矢量化函数:

q_IN_w_vec(r_g, r_o, R, a_w, a_o, a_g, mu_w, IFT_ow, sigma_dia, theta_IN_CA_deg, D_IN_ads_coeff, nablaP, deltaP)

输出现在是一个数组,其中 r_o 中的每个元素都有一个函数值。

于 2017-06-01T19:59:49.363 回答