diff --git a/src/main/java/neqsim/process/equipment/heatexchanger/MultiStreamHeatExchanger.java b/src/main/java/neqsim/process/equipment/heatexchanger/MultiStreamHeatExchanger.java index cb63acee2..0f457ad00 100644 --- a/src/main/java/neqsim/process/equipment/heatexchanger/MultiStreamHeatExchanger.java +++ b/src/main/java/neqsim/process/equipment/heatexchanger/MultiStreamHeatExchanger.java @@ -42,7 +42,7 @@ public class MultiStreamHeatExchanger extends Heater implements MultiStreamHeatE protected double dT = 0.0; private double temperatureApproach = 0.0; - + private boolean UAvalueIsSet = false; private double UAvalue = 500.0; // Overall heat transfer coefficient times area private double duty = 0.0; @@ -55,6 +55,8 @@ public class MultiStreamHeatExchanger extends Heater implements MultiStreamHeatE private String flowArrangement = "counterflow"; // Default arrangement private boolean useDeltaT = false; private double deltaT = 1.0; + int MAX_ITERATIONS = 100; + int iterations = 0; /** * Constructor for MultiStreamHeatExchanger. @@ -194,6 +196,7 @@ public double getUAvalue() { * @param UAvalue UA value to set */ public void setUAvalue(double UAvalue) { + UAvalueIsSet = true; this.UAvalue = UAvalue; } @@ -629,6 +632,86 @@ public void run(UUID id) { logger.debug("Adjusted heated stream " + i + ": ΔH = " + targetDeltaH); } + + // ----------------------- LMTD and UA Calculations ----------------------- + + // Re-identify the hottest and coldest inlet streams after adjustment + double adjustedHottestTemp = Double.NEGATIVE_INFINITY; + double adjustedColdestTemp = Double.POSITIVE_INFINITY; + int adjustedHottestIndex = -1; + int adjustedColdestIndex = -1; + + for (int i = 0; i < inStreams.size(); i++) { + StreamInterface inStream = inStreams.get(i); + double currentTemp = inStream.getThermoSystem().getTemperature("K"); + + if (currentTemp > adjustedHottestTemp) { + adjustedHottestTemp = currentTemp; + adjustedHottestIndex = i; + } + + if (currentTemp < adjustedColdestTemp) { + adjustedColdestTemp = currentTemp; + adjustedColdestIndex = i; + } + } + + // Ensure valid indices + if (adjustedHottestIndex == -1 || adjustedColdestIndex == -1) { + throw new IllegalStateException( + "Unable to determine adjusted hottest or coldest inlet streams."); + } + + // Outlet temperatures after adjustment + double hotInletTemp = adjustedHottestTemp; + double coldInletTemp = adjustedColdestTemp; + + StreamInterface hotOutletStream = outStreams.get(adjustedHottestIndex); + double hotOutletTemp = hotOutletStream.getThermoSystem().getTemperature("K"); + + StreamInterface coldOutletStream = outStreams.get(adjustedColdestIndex); + double coldOutletTemp = coldOutletStream.getThermoSystem().getTemperature("K"); + + // Calculate temperature differences + double deltaT1 = hotInletTemp - coldOutletTemp; // Hot inlet - Cold outlet + double deltaT2 = hotOutletTemp - coldInletTemp; // Hot outlet - Cold inlet + + // Validate temperature differences + if (deltaT1 <= 0 || deltaT2 <= 0) { + throw new IllegalStateException("Invalid temperature differences for LMTD calculation."); + } + + // Calculate LMTD + double LMTD; + if (deltaT1 == deltaT2) { + // Avoid division by zero in logarithm + LMTD = deltaT1; + } else { + LMTD = (deltaT1 - deltaT2) / Math.log(deltaT1 / deltaT2); + } + + // Total heat transfer rate (assuming energy balance is achieved) + double totalQ = heatingIsLimiting ? totalHeatGained : totalHeatLost; + + // Calculate UA + double UA = totalQ / LMTD; + // setUAvalue(UA); + logger.info("Overall LMTD: " + LMTD + " K"); + logger.info("Overall UA: " + UA + " W/K"); + + if (UAvalueIsSet && Math.abs((UA - getUAvalue()) / getUAvalue()) > 0.001 + && iterations < MAX_ITERATIONS) { + iterations++; + setTemperatureApproach(getTemperatureApproach() * UA / getUAvalue()); + firstTime = true; + run(id); + return; + } + // Log the results + logger.info("Overall LMTD: " + LMTD + " K"); + logger.info("Overall UA: " + UA + " W/K"); + logger.info("iterations: " + iterations); + iterations = 0; } setCalculationIdentifier(id); } diff --git a/src/test/java/neqsim/process/equipment/heatexchanger/MultiStreamHeatExchangerTest.java b/src/test/java/neqsim/process/equipment/heatexchanger/MultiStreamHeatExchangerTest.java index 6648eaddb..3cde44b4e 100644 --- a/src/test/java/neqsim/process/equipment/heatexchanger/MultiStreamHeatExchangerTest.java +++ b/src/test/java/neqsim/process/equipment/heatexchanger/MultiStreamHeatExchangerTest.java @@ -45,7 +45,8 @@ void testRun1() { heatEx.addInStream(stream_Hot); heatEx.addInStream(stream_Cold); heatEx.addInStream(stream_Cold2); - heatEx.setTemperatureApproach(5.0); + // heatEx.setUAvalue(1000); + heatEx.setTemperatureApproach(5); neqsim.process.processmodel.ProcessSystem operations = @@ -61,6 +62,14 @@ void testRun1() { assertEquals(95, heatEx.getOutStream(2).getTemperature("C"), 1e-3); assertEquals(70.5921794735, heatEx.getOutStream(0).getTemperature("C"), 1e-3); + heatEx.setUAvalue(1000); + + operations.run(); + assertEquals(97.992627692, heatEx.getOutStream(1).getTemperature("C"), 1e-3); + assertEquals(97.992627692, heatEx.getOutStream(2).getTemperature("C"), 1e-3); + assertEquals(69.477801, heatEx.getOutStream(0).getTemperature("C"), 1e-3); + assertEquals(1000, heatEx.getUAvalue(), 0.1); + }