Solving a system of a changing number of nonlinear equations
7 views (last 30 days)
Show older comments
I'm trying to solve the following system of nonlinear equations for a spacecraft thermal modeling project:
This system grows in size with the number of nodes, and because of the sums, I really don't want to have to code the equations in manually (especially since I'll be altering the number of nodes as I add detail to the model--if I had a fixed set I might just suck it up and do it).
My advisor has recommended I use fsolve to work this out, but while I think he'd be right for using it for a fixed number of nodes, for a dynamic version I'm not so sure.
This is the cleanest version of what I've tried so far.
Currently, it gets through the loop, but then 'crashes' on trying to solve infinitely, and I think is getting stuck in a NaN/Infinity loop between trustnleqn.m and sym.m.
fun = @test1
x0 = T_0
X = fsolve(fun,x0)
function One = test1(X)
load 'AppxSteadyStateTestInput.mat'
boltzmann = 5.67E-8;
N = numel(nodes);
One = zeros(N, 1);
for i = 1:1:N
for j = 1:1:N
One(i) = -(Q_external(i)+Q_d(i) - boltzmann*eps_outside(i)*A_r(i)*X(i) - sum(Conductances(i,j)*(X(i)-X(j)))-boltzmann*sum(F_times_A(i)*epsilon_inside(i,j)*(X(i)^4-X(j)^4)));
end
end
end
I'm not sure if I'm trying to do something impossible, or if I just haven't found the right way to do it yet.
I've also attempted the same math with vpasolve, but I get wildly incorrect numbers, but at least this code runs, so maybe that's just an input issue or some other minor problem....
load 'AppxSteadyStateTestInput.mat'
boltzmann = 5.67E-8;
% Conductances = zeros(size(Conductances))
N = numel(nodes);
x = sym('T', [N 1] );
T_0 = [273; 273; 273; 273; 273; 273; 273; 273; 293; 273]; %initial conditions
results = sym('results',[N 1]);
SUM1 = sym(zeros(N,N));
SUM2 = sym(zeros(N,N));
for i = 1:1:N
for j = 1:1:N
syms k
SUM1(i,j) = symsum(Conductances(i,j)*(x(i)-x(j)), k, i, j);
SUM2(i,j) = symsum(F_times_A(i)*epsilon_inside(i,j)*(x(i)^4-x(j)^4),k,i,j);
results(i) = -(Q_external(i)+Q_d(i) - boltzmann*eps_outside(i)*A_r(i)*x(i) - SUM1(i,j) -boltzmann*SUM2(i,j));
end
end
disp('coderun')
vpasolve(results,x)
2 Comments
Walter Roberson
on 11 Jul 2025
SUM1(i,j) = symsum(Conductances(i,j)*(x(i)-x(j)), k, i, j);
Note that symsum() is completely unable to have the variable of summation be used for indices. So your symsum() here is equvailent to
EXPRESSION = Conductances(i,j)*(x(i)-x(j));
SUM1(i,j) = symsum(EXPRESSION, k, i, j);
which in turn is equivalent to
EXPRESSION = Conductances(i,j)*(x(i)-x(j));
SUM1(i,j) = EXPRESSION .* (j-i+1);
Using symsum() as a replacement for straight multiplication is inefficient and confusing.
The same remarks apply to the second symsum -- as written it is equivalent to multiplication.
Matt J
on 12 Jul 2025
Edited: Matt J
on 12 Jul 2025
Your code is difficult to interpret, since you use variables that are entirely different from your mathematical expression,

Also, it appears that the code contains an extra term,
boltzmann*eps_outside(i)*A_r(i)*X(i)
not present in the original equation.
Answers (2)
Torsten
on 11 Jul 2025
Edited: Torsten
on 12 Jul 2025
The solver doesn't converge. You should check parameters and equations.
load 'AppxSteadyStateTestInput.mat'
fun = @(x)test1(x,boltzmann,nodes,Q_external,Q_d,eps_outside,A_r,Conductances,F_times_A,epsilon_inside);
x0 = T_0;
X = fsolve(fun,x0,optimset('MaxFunEvals',1000000,'MaxIter',1000000))
function One = test1(X,boltzmann,nodes,Q_external,Q_d,eps_outside,A_r,Conductances,F_times_A,epsilon_inside)
N = numel(nodes);
One = zeros(N, 1);
for i = 1:N
One(i) = Q_external(i) + Q_d(i) - boltzmann*eps_outside(i)*A_r(i)*X(i);
for j = 1:N
One(i) = One(i) - Conductances(i,j)*(X(i)-X(j)) - boltzmann*F_times_A(i)*epsilon_inside(i,j)*(X(i)^4-X(j)^4);
end
end
end
0 Comments
Matt J
on 12 Jul 2025
Edited: Matt J
on 14 Jul 2025
Because your equations are 4-th order polynomials, they are apt to have multiple roots. You probably won't get a physically sensible result unless you impose some bounds on T (and maybe other constraints). Here is how that might look:
load 'AppxSteadyStateTestInput.mat';
W0=-boltzmann.*eps_outside.*A_r;
W1=-Conductances;
W2=-boltzmann.*F_times_A.*epsilon_inside;
Q = Q_external+Q_d;
W1=diag(W0)+diag(sum(W1,2))-W1;
W2=diag(sum(W2,2))-W2;
fun=@(T) deal( Q + W1*T + W2*T.^4 , W1+4*W2.*(T.^3') );
opts=optimoptions('lsqnonlin',MaxFunEval=Inf,MaxIterations=1e4, ...
OptimalityTol=1e-12, FunctionTol=1e-12,StepTol=1e-12,...
SpecifyObjectiveGradient=true);
lb=zeros(size(T_0));
[T, resnorm,residuals]=lsqnonlin(fun,T_0,lb+200,lb+350, opts)
4 Comments
Matt J
on 14 Jul 2025
Edited: Matt J
on 14 Jul 2025
and since I am attempting to replicate a model from literature, I'm using the paper's values exactly as inputs
If this has already been done in previous literature, it would be wise, as a sanity-check, to plug in their solution for T and check if it solves the equations -- the equations as implemented by you.
I don't see how the equations, as you've presented them to us, have a well-behaved solution.
Torsten
on 14 Jul 2025
Edited: Torsten
on 14 Jul 2025
and since I am attempting to replicate a model from literature, I'm using the paper's values exactly as inputs,
Maybe you also have the solution for T from the paper, and you could evaluate your function with it to see where you might have made a mistake in the implementation.
I think that somewhere in your equations, there should appear a fixed environmental temperature in the chain of resistances to close the system.
Although your system is stationary and includes radiative heat transfer, this answer might help:
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!