I want to solve the following set of 3 coupled pdes in python using fipy
∇2n − (∇2ψ)n − (∇ψ).∇n = n/10,
∇2p + (∇2ψ)p + (∇ψ).∇p = p/10,
∇2ψ = −(p − n)
The variables are p,n and ψ. As can be seen from the first and second equation, the first term can be set as the diffusion term in the pde solver in fipy. If the other terms of the first and second equation are to be incorporated in the fipy pde solver, I suppose that they should be incorporated in the Implicit Source Term in fipy. But considering the presence of vector identities in these terms, I am facing some difficulty in incorporating these equations in the fipy pde solver. Any help regarding this would be appreciated.
Assuming the instances of 2 that appear in your equations are squaring of the nabla (del) operator, you certainly can write for the first equation:
DiffusionTerm(var=n) - ImplicitSourceTerm(coeff=psi.faceGrad.divergence, var=n) - psi.grad.dot(n.grad) == ImplicitSourceTerm(coeff=1./10, var=n)
however, this is not a very implicit representation.
Better is to apply the chain rule:
$\nabla (n \nabla \psi) \equiv \nabla n \cdot \nabla \psi + n \nabla^2 \psi$
such that
$\nabla^2 n - \nabla(n \nabla psi) == n / 10$
This is then
DiffusionTerm(var=n) - DiffusionTerm(coeff=n, var=psi) == ImplicitSourceTerm(coeff=1./10, var=n)
if you wish to couple your equations, and
DiffusionTerm(var=n) - ConvectionTerm(coeff=psi.faceGrad, var=n) == ImplicitSourceTerm(coeff=1./10, var=n)
if you don't.
Related
I cannot figure out how to solve this separable differential equation using sympy. Help would be greatly appreciated.
y′=(y−4)(y−2),y(0)=5
Here was my attempt, thanks in advance!!!
import sympy as sp
x,y,t = sp.symbols('x,y,t')
y_ = sp.Function('y_')(x)
diff_eq = sp.Eq(sp.Derivative(y_,x), (y-4)*(y-2))
ics = {y_.subs(x,0):5}
sp.dsolve(diff_eq, y_, ics = ics)
the output is y(x) = xy^2 -6xy +8x + 5
The primary error is the introduction of y_. This makes the variable y a constant parameter of the ODE and you get the wrong solution.
If you correct this you get an error of "too many solutions for the integration constant". This is a bug caused by not simplifying the integration constant after it first occurs. So multiplication and addition of constants should just be absorbed, an additive constant in an exponent should become a multiplicative factor for the exponential. As it is, exp(2*C_1)==3 has two solutions if C_1 is considered as an angle (it's a bit of tortured logic from computing roots in the complex plane).
The newer versions can actually solve this fully if you give the third hint in the classification list 'separable', '1st_exact', '1st_rational_riccati', ... that does something different than partial fraction decomposition of the first two
from sympy import *
x = Symbol('x')
y = Function('y')(x)
dsolve(Eq(y.diff(x), (y-2)*(y-4)),y,
ics={y.subs(x,0):5},
hint='1st_rational_riccati')
returning
\displaystyle y{\left(x \right)} = \frac{2 \cdot \left(6 - e^{2 x}\right)}{3 - e^{2 x}}
I'm attempting to implement the solution given to this question I recently posed over on Math SE. I'll recreate the relevant details here.
I have a system consisting of equations of the form:
Here, c, a_ir, and the vectors p_r are knowns. The vectors x0 and v, as well as the ti's are unknown. Further, T and R are known, but will vary (i.e. cannot be hard-coded).
I'm most familiar with the symbolic manipulation and solution of such systems, as well as the SymPy package, so I began there. Unfortunately, as it turns out, perhaps not surprisingly SymPy's solvers aren't well-suited for such a problem. As the knowns in question will come from real-world experimental data, a solution(s) may only be obtained numerically, and SymPy offers only one numerical solver, nsolve(), which chocked up quickly.
I'd like to translate what I've done in SymPy to something compatible with SciPy, which offers far more flexibility and a host of linear and nonlinear solvers. Unfortunately, I'm not terribly familiar with SciPy, and it isn't clear to me how the very symbolic expressions I have in SymPy can be translated to SciPy.
Here's what I have thus far (admittedly, its a fairly crude first-draft):
T = 10; R = 3
x,y,z, vx,vy,vz = sp.symbols('x,y,z, vx,vy,vz', real=True)
collection = sp.symbols(" ".join(f"t{x}" for x in range(T)), real=True)
#dataclass
class Vertexer:
receivers: list
def find(self, data):
eqs = []
for r in range(R):
for i in range(T):
eqs.append(sp.Eq(c**2 * (data[r][i] - collection[i])**2, (vx**2 + vy**2 + vz**2) * (collection[i] - collection[0])**2 + 2 * (collection[i] - collection[0]) * (vx * (x - self.receivers[r][0]) + vy * (y - self.receivers[r][1]) + vz * (z - self.receivers[r][2])) + ((x - self.receivers[r][0])**2 + (y - self.receivers[r][1])**2 + (z - self.receivers[r][2])**2)))
print(sp.nsolve(eqs, (x,y,z,vx,vy,vz) + collection))
Here, data is a list containing R lists of size T, which in turn contain the air'S. Eventually, T and R would be determined by the size of this matrix, not hard coded as done here. receivers is a list containing R lists, which represent the vector components of the pr's (e.g. [[p1x, p1y, p1z], [p2x, ...).
I'm not sure where to begin translating this to something workable in SciPy. For one, here I "dynamically" generate symbols for the unknowns t_1, t_2,.... t_T, in addition to a number of other unknowns (vx, vy, x, etc). I'm not sure how one would translate this symbolic expression with a potentially large, dynamic number of symbolic unknowns.
If I could simply rewrite the expression as something compatible with the SciPy solvers, moving forward with solving it should be fairly trivial.
How can this be approached?
I'm trying to solve a non-linear PDE HJB equation using FiPy, but i have some difficulties translating the PDE into the proper FiPy syntax:
I tried something like :
eqX = TransientTerm() == -DiffusionTerm(coeff=1) + (phi.faceGrad * phi.faceGrad)
and It doesn't work because of the square of the gradient
My equation: (du/dt = - \delta u + ||\grad(u)||^2)
Does FiPy allow to solve this kind of equations? if not is there a package or a way to solve it using finite difference ?
Thank you!
It's possible to recast the final term to be a diffusion term and a source term so that the equation can be rewritten as,
eqn = TransientTerm() = DiffusionTerm(u - 1) - u * u.faceGrad.divergence
That won't give an error, but might not be very stable
I have a question from school to simulate pendulum motion based on taylor series expansion.
Angular frequency d 2 θ d t 2 = − m G R I sin ( θ )
I am quite new to python. I know now how to simulate using Euler's method.
for n in range(N_t):
u[n+1] = u[n] + dt*v[n]
v[n+1] = v[n] + dt*(m*g*r/I)*sin(u[n])
How can I simulate it using taylor expansion?
Should I run it the code only as below?
f′′(x0) = 2a2
In the equation u''=f(u) you get higher order derivatives by deriving this equation by applying chain and product rule and substituting back the ODE for all second derivatives of u. The values of u and u' are taken from the current state vector.
u''' = f'(u)u'
u^{(4)} = f''(u)*u'^2 + f'(u)*u''
= f''(u)*u'^2 + f'(u)*f(u)
u^{(5)} = f'''(u)*u'^3 + 3f''(u)*u'*f(u) + f'(u)^2*u'
There is also a systematic way using Taylor series arithmetics of automatic/algorithmic differentiation.
(2022/06/29) To solve x''=-sin(x) -- the constant factors become trivial by rescaling the time -- via Taylor series anywhere, reformulate this as system
x'=y
y'=-v
u=cos(x) ==> u' = -v*y
v=sin(x) ==> v' = u*y
the last two via the trigonometric derivatives and the chain rule. Comparing coefficients left and right results in coupled incremental formulas for the coefficients of the Taylor series of all variables, with x(t0)=x0, y(t0)=y0, u(t0)=cos(x0), v(t0)=sin(x0).
I assume you meant this from your code,
I also assume that u := θ and v := θ'.
So, the Taylor expansion of sin(x) is
and your equation is now
So, you can calculate u and v from the above equation. Or, I don't know if your teacher wanted you to calculate the integrals first and then use Taylor series.
I am working on implementing the Alternating direction implicit method to solve FitzHugh–Nagumo reaction diffusion model. I have found a Python implementation example for it in a blog, but I think there is an error in the method - in the stencil presented here:
Shouldn't it be half time step size multiplying the reaction term f ?
Replacing the difference quotients by the differential quotients, one gets
U_t = D/2 * U_xx + D/2 * U_yy + Δt*f
in both instances, which is not the equation
U_t = D * (U_xx + U_yy) + f
that was the originally posed task.
So the coefficients should be 1/(Δt/2) as it was at U_t, D/(Δp^2) at U_pp, p=x,y and 1 for f.
It seems the formula is a mix-up of the one with difference quotients and the next stage where it gets multiplied by Δt/2.
And in that next formula one does not need new constants as indeed α_p=σ_p, p=x,y and then you are right that the factor of f should be Δt/2.