diff --git a/src/main/java/neqsim/process/equipment/compressor/Compressor.java b/src/main/java/neqsim/process/equipment/compressor/Compressor.java index d97bc3cf8..8da288cc0 100644 --- a/src/main/java/neqsim/process/equipment/compressor/Compressor.java +++ b/src/main/java/neqsim/process/equipment/compressor/Compressor.java @@ -80,8 +80,7 @@ public Compressor(String name) { *

* * @param name a {@link java.lang.String} object - * @param inletStream a {@link neqsim.process.equipment.stream.StreamInterface} - * object + * @param inletStream a {@link neqsim.process.equipment.stream.StreamInterface} object */ public Compressor(String name, StreamInterface inletStream) { this(name); @@ -926,8 +925,7 @@ public SystemInterface getThermoSystem() { * Getter for the field compressorChart. *

* - * @return a {@link neqsim.process.equipment.compressor.CompressorChartInterface} - * object + * @return a {@link neqsim.process.equipment.compressor.CompressorChartInterface} object */ public CompressorChartInterface getCompressorChart() { return compressorChart; @@ -938,8 +936,7 @@ public CompressorChartInterface getCompressorChart() { * Setter for the field compressorChart. *

* - * @param compressorChart a - * {@link neqsim.process.equipment.compressor.CompressorChart} object + * @param compressorChart a {@link neqsim.process.equipment.compressor.CompressorChart} object */ public void setCompressorChart(CompressorChart compressorChart) { this.compressorChart = compressorChart; @@ -972,6 +969,19 @@ public double getDistanceToSurge() { / getCompressorChart().getSurgeCurve().getSurgeFlow(getPolytropicFluidHead()) - 1; } + /** {@inheritDoc} */ + @Override + public double getSurgeFlowRateMargin() { + return getInletStream().getFlowRate("m3/hr") + - getCompressorChart().getSurgeCurve().getSurgeFlow(getPolytropicFluidHead()); + } + + /** {@inheritDoc} */ + @Override + public double getSurgeFlowRate() { + return getCompressorChart().getSurgeCurve().getSurgeFlow(getPolytropicFluidHead()); + } + /** *

* isStoneWall. @@ -990,8 +1000,7 @@ public boolean isStoneWall(double flow, double head) { * Setter for the field antiSurge. *

* - * @param antiSurge a {@link neqsim.process.equipment.compressor.AntiSurge} - * object + * @param antiSurge a {@link neqsim.process.equipment.compressor.AntiSurge} object */ public void setAntiSurge(AntiSurge antiSurge) { this.antiSurge = antiSurge; @@ -1252,9 +1261,7 @@ public void setUseGERG2008(boolean useGERG2008) { * Getter for the field propertyProfile. *

* - * @return a - * {@link neqsim.process.equipment.compressor.CompressorPropertyProfile} - * object + * @return a {@link neqsim.process.equipment.compressor.CompressorPropertyProfile} object */ public CompressorPropertyProfile getPropertyProfile() { return propertyProfile; @@ -1265,8 +1272,7 @@ public CompressorPropertyProfile getPropertyProfile() { * Setter for the field propertyProfile. *

* - * @param propertyProfile a - * {@link neqsim.process.equipment.compressor.CompressorPropertyProfile} + * @param propertyProfile a {@link neqsim.process.equipment.compressor.CompressorPropertyProfile} * object */ public void setPropertyProfile(CompressorPropertyProfile propertyProfile) { @@ -1459,4 +1465,18 @@ public void setIsSetMaxOutletPressure(boolean isSetMaxOutletPressure) { public double getActualCompressionRatio() { return actualCompressionRatio; } + + /** + *

+ * Set CompressorChartType + *

+ * + */ + public void setCompressorChartType(String type) { + if (type.equals("simple")) { + compressorChart = new CompressorChart(); + } else { + compressorChart = new CompressorChartAlternativeMapLookup(); + } + } } diff --git a/src/main/java/neqsim/process/equipment/compressor/CompressorChart.java b/src/main/java/neqsim/process/equipment/compressor/CompressorChart.java index 925c0c350..2dfa7dfa6 100644 --- a/src/main/java/neqsim/process/equipment/compressor/CompressorChart.java +++ b/src/main/java/neqsim/process/equipment/compressor/CompressorChart.java @@ -66,7 +66,23 @@ public void addCurve(double speed, double[] flow, double[] head, double[] polytr chartValues.add(curve); } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + * + * This method initializes the compressor performance curves, including speed, flow, head, and + * polytropic efficiency. + * + *

+ * The method takes chart conditions and initializes internal variables for different performance + * parameters based on input arrays for speed, flow, head, and polytropic efficiency. It also + * normalizes these parameters by calculating reduced values based on speed. + * + * @param chartConditions An array of conditions used for the compressor chart. (Currently unused) + * @param speed An array representing the compressor speed values. + * @param flow A 2D array representing the flow rates at different speeds. + * @param head A 2D array representing the head values at different speeds. + * @param polyEff A 2D array representing the polytropic efficiency values at different speeds. + */ @Override public void setCurves(double[] chartConditions, double[] speed, double[][] flow, double[][] head, double[][] polyEff) { @@ -75,9 +91,16 @@ public void setCurves(double[] chartConditions, double[] speed, double[][] flow, this.polytropicEfficiency = polyEff; this.flow = flow; - this.redhead = new double[head.length][head[0].length]; - this.redpolytropicEfficiency = new double[polyEff.length][polyEff[0].length]; - this.redflow = new double[flow.length][flow[0].length]; + // Dynamically initialize arrays based on the maximum length of flow, head, and polyEff + int maxLength = 0; + for (double[] f : flow) { + if (f.length > maxLength) + maxLength = f.length; + } + + this.redhead = new double[head.length][maxLength]; + this.redpolytropicEfficiency = new double[polyEff.length][maxLength]; + this.redflow = new double[flow.length][maxLength]; for (int i = 0; i < speed.length; i++) { if (speed[i] > maxSpeedCurve) { @@ -88,7 +111,8 @@ public void setCurves(double[] chartConditions, double[] speed, double[][] flow, } CompressorCurve curve = new CompressorCurve(speed[i], flow[i], head[i], polyEff[i]); chartValues.add(curve); - for (int j = 0; j < flow[i].length; j++) { + + for (int j = 0; j < flow[i].length; j++) { // Handle differing lengths for each speed redflow[i][j] = flow[i][j] / speed[i]; redpolytropicEfficiency[i][j] = polyEff[i][j]; redhead[i][j] = head[i][j] / speed[i] / speed[i]; @@ -98,6 +122,13 @@ public void setCurves(double[] chartConditions, double[] speed, double[][] flow, // TODO: MLLU: not correct. speed[0] should be the requested speed fanLawCorrectionFitter.add(speed[i] / speed[0], flow[i][j] / flowFanLaw); } + + // Fill remaining slots with default values (e.g., 0) if arrays are shorter + for (int j = flow[i].length; j < maxLength; j++) { + redflow[i][j] = 0; + redpolytropicEfficiency[i][j] = 0; + redhead[i][j] = 0; + } } referenceSpeed = (maxSpeedCurve + minSpeedCurve) / 2.0; diff --git a/src/main/java/neqsim/process/equipment/compressor/CompressorInterface.java b/src/main/java/neqsim/process/equipment/compressor/CompressorInterface.java index d9bfdf543..184862452 100644 --- a/src/main/java/neqsim/process/equipment/compressor/CompressorInterface.java +++ b/src/main/java/neqsim/process/equipment/compressor/CompressorInterface.java @@ -73,37 +73,73 @@ public interface CompressorInterface extends ProcessEquipmentInterface, TwoPortI public AntiSurge getAntiSurge(); /** - *

getDistanceToSurge.

+ *

+ * getDistanceToSurge. + *

* * @return a double */ public double getDistanceToSurge(); /** - *

setMaximumSpeed.

+ *

+ * setMaximumSpeed. + *

* * @param maxSpeed a double */ public void setMaximumSpeed(double maxSpeed); /** - *

setMinimumSpeed.

+ *

+ * setMinimumSpeed. + *

* * @param minspeed a double */ public void setMinimumSpeed(double minspeed); /** - *

getMaximumSpeed.

+ *

+ * getMaximumSpeed. + *

* * @return a double */ public double getMaximumSpeed(); /** - *

getMinimumSpeed.

+ *

+ * getMinimumSpeed. + *

* * @return a double */ public double getMinimumSpeed(); + + /** + *

+ * getSurgeFlowRateMargin. + *

+ * + * @return a double + */ + public double getSurgeFlowRateMargin(); + + /** + *

+ * getSurgeFlowRate. + *

+ * + * @return a double + */ + public double getSurgeFlowRate(); + + /** + *

+ * Set CompressorChartType + *

+ * + */ + public void setCompressorChartType(String type); } diff --git a/src/test/java/neqsim/process/equipment/compressor/CompressorChartTest.java b/src/test/java/neqsim/process/equipment/compressor/CompressorChartTest.java index d8e0229cc..e0c0b8c9b 100644 --- a/src/test/java/neqsim/process/equipment/compressor/CompressorChartTest.java +++ b/src/test/java/neqsim/process/equipment/compressor/CompressorChartTest.java @@ -4,10 +4,9 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import neqsim.process.equipment.compressor.Compressor; -import neqsim.process.equipment.compressor.CompressorChart; import neqsim.process.equipment.stream.Stream; import neqsim.thermo.system.SystemInterface; +import neqsim.thermo.system.SystemPrEos; import neqsim.thermo.system.SystemSrkEos; public class CompressorChartTest { @@ -178,4 +177,91 @@ void testSetHeadUnit() { "neqsim.util.exception.InvalidInputException: CompressorChart:setHeadUnit - Input headUnit does not support value doesNotExist", thrown.getMessage()); } + + @Test + public void runCurveTest() { + SystemInterface testFluid = new SystemPrEos(273.15 + 29.96, 75.73); + + testFluid.addComponent("nitrogen", 0.7823); + testFluid.addComponent("CO2", 1.245); + testFluid.addComponent("methane", 88.4681); + testFluid.addComponent("ethane", 4.7652); + testFluid.addComponent("propane", 2.3669); + testFluid.addComponent("i-butane", 0.3848); + testFluid.addComponent("n-butane", 0.873); + testFluid.addComponent("i-pentane", 0.243); + testFluid.addComponent("n-pentane", 0.2947); + testFluid.addComponent("n-hexane", 0.2455); + testFluid.addComponent("n-heptane", 0.1735); + testFluid.addComponent("n-octane", 0.064); + testFluid.addComponent("water", 0.076); + testFluid.setMixingRule("classic"); + + testFluid.setTemperature(29.96, "C"); + testFluid.setPressure(75.73, "bara"); + testFluid.setTotalFlowRate(559401.418270102, "kg/hr"); + + Stream stream_1 = new Stream("Stream1", testFluid); + stream_1.run(); + + stream_1.getFluid().prettyPrint(); + + Compressor comp1 = new Compressor("compressor 1", stream_1); + //comp1.setCompressorChartType("interpolate"); + comp1.setUsePolytropicCalc(true); + comp1.setSpeed(8765); + + double[] chartConditions = new double[] {0.3, 1.0, 1.0, 1.0}; + + double[] speed = new double[] {7000, 7500, 8000, 8500, 9000, 9500, 9659, 10000, 10500}; + + double[][] flow = new double[][] {{4512.7, 5120.8, 5760.9, 6401, 6868.27}, + {4862.47, 5486.57, 6172.39, 6858.21, 7550.89}, + {5237.84, 5852.34, 6583.88, 7315.43, 8046.97, 8266.43}, + {5642.94, 6218.11, 6995.38, 7772.64, 8549.9, 9000.72}, + {6221.77, 6583.88, 7406.87, 8229.85, 9052.84, 9768.84}, + {6888.85, 6949.65, 7818.36, 8687.07, 9555.77, 10424.5, 10546.1}, + {7109.83, 7948.87, 8832.08, 9715.29, 10598.5, 10801.6}, + {7598.9, 8229.85, 9144.28, 10058.7, 10973.1, 11338.9}, + {8334.1, 8641.35, 9601.5, 10561.6, 11521.8, 11963.5}}; + + double[][] head = new double[][] {{61.885, 59.639, 56.433, 52.481, 49.132}, + {71.416, 69.079, 65.589, 61.216, 55.858}, {81.621, 79.311, 75.545, 70.727, 64.867, 62.879,}, + {92.493, 90.312, 86.3, 81.079, 74.658, 70.216}, + {103.512, 102.073, 97.83, 92.254, 85.292, 77.638}, + {114.891, 114.632, 110.169, 104.221, 96.727, 87.002, 85.262}, + {118.595, 114.252, 108.203, 100.55, 90.532, 87.54}, + {126.747, 123.376, 117.113, 109.056, 98.369, 92.632}, + {139.082, 137.398, 130.867, 122.264, 110.548, 103.247},}; + double[][] polyEff = new double[][] {{78.3, 78.2, 77.2, 75.4, 73.4}, + + {78.3, 78.3, 77.5, 75.8, 73}, {78.2, 78.4, 77.7, 76.1, 73.5, 72.5}, + {78.2, 78.4, 77.9, 76.4, 74, 71.9}, {78.3, 78.4, 78, 76.7, 74.5, 71.2}, + {78.3, 78.4, 78.1, 77, 74.9, 71.3, 70.5}, {78.4, 78.1, 77.1, 75, 71.4, 70.2}, + {78.3, 78.2, 77.2, 75.2, 71.7, 69.5}, {78.2, 78.2, 77.3, 75.5, 72.2, 69.6}}; + + comp1.getCompressorChart().setCurves(chartConditions, speed, flow, head, polyEff); + comp1.getCompressorChart().setHeadUnit("kJ/kg"); + + double[] surgeflow = + new double[] {4512.7, 4862.47, 5237.84, 5642.94, 6221.77, 6888.85, 7109.83, 7598.9}; + double[] surgehead = + new double[] {61.885, 71.416, 81.621, 92.493, 103.512, 114.891, 118.595, 126.747}; + comp1.getCompressorChart().getSurgeCurve().setCurve(chartConditions, surgeflow, surgehead); + // comp1.getAntiSurge().setActive(true); + comp1.getAntiSurge().setSurgeControlFactor(1.0); + comp1.run(); + + System.out.println("speed " + comp1.getSpeed()); + System.out.println("out pres " + comp1.getOutletPressure()); + System.out.println("out temp " + (comp1.getOutTemperature() - 273.15)); + System.out.println("feed flow " + (comp1.getInletStream().getFlowRate("m3/hr"))); + System.out.println("polytropic head " + comp1.getPolytropicFluidHead()); + System.out.println("polytropic efficiency " + comp1.getPolytropicEfficiency()); + System.out.println("dist to surge " + comp1.getDistanceToSurge()); + System.out.println("surge flow rate margin " + comp1.getSurgeFlowRateMargin()); + System.out.println("surge flow rate " + comp1.getSurgeFlowRate()); + System.out.println("duty " + comp1.getPower("MW")); + } + }