使用SYSPY计算速度Jacobian

发布于 2025-01-21 13:27:27 字数 3092 浏览 0 评论 0原文

我想在多孔介质中获得对流方程的通量雅各布的分析表达,这在执行计算流体动力学时很有用。我以为我可以轻松地在sympy做到这一点,但我被困在某个地方。

这是我的方程式:

“”

phi呈孔隙率,c元素的浓度和v流体速度。

在我的情况下,jacobian的通量很简单:

“”

我可以使用darcy的定律来计算v:

“”

具有k的渗透性,nf流体粘度和pf流体压力。

渗透性取决于这种非常简单的关系:

“”

通过做这种非常简单的变量更改,我可以简化我的问题:

”>

alt = “ 我尝试以这种方式解决的方法:

from sympy import * 

# Create symbols
k0, phi, n, Pn, Pc, Ps, C = symbols('k0 phi n P_{i+1} P_{i} P_{i-1} C')
C_tild = phi * C
dx = Symbol(r"\Delta x")
nf = Symbol(r"\mu_f")

# Darcy's law while using finite differences for the Gradient operator in the pressure term
qf = (k0 * phi**n / nf) * (((Pn + Pc)/2 - (Ps + Pc)/2) / dx)
vf = qf / phi

flux = vf * C_tild
display(flux)
derivative = diff(flux, C_tild)

此返回错误,因为我试图同时使用两个变量(PHI和C)进行衍生物。 我在这里做错了什么?我如何使Sympy了解变量的变化?还是可以用更简单的表达来重写雅各布?

编辑

错误如下:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/var/folders/h6/3p69g_d146x78r6b75_h_td40000gp/T/ipykernel_64334/485359947.py in <module>
     11 flux = vf * C_tild
     12 display(flux)
---> 13 derivative = diff(flux, C_tild)

~/opt/anaconda3/envs/Two-phase_flow/lib/python3.9/site-packages/sympy/core/function.py in diff(f, *symbols, **kwargs)
   2497     """
   2498     if hasattr(f, 'diff'):
-> 2499         return f.diff(*symbols, **kwargs)
   2500     kwargs.setdefault('evaluate', True)
   2501     return _derivative_dispatch(f, *symbols, **kwargs)

~/opt/anaconda3/envs/Two-phase_flow/lib/python3.9/site-packages/sympy/core/expr.py in diff(self, *symbols, **assumptions)
   3526     def diff(self, *symbols, **assumptions):
   3527         assumptions.setdefault("evaluate", True)
-> 3528         return _derivative_dispatch(self, *symbols, **assumptions)
   3529 
   3530     ###########################################################################

~/opt/anaconda3/envs/Two-phase_flow/lib/python3.9/site-packages/sympy/core/function.py in _derivative_dispatch(expr, *variables, **kwargs)
   1921         from sympy.tensor.array.array_derivatives import ArrayDerivative
   1922         return ArrayDerivative(expr, *variables, **kwargs)
-> 1923     return Derivative(expr, *variables, **kwargs)
   1924 
   1925 

~/opt/anaconda3/envs/Two-phase_flow/lib/python3.9/site-packages/sympy/core/function.py in __new__(cls, expr, *variables, **kwargs)
   1346             if not v._diff_wrt:
   1347                 __ = ''  # filler to make error message neater
-> 1348                 raise ValueError(filldedent('''
   1349                     Can't calculate derivative wrt %s.%s''' % (v,
   1350                     __)))

ValueError: 
Can't calculate derivative wrt C*phi.

I want to obtain the analytical expression of the flux Jacobian of an advection equation in a porous media, which is useful when doing computational fluid dynamics. I thought that I could do that easily in Sympy but I am stuck somewhere.

Here are my equations:

with phi beeing the porosity, C the concentration of an element and v the fluid velocity.

The flux jacobian in my case is simply:

I can compute v using Darcy's law:

with k the permeability, nf the fluid viscosity and Pf the fluid pressure.

The permeability depends on phi with this very simple relationship:

by doing this very simple change of variable, I can simplify my problem:

That is what I've tried to solve in Sympy that way:

from sympy import * 

# Create symbols
k0, phi, n, Pn, Pc, Ps, C = symbols('k0 phi n P_{i+1} P_{i} P_{i-1} C')
C_tild = phi * C
dx = Symbol(r"\Delta x")
nf = Symbol(r"\mu_f")

# Darcy's law while using finite differences for the Gradient operator in the pressure term
qf = (k0 * phi**n / nf) * (((Pn + Pc)/2 - (Ps + Pc)/2) / dx)
vf = qf / phi

flux = vf * C_tild
display(flux)
derivative = diff(flux, C_tild)

This return an error because I am trying to do a derivative with two variables (phi and C) at the same time.
What am I doing wrong here? How can I make Sympy understand my change of variable? Or can I rewrite my Jacobian with a simpler expression?

EDIT

The error is the following:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/var/folders/h6/3p69g_d146x78r6b75_h_td40000gp/T/ipykernel_64334/485359947.py in <module>
     11 flux = vf * C_tild
     12 display(flux)
---> 13 derivative = diff(flux, C_tild)

~/opt/anaconda3/envs/Two-phase_flow/lib/python3.9/site-packages/sympy/core/function.py in diff(f, *symbols, **kwargs)
   2497     """
   2498     if hasattr(f, 'diff'):
