This notebook solves for the inter-stage pressures that minimize total compression work in a 5‑stage reciprocating/centrifugal compressor operating between P₁ = 1 bar and P₅ (final) = 8 bar, with the gas returned to the suction temperature T₁ = 300 K before each subsequent stage (perfect inter-cooling), using air as the working fluid (γ = 1.4, R = 0.287 kJ/kg·K).
​
The problem is solved two independent ways, and the results are cross‑checked:
1. Analytical solution — The total specific work is written as a symbolic function of the four intermediate pressures P₂, P₃, P₄, P₅. Setting the partial derivatives with respect to each intermediate pressure to zero and solving with NSolve yields the classical minimum‑work result: all stage pressure ratios are equal, r = (P_final/P₁)^(1/n) ≈ 1.51572, giving a minimum total specific work of 190.111 kJ/kg and per‑stage work of 38.0223 kJ/kg.
2. Numerical/meta-heuristic solution — A custom Particle Swarm Optimization (PSO) routine (with velocity clamping, inertia weight annealing, and boundary clipping) searches the 4‑dimensional space of intermediate pressures directly against the total‑work loss function, without using calculus. Over 150 iterations the swarm converges to the same optimum, {1.51572, 2.2974, 3.4822, 5.27803}, with the same minimum work of 190.111 kJ/kg, and the pressure ratio check confirms all four stage ratios are equal.
A log‑scale convergence plot (loss minus best‑known loss vs. iteration) shows the PSO gap shrinking from O(1) to below 10⁻¹² within ~110 iterations, visually confirming agreement between the two independent methods.
​
Both the closed‑form calculus approach and a derivative‑free PSO search independently confirm the well‑known thermodynamic result — for minimum total compression work under perfect inter-cooling, every stage must operate at the same pressure ratio (equal geometric spacing of intermediate pressures). Note that for problems with unequal inter-stage cooling only numerical approach is available.
Number of stages
n=5;
Suction pressure, e.g. bar
P1=1.0;
Final discharge pressure, e.g. bar
Pn=8.0;
Suction temperature, K (same for every stage due to perfect inter-cooling)
T1=300.0;
Ratio of specific heats, cp/cv
gamma=1.4;
Specific gas constant, kJ/(kg K)
R=0.287;

ANALYTICAL SOLUTION

General symbolic formula
WtotalSymbolic[{P2_,P3_,P4_,P5_}]:=Module[{r},r={P2/P1,P3/P2,P4/P3,P5/P4,Pn/P5};Sum[(gamma/(gamma-1))*R*T1*((r[[i]])^((gamma-1)/(gamma))-1),{i,1,5}]]
In[]:=
eq1=D[WtotalSymbolic[{P2,P3,P4,P5}],P2]==0;
In[]:=
eq2=D[WtotalSymbolic[{P2,P3,P4,P5}],P3]==0;
In[]:=
eq3=D[WtotalSymbolic[{P2,P3,P4,P5}],P4]==0;
In[]:=
eq4=D[WtotalSymbolic[{P2,P3,P4,P5}],P5]==0;
Intermediate pressure for minimum Wtot
sol=Flatten@NSolve[{eq1,eq2,eq3,eq4},{P2,P3,P4,P5},Reals]
Out[]=
{P21.51572,P32.2974,P43.4822,P55.27803}
Pressure ratio
r={P2/P1,P3/P2,P4/P3,P5/P4,Pn/P5}/.sol
Out[]=
{1.51572,1.51572,1.51572,1.51572,1.51572}
Stage pressure ratio (equal in every stage for minimum work)
r=(Pn/P1)^(1/n);​​Print["Stage pressure ratio r = ",r];
Stage pressure ratio r = 1.51572
Work per stage (per unit mass)
WstagePerKg=(gamma/(gamma-1))*R*T1*(r^((gamma-1)/gamma)-1);​​Print["Work per stage (kJ/kg) = ",WstagePerKg];
Work per stage (kJ/kg) = 38.0223
Total work for n stages
Wtotal=n*WstagePerKg;​​Print["Total work (kJ/kg) = ",Wtotal];
Total work (kJ/kg) = 190.111
Total work
5WstagePerKg5
Out[]=
190.111

Numerical Solution based on PSO

