diff --git a/src/main/java/neqsim/processSimulation/processEquipment/compressor/Compressor.java b/src/main/java/neqsim/processSimulation/processEquipment/compressor/Compressor.java index 7c040f06f6..9ad463572f 100644 --- a/src/main/java/neqsim/processSimulation/processEquipment/compressor/Compressor.java +++ b/src/main/java/neqsim/processSimulation/processEquipment/compressor/Compressor.java @@ -34,6 +34,8 @@ public class Compressor extends TwoPortEquipment implements CompressorInterface public SystemInterface thermoSystem; private double outTemperature = 298.15; private boolean useOutTemperature = false; + private double compressionRatio = 2.0; + private boolean useCompressionRatio = false; private CompressorPropertyProfile propertyProfile = new CompressorPropertyProfile(); public double dH = 0.0; public double inletEnthalpy = 0; @@ -360,6 +362,9 @@ public void run(UUID id) { double orginalMolarFLow = thermoSystem.getTotalNumberOfMoles(); double fractionAntiSurge = 0.0; double kappa = 0.0; + if (useCompressionRatio) { + setOutletPressure(presinn * compressionRatio); + } if (useOutTemperature) { if (useRigorousPolytropicMethod) { solveEfficiency(outTemperature); @@ -668,7 +673,7 @@ public void run(UUID id) { polytropicFluidHead = getPower() / getThermoSystem().getFlowRate("kg/sec") / 1000.0 * getPolytropicEfficiency(); polytropicHeadMeter = polytropicFluidHead * 1000.0 / 9.81; - + compressionRatio = getOutletPressure() / presinn; setCalculationIdentifier(id); } @@ -1401,4 +1406,13 @@ public double getMaximumSpeed() { public double getMinimumSpeed() { return minspeed; } + + public void setCompressionRatio(double compRatio) { + this.compressionRatio = compRatio; + useCompressionRatio = true; + } + + public double getCompressionRatio() { + return compressionRatio; + } } diff --git a/src/main/java/neqsim/processSimulation/processEquipment/pipeline/PipeBeggsAndBrills.java b/src/main/java/neqsim/processSimulation/processEquipment/pipeline/PipeBeggsAndBrills.java index 6f1212fa92..5fec96a788 100644 --- a/src/main/java/neqsim/processSimulation/processEquipment/pipeline/PipeBeggsAndBrills.java +++ b/src/main/java/neqsim/processSimulation/processEquipment/pipeline/PipeBeggsAndBrills.java @@ -36,7 +36,7 @@ public class PipeBeggsAndBrills extends Pipeline { // Roughness of the pipe wall [m] private double pipeWallRoughness = 1e-5; - // Flag to run isothermal calculations + // Flag to run isothermal calculations private boolean runIsothermal = false; // Flow pattern of the fluid in the pipe @@ -109,7 +109,7 @@ public class PipeBeggsAndBrills extends Pipeline { private double cumulativeElevation; - //For segment calculation + // For segment calculation double length; double elevation; @@ -340,7 +340,7 @@ public void calculateMissingValue() { throw new RuntimeException( new neqsim.util.exception.InvalidInputException("PipeBeggsAndBrills", "calcMissingValue", "elevation or length or angle", "cannot be null")); - } + } } @@ -675,7 +675,7 @@ public void run(UUID id) { testOps.TPflash(); system.initProperties(); - if (!runIsothermal){ + if (!runIsothermal) { enthalpyInlet = system.getEnthalpy(); } double pipeInletPressure = system.getPressure(); @@ -700,7 +700,7 @@ public void run(UUID id) { } system.setPressure(pressureOut); - if (!runIsothermal){ + if (!runIsothermal) { testOps.PHflash(enthalpyInlet); } system.initProperties(); @@ -711,6 +711,21 @@ public void run(UUID id) { outStream.setCalculationIdentifier(id); } + /** + * {@inheritDoc} + * + *
+ * runTransient. + *
+ */ + @Override + public void runTransient(double dt, UUID id) { + run(id); + increaseTime(dt); + return; + + } + /** {@inheritDoc} */ @Override public void displayResult() { @@ -740,14 +755,14 @@ public double getAngle() { /** - * @return total length of the pipe in m + * @return total length of the pipe in m */ public double getLength() { return cumulativeLength; } - /** - * @return total elevation of the pipe in m + /** + * @return total elevation of the pipe in m */ public double getElevation() { return cumulativeElevation; diff --git a/src/main/java/neqsim/processSimulation/processEquipment/reservoir/WellFlow.java b/src/main/java/neqsim/processSimulation/processEquipment/reservoir/WellFlow.java index b6a438c12d..f804d1126a 100644 --- a/src/main/java/neqsim/processSimulation/processEquipment/reservoir/WellFlow.java +++ b/src/main/java/neqsim/processSimulation/processEquipment/reservoir/WellFlow.java @@ -1,5 +1,13 @@ package neqsim.processSimulation.processEquipment.reservoir; +import java.util.UUID; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import neqsim.processSimulation.processEquipment.TwoPortEquipment; +import neqsim.processSimulation.processEquipment.stream.StreamInterface; +import neqsim.processSimulation.processEquipment.valve.ThrottlingValve; +import neqsim.thermo.system.SystemInterface; + /** ** WellFlow class. @@ -8,5 +16,93 @@ * @author asmund * @version $Id: $Id */ -public class WellFlow { +public class WellFlow extends TwoPortEquipment { + private static final long serialVersionUID = 1000; + static Logger logger = LogManager.getLogger(ThrottlingValve.class); + SystemInterface thermoSystem; + private double wellProductionIndex = 0; + double pressureOut = 1.0; + String pressureUnit = "bara"; + boolean useWellProductionIndex = false; + boolean calcpressure = true; + + + /** + *
+ * Constructor for WellFlow. + *
+ * + * @param name a {@link java.lang.String} object + */ + public WellFlow(String name) { + super(name); + } + + /** {@inheritDoc} */ + @Override + public void setInletStream(StreamInterface stream) { + super.setInletStream(stream); + StreamInterface outStream = stream.clone(); + outStream.setName("outStream"); + super.setOutletStream(outStream); + } + + /** {@inheritDoc} */ + @Override + public void run(UUID id) { + thermoSystem = getInletStream().getThermoSystem().clone(); + thermoSystem.setPressure(pressureOut, pressureUnit); + outStream.setThermoSystem(thermoSystem); + if (useWellProductionIndex) { + if (calcpressure) { + double presout = 1.0; + if (Math.pow(getInletStream().getPressure("bara"), 2.0) + - getInletStream().getFlowRate("MSm3/day") / wellProductionIndex > 0) { + presout = Math.sqrt(Math.pow(getInletStream().getPressure("bara"), 2.0) + - getInletStream().getFlowRate("MSm3/day") / wellProductionIndex); + } else { + logger.error("pressure lower that 0"); + throw new RuntimeException( + new neqsim.util.exception.InvalidInputException("WellFlow", "run: calcOutletPressure", + "pressure", "- Outlet pressure is negative" + pressureOut)); + } + // System.out.println("out pres " + presout); + outStream.setPressure(presout, "bara"); + } else { + double flow = wellProductionIndex * (Math.pow(getInletStream().getPressure("bara"), 2.0) + - Math.pow(thermoSystem.getPressure("bara"), 2.0)); + outStream.setFlowRate(flow, "MSm3/day"); + } + } else { + wellProductionIndex = getInletStream().getFlowRate("MSm3/day") + / (Math.pow(getInletStream().getPressure("bara"), 2.0) + - Math.pow(thermoSystem.getPressure("bara"), 2.0)); + } + outStream.run(); + } + + /** {@inheritDoc} */ + @Override + public void runTransient(double dt, UUID id) { + if (getCalculateSteadyState()) { + run(id); + increaseTime(dt); + return; + } + double flow = wellProductionIndex * (Math.pow(getInletStream().getPressure("bara"), 2.0) + - Math.pow(thermoSystem.getPressure("bara"), 2.0)); + + outStream.setFlowRate(flow, "MSm3/day"); + outStream.run(); + } + + public double getWellProductionIndex() { + return wellProductionIndex; + } + + public void setWellProductionIndex(double wellProductionIndex) { + useWellProductionIndex = true; + this.wellProductionIndex = wellProductionIndex; + } + } diff --git a/src/main/java/neqsim/processSimulation/processEquipment/util/Adjuster.java b/src/main/java/neqsim/processSimulation/processEquipment/util/Adjuster.java index ed9e6970ce..1d1e228047 100644 --- a/src/main/java/neqsim/processSimulation/processEquipment/util/Adjuster.java +++ b/src/main/java/neqsim/processSimulation/processEquipment/util/Adjuster.java @@ -23,6 +23,9 @@ public class Adjuster extends ProcessEquipmentBaseClass { ProcessEquipmentInterface targetEquipment = null; String adjustedVariable = ""; + String adjustedVariableUnit = ""; + double maxAdjustedValue = 1e10; + double minAdjustedValue = -1e10; String targetVariable = ""; String targetPhase = ""; String targetComponent = ""; @@ -59,6 +62,22 @@ public Adjuster(String name) { super(name); } + /** + *+ * setAdjustedVariable. + *
+ * + * @param adjustedEquipment a + * {@link neqsim.processSimulation.processEquipment.ProcessEquipmentInterface} object + * @param adjstedVariable a {@link java.lang.String} object + */ + public void setAdjustedVariable(ProcessEquipmentInterface adjustedEquipment, + String adjstedVariable, String unit) { + this.adjustedEquipment = adjustedEquipment; + this.adjustedVariable = adjstedVariable; + this.adjustedVariableUnit = unit; + } + /** ** setAdjustedVariable. @@ -144,6 +163,8 @@ public void run(UUID id) { if (adjustedVariable.equals("mass flow")) { inputValue = ((Stream) adjustedEquipment).getThermoSystem().getFlowRate("kg/hr"); + } else if (adjustedVariable.equals("flow") && adjustedVariableUnit != null) { + inputValue = ((Stream) adjustedEquipment).getThermoSystem().getFlowRate(adjustedVariableUnit); } else { inputValue = ((Stream) adjustedEquipment).getThermoSystem().getNumberOfMoles(); } @@ -177,6 +198,9 @@ public void run(UUID id) { if (adjustedVariable.equals("mass flow")) { ((Stream) adjustedEquipment).getThermoSystem().setTotalFlowRate(inputValue + deviation, "kg/hr"); + } else if (adjustedVariable.equals("flow") && adjustedVariableUnit != null) { + ((Stream) adjustedEquipment).getThermoSystem().setTotalFlowRate( + inputValue + Math.signum(deviation) * inputValue / 100.0, adjustedVariableUnit); } else { ((Stream) adjustedEquipment).getThermoSystem().setTotalFlowRate(inputValue + deviation, "mol/sec"); @@ -184,9 +208,20 @@ public void run(UUID id) { } else { double derivate = (error - oldError) / (inputValue - oldInputValue); double newVal = error / derivate; + if (inputValue - newVal > maxAdjustedValue) { + newVal = inputValue - maxAdjustedValue; + error = 0; + } + if (inputValue - newVal < minAdjustedValue) { + newVal = inputValue - minAdjustedValue; + error = 0; + } if (adjustedVariable.equals("mass flow")) { ((Stream) adjustedEquipment).getThermoSystem().setTotalFlowRate(inputValue - newVal, "kg/hr"); + } else if (adjustedVariable.equals("flow") && adjustedVariableUnit != null) { + ((Stream) adjustedEquipment).getThermoSystem().setTotalFlowRate(inputValue - newVal, + adjustedVariableUnit); } else { ((Stream) adjustedEquipment).getThermoSystem().setTotalFlowRate(inputValue - newVal, "mol/sec"); @@ -305,4 +340,28 @@ public boolean isActivateWhenLess() { public void setActivateWhenLess(boolean activateWhenLess) { this.activateWhenLess = activateWhenLess; } + + public void setMaxAdjustedValue(double maxVal) { + maxAdjustedValue = maxVal; + if (maxAdjustedValue < minAdjustedValue) { + minAdjustedValue = maxAdjustedValue; + } + } + + public void setMinAdjustedValue(double minVal) { + minAdjustedValue = minVal; + if (minAdjustedValue > maxAdjustedValue) { + maxAdjustedValue = minAdjustedValue; + } + + } + + public double getMaxAdjustedValue() { + return maxAdjustedValue; + } + + public double getMinAdjustedValue() { + return minAdjustedValue; + } + } diff --git a/src/main/java/neqsim/processSimulation/processSystem/ProcessSystem.java b/src/main/java/neqsim/processSimulation/processSystem/ProcessSystem.java index c63a5a38f9..0879fb25bc 100644 --- a/src/main/java/neqsim/processSimulation/processSystem/ProcessSystem.java +++ b/src/main/java/neqsim/processSimulation/processSystem/ProcessSystem.java @@ -95,6 +95,38 @@ public void add(ProcessEquipmentInterface operation) { } } + /** + *
+ * add. + *
+ * + */ + public void add(int position, ProcessEquipmentInterface operation) { + ArrayList* add. diff --git a/src/test/java/neqsim/processSimulation/processEquipment/reservoir/WellFlowTest.java b/src/test/java/neqsim/processSimulation/processEquipment/reservoir/WellFlowTest.java new file mode 100644 index 0000000000..daef85468a --- /dev/null +++ b/src/test/java/neqsim/processSimulation/processEquipment/reservoir/WellFlowTest.java @@ -0,0 +1,192 @@ +package neqsim.processSimulation.processEquipment.reservoir; + +import org.junit.jupiter.api.Test; +import neqsim.processSimulation.processEquipment.compressor.Compressor; +import neqsim.processSimulation.processEquipment.pipeline.PipeBeggsAndBrills; +import neqsim.processSimulation.processEquipment.stream.StreamInterface; +import neqsim.processSimulation.processEquipment.util.Adjuster; +import neqsim.processSimulation.processEquipment.valve.ThrottlingValve; +import neqsim.processSimulation.processSystem.ProcessSystem; + +public class WellFlowTest { + @Test + void testRun() { + + neqsim.thermo.system.SystemInterface fluid1 = + new neqsim.thermo.system.SystemPrEos(373.15, 100.0); + fluid1.addComponent("water", 3.599); + fluid1.addComponent("nitrogen", 0.599); + fluid1.addComponent("CO2", 0.51); + fluid1.addComponent("methane", 62.8); + fluid1.addComponent("n-heptane", 12.8); + fluid1.setMixingRule(2); + fluid1.setMultiPhaseCheck(true); + + SimpleReservoir reservoirOps = new SimpleReservoir("Well 1 reservoir"); + reservoirOps.setReservoirFluid(fluid1, 1e9, 10.0, 10.0e7); + + StreamInterface producedGasStream = reservoirOps.addGasProducer("gasproducer_1"); + producedGasStream.setFlowRate(1.0, "MSm3/day"); + + WellFlow wellflow = new WellFlow("well flow unit"); + wellflow.setInletStream(producedGasStream); + wellflow.setWellProductionIndex(5.000100751427403E-4); + + ProcessSystem process = new ProcessSystem(); + process.add(reservoirOps); + process.add(wellflow); + + process.run(); + /* + * System.out.println("production index " + wellflow.getWellProductionIndex() + + * " MSm3/day/bar^2"); System.out.println("reservoir pressure " + + * producedGasStream.getPressure("bara")); System.out .println("pres bottomhole " + + * wellflow.getOutletStream().getPressure("bara") + " bara"); + */ + } + + @Test + void testRunTransient() { + neqsim.thermo.system.SystemInterface fluid1 = + new neqsim.thermo.system.SystemPrEos(373.15, 100.0); + fluid1.addComponent("water", 3.599); + fluid1.addComponent("nitrogen", 0.599); + fluid1.addComponent("CO2", 0.51); + fluid1.addComponent("methane", 62.8); + fluid1.setMixingRule(2); + fluid1.setMultiPhaseCheck(true); + + SimpleReservoir reservoirOps = new SimpleReservoir("Well 1 reservoir"); + reservoirOps.setReservoirFluid(fluid1, 1e9, 1.0, 10.0e7); + reservoirOps.setLowPressureLimit(10.0, "bara"); + + StreamInterface producedGasStream = reservoirOps.addGasProducer("gasproducer_1"); + producedGasStream.setFlowRate(9.0, "MSm3/day"); + + WellFlow wellflow = new WellFlow("well flow unit"); + wellflow.setInletStream(producedGasStream); + wellflow.setWellProductionIndex(10.000100751427403E-3); + + PipeBeggsAndBrills pipe = new PipeBeggsAndBrills(wellflow.getOutletStream()); + pipe.setPipeWallRoughness(5e-6); + pipe.setLength(300.0); + pipe.setElevation(300); + pipe.setDiameter(0.625); + + PipeBeggsAndBrills pipeline = new PipeBeggsAndBrills(wellflow.getOutletStream()); + pipeline.setPipeWallRoughness(5e-6); + pipeline.setLength(60000.0); + pipeline.setElevation(200); + pipeline.setDiameter(0.725); + + ThrottlingValve chokeValve = new ThrottlingValve("chocke"); + chokeValve.setInletStream(pipeline.getOutletStream()); + chokeValve.setOutletPressure(55.0, "bara"); + + + Adjuster adjuster = new Adjuster("adjuster"); + adjuster.setTargetVariable(pipeline.getOutletStream(), "pressure", + chokeValve.getOutletPressure(), "bara"); + adjuster.setAdjustedVariable(producedGasStream, "flow", "MSm3/day"); + adjuster.setMaxAdjustedValue(9.0); + adjuster.setMinAdjustedValue(1.0); + + ProcessSystem process = new ProcessSystem(); + process.add(reservoirOps); + process.add(wellflow); + process.add(pipe); + process.add(pipeline); + process.add(adjuster); + process.run(); + /* + * System.out.println("production flow rate " + producedGasStream.getFlowRate("MSm3/day")); + * System.out.println("production index " + wellflow.getWellProductionIndex() + + * " MSm3/day/bar^2"); System.out.println("reservoir pressure " + + * producedGasStream.getPressure("bara")); System.out .println("pres bottomhole " + + * wellflow.getOutletStream().getPressure("bara") + " bara"); + * System.out.println("xmas pressure " + pipe.getOutletStream().getPressure("bara") + " bara"); + * System.out .println("top side pressure " + pipeline.getOutletStream().getPressure("bara") + + * " bara"); + */ + // process.setTimeStep(60 * 60 * 24 * 365); + + for (int i = 0; i < 10; i++) { + reservoirOps.runTransient(60 * 60 * 24 * 365); + process.run(); + /* + * System.out.println("production flow rate " + producedGasStream.getFlowRate("MSm3/day")); + * System.out.println("reservoir pressure " + wellflow.getInletStream().getPressure("bara")); + * System.out .println("pres bottomhole " + wellflow.getOutletStream().getPressure("bara") + + * " bara"); + * + * System.out.println("xmas pressure " + pipe.getOutletStream().getPressure("bara") + + * " bara"); System.out .println("top side pressure " + + * pipeline.getOutletStream().getPressure("bara") + " bara"); System.out + * .println("Total produced gas " + reservoirOps.getGasProductionTotal("GMSm3") + " GMSm3"); + * System.out.println("gas velocity " + pipeline.getSuperficialVelocity()); + */ + } + + Compressor compressor = new Compressor("subcomp"); + compressor.setInletStream(pipe.getOutletStream()); + compressor.setCompressionRatio(3.0); + pipeline.setInletStream(compressor.getOutletStream()); + + process.add(3, compressor); + + for (int i = 0; i < 8; i++) { + reservoirOps.runTransient(60 * 60 * 24 * 365); + process.run(); + /* + * System.out.println("Compressor in pressure " + compressor.getInletStream().getPressure() + + * " out pressure " + compressor.getOutletStream().getPressure() + " flow " + + * compressor.getInletStream().getFlowRate("m3/hr")); + * System.out.println("production flow rate " + producedGasStream.getFlowRate("MSm3/day")); + * System.out.println("reservoir pressure " + wellflow.getInletStream().getPressure("bara")); + * System.out .println("pres bottomhole " + wellflow.getOutletStream().getPressure("bara") + + * " bara"); + * + * System.out.println("xmas pressure " + pipe.getOutletStream().getPressure("bara") + + * " bara"); System.out .println("top side pressure " + + * pipeline.getOutletStream().getPressure("bara") + " bara"); System.out + * .println("Total produced gas " + reservoirOps.getGasProductionTotal("GMSm3") + " GMSm3"); + * System.out.println("gas velocity " + pipeline.getSuperficialVelocity()); + */ + + } + + adjuster.setMaxAdjustedValue(4.0); + adjuster.setTargetVariable(pipeline.getOutletStream(), "pressure", 22.0, "bara"); + boolean reset = false; + for (int i = 0; i < 35; i++) { + if (wellflow.getOutletStream().getPressure("bara") > 15 || reset) { + reset = false; + reservoirOps.runTransient(60 * 60 * 24 * 365); + compressor.setOutletPressure(pipe.getOutletPressure() * 3.5); + process.run(); + /* + * System.out.println("Compressor in pressure " + compressor.getInletStream().getPressure() + * + " out pressure " + compressor.getOutletStream().getPressure() + " flow " + + * compressor.getInletStream().getFlowRate("m3/hr")); + * System.out.println("production flow rate " + producedGasStream.getFlowRate("MSm3/day")); + * System.out.println("reservoir pressure " + + * wellflow.getInletStream().getPressure("bara")); System.out .println("pres bottomhole " + + * wellflow.getOutletStream().getPressure("bara") + " bara"); + * + * System.out.println("xmas pressure " + pipe.getOutletStream().getPressure("bara") + + * " bara"); System.out.println( "top side pressure " + + * pipeline.getOutletStream().getPressure("bara") + " bara"); System.out.println( + * "Total produced gas " + reservoirOps.getGasProductionTotal("GMSm3") + " GMSm3"); + * System.out.println("gas velocity " + pipeline.getSuperficialVelocity()); + */ + } else { + reset = true; + adjuster.setMaxAdjustedValue(adjuster.getMaxAdjustedValue() / 2.0); + adjuster.setMinAdjustedValue(adjuster.getMinAdjustedValue() / 2.0); + } + + } + } + + +}