-> 2499         return f.diff(*symbols, **kwargs)
   2500     kwargs.setdefault('evaluate', True)
   2501     return _derivative_dispatch(f, *symbols, **kwargs)

~/opt/anaconda3/envs/Two-phase_flow/lib/python3.9/site-packages/sympy/core/expr.py in diff(self, *symbols, **assumptions)
   3526     def diff(self, *symbols, **assumptions):
   3527         assumptions.setdefault("evaluate", True)
-> 3528         return _derivative_dispatch(self, *symbols, **assumptions)
   3529 
   3530     ###########################################################################

~/opt/anaconda3/envs/Two-phase_flow/lib/python3.9/site-packages/sympy/core/function.py in _derivative_dispatch(expr, *variables, **kwargs)
   1921         from sympy.tensor.array.array_derivatives import ArrayDerivative
   1922         return ArrayDerivative(expr, *variables, **kwargs)
-> 1923     return Derivative(expr, *variables, **kwargs)
   1924 
   1925 

~/opt/anaconda3/envs/Two-phase_flow/lib/python3.9/site-packages/sympy/core/function.py in __new__(cls, expr, *variables, **kwargs)
   1346             if not v._diff_wrt:
   1347                 __ = ''  # filler to make error message neater
-> 1348                 raise ValueError(filldedent('''
   1349                     Can't calculate derivative wrt %s.%s''' % (v,
   1350                     __)))

ValueError: 
Can't calculate derivative wrt C*phi.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凤舞天涯 2025-01-28 13:27:27

仅供参考,这是isympy会话中的代码,

In [7]: k0, phi, n, Pn, Pc, Ps, C = symbols('k0 phi n P_{i+1} P_{i} P_{i-1} C')
   ...: C_tild = phi * C
   ...: dx = Symbol(r"\Delta x")
   ...: nf = Symbol(r"\mu_f")
   ...: 
   ...: # Darcy's law while using finite differences for the Gradient operator i
   ...: n the pressure term
   ...: qf = (k0 * phi**n / nf) * (((Pn + Pc)/2 - (Ps + Pc)/2) / dx)
   ...: vf = qf / phi
   ...: 
   ...: flux = vf * C_tild

In [8]: flux
Out[8]: 
      n ⎛P_{i+1}   P_{i-1}⎞
C⋅k₀⋅φ ⋅⎜─────── - ───────⎟
        ⎝   2         2   ⎠
───────────────────────────
       \Delta x⋅\mu_f      

In [9]: C_tild
Out[9]: C⋅φ

因为c是一个简单的乘数,我认为它不会为计算添加任何内容。只需使用flux没有c,才能获得:

In [18]: diff(vf*phi, phi)
Out[18]: 
      n ⎛P_{i+1}   P_{i-1}⎞
k₀⋅n⋅φ ⋅⎜─────── - ───────⎟
        ⎝   2         2   ⎠
───────────────────────────
      \Delta x⋅\mu_f⋅φ    

Just for reference, here's your code in a isympy session

In [7]: k0, phi, n, Pn, Pc, Ps, C = symbols('k0 phi n P_{i+1} P_{i} P_{i-1} C')
   ...: C_tild = phi * C
   ...: dx = Symbol(r"\Delta x")
   ...: nf = Symbol(r"\mu_f")
   ...: 
   ...: # Darcy's law while using finite differences for the Gradient operator i
   ...: n the pressure term
   ...: qf = (k0 * phi**n / nf) * (((Pn + Pc)/2 - (Ps + Pc)/2) / dx)
   ...: vf = qf / phi
   ...: 
   ...: flux = vf * C_tild

In [8]: flux
Out[8]: 
      n ⎛P_{i+1}   P_{i-1}⎞
C⋅k₀⋅φ ⋅⎜─────── - ───────⎟
        ⎝   2         2   ⎠
───────────────────────────
       \Delta x⋅\mu_f      

In [9]: C_tild
Out[9]: C⋅φ

Since C is a simple multiplier, I don't think it adds anything to the calculation. Just use flux without the C, to get:

In [18]: diff(vf*phi, phi)
Out[18]: 
      n ⎛P_{i+1}   P_{i-1}⎞
k₀⋅n⋅φ ⋅⎜─────── - ───────⎟
        ⎝   2         2   ⎠
───────────────────────────
      \Delta x⋅\mu_f⋅φ    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文