I am basically building a general tool for solving for the operating point of a pump in a system - i.e., two equations and two unknowns - pump curve/system curve and head (H
) and flowrate (Q
).
My posted example is not purely MWE, but is grouped in 3 sections and is easy to follow.
First is the imports and symbols.
Second is the pump curve fit (in case it is relevant to being one of the 'equations').
Third is the class and its use (where the problem is I believe).
import pint
u = pint.UnitRegistry()
from sympy import *
from sympy.solvers import solve
from sympy import Symbol, symbols, Eq
m, n = symbols('m n')
Q, H = symbols('Q H')
m = m*u.foot
n = n*u.foot**2
import numpy as np
globalPi = np.pi
import os
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
# =========================================
# =========================================
# https://www.askpython.com/python/examples/curve-fitting-in-python
# Red Lion RL-SWJ100 @ 5' lift
x_data = np.array([ 17.3, 17, 12.9, 8.5, 4.4 ])
y_data = np.array([ 20, 30, 40, 50, 60])
plt.scatter(x_data , y_data)
plt.show()
#Defining our function
#def fit_f(x,a,b,c,d):
def fit_f(x,a,b,c):
# return a*(x-b)**2+c+d*0.0001*np.cos(x)
return a*(x-b)**2+c
#using our curve_fit() function
#popt, pcov = curve_fit(fit_f,x_data,y_data,p0=[1,2,-16,1])
popt, pcov = curve_fit(fit_f,x_data,y_data,p0=[1,2,6])
print(popt)
print(pcov)
#a_opt, b_opt, c_opt, d_opt = popt
a_opt, b_opt, c_opt = popt
x_model = np.linspace(min(x_data), max(y_data), 100)
#y_model = fit_f(x_model, a_opt, b_opt, c_opt,d_opt)
y_model = fit_f(x_model, a_opt, b_opt, c_opt)
plt.scatter(x_data, y_data)
plt.plot(x_model, y_model, color='r')
plt.title("title")
plt.xlabel('Q')
plt.ylabel('H')
plt.xlim(0,30)
plt.ylim(0,80)
fit_f(10,a_opt,b_opt,c_opt)
fit_f(Q,a_opt,b_opt,c_opt)
# =========================================
# =========================================
class Problem:
name = "system_curve"
def __init__(self, e):
self.e = e
def pumpHeadNeededWithExtraHead(self):
def pumpHeadNeeded():
print("Extra head (loss or gain) is: ", self.e)
# eq1 = Eq(Q**2 - 3*H,0)
# eq2 = Eq(Q - 2*H**2,4)
eq1 = Eq( m**2 , n )
eq2 = Eq(-m**2 - n , 3*u.foot**2)
# tmp = solve([eq1, eq2],Q,H)
tmp = solve([eq1, eq2],m,n)
print( N( tmp[1][0] ,4) )
self.height = tmp[0]*u.foot
return self.height
self.pumpHeadNeeded = pumpHeadNeeded
return pumpHeadNeeded
a = Problem(0*u.foot)
a.pumpHeadNeededWithExtraHead()()
The equations with Q & H have no units and can be solved easily.
The equations that are commented (x has units ft, y has units of ft**2) have each term dimensionally consistent.
The output from Spyder (though I am using Jupyter too) is;
runfile('C:/untitled0.py', wdir='C:/')
[-0.07771575 -6.6559499 69.03248368]
[[ 1.41000834e-02 -3.23123342e+00 4.11231816e+00]
[-3.23123342e+00 7.47431731e+02 -9.62567370e+02]
[ 4.11231816e+00 -9.62567370e+02 1.26208086e+03]]
Extra head (loss or gain) is: 0 foot
Traceback (most recent call last):
File "C:\Users\name\Anaconda3\Libsite-packages\sympy\multipledispatch\dispatcher.py", line 234, in __call__
func = self._cache[types]
KeyError: (<class 'pint.quantity.build_quantity_class.<locals>.Quantity'>, <class 'pint.quantity.build_quantity_class.<locals>.Quantity'>)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\untitled0.py", line 104, in <module>
a.pumpHeadNeededWithExtraHead()()
File "C:\untitled0.py", line 90, in pumpHeadNeeded
eq1 = Eq( m**2 , n )
File "C:\Users\name\Anaconda3\Lib\site-packages\sympy\core\relational.py", line 506, in __new__
val = is_eq(lhs, rhs)
File "C:\Users\name\Anaconda3\Lib\site-packages\sympy\core\relational.py", line 1362, in is_eq
retval = _eval_is_eq(lhs, rhs)
File "C:\Users\name\Anaconda3\Lib\site-packages\sympy\multipledispatch\dispatcher.py", line 238, in __call__
raise NotImplementedError(
NotImplementedError: Could not find signature for _eval_is_eq: <Quantity, Quantity>
If the three hash marks are traded to the other equations, it runs just fine on my laptop.
Thanks!