0

Firstly, can I plot something that I have declared as function? Because I'm getting loads of errors but it doesn't show where in my code the error is coming from e.g.:

import sympy as sy

rho = 1000 # Density of water [kg/m3]
A = 1.0 # Cross-sectional area of tank [m2]
c = 50 # Valve constant [kg/s per opening percent]
o = 100 # Percent valve opening 

h = sy.Function('h')
t = sy.symbols('t')

m_bal = sy.Eq(h(t).diff(t),c/(rho*A)*o)
gen_sol = sy.dsolve(m_bal,h(t))
C = gen_sol.subs([(t,0),(h(0),0)])
sol = gen_sol.subs([(C.rhs,C.lhs)])
sy.plot(t,h)

Then I get:

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-54-7aa8880d452a> in <module>()
     14 C = gen_sol.subs([(t,0),(h(0),0)])
     15 sol = gen_sol.subs([(C.rhs,C.lhs)])
---> 16 sy.plot(t,h)

~\Anaconda3\lib\site-packages\sympy\plotting\plot.py in plot(*args, **kwargs)
   1288     show = kwargs.pop('show', True)
   1289     series = []
-> 1290     plot_expr = check_arguments(args, 1, 1)
   1291     series = [LineOver1DRangeSeries(*arg, **kwargs) for arg in plot_expr]
   1292 

~\Anaconda3\lib\site-packages\sympy\plotting\plot.py in check_arguments(args, expr_len, nb_of_free_symbols)
   1791 
   1792         exprs = args[:i]
-> 1793         assert all(isinstance(e, Expr) for expr in exprs for e in expr)
   1794         free_symbols = list(set().union(*[e.free_symbols for expr in exprs
   1795                                         for e in expr]))

AssertionError: 

Secondly, I want to plot that for t = 0s to t = 10s and I only want o = 100 for t = [2,7]. I have done this but I don't know where I'm going wrong:

import sympy as sy
sy.init_printing()

rho = 1000 # Density of water [kg/m3]
A = 1.0 # Cross-sectional area of tank [m2]
c = 50 # Valve constant [kg/s per opening percent]
o = 100

h = sy.Function('h')
t = sy.symbols('t')

m_bal = sy.Eq(h(t).diff(t),c/(rho*A)*o)
gen_sol = sy.dsolve(m_bal,h(t))
C = gen_sol.subs([(t,0),(h(0),0)])
sol = gen_sol.subs([(C.rhs,C.lhs)])
sy.plot(t,h)

Can I do this on sympy or do I have to use matplotlib and numpy and do:

o= np.zeros(100) # % Valve opening 
o[21:70] = 100 # % opening at times 2s to 7s

1 Answer 1

1

sy.plot(t, h) is problematic for multiple reasons. First, in SymPy's plot the function comes before the variable: for example, sy.plot(t**2, (t, 0, 3)).

Second, nothing you did with the ODE had any impact on t or h. You are just trying to plot something with sy.Function('h') with no indication of what h is. SymPy objects do not mutate; unless you assign something to h, it's not going to change.

The attempt to enforce the initial condition also looks strange. In the current version of SymPy (1.2) the initial conditions can be imposed by dsolve itself. This is how I would solve and plot the solution:

sol = sy.dsolve(m_bal, h(t), ics={h(0): 0})
sy.plot(sol.rhs, (t, 0, 3))
Sign up to request clarification or add additional context in comments.

2 Comments

When I use ics={} and then print the solution, the integration constant is still not replaced by a value. But when I plot it, it takes the initial condition into account. How can I replace that constant? And thanks for your help btw
That's why I wrote "In the current version of SymPy (1.2)". In an older version such as yours, refer to stackoverflow.com/questions/41192748

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.