From 260b7ccfcb3d8a0d8649fe6ec6d4bef05be60692 Mon Sep 17 00:00:00 2001 From: Even Solbraa <41290109+EvenSol@users.noreply.github.com> Date: Mon, 13 Jan 2025 08:53:33 +0000 Subject: [PATCH 1/4] updated TwoPhaseSeparator --- .../separator/TwoPhaseSeparator.java | 73 +------------------ 1 file changed, 3 insertions(+), 70 deletions(-) diff --git a/src/main/java/neqsim/process/equipment/separator/TwoPhaseSeparator.java b/src/main/java/neqsim/process/equipment/separator/TwoPhaseSeparator.java index 58dae0ee1..d7b3858ef 100644 --- a/src/main/java/neqsim/process/equipment/separator/TwoPhaseSeparator.java +++ b/src/main/java/neqsim/process/equipment/separator/TwoPhaseSeparator.java @@ -18,17 +18,6 @@ public class TwoPhaseSeparator extends Separator { /** Serialization version UID. */ private static final long serialVersionUID = 1000; - SystemInterface thermoSystem; - - SystemInterface gasSystem; - SystemInterface waterSystem; - SystemInterface liquidSystem; - SystemInterface thermoSystemCloned; - - StreamInterface inletStream; - StreamInterface gasOutStream; - StreamInterface liquidOutStream; - /** * Constructor for TwoPhaseSeparator. * @@ -43,68 +32,12 @@ public TwoPhaseSeparator(String name) { * Constructor for TwoPhaseSeparator. *

* - * @param name a {@link java.lang.String} object - * @param inletStream a {@link neqsim.process.equipment.stream.StreamInterface} object + * @param name a {@link java.lang.String} object + * @param inletStream a {@link neqsim.process.equipment.stream.StreamInterface} + * object */ public TwoPhaseSeparator(String name, StreamInterface inletStream) { super(name, inletStream); } - /** {@inheritDoc} */ - @Override - public void setInletStream(StreamInterface inletStream) { - this.inletStream = inletStream; - - thermoSystem = inletStream.getThermoSystem().clone(); - gasSystem = thermoSystem.phaseToSystem(thermoSystem.getPhases()[0]); - gasOutStream = new Stream("gasOutStream", gasSystem); - - thermoSystem = inletStream.getThermoSystem().clone(); - liquidSystem = thermoSystem.phaseToSystem(thermoSystem.getPhases()[1]); - liquidOutStream = new Stream("liquidOutStream", liquidSystem); - } - - /** {@inheritDoc} */ - @Override - public StreamInterface getLiquidOutStream() { - return liquidOutStream; - } - - /** {@inheritDoc} */ - @Override - public StreamInterface getGasOutStream() { - return gasOutStream; - } - - /** {@inheritDoc} */ - @Override - public StreamInterface getGas() { - return getGasOutStream(); - } - - /** {@inheritDoc} */ - @Override - public StreamInterface getLiquid() { - return getLiquidOutStream(); - } - - /** {@inheritDoc} */ - @Override - public void run(UUID id) { - thermoSystem = inletStream.getThermoSystem().clone(); - gasSystem = thermoSystem.phaseToSystem(thermoSystem.getPhases()[0]); - gasSystem.setNumberOfPhases(1); - gasOutStream.setThermoSystem(gasSystem); - - thermoSystem = inletStream.getThermoSystem().clone(); - liquidSystem = thermoSystem.phaseToSystem(thermoSystem.getPhases()[1]); - liquidSystem.setNumberOfPhases(1); - liquidOutStream.setThermoSystem(liquidSystem); - setCalculationIdentifier(id); - } - - /** {@inheritDoc} */ - @Override - @ExcludeFromJacocoGeneratedReport - public void displayResult() {} } From 7260f37b984fcd1273b6c8a9513a4e3d1fa44d90 Mon Sep 17 00:00:00 2001 From: Even Solbraa <41290109+EvenSol@users.noreply.github.com> Date: Mon, 13 Jan 2025 21:39:42 +0000 Subject: [PATCH 2/4] added possibility to add part models --- .../process/processmodel/ProcessModel.java | 140 ++++++++- .../processmodel/LargeCombinedModelsTest.java | 289 +++++++++--------- 2 files changed, 287 insertions(+), 142 deletions(-) diff --git a/src/main/java/neqsim/process/processmodel/ProcessModel.java b/src/main/java/neqsim/process/processmodel/ProcessModel.java index dac8bf6f5..17ca43ff1 100644 --- a/src/main/java/neqsim/process/processmodel/ProcessModel.java +++ b/src/main/java/neqsim/process/processmodel/ProcessModel.java @@ -1,20 +1,38 @@ package neqsim.process.processmodel; +import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** *

- * ProcessModel class. Manages a collection of processes that can be run in steps or continuously. + * ProcessModel class. Manages a collection of processes that can be run in + * steps or continuously. + * + * Extended to also allow grouping of processes and the ability to run only the + * processes + * within a given group instead of always running all. *

