Scipy fsolve无法收敛到正确的值。

huangapple go评论65阅读模式
英文:

Scipy fsolve doesn't converge to correct value

问题

使用fsolve时,迭代的值如下所示:

1
1.0
1.0
1.0000000149011612
101.0
nan
1.0000000149011612
101.0
nan
nan
nan
nan
nan
nan
nan

代码迭代的模式似乎不受给定的P、T、kf或kp值的影响。此外,代码还生成了运行时警告。因此,您的问题是代码本身是否存在问题。

RuntimeWarning: invalid value encountered in sqrt
  return 2*L*np.sqrt(R**2-(R-h)**2)

希望这有所帮助。如果您需要进一步的解释或帮助,请随时提出。

英文:

I'm trying to solve for the initial value of a simple differential equation (dh/dt, trying to find h at t=0). However, using fsolve, the value for the iterations are:

1
1.0
1.0
1.0000000149011612
101.0
nan
1.0000000149011612
101.0
nan
nan
nan
nan
nan
nan
nan

The code iterations follow the same pattern no matter what values I give P,T,kf or kp. Running the code also gives the error warning. So my question is is the issue is in the code itself?

# -*- coding: utf-8 -*-
"""
Created on Mon Apr  3 16:46:15 2023

@author: houle
"""

import numpy as np
import math
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
from scipy.optimize import fsolve

class parametre_antoine():
    A = 8.13484
    B = 1662.48
    C = 238.131
    mmhg_atm = 760
    
prm_antoine = parametre_antoine() 

rho = 0.8 #kg/L
Tin = 110 #C   
R = 1
kp = -200
kf = 300
M = 46.068/1000 #kg/mol
L = 5
M = 46.068 #g/mol
Vtot = np.pi*R**2*L

theta = [rho,R,kp,kf,M,L,prm_antoine,Vtot]

Fin = 20000
u = [Fin]

P = 3.3
T = 300

def Aire(R,L,h):
    return 2*L*np.sqrt(R**2-(R-h)**2)

def dv_dh(R,L,h):
    dVdh = R/np.sqrt(1-(h/R-1)**2)+L*np.sqrt((2*R-h)*h)-(L*(2*R-2*h)*(R-h))/(2*np.sqrt((2*R-h)*h))
    return dVdh

def dh_dt(h,theta,u,T,P):
    [rho,R,kp,kf,M,L,prm_antoine,Vtot] = theta
    [Fin] = u
    dhdt =(Fin- kp*(psat(prm_antoine,T)-P)*Aire(R,L,h)-kf*h**0.5)/rho/ dv_dh(R,L,h)
    print(h)
    return dhdt

def psat(prm,T):
    #T en Celcius
    #Valide entre -114 et 243C
    #Retourne la tension de vapeur en atm
    p_mmhg = 10**(prm.A-prm.B/(T+prm.C))
    p_atm = p_mmhg / prm.mmhg_atm
    return p_atm

x0 = [1]
u0 = [Fin]
x0 = fsolve(dh_dt, x0, args=(theta, u0,T,P))
RuntimeWarning: invalid value encountered in sqrt
  return 2*L*np.sqrt(R**2-(R-h)**2)

答案1

得分: 0

根据您提供的内容,以下是已经翻译好的代码部分:

IIUC有很多需要改变的事情此代码运行并生成输出

    import numpy as np
    from scipy.optimize import fsolve
    
    # 定义参数
    rho = 0.8  # kg/L
    R = 1  # m
    L = 5  # m
    kp = -200
    kf = 300
    M = 46.068  # g/mol
    prm_A = 8.13484
    prm_B = 1662.48
    prm_C = 238.131
    mmhg_atm = 760
    Vtot = np.pi * R ** 2 * L
    P = 3.3  # atm
    T = 300  # K
    Fin = 20000  # L/h
    
    # 定义函数
    def psat(T):
        p_mmhg = 10 ** (prm_A - prm_B / (T + prm_C))
        p_atm = p_mmhg / mmhg_atm
        return p_atm
    
    def Aire(R, L, h):
        if h >= R:
            return 0
        else:
            return 2 * L * np.sqrt(R ** 2 - (R - h) ** 2)
    
    def dv_dh(R, L, h):
        if h >= R:
            return 0
        else:
            return R / np.sqrt(1 - (h / R - 1) ** 2) + L * np.sqrt((2 * R - h) * h) - (L * (2 * R - 2 * h) * (R - h)) / (2 * np.sqrt((2 * R - h) * h))
    
    def dh_dt(h):
        return (Fin - kp * (psat(T) - P) * Aire(R, L, h) - kf * h ** 0.5) / rho / dv_dh(R, L, h)
    
    # 解决初始值 h 的问题
    x0 = [0.5 * R]
    h0 = fsolve(dh_dt, x0)[0]
    
    print(f"The initial value of h is {h0:.4f} m.")

请注意,已经翻译的代码部分中已将 HTML 实体 > 替换为正确的 Python 表达式 >=,以确保代码的正确性。

英文:

IIUC, there was a bevy of things that needed to change. This code runs and produces an output:

import numpy as np
from scipy.optimize import fsolve
# Define the parameters
rho = 0.8 # kg/L
R = 1 # m
L = 5 # m
kp = -200
kf = 300
M = 46.068 # g/mol
prm_A = 8.13484
prm_B = 1662.48
prm_C = 238.131
mmhg_atm = 760
Vtot = np.pi*R**2*L
P = 3.3 # atm
T = 300 # K
Fin = 20000 # L/h
# Define the functions
def psat(T):
p_mmhg = 10**(prm_A-prm_B/(T+prm_C))
p_atm = p_mmhg / mmhg_atm
return p_atm
def Aire(R,L,h):
if h >= R:
return 0
else:
return 2*L*np.sqrt(R**2-(R-h)**2)
def dv_dh(R,L,h):
if h >= R:
return 0
else:
return R/np.sqrt(1-(h/R-1)**2)+L*np.sqrt((2*R-h)*h)-(L*(2*R-2*h)*(R-h))/(2*np.sqrt((2*R-h)*h))
def dh_dt(h):
return (Fin- kp*(psat(T)-P)*Aire(R,L,h)-kf*h**0.5)/rho/ dv_dh(R,L,h)
# Solve for the initial value of h
x0 = [0.5*R]
h0 = fsolve(dh_dt, x0)[0]
print(f"The initial value of h is {h0:.4f} m.")

A few notes...

  • I refactored a few things, including removing some imports that weren't needed and a few variables that weren't being used
  • Changed the initial value of x0 to [0.5*R], which is a better initial guess for the root-finding algorithm used by fsolve.
  • Modified the Aire and dv_dh functions to handle cases where h >= R, which can cause invalid values to be passed to np.sqrt.

huangapple
  • 本文由 发表于 2023年4月4日 09:38:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75924877.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定