Clip each COLUMN of a matrix against its own scalar bound
clipMatrix[mat_,lbv_,ubv_]:=Transpose[MapThread[Clip[#1,{#2,#3}]&,{Transpose[mat],lbv,ubv}]];​​​​clampMatrix[mat_,vmaxv_]:=Transpose[MapThread[Clip[#1,{-#2,#2}]&,{Transpose[mat],vmaxv}]];
PSO Optimizer
psoOptimize[lossFunc_,dim_,lb_,ub_,nParticles_:30,nIter_:100,wMax_:0.9,wMin_:0.4,c1_:1.42,c2_:1.42,vClampFrac_:0.2]:=Module[{particles,velocities,pbest,pbestScore,gbest,gbestScore,convergence={},r1,r2,scores,gbestIdx,vmax,wIter},vmax=vClampFrac*(ub-lb);​​particles=Transpose@Table[RandomReal[{lb[[i]],ub[[i]]},nParticles],{i,dim}];​​velocities=ConstantArray[0.,{nParticles,dim}];​​pbest=particles;​​pbestScore=lossFunc/@particles;​​gbestIdx=First@Ordering[pbestScore,1];​​gbestScore=pbestScore[[gbestIdx]];​​gbest=pbest[[gbestIdx]];​​Do[wIter=wMax-(wMax-wMin)*(j-1)/(nIter-1);​​r1=RandomReal[1,{nParticles,dim}];​​r2=RandomReal[1,{nParticles,dim}];​​velocities=wIter*velocities+c1*r1*(pbest-particles)+c2*r2*(ConstantArray[gbest,nParticles]-particles);​​velocities=clampMatrix[velocities,vmax];​​particles+=velocities;​​particles=clipMatrix[particles,lb,ub];​​scores=lossFunc/@particles;​​pbest=MapThread[If[#3<#2,#1,#4]&,{particles,pbestScore,scores,pbest}];​​pbestScore=MapThread[Min,{pbestScore,scores}];​​gbestIdx=First@Ordering[pbestScore,1];​​If[pbestScore[[gbestIdx]]<gbestScore,gbestScore=pbestScore[[gbestIdx]];​​gbest=pbest[[gbestIdx]];];​​AppendTo[convergence,gbestScore];​​If[j<10||Mod[j,10]==0,Print["PSO Iter ",j," Loss = ",gbestScore]];,{j,nIter}];​​{gbest,gbestScore,convergence}];
In[]:=
dim=4;
In[]:=
UB=10{1,1,1,1};​​LB=1{1,1,1,1};
{gbest,gbestScore,convergence}=psoOptimize[WtotalSymbolic,4,LB,UB,30,150];
PSO Iter 1 Loss = 196.261
PSO Iter 2 Loss = 194.464
PSO Iter 3 Loss = 192.592
PSO Iter 4 Loss = 192.265
PSO Iter 5 Loss = 190.555
PSO Iter 6 Loss = 190.555
PSO Iter 7 Loss = 190.555
PSO Iter 8 Loss = 190.555
PSO Iter 9 Loss = 190.544
PSO Iter 10 Loss = 190.544
PSO Iter 20 Loss = 190.123
PSO Iter 30 Loss = 190.123
PSO Iter 40 Loss = 190.116
PSO Iter 50 Loss = 190.112
PSO Iter 60 Loss = 190.112
PSO Iter 70 Loss = 190.111
PSO Iter 80 Loss = 190.111
PSO Iter 90 Loss = 190.111
PSO Iter 100 Loss = 190.111
PSO Iter 110 Loss = 190.111
PSO Iter 120 Loss = 190.111
PSO Iter 130 Loss = 190.111
PSO Iter 140 Loss = 190.111
PSO Iter 150 Loss = 190.111
Intermediate pressure for minimum Wtot
gbest
Out[]=
{1.51572,2.2974,3.4822,5.27803}
Minimum Wtot
gbestScore
Out[]=
190.111
All stage pressure ratios are equal for equal inter-stage cooling
{gbest[[1]]/P1,gbest[[2]]/gbest[[1]],gbest[[3]]/gbest[[2]],gbest[[4]]/gbest[[3]],Pn/gbest[[4]]}
Out[]=
{1.51572,1.51572,1.51572,1.51572,1.51572}
(Gap to the best-known solution at each iteration
gap=convergence-gbestScore;
Convergence plot
ListLogPlotgap,

Out[]=

CITE THIS NOTEBOOK

Optimal inter-stage pressures for a 5‑stage compressor with perfect inter-cooling​
by Housam Binous​
Wolfram Community, STAFF PICKS, July 4, 2026
https://community.wolfram.com/groups/-/m/t/3744114