How to solve a thermal model? NEED HELP!!
67 views (last 30 days)
Show older comments
Hi everyone,
I'm working on a transient thermal analysis using a thermal network model in MATLAB, and I'm encountering an issue I can't quite resolve. I want to solve this energy balance:





System Description:
The model consists of 16 nodes, where node 16 represents ambient air. Internal heat is generated at various nodes (1–15), and heat can only exit the system through node 15, which is thermally connected to the ambient (heat sink). The goal is to simulate temperature evolution over time in this network.
Model Setup:
S – a [16×16] thermal conductance matrix, including node 16.
S_eff – the [15×15] reduced matrix, excluding the ambient node.
Q_gen – a [15×1] vector of internal heat generation values.
MC – a [15×1] vector of thermal capacities (mass × specific heat) for nodes 1–15.
G_air – a [15×1] vector, where G_air(i) = 1 / R_i-amb, modeling conductance to ambient.
T_air – a fixed ambient temperature (293.15 K).
Transient Solver:
I'm using a forward Euler integration scheme. My understanding is that the term G_air .* (T_air) captures the heat leaving each node to the environment (with the only non-zero value corresponding to node 15), while -S_eff * T_nodes represents heat transfer between internal nodes. The energy balance at each time step is:
MC .* (dT/dt) = Q_gen + G_air .* (T_air) - S_eff * T
MATLAB Code:
T0 = 298.15; % Initial temperature in K (25 °C)
T_air = 293.15;
dt = 0.01; tol = 0.1; max_steps = 1e6;
T = T0 * ones(15,1); % Nodes 1–15
T_hist = T;
Q_eff = Q_gen + G_air * T_air;
time_vector = 0;
for k = 1:max_steps
dTdt = (Q_eff - S_eff * T) ./ MC;
dE = abs(dTdt .* MC);
if all(dE < tol)
fprintf('Converged at step %d (t = %.2f s)\n', k, k * dt);
break;
end
T = T + dt * dTdt;
T_hist(:, end+1) = T;
time_vector(end+1) = k * dt;
end
Problem:
The steady-state solution, calculated as:
T_nodes = S_eff \ (Q_gen + G_air * T_air);
returns a physically reasonable result (e.g., ~174°C). However, the transient solution diverges downward, reaching unrealistic values (e.g., −157°C), as if the system were cooling despite internal heating.
![node 14 [C]](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1832113/node%2014%20[C].jpeg)
I’ve attached my simulation results and input matrices in case they’re helpful. If anyone can spot what’s going wrong or has suggestions on better practices for transient simulation in MATLAB, I’d really appreciate it!
Thanks so much in advance!
4 Comments
Torsten
on 16 Apr 2025
I guess your ODEs for T_i are stiff, and you use an explicit integration method (Euler forward). Did you try a smaller time step ?
Accepted Answer
Torsten
on 17 Apr 2025 at 20:58
Edited: Torsten
on 18 Apr 2025 at 0:00
Params = load('Params.mat');
S_matrix = load('S_matrix.mat');
MC = Params.MC;
Q = Params.Q;
S = S_matrix.S;
T0 = 298.15;
T_air = 293.15;
y0 = [T0*ones(17,1);T_air];
y0(1) = (Q(1) - S(1,3:18)*y0(3:18))/S(1,1);
y0(2) = (Q(2) - S(2,3:18)*y0(3:18))/S(2,2);
M = eye(18);
M(1,1) = 0;
M(2,2) = 0;
options = odeset('Mass',M);
tspan = [0 20000];
[T,Y] = ode15s(@(t,y)fun(t,y,MC,Q,S),tspan,y0,options);
plot(T,Y-273.15)
grid on
Y(end,1:10)-273.15
Y(end,11:18)-273.15
function dTdt = fun(t,T,MC,Q,S)
n = numel(T);
dTdt = zeros(n,1);
dTdt(1) = Q(1) - S(1,:)*T;
dTdt(2) = Q(2) - S(2,:)*T;
dTdt(3:n-1) = (Q(3:n-1) - S(3:n-1,:)*T)./MC(3:n-1);
dTdt(n) = 0;
end
9 Comments
Torsten
on 18 Apr 2025 at 21:03
Edited: Torsten
on 18 Apr 2025 at 23:52
You already set M = diag(MC).
So
dTdt = (Q - S(1:17, 1:17) * T - S(1:17, 18) * T_air) ./ MC;
has to be changed to
dTdt = Q - S(1:17, 1:17) * T - S(1:17, 18) * T_air;
Otherwise you would divide by MC.^2 (and additionally by 0 for nodes 1 and 2).
More Answers (1)
Torsten
on 16 Apr 2025
Edited: Torsten
on 16 Apr 2025
I get these curves with your equations and your data.
T0 = 298.15;
T_air = 293.15;
G_air = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 22.6305575112];
MC = [137.8208259751 591.4641353992 182.006441341 2436.9295445096 454.7099992049 640.8641472606 1679.8407170664 245.2936372241 245.2936372241 237.4649788763 237.4649788763 237.4649788763 237.4649788763 2235.552 13540.63392];
Q_gen = [359.1893251004 346.2558099057 410.9467641385 373.4019314744 48.447 0 22.0506266673 66.2445241332 66.0841062751 32.8397915689 32.8534513026 4.7328994143 4.6852295455 1527.6932754538 0];
S_eff = [66.7227944533383 0 0 0 -21.125528529005 0 0 0 0 0 0 0 0 -22.1510837715006 0
0 85.6332899505597 0 0 0 -6.26902680203049 0 0 0 0 0 0 0 -56.7623197632202 0
0 0 103.735901694769 0 0 -63.486611502084 0 0 0 0 0 0 0 -23.148051397717 0
0 0 0 104.875162688071 0 0 -14.1390959198035 0 0 0 0 0 0 -75.197227789859 0
-21.125528529005 0 0 0 136.868718804119 0 0 -10.3490606606084 -10.3490606606084 0 0 0 0 -95.0450689538968 0
0 -6.26902680203049 -63.486611502084 0 0 159.296129885689 0 0 0 -15.2814860879717 -15.2814860879717 0 0 -58.9775194056312 0
0 0 0 -14.1390959198035 0 0 175.473307903045 0 0 0 0 -15.2814860879717 -15.2814860879717 -130.771239807298 0
0 0 0 0 -10.3490606606084 0 0 32.2823856766301 0 0 0 0 0 -6.008559285848 -15.9247657301737
0 0 0 0 -10.3490606606084 0 0 0 32.2823856766301 0 0 0 0 -6.008559285848 -15.9247657301737
0 0 0 0 0 -15.2814860879717 0 0 0 41.0438730036644 0 0 0 -3.99063940270331 -21.7717475129894
0 0 0 0 0 -15.2814860879717 0 0 0 0 41.0438730036644 0 0 -3.99063940270331 -21.7717475129894
0 0 0 0 0 0 -15.2814860879717 0 0 0 0 39.3004065856245 0 -2.24717298466343 -21.7717475129894
0 0 0 0 0 0 -15.2814860879717 0 0 0 0 0 39.3004065856245 -2.24717298466343 -21.7717475129894
-22.1510837715006 -56.7623197632202 -23.148051397717 -75.197227789859 -95.0450689538968 -58.9775194056312 -130.771239807298 -6.008559285848 -6.008559285848 -3.99063940270331 -3.99063940270331 -2.24717298466343 -2.24717298466343 807.096354173603 -320.551099938051
0 0 0 0 0 0 0 -15.9247657301737 -15.9247657301737 -21.7717475129894 -21.7717475129894 -21.7717475129894 -21.7717475129894 -320.551099938051 462.118178961545];
y0 = T0*ones(15,1);
tspan = [0 3600];
[T,Y] = ode15s(@(t,y)fun(t,y,T_air,G_air,MC,Q_gen,S_eff),tspan,y0);
plot(T,Y)
grid on
Y(end,1:10)
Y(end,11:15)
function dTdt = fun(t,T,T_air,G_air,MC,Q_gen,S_eff)
n = size(T,1);
dTdt = zeros(n,1);
for i = 1:n
dTdt(i) = (Q_gen(i) + G_air(i)*T_air - S_eff(i,:)*T)/MC(i);
end
end
8 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!