I am Trying to model some temperature curves with a physically informed NN (PINN).
I started solve the FOPDT first, to be able to apply it later.
function FOPDT(z)
τ, Κ, θ = z
return [T1[i] .- (1 ./ τ) .* (-T1[i] .+ Κ .* 100 .*(i .- θ)) for i in [1, 75, 130]]
end
initial_x = [1.0, 1.0, 1.0]
sol = nlsolve(FOPDT, initial_x, xtol=1e-2, ftol=1e-2, iterations=1_000_000)
sol
The temperatures at the time steps are:
0 s → 21.5 °C
75 s → 46.0 °C
130 s → 60.3 °C
But I was not able to find a static solution. Hence I used Scipy.optimize.fsolve. I tried to use
this solution as starting parameters but this also did not converge. Are there some other hints, how to solve the equation? Did I do any other mistake, e.g. in function?
T1
isn’t defined in your example.
using NonlinearSolve
function FOPDT(dz,z,p)
τ, Κ, θ = z
return dz .= [T1[i] .- (1 ./ τ) .* (-T1[i] .+ Κ .* 100 .*(i .- θ)) for i in [1, 75, 130]]
end
initial_x = [1.0, 1.0, 1.0]
prob = NonlinearProblem(FOPDT, initial_x)
sol = solve(prob, NonlinearSolve.NewtonRaphson(), abstol=1e-2)
Can you please give enough information to run this?
Hi,
I added the temperatures from the text.
function FOPDT(z)
τ, Κ, θ = z
return [T - (1 / τ) * (-T + Κ * 100 *(i - θ)) for (T, i) in zip([21.543, 46.035,60.279], [1, 75, 130])]
end
initial_x = [145.7, 66.3, 73.4] # from scipy.optimize.fsolve
sol = nlsolve(FOPDT, initial_x, xtol=1e-1, ftol=1e-2)
The result is:
Results of Nonlinear Solver Algorithm
* Algorithm: Trust-region with dogleg and autoscaling
* Starting Point: [145.7, 66.3, 73.4]
* Zero: [-7.290966107926511e11, -2.2018393026492186e9, -72.45793039799061]
* Inf-norm of residuals: 1.503362
* Iterations: 183
* Convergence: true
* |x - x'| < 1.0e-01: true
* |f(x)| < 1.0e-02: false
* Function Calls (f): 184
* Jacobian Calls (df/dx): 100
That point very much evaluates to non-zero. But can you share the SciPy code? It would take the comparison in order to see what’s different in the function.
Here is the scipy variant:
from scipy.optimize import fsolve
def f(z):
tau, kappa, theta = z
return [T-1/tau*(-T + kappa*100*(i - theta)) for T, i in zip([21.543, 46.035, 60.279], [0, 75, 130])]
tau, kappa, theta = fsolve(f, [1, 1, 1], xtol=1e-01, maxfev=100_000)
A solution was only found with adding the xtol parameter and setting it to: 1e-1. I don’t know how much to trust the result.
Well that’s easy to check:
>>> def f(z):
... tau, kappa, theta = z
... return [T-1/tau*(-T + kappa*100*(i - theta)) for T, i in zip([21.543, 46.035, 60.279], [0, 75, 130])]
...
>>> tau, kappa, theta = fsolve(f, [1, 1, 1], xtol=1e-01, maxfev=100_000)
>>> f([tau, kappa, theta])
[3360.9606761659174, -27.294401084985765, -2515.757097939305]
It’s also not a zero in the Python code.
Strange. But I assume I did a mistake in the formula.
In addition, I solved the solution for cooling phase and than for the heating phase.
Cooling:
def f_off(z):
_tau = z[0]
def k(c: float):
return c + 273.15
return [dT + k(T)/_tau for dT, T in zip([-0.2425,], [76.006,] )]
r = fsolve(f_off, [1.0,], xtol=1e-6, maxfev=1000_000)
Heating:
def f_on(z):
_tau = 1439.818557
_kappa, _theta = z
def k(c: float):
return c + 273.15
return [dT + 1/_tau*(T + _kappa*100*(_theta -i)) for dT, T, i in zip([0.279, 0.3065], [46.035, 60.279], [75, 130])]
kappa, theta = fsolve(f_on, [66, 73], xtol=5e-00, maxfev=1000_000)
I got:
tau = 1439.818557,
kapp = 0.0097885
theta = 72.93
Again no solution found in the Julia. Should I try another library? Which?
I did a bug fix and compared the python and the julia solution.
Both are stable and results are the same with:
function FOPDT_off(z)
τ = z[1]
k(c) = c + 273.15
return [dT + k(T) / τ for (dT, T) in zip([-0.2425,], [76.006,])]
end
function FOPDT_on(z)
τ = 1439.8
Κ, θ = z
k(c) = c + 273.15
return [dT + (1 / τ) * (k(T) + Κ * 100 *(θ -i)) for (dT, T, i) in zip(
[0.279, 0.3065],
[46.035,60.279],
[75, 130])]
end
The solutions are: τ=1439.8, Κ=0.009788, θ=-661.4 .
1 Like