This notebook finds the optimal interstage pressures (P2, P3) for a 3-stage propane compression train (1 bar → 20 bar) that minimize total compressor work, using an ideal-gas model with stage-dependent isentropic efficiencies (0.82, 0.80, 0.78) and unequal interstage cooling (suction temperatures rising from 300 K to 313 K across stages).
​
For each stage, it solves the ideal-gas entropy balance for the isentropic outlet temperature, computes the ideal work by integrating Cp over that temperature rise, then divides by the stage efficiency to get actual work and back-solves for the actual (higher) outlet temperature.
​
A custom particle swarm optimizer searches over {P2, P3} to minimize total actual work summed across all three stages.
​
Calculation yields a minimum total work ≈ 226.4 kJ/kg, optimal pressures ≈ {1, 4.17, 11.65, 20} bar, with stage pressure ratios ≈ {4.17, 2.79, 1.71} — a front-loaded ratio distribution driven by the combination of unequal cooling and declining efficiency across stages.
Number of stages
n=3;
Suction pressure, e.g.bar
P1=1.0*^5;
Final discharge pressure, e.g.bar
Pn=20.0*^5;
J/(mol K)
Rgas=8.314;
kg/mol, molar mass of propane
Mmass=0.04410;
Ideal-gas Cp0 correlation for propane: Cp0/R = A + B T + C T^2 (Smith, Van Ness, Abbott coefficients)
Acp=1.213;​​Bcp=28.785*^-3;​​Ccp=-8.824*^-6;
K, reference state
Tref=300.0;
Pa (1 bar)
Pref=1.0*^5;
CpOverR[T_]:=Acp+Bcp*T+Ccp*T^2;
T1=300.0;​​dT={5.0,8.0};​​Tin=Prepend[T1+Accumulate[dT],T1];
Print["Stage suction temperatures (K): ",Tin];
Stage suction temperatures (K): {300.,305.,313.}
Stage-dependent efficiency:IG case,unequal interstage cooling
Define per-stage isentropic efficiencies (fraction,0<eta<=1)
Typically efficiency drops slightly at higher stages due to lower volumetric flow/higher pressure ratio-adjust to your compressor data
etaStage={0.82,0.80,0.78};
K, reference state
Tref=300.0;
Pa (1 bar)
Pref=1.0*^5;
Ideal-gas enthalpy relative to Tref (J/mol)
Hig[T_?NumericQ]:=NIntegrate[Rgas*CpOverR[Tt],{Tt,Tref,T}];
Ideal-gas entropy relative to (Tref, Pref) (J/mol/K)
Sig[T_?NumericQ,P_?NumericQ]:=​​NIntegrate[Rgas*CpOverR[Tt]/Tt,{Tt,Tref,T}]-Rgas*Log[P/Pref];
Modified per-stage work calculation (ideal gas)
stageWorkIG[stage_,P_,Pnext_,Tin_,eta_]:=Module[{Sin,entropyResidualIG,Toutisentropic,wIdeal,wActual,ToutActual,Tout,T},entropyResidualIG[Tout_]:=Sig[Tout,Pnext]-Sig[Tin,P]==0;​​(*Step1:solveforISENTROPICoutletT(reversiblereferencecase)*)Toutisentropic=Tout/.FindRoot[entropyResidualIG[Tout],{Tout,350,330},MaxIterations->1000];​​(*Step2:ideal(isentropic)workperunitmass*)wIdeal=Integrate[CpOverR[T]*Rgas,{T,Tin,Toutisentropic}];​​(*Step3:actualwork=idealwork/isentropicefficiency*)wActual=wIdeal/eta;​​(*Step4:actualoutlettemperature(higherthanisentropic,sincerealcompressionaddsextraenthalpy=irreversibility)*)ToutActual=ToutActual/.FindRoot[Integrate[CpOverR[T]*Rgas,{T,Tin,ToutActual}]==wActual,{ToutActual,350,330},MaxIterations->1000];​​{wActual,ToutActual}];
Total work objective: IG,unequal cooling,stage-dependent efficiency
WtotalIGeta[{P2_,P3_}]:=Module[{Pstages,results,totalWork=0},Pstages={P1,P2,P3,Pn};​​Do[results=stageWorkIG[i,Pstages[[i]],Pstages[[i+1]],Tin[[i]],etaStage[[i]]];​​totalWork+=results[[1]],{i,1,n}];​​totalWork];
Custom Particle Swarm Optimizer (same as ideal-gas notebooks)
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}]];
In[]:=
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}];
Dimension of search space
dim=2;
Bounds: P2,P3,P4 all strictly between P1 and Pn
LB=10^5{2.6,4.7};​​UB=10^5{5.8,15.2};
Run PSO with the efficiency-corrected ideal-gas objective
{gbest,gbestScore,convergence}=psoOptimize[WtotalIGeta,dim,LB,UB,20,50];
PSO Iter 1 Loss = 9985.41
PSO Iter 2 Loss = 9985.41
PSO Iter 3 Loss = 9985.41
PSO Iter 4 Loss = 9985.41
PSO Iter 5 Loss = 9985.41
PSO Iter 6 Loss = 9985.41
PSO Iter 7 Loss = 9985.4
PSO Iter 8 Loss = 9985.4
PSO Iter 9 Loss = 9985.4
PSO Iter 10 Loss = 9985.4
PSO Iter 20 Loss = 9985.4
PSO Iter 30 Loss = 9985.4
PSO Iter 40 Loss = 9985.4
PSO Iter 50 Loss = 9985.4
In[]:=
Pstages=Prepend[Append[gbest,Pn],P1]/1*^5;​​ratios=Table[Pstages[[i+1]]/Pstages[[i]],{i,1,3}];​​​​Print["Minimum total work (IG, unequal cooling, stage-dependent efficiency, kJ/kg): ",gbestScore/10^3/Mmass];​​Print["Optimal interstage pressures (bar): ",Pstages];​​Print["Stage pressure ratios: ",ratios];
Minimum total work (IG, unequal cooling, stage-dependent efficiency, kJ/kg): 226.426
Optimal interstage pressures (bar): {1.,4.17041,11.6675,20.}
Convergence plot (log scale)

CITE THIS NOTEBOOK

3-stage propane compressor PSO optimization — ideal gas, unequal cooling, stage-dependent efficiency​
by Housam Binous​
Wolfram Community, STAFF PICKS, July 4, 2026
https://community.wolfram.com/groups/-/m/t/3744725