*/ public class ProcessModel implements Runnable { /** Logger object for class. */ static Logger logger = LogManager.getLogger(ProcessModel.class); + + /** Map of process name -> ProcessSystem. */ private Map processes = new LinkedHashMap<>(); + /** + * Map of group name -> list of process names in that group. + * + * We store process *names* here, pointing to the actual ProcessSystem in + * `processes`. + * Alternatively, you can store the ProcessSystem references directly. + */ + private Map> groups = new LinkedHashMap<>(); + private boolean runStep = false; private int maxIterations = 50; @@ -64,11 +82,111 @@ public boolean remove(String name) { return processes.remove(name) != null; } + /** + * Creates a new group or clears it if it already exists. + */ + public void createGroup(String groupName) { + if (groupName == null || groupName.isEmpty()) { + throw new IllegalArgumentException("Group name cannot be null or empty"); + } + groups.put(groupName, new ArrayList<>()); + } + + /** + * Add a process to a given group (by process name). + */ + public void addProcessToGroup(String groupName, String processName) { + if (!processes.containsKey(processName)) { + throw new IllegalArgumentException("No process with name " + processName + " found"); + } + + groups.computeIfAbsent(groupName, key -> new ArrayList<>()); + List groupProcesses = groups.get(groupName); + if (!groupProcesses.contains(processName)) { + groupProcesses.add(processName); + } + } + + /** + * Remove a process from a given group. + */ + public void removeProcessFromGroup(String groupName, String processName) { + if (groups.containsKey(groupName)) { + groups.get(groupName).remove(processName); + } + } + + /** + * Runs all processes in the specified group (step or continuous). + * + * If the group name doesn't exist or is empty, does nothing. + */ + public void runGroup(String groupName) { + if (!groups.containsKey(groupName) || groups.get(groupName).isEmpty()) { + logger.debug("Group '{}' does not exist or is empty, nothing to run", groupName); + return; + } + + List groupProcesses = groups.get(groupName); + if (runStep) { + // Step mode: just run each process once in step mode + for (String processName : groupProcesses) { + try { + if (Thread.currentThread().isInterrupted()) { + logger.debug("Thread was interrupted, exiting runGroup()..."); + return; + } + processes.get(processName).run_step(); + } catch (Exception e) { + System.err.println("Error running process step: " + e.getMessage()); + e.printStackTrace(); + } + } + } else { + // Continuous mode + int iterations = 0; + while (!Thread.currentThread().isInterrupted() && !isGroupFinished(groupName) + && iterations < maxIterations) { + for (String processName : groupProcesses) { + if (Thread.currentThread().isInterrupted()) { + logger.debug("Thread was interrupted, exiting runGroup()..."); + return; + } + try { + processes.get(processName).run(); + } catch (Exception e) { + System.err.println("Error running process: " + e.getMessage()); + e.printStackTrace(); + } + } + iterations++; + } + } + } + + /** + * Check if the group has all processes finished. + */ + public boolean isGroupFinished(String groupName) { + if (!groups.containsKey(groupName)) { + // no group or group doesn't exist -> consider it "finished" or throw exception + return true; + } + for (String processName : groups.get(groupName)) { + ProcessSystem process = processes.get(processName); + if (process != null && !process.solved()) { + return false; + } + } + return true; + } + /** * The core run method. * - * - If runStep == true, each process is run in "step" mode exactly once. - Otherwise (continuous - * mode), it loops up to maxIterations or until all processes are finished (isFinished() == true). + * - If runStep == true, each process is run in "step" mode exactly once. + * - Otherwise (continuous mode), it loops up to maxIterations or until all + * processes are finished (isFinished() == true). */ @Override public void run() { @@ -162,4 +280,20 @@ public Map getThreads() { } return threads; } + + public double getPower(String unit) { + double totalPower = 0.0; + for (ProcessSystem process : processes.values()) { + totalPower += process.getPower(unit); + } + return totalPower; + } + + public double getTotalDuty(String unit) { + double totalDuty = 0.0; + for (ProcessSystem process : processes.values()) { + totalDuty += process.getTotalDuty(unit); + } + return totalDuty; + } } diff --git a/src/test/java/neqsim/process/processmodel/LargeCombinedModelsTest.java b/src/test/java/neqsim/process/processmodel/LargeCombinedModelsTest.java index a120fb417..a2ea31c73 100644 --- a/src/test/java/neqsim/process/processmodel/LargeCombinedModelsTest.java +++ b/src/test/java/neqsim/process/processmodel/LargeCombinedModelsTest.java @@ -76,7 +76,8 @@ public static void updateInput(ProcessSystem process, ProcessInput input) { * Creates a process system that models the well stream and manifold. * * @param feedFluid the fluid used as the feed for the well streams - * @return a ProcessSystem object representing the well stream and manifold model + * @return a ProcessSystem object representing the well stream and manifold + * model */ public ProcessSystem getWellStreamAndManifoldModel(SystemInterface feedFluid) { ProcessSystem process = new ProcessSystem(); @@ -94,11 +95,11 @@ public ProcessSystem getWellStreamAndManifoldModel(SystemInterface feedFluid) { process.add(wellStreamLP); Splitter hpManifold = new Splitter("HP manifold", wellStreamHP, 2); - hpManifold.setSplitFactors(new double[] {0.4, 0.6}); + hpManifold.setSplitFactors(new double[] { 0.4, 0.6 }); process.add(hpManifold); Splitter lpManifold = new Splitter("LP manifold", wellStreamLP, 2); - lpManifold.setSplitFactors(new double[] {0.5, 0.5}); + lpManifold.setSplitFactors(new double[] { 0.5, 0.5 }); process.add(lpManifold); return process; @@ -107,12 +108,18 @@ public ProcessSystem getWellStreamAndManifoldModel(SystemInterface feedFluid) { /** * Test method for validating the well stream and manifold model. * - * This test performs the following checks: 1. Runs the well stream and manifold process model. 2. - * Asserts that the flow rate of the "HP well stream" matches the expected first stage flow rate. - * 3. Asserts that the flow rates of the split streams from the "HP manifold" match the expected - * split ratios. 4. Asserts that the total flow rate of the "HP well stream" is conserved across - * the split streams. 5. Asserts that the flow rate of the "LP well stream" matches the expected - * second stage flow rate. 6. Asserts that the total flow rate of the "LP well stream" is + * This test performs the following checks: 1. Runs the well stream and manifold + * process model. 2. + * Asserts that the flow rate of the "HP well stream" matches the expected first + * stage flow rate. + * 3. Asserts that the flow rates of the split streams from the "HP manifold" + * match the expected + * split ratios. 4. Asserts that the total flow rate of the "HP well stream" is + * conserved across + * the split streams. 5. Asserts that the flow rate of the "LP well stream" + * matches the expected + * second stage flow rate. 6. Asserts that the total flow rate of the "LP well + * stream" is * conserved across the split streams. */ @Test @@ -147,7 +154,7 @@ public void testWellStreamAndManifoldModel() { /** * Creates a separation train process for the given input streams. * - * @param firstStageStream the input stream for the first stage + * @param firstStageStream the input stream for the first stage * @param seccondStageStream the input stream for the second stage * @return the configured ProcessSystem object representing the separation train */ @@ -160,12 +167,11 @@ public ProcessSystem createSeparationTrainProcess(StreamInterface firstStageStre feedTPsetterFirstStage.setOutTemperature(inp.firstStageTemperature, "C"); // Step 2: First Stage Separator - ThreePhaseSeparator firstStageSeparator = - new ThreePhaseSeparator("1st stage separator", feedTPsetterFirstStage.getOutletStream()); + ThreePhaseSeparator firstStageSeparator = new ThreePhaseSeparator("1st stage separator", + feedTPsetterFirstStage.getOutletStream()); // Step 3: Oil Valve (Throttling Valve) after the First Stage - ThrottlingValve oilValve1 = - new ThrottlingValve("oil depres valve", firstStageSeparator.getOilOutStream()); + ThrottlingValve oilValve1 = new ThrottlingValve("oil depres valve", firstStageSeparator.getOilOutStream()); oilValve1.setOutletPressure(inp.secondStagePressure, "bara"); // Step 4: First Stage Oil Reflux Stream @@ -180,8 +186,7 @@ public ProcessSystem createSeparationTrainProcess(StreamInterface firstStageStre oilFirstStageMixer.addStream(oilFirstStage); // Step 6: Oil Heater from First Stage - Heater oilHeaterFromFirstStage = - new Heater("oil heater second stage", oilFirstStageMixer.getOutletStream()); + Heater oilHeaterFromFirstStage = new Heater("oil heater second stage", oilFirstStageMixer.getOutletStream()); oilHeaterFromFirstStage.setOutTemperature(inp.secondStageTemperature, "C"); Heater tempPresControlLPstream = new Heater("LP stream temp controller", seccondStageStream); @@ -189,8 +194,8 @@ public ProcessSystem createSeparationTrainProcess(StreamInterface firstStageStre tempPresControlLPstream.setOutTemperature(inp.secondStageTemperature, "C"); // Step 7: Second Stage Separator - ThreePhaseSeparator secondStageSeparator = - new ThreePhaseSeparator("2nd stage separator", oilHeaterFromFirstStage.getOutletStream()); + ThreePhaseSeparator secondStageSeparator = new ThreePhaseSeparator("2nd stage separator", + oilHeaterFromFirstStage.getOutletStream()); secondStageSeparator.addStream(tempPresControlLPstream.getOutletStream()); // Step 8: Second Stage Oil Reflux Stream @@ -201,18 +206,17 @@ public ProcessSystem createSeparationTrainProcess(StreamInterface firstStageStre oilSecondStage.setTemperature(inp.gasCoolerTemperature, "C"); // Step 9: Valve for Oil from the Second Stage - ThrottlingValve valve_oil_from_seccond_stage = - new ThrottlingValve("valve oil from second stage", secondStageSeparator.getOilOutStream()); + ThrottlingValve valve_oil_from_seccond_stage = new ThrottlingValve("valve oil from second stage", + secondStageSeparator.getOilOutStream()); valve_oil_from_seccond_stage.setOutletPressure(inp.thirdStagePressure, "bara"); - Mixer oilSeccondStageMixer = - new neqsim.process.equipment.mixer.Mixer("seccond stage oil mixer"); + Mixer oilSeccondStageMixer = new neqsim.process.equipment.mixer.Mixer("seccond stage oil mixer"); oilSeccondStageMixer.addStream(valve_oil_from_seccond_stage.getOutletStream()); oilSeccondStageMixer.addStream(oilSecondStage); - ThreePhaseSeparator thirdStageSeparator = - new neqsim.process.equipment.separator.ThreePhaseSeparator("3rd stage separator", - oilSeccondStageMixer.getOutletStream()); + ThreePhaseSeparator thirdStageSeparator = new neqsim.process.equipment.separator.ThreePhaseSeparator( + "3rd stage separator", + oilSeccondStageMixer.getOutletStream()); ThrottlingValve valve_oil_from_third_stage = new neqsim.process.equipment.valve.ThrottlingValve( "valve oil from third stage", thirdStageSeparator.getOilOutStream()); @@ -228,9 +232,9 @@ public ProcessSystem createSeparationTrainProcess(StreamInterface firstStageStre oilThirdStageMixer.addStream(valve_oil_from_third_stage.getOutletStream()); oilThirdStageMixer.addStream(oilThirdStage); - ThreePhaseSeparator fourthStageSeparator = - new neqsim.process.equipment.separator.ThreePhaseSeparator("4th stage separator", - oilThirdStageMixer.getOutletStream()); + ThreePhaseSeparator fourthStageSeparator = new neqsim.process.equipment.separator.ThreePhaseSeparator( + "4th stage separator", + oilThirdStageMixer.getOutletStream()); Cooler firstStageCooler = new neqsim.process.equipment.heatexchanger.Cooler("1st stage cooler", fourthStageSeparator.getGasOutStream()); @@ -295,9 +299,9 @@ public ProcessSystem createSeparationTrainProcess(StreamInterface firstStageStre Separator dewPointScrubber = new neqsim.process.equipment.separator.Separator( "dew point scrubber", dewPointControlCooler.getOutletStream()); - neqsim.process.equipment.heatexchanger.Cooler dewPointControlCooler2 = - new neqsim.process.equipment.heatexchanger.Cooler("dew point cooler 2", - dewPointScrubber.getGasOutStream()); + neqsim.process.equipment.heatexchanger.Cooler dewPointControlCooler2 = new neqsim.process.equipment.heatexchanger.Cooler( + "dew point cooler 2", + dewPointScrubber.getGasOutStream()); dewPointControlCooler2.setOutTemperature(inp.inletTexTemperature, "C"); dewPointControlCooler2.setOutPressure(inp.inletTexPressure, "bara"); @@ -378,13 +382,20 @@ public ProcessSystem createSeparationTrainProcess(StreamInterface firstStageStre /** * Test method for the separation train process. * - * This test performs the following steps: 1. Creates a process system for the well stream and - * manifold model. 2. Asserts that the flow rate of the "HP well stream" matches the expected - * input flow rate. 3. Creates two separation train processes for the split streams from the HP - * and LP manifolds. 4. Runs the main process and both separation train processes. 5. Asserts that - * the combined gas outflow rate from the dew point scrubbers in both separation train processes - * matches the expected value. 6. Asserts that the mass balance is maintained by checking that the - * total flow rate of the well streams equals the sum of the flow rates of the export oil and + * This test performs the following steps: 1. Creates a process system for the + * well stream and + * manifold model. 2. Asserts that the flow rate of the "HP well stream" matches + * the expected + * input flow rate. 3. Creates two separation train processes for the split + * streams from the HP + * and LP manifolds. 4. Runs the main process and both separation train + * processes. 5. Asserts that + * the combined gas outflow rate from the dew point scrubbers in both separation + * train processes + * matches the expected value. 6. Asserts that the mass balance is maintained by + * checking that the + * total flow rate of the well streams equals the sum of the flow rates of the + * export oil and * gas/liquid outflows from the dew point scrubbers. */ @Test @@ -395,14 +406,14 @@ public void testSeparationTrainProcess() { Assertions.assertEquals(inp.flowFirstStage, ((Stream) process.getUnit("HP well stream")).getFlowRate("MSm3/day"), 0.1); - ProcessSystem sepprocessTrain1 = - createSeparationTrainProcess(((Splitter) process.getUnit("HP manifold")).getSplitStream(0), - ((Splitter) process.getUnit("LP manifold")).getSplitStream(0)); + ProcessSystem sepprocessTrain1 = createSeparationTrainProcess( + ((Splitter) process.getUnit("HP manifold")).getSplitStream(0), + ((Splitter) process.getUnit("LP manifold")).getSplitStream(0)); sepprocessTrain1.setRunInSteps(false); - ProcessSystem sepprocessTrain2 = - createSeparationTrainProcess(((Splitter) process.getUnit("HP manifold")).getSplitStream(1), - ((Splitter) process.getUnit("LP manifold")).getSplitStream(1)); + ProcessSystem sepprocessTrain2 = createSeparationTrainProcess( + ((Splitter) process.getUnit("HP manifold")).getSplitStream(1), + ((Splitter) process.getUnit("LP manifold")).getSplitStream(1)); sepprocessTrain2.setRunInSteps(false); process.run(); @@ -437,11 +448,11 @@ public void testSeparationTrainProcess() { /** * Creates an expander process model. * - * @param dewPointScrubber2 the second dew point scrubber separator + * @param dewPointScrubber2 the second dew point scrubber separator * @param fourthStageSeparator the fourth stage separator - * @param secondstagegasmixer the second stage gas mixer - * @param firststagegasmixer the first stage gas mixer - * @param mpLiqmixer the mixer for medium pressure liquid + * @param secondstagegasmixer the second stage gas mixer + * @param firststagegasmixer the first stage gas mixer + * @param mpLiqmixer the mixer for medium pressure liquid * @return the created process system */ public ProcessSystem createExpanderProcessModel(Separator dewPointScrubber2, @@ -449,11 +460,9 @@ public ProcessSystem createExpanderProcessModel(Separator dewPointScrubber2, Mixer mpLiqmixer) { ProcessSystem process = new ProcessSystem(); - EnergyStream expander_energy_stream = - new neqsim.process.equipment.stream.EnergyStream("expander energy"); + EnergyStream expander_energy_stream = new neqsim.process.equipment.stream.EnergyStream("expander energy"); - Expander turboexpander = - new neqsim.process.equipment.expander.Expander("TEX", dewPointScrubber2.getGasOutStream()); + Expander turboexpander = new neqsim.process.equipment.expander.Expander("TEX", dewPointScrubber2.getGasOutStream()); turboexpander.setPolytropicEfficiency(0.75); turboexpander.setUsePolytropicCalc(true); turboexpander.setOutletPressure(inp.outletTexPressure, "bara"); @@ -484,8 +493,8 @@ public ProcessSystem createExpanderProcessModel(Separator dewPointScrubber2, NGLfeedvalve.setOutletPressure(inp.nglColumnTopPressure, "bara"); process.add(NGLfeedvalve); - DistillationColumn NGLcolumn = - new neqsim.process.equipment.distillation.DistillationColumn("NGL column", 5, true, false); + DistillationColumn NGLcolumn = new neqsim.process.equipment.distillation.DistillationColumn("NGL column", 5, true, + false); NGLcolumn.addFeedStream(NGLfeedvalve.getOutletStream(), 5); NGLcolumn.getReboiler().setOutTemperature(273.15 + inp.nglColumnBottomTemperature); NGLcolumn.setTopPressure(inp.nglColumnTopPressure); @@ -497,7 +506,7 @@ public ProcessSystem createExpanderProcessModel(Separator dewPointScrubber2, Splitter NGLsplitter = new neqsim.process.equipment.splitter.Splitter("NGL splitter", NGLcolumn.getLiquidOutStream(), 2); - NGLsplitter.setSplitFactors(new double[] {inp.nglRoutingToOil, 1.0 - inp.nglRoutingToOil}); + NGLsplitter.setSplitFactors(new double[] { inp.nglRoutingToOil, 1.0 - inp.nglRoutingToOil }); process.add(NGLsplitter); Mixer NGLiqmixer = new neqsim.process.equipment.mixer.Mixer("NGL mixer"); @@ -512,8 +521,7 @@ public ProcessSystem createExpanderProcessModel(Separator dewPointScrubber2, exportoil.setOutPressure(inp.exportOilPressure, "bara"); process.add(exportoil); - Stream exportoilstream = - new neqsim.process.equipment.stream.Stream("export oil", exportoil.getOutletStream()); + Stream exportoilstream = new neqsim.process.equipment.stream.Stream("export oil", exportoil.getOutletStream()); process.add(exportoilstream); Heater preheater = new neqsim.process.equipment.heatexchanger.Heater("compresor pre heater", @@ -555,21 +563,21 @@ public void testExpanderProcess() { sepprocessTrain2.setRunInSteps(true); sepprocessTrain2.run(); - ProcessSystem expanderProcess1 = - createExpanderProcessModel((Separator) sepprocessTrain1.getUnit("dew point scrubber 2"), - (ThreePhaseSeparator) sepprocessTrain1.getUnit("4th stage separator"), - (Mixer) sepprocessTrain1.getUnit("second Stage mixer"), - (Mixer) sepprocessTrain1.getUnit("first stage mixer"), - (Mixer) sepprocessTrain1.getUnit("MP liq gas mixer")); + ProcessSystem expanderProcess1 = createExpanderProcessModel( + (Separator) sepprocessTrain1.getUnit("dew point scrubber 2"), + (ThreePhaseSeparator) sepprocessTrain1.getUnit("4th stage separator"), + (Mixer) sepprocessTrain1.getUnit("second Stage mixer"), + (Mixer) sepprocessTrain1.getUnit("first stage mixer"), + (Mixer) sepprocessTrain1.getUnit("MP liq gas mixer")); expanderProcess1.setRunInSteps(true); expanderProcess1.run(); - ProcessSystem expanderProcess2 = - createExpanderProcessModel((Separator) sepprocessTrain2.getUnit("dew point scrubber 2"), - (ThreePhaseSeparator) sepprocessTrain2.getUnit("4th stage separator"), - (Mixer) sepprocessTrain2.getUnit("second Stage mixer"), - (Mixer) sepprocessTrain2.getUnit("first stage mixer"), - (Mixer) sepprocessTrain2.getUnit("MP liq gas mixer")); + ProcessSystem expanderProcess2 = createExpanderProcessModel( + (Separator) sepprocessTrain2.getUnit("dew point scrubber 2"), + (ThreePhaseSeparator) sepprocessTrain2.getUnit("4th stage separator"), + (Mixer) sepprocessTrain2.getUnit("second Stage mixer"), + (Mixer) sepprocessTrain2.getUnit("first stage mixer"), + (Mixer) sepprocessTrain2.getUnit("MP liq gas mixer")); expanderProcess2.setRunInSteps(true); expanderProcess2.run(); @@ -689,56 +697,56 @@ public ProcessSystem getExportCopressorModel(StreamInterface feedStream) { // Define chart data double[] chartConditions = {}; // Used to set molecular weight etc. - double[] speed = {6056, 6922, 7788, 8452, 8653, 9062}; - - double[][] flow = {{5142.0765, 6978.1421, 8087.4317, 9120.2186}, - {5848.6679, 7627.7535, 9001.4248, 10434.2025}, - {6663.9168, 6684.2612, 8968.5565, 10866.4216, 12176.113}, - {7842.1913, 9985.0959, 11963.8853, 13415.3073}, - {8288.4078, 9986.9093, 12007.0675, 13862.3171}, - {8736.8911, 11001.182, 12657.5213, 14593.6951}}; - - double[][] head = {{63.51995404800001, 59.95565633700001, 52.876617111, 42.72948567000001}, - {82.842135201, 77.94996177600001, 69.992872614, 55.8786330900000}, - {106.11871754400002, 106.557742512, 99.451383417, 84.443210586, 63.7378782930000}, - {124.987260753, 118.76466984300001, 103.75395524100001, 83.483835750000}, - {129.36988610100002, 125.79923445300001, 114.30453176100002, 90.94408372800001}, - {142.54571770200002, 136.319314626, 126.15502941900002, 102.7920396150000}}; - - double[][] flowPolyEff = {{5142.0765, 6978.1421, 8087.4317, 9120.2186}, - {5868.8525, 7743.1694, 8508.1967, 9273.224, 10459.0164}, - {6748.6339, 9005.4645, 10114.7541, 10918.0328, 12161.2022}, - {7896.1749, 10650.2732, 11568.306, 12065.5738, 13404.3716}, - {8278.6885, 10956.2842, 11912.5683, 12486.3388, 13863.388}, - {8775.9563, 10803.2787, 11989.071, 12868.8525, 14551.9126}}; - - double[][] polyEff = {{75.6796, 79.4536, 76.4411, 65.3459}, - {75.2319, 79.0048, 78.556, 75.9795, 64.8797}, {75.6307, 79.8175, 78.9327, 75.0785, 59.7215}, - {76.0214, 78.9164, 78.0374, 75.0436, 63.088}, {75.5842, 78.9071, 78.027, 75.0308, 64.7762}, - {75.9947, 78.4862, 79.7268, 76.7213, 65.6063}}; + double[] speed = { 6056, 6922, 7788, 8452, 8653, 9062 }; + + double[][] flow = { { 5142.0765, 6978.1421, 8087.4317, 9120.2186 }, + { 5848.6679, 7627.7535, 9001.4248, 10434.2025 }, + { 6663.9168, 6684.2612, 8968.5565, 10866.4216, 12176.113 }, + { 7842.1913, 9985.0959, 11963.8853, 13415.3073 }, + { 8288.4078, 9986.9093, 12007.0675, 13862.3171 }, + { 8736.8911, 11001.182, 12657.5213, 14593.6951 } }; + + double[][] head = { { 63.51995404800001, 59.95565633700001, 52.876617111, 42.72948567000001 }, + { 82.842135201, 77.94996177600001, 69.992872614, 55.8786330900000 }, + { 106.11871754400002, 106.557742512, 99.451383417, 84.443210586, 63.7378782930000 }, + { 124.987260753, 118.76466984300001, 103.75395524100001, 83.483835750000 }, + { 129.36988610100002, 125.79923445300001, 114.30453176100002, 90.94408372800001 }, + { 142.54571770200002, 136.319314626, 126.15502941900002, 102.7920396150000 } }; + + double[][] flowPolyEff = { { 5142.0765, 6978.1421, 8087.4317, 9120.2186 }, + { 5868.8525, 7743.1694, 8508.1967, 9273.224, 10459.0164 }, + { 6748.6339, 9005.4645, 10114.7541, 10918.0328, 12161.2022 }, + { 7896.1749, 10650.2732, 11568.306, 12065.5738, 13404.3716 }, + { 8278.6885, 10956.2842, 11912.5683, 12486.3388, 13863.388 }, + { 8775.9563, 10803.2787, 11989.071, 12868.8525, 14551.9126 } }; + + double[][] polyEff = { { 75.6796, 79.4536, 76.4411, 65.3459 }, + { 75.2319, 79.0048, 78.556, 75.9795, 64.8797 }, { 75.6307, 79.8175, 78.9327, 75.0785, 59.7215 }, + { 76.0214, 78.9164, 78.0374, 75.0436, 63.088 }, { 75.5842, 78.9071, 78.027, 75.0308, 64.7762 }, + { 75.9947, 78.4862, 79.7268, 76.7213, 65.6063 } }; String headUnit = "kJ/kg"; - double[] surgeFlow = {5588.855374539698, 5588.855374539698, 5626.89941, 5826.08345, 6025.26749, + double[] surgeFlow = { 5588.855374539698, 5588.855374539698, 5626.89941, 5826.08345, 6025.26749, 6224.45153, 6423.63557, 6622.8196100000005, 6822.003650000001, 7021.18769, 7220.37173, 7419.55577, 7618.73981, 7817.92385, 8017.10789, 8216.29193, 8415.47597, 8614.66001, - 8813.84405, 9013.02809, 9212.21213, 9411.39617, 9546.675330043363}; + 8813.84405, 9013.02809, 9212.21213, 9411.39617, 9546.675330043363 }; - double[] surgeHead = {42.72948567000001, 62.60864535225944, 63.51995404800001, + double[] surgeHead = { 42.72948567000001, 62.60864535225944, 63.51995404800001, 68.29121833446465, 73.06248262092927, 77.8337469073939, 82.60501119385853, 87.7551980890982, 92.92520167324781, 98.09520525739738, 103.26520884154696, 107.41797208771176, 110.31767659420001, 113.21738110068823, 116.11708560717645, 119.01679011366468, 121.9164946201529, 124.81619912664114, 126.6608293908074, 128.43931588909822, - 131.9061592019831, 137.22593845199154, 140.8389551804265}; + 131.9061592019831, 137.22593845199154, 140.8389551804265 }; - double[] chokeFlow = {9136.016, 10434.202, 12176.113, 13415.308, 13862.317, 14593.695, - 12657.521, 11001.182, 8736.891}; - double[] chokeHead = {42.729485, 55.87863, 63.737877, 83.48383, 90.944084, 102.79204, 126.15503, - 136.31932, 142.54572}; + double[] chokeFlow = { 9136.016, 10434.202, 12176.113, 13415.308, 13862.317, 14593.695, + 12657.521, 11001.182, 8736.891 }; + double[] chokeHead = { 42.729485, 55.87863, 63.737877, 83.48383, 90.944084, 102.79204, 126.15503, + 136.31932, 142.54572 }; // Compressor setup - Compressor compressor_KA27831 = - new neqsim.process.equipment.compressor.Compressor("KA27831", valve_dp1.getOutletStream()); + Compressor compressor_KA27831 = new neqsim.process.equipment.compressor.Compressor("KA27831", + valve_dp1.getOutletStream()); compressor_KA27831.setUsePolytropicCalc(true); compressor_KA27831.setSpeed(inp.speed27831DXCompressor); compressor_KA27831.setUseGERG2008(false); @@ -759,42 +767,42 @@ public ProcessSystem getExportCopressorModel(StreamInterface feedStream) { double[] chartConditions_KA27841 = {}; // Used to set molecular weight etc. - double[] speed_KA27841 = {6057, 6922, 7890, 8653, 9086}; + double[] speed_KA27841 = { 6057, 6922, 7890, 8653, 9086 }; - double[][] flow_KA27841 = {{2061.8, 2494.38, 3241.57, 3772.47, 4106.74}, - {2356.74, 3064.61, 3831.46, 4735.96}, {2848.31, 3949.44, 4657.3, 5365.17}, - {3398.88, 4441.01, 5306.18, 6033.71}, {3634.83, 4500, 5483.15, 6367.98}}; + double[][] flow_KA27841 = { { 2061.8, 2494.38, 3241.57, 3772.47, 4106.74 }, + { 2356.74, 3064.61, 3831.46, 4735.96 }, { 2848.31, 3949.44, 4657.3, 5365.17 }, + { 3398.88, 4441.01, 5306.18, 6033.71 }, { 3634.83, 4500, 5483.15, 6367.98 } }; - double[][] head_KA27841 = {{41.44, 40.18, 35.99, 30.53, 25.92}, {53.61, 51.52, 46.06, 33.05}, - {67.88, 63.69, 56.55, 41.44}, {84.25, 78.38, 69.14, 53.61}, {92.64, 87.61, 77.54, 58.65}}; + double[][] head_KA27841 = { { 41.44, 40.18, 35.99, 30.53, 25.92 }, { 53.61, 51.52, 46.06, 33.05 }, + { 67.88, 63.69, 56.55, 41.44 }, { 84.25, 78.38, 69.14, 53.61 }, { 92.64, 87.61, 77.54, 58.65 } }; - double[][] flowPolyEff_KA27841 = {{2032.085, 2856.825, 3393.439, 3795.561, 4120.573}, - {2415.522, 3451.125, 3949.375, 4724.254}, {3009.797, 3987.866, 4658.589, 4984.06, 5471.654}, - {3450.717, 4754.537, 5329.311, 6056.369}, {3623.19, 4869.604, 5501.988, 6343.96}}; + double[][] flowPolyEff_KA27841 = { { 2032.085, 2856.825, 3393.439, 3795.561, 4120.573 }, + { 2415.522, 3451.125, 3949.375, 4724.254 }, { 3009.797, 3987.866, 4658.589, 4984.06, 5471.654 }, + { 3450.717, 4754.537, 5329.311, 6056.369 }, { 3623.19, 4869.604, 5501.988, 6343.96 } }; - double[][] polyEff_KA27841 = {{74.468, 78.298, 77.234, 73.617, 66.383}, - {74.894, 78.723, 77.447, 65.106}, {75.106, 78.723, 77.021, 73.617, 63.404}, - {75.319, 77.872, 75.319, 63.83}, {74.894, 78.298, 76.596, 64.255}}; + double[][] polyEff_KA27841 = { { 74.468, 78.298, 77.234, 73.617, 66.383 }, + { 74.894, 78.723, 77.447, 65.106 }, { 75.106, 78.723, 77.021, 73.617, 63.404 }, + { 75.319, 77.872, 75.319, 63.83 }, { 74.894, 78.298, 76.596, 64.255 } }; String headUnit_KA27841 = "kJ/kg"; - double[] surgeFlow_KA27841 = {2254.705013080774, 2254.705013080774, 2267.9775799999998, + double[] surgeFlow_KA27841 = { 2254.705013080774, 2254.705013080774, 2267.9775799999998, 2354.4944334999996, 2441.011287, 2527.5281404999996, 2614.044994, 2700.5618474999997, 2787.0787009999995, 2873.5955544999997, 2960.112408, 3046.6292614999998, 3133.1461149999996, 3219.6629685, 3306.179822, 3392.6966755, 3479.2135289999997, 3565.7303825, - 3652.2472359999997, 3738.7640895, 3825.2809429999998, 3911.7977965, 3944.639486569277}; + 3652.2472359999997, 3738.7640895, 3825.2809429999998, 3911.7977965, 3944.639486569277 }; - double[] surgeHead_KA27841 = {25.915186872000003, 40.94541953943677, 41.443315209000005, + double[] surgeHead_KA27841 = { 25.915186872000003, 40.94541953943677, 41.443315209000005, 44.68883410252227, 47.93435299604455, 51.179871889566826, 54.18477452074823, 56.46782928268527, 58.75088404462232, 61.03393880655938, 63.31699356849644, 65.60004833043348, 67.88310309625099, 70.17226196517589, 72.46142083410078, 74.75057970302565, 77.03973857195052, 79.32889744087541, 81.7325145287474, - 84.25058989377591, 87.04845041018393, 89.84631092659198, 90.90837530156303}; + 84.25058989377591, 87.04845041018393, 89.84631092659198, 90.90837530156303 }; - double[] chokeFlow_KA27841 = - {4106.7416, 4735.9551, 5365.1685, 5876.4045, 6033.7079, 6367.98, 5483.15, 4500, 3634.83}; - double[] chokeHead_KA27841 = {25.91518687, 33.04973304, 41.44331521, 49.83689836, 53.61401029, - 58.65, 77.54, 87.61, 92.64}; + double[] chokeFlow_KA27841 = { 4106.7416, 4735.9551, 5365.1685, 5876.4045, 6033.7079, 6367.98, 5483.15, 4500, + 3634.83 }; + double[] chokeHead_KA27841 = { 25.91518687, 33.04973304, 41.44331521, 49.83689836, 53.61401029, + 58.65, 77.54, 87.61, 92.64 }; Compressor compressor_KA27841 = new neqsim.process.equipment.compressor.Compressor("KA27841", cooler_HA27831.getOutletStream()); @@ -812,7 +820,7 @@ public ProcessSystem getExportCopressorModel(StreamInterface feedStream) { Splitter splitter_TEE_104 = new neqsim.process.equipment.splitter.Splitter("TEE-104", compressor_KA27841.getOutletStream(), 2); - splitter_TEE_104.setFlowRates(new double[] {-1, 0.0001}, "MSm3/day"); + splitter_TEE_104.setFlowRates(new double[] { -1, 0.0001 }, "MSm3/day"); process.add(splitter_TEE_104); return process; @@ -850,19 +858,19 @@ public ProcessModel getCombinedModel() { ((Splitter) wellProcess.getUnit("HP manifold")).getSplitStream(1), ((Splitter) wellProcess.getUnit("LP manifold")).getSplitStream(1)); - ProcessSystem expanderProcessA = - createExpanderProcessModel((Separator) separationTrainA.getUnit("dew point scrubber 2"), - (ThreePhaseSeparator) separationTrainA.getUnit("4th stage separator"), - (Mixer) separationTrainA.getUnit("second Stage mixer"), - (Mixer) separationTrainA.getUnit("first stage mixer"), - (Mixer) separationTrainA.getUnit("MP liq gas mixer")); + ProcessSystem expanderProcessA = createExpanderProcessModel( + (Separator) separationTrainA.getUnit("dew point scrubber 2"), + (ThreePhaseSeparator) separationTrainA.getUnit("4th stage separator"), + (Mixer) separationTrainA.getUnit("second Stage mixer"), + (Mixer) separationTrainA.getUnit("first stage mixer"), + (Mixer) separationTrainA.getUnit("MP liq gas mixer")); - ProcessSystem expanderProcessB = - createExpanderProcessModel((Separator) separationTrainB.getUnit("dew point scrubber 2"), - (ThreePhaseSeparator) separationTrainB.getUnit("4th stage separator"), - (Mixer) separationTrainB.getUnit("second Stage mixer"), - (Mixer) separationTrainB.getUnit("first stage mixer"), - (Mixer) separationTrainB.getUnit("MP liq gas mixer")); + ProcessSystem expanderProcessB = createExpanderProcessModel( + (Separator) separationTrainB.getUnit("dew point scrubber 2"), + (ThreePhaseSeparator) separationTrainB.getUnit("4th stage separator"), + (Mixer) separationTrainB.getUnit("second Stage mixer"), + (Mixer) separationTrainB.getUnit("first stage mixer"), + (Mixer) separationTrainB.getUnit("MP liq gas mixer")); ProcessSystem exportCompressorTrainA = getExportCopressorModel( ((ThrottlingValve) expanderProcessA.getUnit("gas split valve")).getOutletStream()); @@ -1006,6 +1014,7 @@ public void testCombinedProcessRunStep() { ((Compressor) fullProcess.get("compressor process B").getUnit("KA27841")).getOutletStream() .getPressure("bara"), 1.5); + } // @Test @@ -1120,6 +1129,7 @@ public void testCombinedProcess() { ((Compressor) fullProcess.get("compressor process B").getUnit("KA27841")).getOutletStream() .getPressure("bara"), 0.5); + } // @Test @@ -1222,6 +1232,7 @@ public void testCombinedProcessAsThread2() { + ((Stream) fullProcess.get("well and manifold process").getUnit("LP well stream")) .getFlowRate("kg/hr")) / 100.0); + } // @Test From 431e7d1c28f9b52f9dac7c686cf353ff7a2ff805 Mon Sep 17 00:00:00 2001 From: Even Solbraa <41290109+EvenSol@users.noreply.github.com> Date: Mon, 13 Jan 2025 21:49:12 +0000 Subject: [PATCH 3/4] update --- .../process/processmodel/ProcessModel.java | 86 ++++++++++++++++--- 1 file changed, 74 insertions(+), 12 deletions(-) diff --git a/src/main/java/neqsim/process/processmodel/ProcessModel.java b/src/main/java/neqsim/process/processmodel/ProcessModel.java index 17ca43ff1..6669d569a 100644 --- a/src/main/java/neqsim/process/processmodel/ProcessModel.java +++ b/src/main/java/neqsim/process/processmodel/ProcessModel.java @@ -9,14 +9,52 @@ /** *

- * ProcessModel class. Manages a collection of processes that can be run in - * steps or continuously. + * ProcessModel class. Manages a collection of processes that can be run in steps or continuously. * - * Extended to also allow grouping of processes and the ability to run only the - * processes - * within a given group instead of always running all. + * Extended to also allow grouping of processes and the ability to run only the processes within a + * given group instead of always running all. *

*/ +/** + * The ProcessModel class represents a model that manages and runs multiple process systems. It + * supports both step mode and continuous mode execution, and allows grouping of processes. + * + *

+ * This class implements the Runnable interface, enabling it to be executed in a separate thread. + * + *

+ * Features: + *

    + *
  • Add, retrieve, and remove processes by name.
  • + *
  • Create and manage groups of processes.
  • + *
  • Run processes in step mode or continuous mode.
  • + *
  • Check if all processes or groups of processes are finished.
  • + *
  • Run the model in a new thread or get individual threads for each process.
  • + *
  • Calculate total power and heater duty for all processes.
  • + *
+ * + *

+ * Usage example: + * + *

+ * {@code
+ * ProcessModel model = new ProcessModel();
+ * model.add("process1", new ProcessSystem());
+ * model.createGroup("group1");
+ * model.addProcessToGroup("group1", "process1");
+ * model.runAsThread();
+ * }
+ * 
+ * + *

+ * Thread safety: This class is not thread-safe and should be synchronized externally if used in a + * multi-threaded environment. + * + *

+ * Logging: This class uses a logger to log debug information and errors. + * + * @see ProcessSystem + */ public class ProcessModel implements Runnable { /** Logger object for class. */ static Logger logger = LogManager.getLogger(ProcessModel.class); @@ -27,8 +65,7 @@ public class ProcessModel implements Runnable { /** * Map of group name -> list of process names in that group. * - * We store process *names* here, pointing to the actual ProcessSystem in - * `processes`. + * We store process *names* here, pointing to the actual ProcessSystem in `processes`. * Alternatively, you can store the ProcessSystem references directly. */ private Map> groups = new LinkedHashMap<>(); @@ -184,9 +221,8 @@ public boolean isGroupFinished(String groupName) { /** * The core run method. * - * - If runStep == true, each process is run in "step" mode exactly once. - * - Otherwise (continuous mode), it loops up to maxIterations or until all - * processes are finished (isFinished() == true). + * - If runStep == true, each process is run in "step" mode exactly once. - Otherwise (continuous + * mode), it loops up to maxIterations or until all processes are finished (isFinished() == true). */ @Override public void run() { @@ -281,6 +317,12 @@ public Map getThreads() { return threads; } + /** + * Calculates the total power consumption of all processes in the specified unit. + * + * @param unit the unit of power to be used (e.g., "kW", "MW"). + * @return the total power consumption of all processes in the specified unit. + */ public double getPower(String unit) { double totalPower = 0.0; for (ProcessSystem process : processes.values()) { @@ -289,10 +331,30 @@ public double getPower(String unit) { return totalPower; } - public double getTotalDuty(String unit) { + /** + * Calculates the total heater duty for all processes in the specified unit. + * + * @param unit the unit for which the heater duty is to be calculated + * @return the total heater duty for the specified unit + */ + public double getHeaterDuty(String unit) { + double totalDuty = 0.0; + for (ProcessSystem process : processes.values()) { + totalDuty += process.getHeaterDuty(unit); + } + return totalDuty; + } + + /** + * Calculates the total cooler duty for all processes in the specified unit. + * + * @param unit the unit for which the cooler duty is to be calculated + * @return the total cooler duty for the specified unit + */ + public double getCoolerDuty(String unit) { double totalDuty = 0.0; for (ProcessSystem process : processes.values()) { - totalDuty += process.getTotalDuty(unit); + totalDuty += process.getCoolerDuty(unit); } return totalDuty; } From a20dda011d0770aa85738b93aa6adc2ec7368b2a Mon Sep 17 00:00:00 2001 From: Even Solbraa <41290109+EvenSol@users.noreply.github.com> Date: Tue, 14 Jan 2025 19:11:10 +0000 Subject: [PATCH 4/4] update --- .../process/processmodel/ProcessModel.java | 65 +++++-------------- 1 file changed, 17 insertions(+), 48 deletions(-) diff --git a/src/main/java/neqsim/process/processmodel/ProcessModel.java b/src/main/java/neqsim/process/processmodel/ProcessModel.java index 6669d569a..48d1b5f53 100644 --- a/src/main/java/neqsim/process/processmodel/ProcessModel.java +++ b/src/main/java/neqsim/process/processmodel/ProcessModel.java @@ -8,52 +8,17 @@ import org.apache.logging.log4j.Logger; /** - *

- * ProcessModel class. Manages a collection of processes that can be run in steps or continuously. + * A process model that can run multiple processes in parallel. * - * Extended to also allow grouping of processes and the ability to run only the processes within a - * given group instead of always running all. - *

- */ -/** - * The ProcessModel class represents a model that manages and runs multiple process systems. It - * supports both step mode and continuous mode execution, and allows grouping of processes. - * - *

- * This class implements the Runnable interface, enabling it to be executed in a separate thread. - * - *

- * Features: - *

    - *
  • Add, retrieve, and remove processes by name.
  • - *
  • Create and manage groups of processes.
  • - *
  • Run processes in step mode or continuous mode.
  • - *
  • Check if all processes or groups of processes are finished.
  • - *
  • Run the model in a new thread or get individual threads for each process.
  • - *
  • Calculate total power and heater duty for all processes.
  • - *
- * - *

- * Usage example: - * - *

- * {@code
- * ProcessModel model = new ProcessModel();
- * model.add("process1", new ProcessSystem());
- * model.createGroup("group1");
- * model.addProcessToGroup("group1", "process1");
- * model.runAsThread();
- * }
- * 
- * - *

- * Thread safety: This class is not thread-safe and should be synchronized externally if used in a - * multi-threaded environment. - * - *

- * Logging: This class uses a logger to log debug information and errors. + * This class is a simple model that can run multiple processes in parallel. It + * can run in two modes: + * - Step mode: each process is run once in a loop, in the order they were + * added. - Continuous mode: + * each process is run in a loop until all processes are finished or a maximum + * number of iterations + * is reached. * - * @see ProcessSystem + * You can also create groups of processes and run them separately. */ public class ProcessModel implements Runnable { /** Logger object for class. */ @@ -65,7 +30,8 @@ public class ProcessModel implements Runnable { /** * Map of group name -> list of process names in that group. * - * We store process *names* here, pointing to the actual ProcessSystem in `processes`. + * We store process *names* here, pointing to the actual ProcessSystem in + * `processes`. * Alternatively, you can store the ProcessSystem references directly. */ private Map> groups = new LinkedHashMap<>(); @@ -221,8 +187,10 @@ public boolean isGroupFinished(String groupName) { /** * The core run method. * - * - If runStep == true, each process is run in "step" mode exactly once. - Otherwise (continuous - * mode), it loops up to maxIterations or until all processes are finished (isFinished() == true). + * - If runStep == true, each process is run in "step" mode exactly once. - + * Otherwise (continuous + * mode), it loops up to maxIterations or until all processes are finished + * (isFinished() == true). */ @Override public void run() { @@ -318,7 +286,8 @@ public Map getThreads() { } /** - * Calculates the total power consumption of all processes in the specified unit. + * Calculates the total power consumption of all processes in the specified + * unit. * * @param unit the unit of power to be used (e.g., "kW", "MW"). * @return the total power consumption of all processes in the specified unit.