I am trying to solve a system of fourth-order differential equations using Sympy. The equations I have used are shown in the image, and written in the code below:
latex_equations :
from sympy import *
x = symbols('x')
EI1,EI2,EI3,a1,a2,a3,Qh,Mecc = symbols('EI1 EI2 EI3 a1 a2 a3 Qh Mecc')
u1,u2,u3 = symbols('u1 u2 u3', cls=Function)
eq = (Eq(EI1*diff(u1(x),x,x,x,x)+EI2*diff(u2(x),x,x,x,x)+EI3*diff(u3(x),x,x,x,x), Qh),Eq(a1*EI1*diff(u1(x),x,x,x,x)+a2*EI2*diff(u2(x),x,x,x,x)+a3*EI3*diff(u3(x),x,x,x,x),Mecc),Eq((u1(x)+u3(x))/2,u2(x)))
dsolve(eq)
And I received the following error:
AttributeError Traceback (most recent call last)
<ipython-input-1-63c42d2751be> in <module>
6 eq = (Eq(EI1*diff(u1(x),x,x,x,x)+EI2*diff(u2(x),x,x,x,x)+EI3*diff(u3(x),x,x,x,x), Qh),Eq(a1*EI1*diff(u1(x),x,x,x,x)+a2*EI2*diff(u2(x),x,x,x,x)+a3*EI3*diff(u3(x),x,x,x,x),Mecc),Eq((u1(x)+u3(x))/2,u2(x)))
7
----> 8 dsolve(eq)
~\Anaconda3\lib\site-packages\sympy\solvers\ode.py in dsolve(eq, func, hint, simplify, ics, xi, eta, x0, n, **kwargs)
583 """
584 if iterable(eq):
--> 585 match = classify_sysode(eq, func)
586 eq = match['eq']
587 order = match['order']
~\Anaconda3\lib\site-packages\sympy\solvers\ode.py in classify_sysode(eq, funcs, **kwargs)
1528 if isinstance(func, list):
1529 for func_elem in func:
-> 1530 if len(func_elem.args) != 1:
1531 raise ValueError("dsolve() and classify_sysode() work with "
1532 "functions of one variable only, not %s" % func)
AttributeError: 'list' object has no attribute 'args'
I tried to solve for a simpler system of equations using dsolve, and it solved fine:
from sympy import *
x = symbols('x')
EI1,EI2 = symbols('EI1 EI2')
u1,u2 = symbols('u1 u2', cls=Function)
eq = (Eq(EI1*diff(u1(x),x), 12*x*u1(x) + 8*u2(x)), Eq(EI2*diff(u2(x),x), 21*u1(x) + 7*x*u2(x)))
dsolve(eq)
The format I used for these two cases is the same, yet one solves and one fails. I know that the first system of equations has a solution, because I have solved for it in Maple.
Have I made an error in my code, or is Sympy dsolve simply not able to solve such a complex system of equations? Is there a limitation to how complex the system of equations may be until dsolve can no longer solve it? Any help or insight into this problem would greatly be appreciated.
Thank you!
SymPy's ODE systems code needs a lot of work and can't currently handle this kind of system.
Firstly the third equation is an algebraic equation (meaning that this is really a DAE rather than ODE system) but that's not a huge problem: just differentiate it 4 times. Then SymPy should really be able to solve the resulting system but unfortunately can't because it's not implemented yet. You can do it yourself manually though:
# Your code first:
from sympy import *
x = symbols('x')
EI1,EI2,EI3,a1,a2,a3,Qh,Mecc = symbols('EI1 EI2 EI3 a1 a2 a3 Qh Mecc')
u1,u2,u3 = symbols('u1 u2 u3', cls=Function)
eq = (Eq(EI1*diff(u1(x),x,x,x,x)+EI2*diff(u2(x),x,x,x,x)+EI3*diff(u3(x),x,x,x,x), Qh),Eq(a1*EI1*diff(u1(x),x,x,x,x)+a2*EI2*diff(u2(x),x,x,x,x)+a3*EI3*diff(u3(x),x,x,x,x),Mecc),Eq((u1(x)+u3(x))/2,u2(x)))
# Differentiate eq3 4 times:
eq1, eq2, eq3 = eq
eq3 = Eq(eq3.lhs.diff(x, 4).doit(), eq3.rhs.diff(x, 4).doit())
eq = eq1, eq2, eq3
# Isolate equations for u1(x).diff(x, 4) etc
derivs = [u(x).diff(x, 4) for u in (u1, u2, u3)]
(sol,) = solve(eq, derivs, dict=True)
eq = [Eq(du, sol[du]) for du in derivs]
# Each can be solved separately:
for e in eq:
pprint(dsolve(e))
This gives the solutions:
4
2 3 x ⋅(EI₂⋅Mecc - EI₂⋅Qh⋅a₂ + 2⋅EI₃⋅Mecc - 2⋅EI₃⋅Qh⋅a₃)
u₁(x) = C₁ + C₂⋅x + C₃⋅x + C₄⋅x + ────────────────────────────────────────────────────────────────────────────────────
24⋅(EI₁⋅EI₂⋅a₁ - EI₁⋅EI₂⋅a₂ + 2⋅EI₁⋅EI₃⋅a₁ - 2⋅EI₁⋅EI₃⋅a₃ + EI₂⋅EI₃⋅a₂ - EI₂⋅EI₃⋅a₃)
4
2 3 x ⋅(-EI₁⋅Mecc + EI₁⋅Qh⋅a₁ + EI₃⋅Mecc - EI₃⋅Qh⋅a₃)
u₂(x) = C₁ + C₂⋅x + C₃⋅x + C₄⋅x + ────────────────────────────────────────────────────────────────────────────────────
24⋅(EI₁⋅EI₂⋅a₁ - EI₁⋅EI₂⋅a₂ + 2⋅EI₁⋅EI₃⋅a₁ - 2⋅EI₁⋅EI₃⋅a₃ + EI₂⋅EI₃⋅a₂ - EI₂⋅EI₃⋅a₃)
4
2 3 x ⋅(-2⋅EI₁⋅Mecc + 2⋅EI₁⋅Qh⋅a₁ - EI₂⋅Mecc + EI₂⋅Qh⋅a₂)
u₃(x) = C₁ + C₂⋅x + C₃⋅x + C₄⋅x + ────────────────────────────────────────────────────────────────────────────────────
24⋅(EI₁⋅EI₂⋅a₁ - EI₁⋅EI₂⋅a₂ + 2⋅EI₁⋅EI₃⋅a₁ - 2⋅EI₁⋅EI₃⋅a₃ + EI₂⋅EI₃⋅a₂ - EI₂⋅EI₃⋅a₃)
Note though that the integration constants for each should be different so C1 in the first equation is not the same as C2 in the second. The ODE system should have 12 different integration constants. Actually though since this is a DAE system then there should be 8 independent constants since there is an algebraic relationship between the three dependent variables.
EDIT: In SymPy 1.8 the dsolve
function can now solve this provided the 3rd equation is differentiated:
In [67]: # Your code first:
...: from sympy import *
...: x = symbols('x')
...: EI1,EI2,EI3,a1,a2,a3,Qh,Mecc = symbols('EI1 EI2 EI3 a1 a2 a3 Qh Mecc')
...: u1,u2,u3 = symbols('u1 u2 u3', cls=Function)
...:
...: eq = (Eq(EI1*diff(u1(x),x,x,x,x)+EI2*diff(u2(x),x,x,x,x)+EI3*diff(u3(x),x,x,x,x), Qh),Eq(a1*EI1*diff(u1(x),x,x,x,x)+a2*EI2*diff(u2(x),x,x,x,x)+a3*EI3
...: *diff(u3(x),x,x,x,x),Mecc),Eq((u1(x)+u3(x))/2,u2(x)))
...:
...: # Differentiate eq3 4 times:
...: eq1, eq2, eq3 = eq
...: eq3 = Eq(eq3.lhs.diff(x, 4).doit(), eq3.rhs.diff(x, 4).doit())
...: eq = eq1, eq2, eq3
In [68]: dsolve(eq)
Out[68]:
⎡ 2 3 4 2 3 4
⎢ C₃⋅x C₄⋅x x ⋅(EI₂⋅(Mecc - Qh⋅a₂) + 2⋅EI₃⋅(Mecc - Qh⋅a₃)) C₇⋅x C₈⋅x x ⋅(EI₁⋅(M
⎢u₁(x) = C₁ + C₂⋅x + ───── + ───── + ──────────────────────────────────────────────────────────────, u₂(x) = C₅ + C₆⋅x + ───── + ───── - ───────────────────
⎣ 2 6 24⋅(EI₁⋅(EI₂⋅(a₁ - a₂) + 2⋅EI₃⋅(a₁ - a₃)) + EI₂⋅EI₃⋅(a₂ - a₃)) 2 6 24⋅(EI₁⋅(EI₂⋅(a₁ -
2 3 4 ⎤
ecc - Qh⋅a₁) - EI₃⋅(Mecc - Qh⋅a₃)) C₁₁⋅x C₁₂⋅x x ⋅(2⋅EI₁⋅(Mecc - Qh⋅a₁) + EI₂⋅(Mecc - Qh⋅a₂)) ⎥
───────────────────────────────────────────, u₃(x) = C₁₀⋅x + ────── + ────── + C₉ - ──────────────────────────────────────────────────────────────⎥
a₂) + 2⋅EI₃⋅(a₁ - a₃)) + EI₂⋅EI₃⋅(a₂ - a₃)) 2 6 24⋅(EI₁⋅(EI₂⋅(a₁ - a₂) + 2⋅EI₃⋅(a₁ - a₃)) + EI₂⋅EI₃⋅(a₂ - a₃))⎦