Skip to content

Commit 36bfcb5

Browse files
committed
update model
1 parent 114d147 commit 36bfcb5

File tree

2 files changed

+169
-80
lines changed

2 files changed

+169
-80
lines changed

src/main/java/neqsim/process/equipment/heatexchanger/MultiStreamHeatExchanger.java

Lines changed: 163 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public class MultiStreamHeatExchanger extends Heater implements MultiStreamHeatE
4141
protected double temperatureOut = 0;
4242

4343
protected double dT = 0.0;
44+
private double temperatureApproach = 0.0;
45+
4446

4547
private double UAvalue = 500.0; // Overall heat transfer coefficient times area
4648
private double duty = 0.0;
@@ -455,94 +457,183 @@ public void setDeltaT(double deltaT) {
455457
*/
456458
@Override
457459
public void run(UUID id) {
458-
if (useDeltaT) {
459-
runDeltaT(id);
460-
return;
461-
}
462-
463-
if (getSpecification().equals("out stream")) {
464-
runSpecifiedStream(id);
465-
} else if (firstTime) {
460+
if (firstTime) {
466461
firstTime = false;
467-
// Initialize all outStreams with guessed temperatures
468-
for (StreamInterface outStream : outStreams) {
469-
SystemInterface systemOut =
470-
inStreams.get(outStreams.indexOf(outStream)).getThermoSystem().clone();
471-
outStream.setThermoSystem(systemOut);
472-
outStream.getThermoSystem().setTemperature(guessOutTemperature, guessOutTemperatureUnit);
473-
outStream.run(id);
474-
}
475-
run(id);
476-
} else {
477-
// Ensure all input streams are run
478-
for (StreamInterface inStream : inStreams) {
462+
463+
// 1. Identify the hottest and coldest inlet streams
464+
double hottestTemperature = Double.NEGATIVE_INFINITY;
465+
double coldestTemperature = Double.POSITIVE_INFINITY;
466+
int hottestIndex = -1;
467+
int coldestIndex = -1;
468+
469+
for (int i = 0; i < inStreams.size(); i++) {
470+
StreamInterface inStream = inStreams.get(i);
471+
// Ensure the inlet stream is run to get the latest temperature
479472
inStream.run();
473+
double currentTemp = inStream.getThermoSystem().getTemperature("K");
474+
475+
if (currentTemp > hottestTemperature) {
476+
hottestTemperature = currentTemp;
477+
hottestIndex = i;
478+
}
479+
480+
if (currentTemp < coldestTemperature) {
481+
coldestTemperature = currentTemp;
482+
coldestIndex = i;
483+
}
480484
}
481485

482-
// Clone thermo systems for all out streams
483-
List<SystemInterface> systemsOut = new ArrayList<>();
484-
for (StreamInterface inStream : inStreams) {
485-
systemsOut.add(inStream.getThermoSystem().clone());
486+
// Check if valid indices were found
487+
if (hottestIndex == -1 || coldestIndex == -1) {
488+
throw new IllegalStateException("Unable to determine hottest or coldest inlet streams.");
486489
}
487490

488-
// Set thermo systems to out streams
491+
// 2. Set the outlet temperatures accordingly
489492
for (int i = 0; i < outStreams.size(); i++) {
490-
outStreams.get(i).setThermoSystem(systemsOut.get(i));
491-
// Set temperature based on some logic, e.g., maintaining a certain delta T
492-
outStreams.get(i).setTemperature(inStreams.get(i).getTemperature() + 10, "K");
493-
if (!outStreams.get(i).getSpecification().equals("TP")) {
494-
outStreams.get(i).runTPflash();
493+
StreamInterface outStream = outStreams.get(i);
494+
SystemInterface systemOut = inStreams.get(i).getThermoSystem().clone();
495+
outStream.setThermoSystem(systemOut);
496+
497+
if (i == hottestIndex) {
498+
// Set the outlet temperature of the hottest inlet stream to the coldest inlet temperature
499+
outStream.getThermoSystem().setTemperature(coldestTemperature + temperatureApproach, "K");
500+
} else if (i == coldestIndex) {
501+
// Set the outlet temperature of the coldest inlet stream to the hottest inlet temperature
502+
outStream.getThermoSystem().setTemperature(hottestTemperature - temperatureApproach, "K");
503+
} else {
504+
// Set the outlet temperature of other streams to the hottest inlet temperature
505+
outStream.getThermoSystem().setTemperature(hottestTemperature - temperatureApproach, "K");
495506
}
496-
outStreams.get(i).run(id);
507+
508+
// Run the outlet stream with the given ID
509+
outStream.run(id);
497510
}
498511

499-
// Calculate enthalpy changes and capacity rates
500-
List<Double> deltaEnthalpies = new ArrayList<>();
501-
List<Double> capacities = new ArrayList<>();
502-
for (int i = 0; i < inStreams.size(); i++) {
503-
double deltaH = outStreams.get(i).getThermoSystem().getEnthalpy()
504-
- inStreams.get(i).getThermoSystem().getEnthalpy();
505-
deltaEnthalpies.add(deltaH);
506-
double C = Math.abs(deltaH) / Math.abs(outStreams.get(i).getThermoSystem().getTemperature()
507-
- inStreams.get(i).getThermoSystem().getTemperature());
508-
capacities.add(C);
512+
// Finalize the setup
513+
run();
514+
return;
515+
}
516+
517+
else {
518+
// Run all input and output streams to ensure they are up-to-date
519+
for (StreamInterface inStream : inStreams) {
520+
inStream.run(id);
521+
}
522+
for (StreamInterface outStream : outStreams) {
523+
outStream.run(id);
509524
}
510525

511-
// Determine Cmin and Cmax among all streams
512-
double Cmin = capacities.stream().min(Double::compare).orElse(1.0);
513-
double Cmax = capacities.stream().max(Double::compare).orElse(1.0);
514-
double Cr = Cmin / Cmax;
526+
// Identify heated and cooled streams
527+
List<Integer> heatedStreamIndices = new ArrayList<>();
528+
List<Integer> cooledStreamIndices = new ArrayList<>();
529+
double totalHeatGained = 0.0; // Total Q for heated streams
530+
double totalHeatLost = 0.0; // Total Q for cooled streams
515531

516-
// Calculate NTU and thermal effectiveness
517-
NTU = UAvalue / Cmin;
518-
thermalEffectiveness = calcThermalEffectiveness(NTU, Cr);
532+
for (int i = 0; i < inStreams.size(); i++) {
533+
double enthalpyIn = inStreams.get(i).getThermoSystem().getEnthalpy();
534+
double enthalpyOut = outStreams.get(i).getThermoSystem().getEnthalpy();
535+
double deltaH = enthalpyOut - enthalpyIn;
536+
537+
if (deltaH > 0) {
538+
// Stream is being heated
539+
heatedStreamIndices.add(i);
540+
totalHeatGained += deltaH;
541+
} else if (deltaH < 0) {
542+
// Stream is being cooled
543+
cooledStreamIndices.add(i);
544+
totalHeatLost += Math.abs(deltaH);
545+
}
546+
// Streams with deltaH == 0 are neither heated nor cooled
547+
}
519548

520-
// Adjust enthalpies based on effectiveness
521-
duty = 0.0;
522-
for (int i = 0; i < deltaEnthalpies.size(); i++) {
523-
deltaEnthalpies.set(i, thermalEffectiveness * deltaEnthalpies.get(i));
524-
duty += deltaEnthalpies.get(i);
549+
logger.debug(": Total Heat Gained = " + totalHeatGained + " J");
550+
logger.debug(": Total Heat Lost = " + totalHeatLost + " J");
551+
552+
// Determine the limiting side
553+
double limitingHeat;
554+
boolean heatingIsLimiting;
555+
556+
if (totalHeatGained < totalHeatLost) {
557+
limitingHeat = totalHeatGained;
558+
heatingIsLimiting = true;
559+
logger.debug("Limiting side: Heating");
560+
} else {
561+
limitingHeat = totalHeatLost;
562+
heatingIsLimiting = false;
563+
logger.debug("Limiting side: Cooling");
525564
}
526565

527-
// Update thermo systems based on adjusted enthalpies
528-
for (int i = 0; i < outStreams.size(); i++) {
529-
ThermodynamicOperations thermoOps =
530-
new ThermodynamicOperations(outStreams.get(i).getThermoSystem());
531-
thermoOps.PHflash(inStreams.get(i).getThermoSystem().getEnthalpy() - deltaEnthalpies.get(i),
532-
0);
533-
if (Math.abs(thermalEffectiveness - 1.0) > 1e-10) {
534-
thermoOps = new ThermodynamicOperations(outStreams.get(i).getThermoSystem());
535-
thermoOps.PHflash(
536-
inStreams.get(i).getThermoSystem().getEnthalpy() + deltaEnthalpies.get(i), 0);
566+
// Calculate scaling factors for each side
567+
double scalingFactor = 1.0;
568+
569+
if (heatingIsLimiting) {
570+
// Scale down the heat lost by cooled streams
571+
scalingFactor = limitingHeat / totalHeatLost;
572+
logger.debug("Scaling factor for cooled streams: " + scalingFactor);
573+
} else {
574+
// Scale down the heat gained by heated streams
575+
scalingFactor = limitingHeat / totalHeatGained;
576+
logger.debug("Scaling factor for heated streams: " + scalingFactor);
577+
}
578+
579+
// Apply scaling factors to adjust outlet enthalpies
580+
double maxTemperatureChange = 0.0;
581+
582+
for (int i : cooledStreamIndices) {
583+
StreamInterface inStream = inStreams.get(i);
584+
StreamInterface outStream = outStreams.get(i);
585+
586+
double enthalpyIn = inStream.getThermoSystem().getEnthalpy();
587+
double targetDeltaH =
588+
-(outStream.getThermoSystem().getEnthalpy() - enthalpyIn) * scalingFactor;
589+
590+
// Adjust the outlet enthalpy
591+
double adjustedEnthalpyOut = enthalpyIn - (Math.abs(targetDeltaH));
592+
ThermodynamicOperations ops = new ThermodynamicOperations(outStream.getThermoSystem());
593+
ops.PHflash(adjustedEnthalpyOut);
594+
595+
// Calculate temperature change for convergence check
596+
double oldTemp = outStream.getThermoSystem().getTemperature("K");
597+
outStream.run(id); // Re-run to update temperature based on adjusted enthalpy
598+
double newTemp = outStream.getThermoSystem().getTemperature("K");
599+
double tempChange = Math.abs(newTemp - oldTemp);
600+
if (tempChange > maxTemperatureChange) {
601+
maxTemperatureChange = tempChange;
537602
}
603+
604+
logger.debug("Adjusted cooled stream " + i + ": ΔH = " + targetDeltaH);
538605
}
539606

540-
hotColdDutyBalance = 1.0; // Adjust as needed for specific applications
541-
}
607+
scalingFactor = 1.0;
608+
for (int i : heatedStreamIndices) {
609+
StreamInterface inStream = inStreams.get(i);
610+
StreamInterface outStream = outStreams.get(i);
611+
612+
double enthalpyIn = inStream.getThermoSystem().getEnthalpy();
613+
double targetDeltaH =
614+
(outStream.getThermoSystem().getEnthalpy() - enthalpyIn) * scalingFactor;
615+
616+
// Adjust the outlet enthalpy
617+
double adjustedEnthalpyOut = enthalpyIn + (Math.abs(targetDeltaH));
618+
ThermodynamicOperations ops = new ThermodynamicOperations(outStream.getThermoSystem());
619+
ops.PHflash(adjustedEnthalpyOut);
620+
621+
// Calculate temperature change for convergence check
622+
double oldTemp = outStream.getThermoSystem().getTemperature("K");
623+
outStream.run(id); // Re-run to update temperature based on adjusted enthalpy
624+
double newTemp = outStream.getThermoSystem().getTemperature("K");
625+
double tempChange = Math.abs(newTemp - oldTemp);
626+
if (tempChange > maxTemperatureChange) {
627+
maxTemperatureChange = tempChange;
628+
}
542629

630+
logger.debug("Adjusted heated stream " + i + ": ΔH = " + targetDeltaH);
631+
}
632+
}
543633
setCalculationIdentifier(id);
544634
}
545635

636+
546637
/**
547638
* Runs the heat exchanger simulation using a specified stream approach.
548639
*
@@ -553,13 +644,12 @@ public void runSpecifiedStream(UUID id) {
553644
// This method needs to be defined based on specific requirements
554645
}
555646

556-
/**
557-
* Runs the heat exchanger simulation using a delta T approach.
558-
*
559-
* @param id Unique identifier for the run
560-
*/
561-
public void runDeltaT(UUID id) {
562-
// Implementation similar to the two-stream case but generalized for multiple streams
563-
// This method needs to be defined based on specific requirements
647+
648+
public double getTemperatureApproach() {
649+
return temperatureApproach;
650+
}
651+
652+
public void setTemperatureApproach(double temperatureApproach) {
653+
this.temperatureApproach = temperatureApproach;
564654
}
565655
}

src/test/java/neqsim/process/equipment/heatexchanger/MultiStreamHeatExchangerTest.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package neqsim.process.equipment.heatexchanger;
22

3+
import static org.junit.jupiter.api.Assertions.assertEquals;
34
import org.apache.logging.log4j.LogManager;
45
import org.apache.logging.log4j.Logger;
56
import org.junit.jupiter.api.BeforeEach;
@@ -44,8 +45,7 @@ void testRun1() {
4445
heatEx.addInStream(stream_Hot);
4546
heatEx.addInStream(stream_Cold);
4647
heatEx.addInStream(stream_Cold2);
47-
heatEx.setGuessOutTemperature(20.0, "C");
48-
heatEx.setUAvalue(1000);
48+
heatEx.setTemperatureApproach(5.0);
4949

5050

5151
neqsim.process.processmodel.ProcessSystem operations =
@@ -57,11 +57,10 @@ void testRun1() {
5757

5858
operations.run();
5959

60-
heatEx.getOutStream(0).getFluid().prettyPrint();
61-
heatEx.getOutStream(1).getFluid().prettyPrint();
62-
heatEx.getOutStream(2).getFluid().prettyPrint();
63-
logger.debug("duty " + heatEx.getDuty());
64-
// resyc.getOutStream().displayResult();
60+
assertEquals(95, heatEx.getOutStream(1).getTemperature("C"), 1e-3);
61+
assertEquals(95, heatEx.getOutStream(2).getTemperature("C"), 1e-3);
62+
assertEquals(70.5921794735, heatEx.getOutStream(0).getTemperature("C"), 1e-3);
63+
6564
}
6665

6766

0 commit comments

Comments
 (0)