import numpy as np
import matplotlib.pyplot as plt
from neurodiffeq import diff
from neurodiffeq.solvers import Solver1D
from neurodiffeq.conditions import DirichletBVP
from neurodiffeq.networks import FCNN, SinActv
def ode_system(Cplus, Cminus, Ca, Phi, y):
dCplus_dy = diff(Cplus, y)
dCminus_dy = diff(Cminus, y)
dCa_dy = diff(Ca, y)
dPhi_dy = diff(Phi, y)
d2Cplus_dy2 = diff(dCplus_dy, y)
d2Cminus_dy2 = diff(dCminus_dy, y)
d2Ca_dy2 = diff(dCa_dy, y)
d2Phi_dy2 = diff(dPhi_dy, y)
eq1 = -V0 * dCplus_dy - diff(Cplus * dPhi_dy, y) - d2Cplus_dy2
eq2 = -V0 * dCminus_dy - diff(-Cminus * dPhi_dy, y) - d2Cminus_dy2
eq3 = -ALPHA * V0 * dCa_dy - diff(-ZA * Ca * dPhi_dy, y) - d2Ca_dy2
eq4 = NU * d2Phi_dy2 - (Cplus - Cminus - ZA * Ca)
return [eq1, eq2, eq3, eq4]
def _boundary_cond(DELTA_V):
cond_a = DirichletBVP(t_0=0, u_0=P, t_1=1, u_1=1.0)
cond_b = DirichletBVP(t_0=0, u_0=0.0, t_1=1, u_1=0.0)
cond_c = DirichletBVP(t_0=0, u_0=0.0, t_1=1, u_1=0.0)
cond_d = DirichletBVP(t_0=0, u_0=0.0, t_1=1, u_1=DELTA_V)
return [cond_a, cond_b, cond_c, cond_d]
N = 500
V0 = 50.0
NU = 1e-4
DELTA_V = 10.0
ZA = 1.0
ALPHA = 1.0
CA0 = 1e-2
P = 1.0
nets = [FCNN(hidden_units=(32, 32), actv=SinActv) for _ in range(4)]
solver = Solver1D(ode_system, _boundary_cond(DELTA_V), t_min=0.0, t_max=1.0, nets=nets)
solver.fit(max_epochs=N)
solution = solver.get_solution()
t = np.linspace(0.0, 1.0, N)
Cplus, Cminus, Ca, Phi = solution(t, to_numpy=True)
fig, axs = plt.subplots(1, 2)
axs[0].plot(t, Cplus, label="C+")
axs[0].plot(t, Cminus, label="C-")
axs[0].plot(t, Ca, label="Ca")
axs[1].plot(t, Phi, label='Phi')
axs[0].legend()
axs[1].legend()
plt.show()
aW1wb3J0IG51bXB5IGFzIG5wCmltcG9ydCBtYXRwbG90bGliLnB5cGxvdCBhcyBwbHQKZnJvbSBuZXVyb2RpZmZlcSBpbXBvcnQgZGlmZgpmcm9tIG5ldXJvZGlmZmVxLnNvbHZlcnMgaW1wb3J0IFNvbHZlcjFECmZyb20gbmV1cm9kaWZmZXEuY29uZGl0aW9ucyBpbXBvcnQgRGlyaWNobGV0QlZQCmZyb20gbmV1cm9kaWZmZXEubmV0d29ya3MgaW1wb3J0IEZDTk4sIFNpbkFjdHYKCgpkZWYgb2RlX3N5c3RlbShDcGx1cywgQ21pbnVzLCBDYSwgUGhpLCB5KToKICAgIGRDcGx1c19keSA9IGRpZmYoQ3BsdXMsIHkpCiAgICBkQ21pbnVzX2R5ID0gZGlmZihDbWludXMsIHkpCiAgICBkQ2FfZHkgPSBkaWZmKENhLCB5KQogICAgZFBoaV9keSA9IGRpZmYoUGhpLCB5KQoKICAgIGQyQ3BsdXNfZHkyID0gZGlmZihkQ3BsdXNfZHksIHkpCiAgICBkMkNtaW51c19keTIgPSBkaWZmKGRDbWludXNfZHksIHkpCiAgICBkMkNhX2R5MiA9IGRpZmYoZENhX2R5LCB5KQogICAgZDJQaGlfZHkyID0gZGlmZihkUGhpX2R5LCB5KQoKICAgIGVxMSA9IC1WMCAqIGRDcGx1c19keSAtIGRpZmYoQ3BsdXMgKiBkUGhpX2R5LCB5KSAtIGQyQ3BsdXNfZHkyCiAgICBlcTIgPSAtVjAgKiBkQ21pbnVzX2R5IC0gZGlmZigtQ21pbnVzICogZFBoaV9keSwgeSkgLSBkMkNtaW51c19keTIKICAgIGVxMyA9IC1BTFBIQSAqIFYwICogZENhX2R5IC0gZGlmZigtWkEgKiBDYSAqIGRQaGlfZHksIHkpIC0gZDJDYV9keTIKICAgIGVxNCA9IE5VICogZDJQaGlfZHkyIC0gKENwbHVzIC0gQ21pbnVzIC0gWkEgKiBDYSkKCiAgICByZXR1cm4gW2VxMSwgZXEyLCBlcTMsIGVxNF0KCgpkZWYgX2JvdW5kYXJ5X2NvbmQoREVMVEFfVik6CiAgICBjb25kX2EgPSBEaXJpY2hsZXRCVlAodF8wPTAsIHVfMD1QLCB0XzE9MSwgdV8xPTEuMCkKICAgIGNvbmRfYiA9IERpcmljaGxldEJWUCh0XzA9MCwgdV8wPTAuMCwgdF8xPTEsIHVfMT0wLjApCiAgICBjb25kX2MgPSBEaXJpY2hsZXRCVlAodF8wPTAsIHVfMD0wLjAsIHRfMT0xLCB1XzE9MC4wKQogICAgY29uZF9kID0gRGlyaWNobGV0QlZQKHRfMD0wLCB1XzA9MC4wLCB0XzE9MSwgdV8xPURFTFRBX1YpCiAgICByZXR1cm4gW2NvbmRfYSwgY29uZF9iLCBjb25kX2MsIGNvbmRfZF0KCgpOID0gNTAwClYwID0gNTAuMApOVSA9IDFlLTQKREVMVEFfViA9IDEwLjAKWkEgPSAxLjAKQUxQSEEgPSAxLjAKQ0EwID0gMWUtMgpQID0gMS4wCgpuZXRzID0gW0ZDTk4oaGlkZGVuX3VuaXRzPSgzMiwgMzIpLCBhY3R2PVNpbkFjdHYpIGZvciBfIGluIHJhbmdlKDQpXQpzb2x2ZXIgPSBTb2x2ZXIxRChvZGVfc3lzdGVtLCBfYm91bmRhcnlfY29uZChERUxUQV9WKSwgdF9taW49MC4wLCB0X21heD0xLjAsIG5ldHM9bmV0cykKc29sdmVyLmZpdChtYXhfZXBvY2hzPU4pCnNvbHV0aW9uID0gc29sdmVyLmdldF9zb2x1dGlvbigpCgp0ID0gbnAubGluc3BhY2UoMC4wLCAxLjAsIE4pCkNwbHVzLCBDbWludXMsIENhLCBQaGkgPSBzb2x1dGlvbih0LCB0b19udW1weT1UcnVlKQoKZmlnLCBheHMgPSBwbHQuc3VicGxvdHMoMSwgMikKYXhzWzBdLnBsb3QodCwgQ3BsdXMsIGxhYmVsPSJDKyIpCmF4c1swXS5wbG90KHQsIENtaW51cywgbGFiZWw9IkMtIikKYXhzWzBdLnBsb3QodCwgQ2EsIGxhYmVsPSJDYSIpCmF4c1sxXS5wbG90KHQsIFBoaSwgbGFiZWw9J1BoaScpCmF4c1swXS5sZWdlbmQoKQpheHNbMV0ubGVnZW5kKCkKcGx0LnNob3coKQo=