Solving a system of a changing number of nonlinear equations
7 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
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 comentarios
Walter Roberson
el 11 de Jul. de 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
el 12 de Jul. de 2025
Editada: Matt J
el 12 de Jul. de 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.
Respuestas (2)
Torsten
el 11 de Jul. de 2025
Editada: Torsten
el 12 de Jul. de 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 comentarios
Matt J
el 12 de Jul. de 2025
Editada: Matt J
el 14 de Jul. de 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 comentarios
Matt J
el 14 de Jul. de 2025
Editada: Matt J
el 14 de Jul. de 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
el 14 de Jul. de 2025
Editada: Torsten
el 14 de Jul. de 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:
Ver también
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!