Skip to content

Commit

Permalink
multi process model with test (#1212)
Browse files Browse the repository at this point in the history
* first version of multi model with test

* update

* update

* update

* update
  • Loading branch information
EvenSol authored Dec 16, 2024
1 parent 93be1b3 commit 27bf800
Show file tree
Hide file tree
Showing 4 changed files with 288 additions and 3 deletions.
4 changes: 3 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
"shengchen.vscode-checkstyle",
"mechatroner.rainbow-csv",
"redhat.vscode-xml",
"vscjava.vscode-java-test"
"vscjava.vscode-java-test",
"GitHub.copilot",
"GitHub.copilot-chat"
],
"settings": {
"java.configuration.updateBuildConfiguration": "interactive",
Expand Down
123 changes: 123 additions & 0 deletions src/main/java/neqsim/process/processmodel/ProcessModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package neqsim.process.processmodel;

import java.util.LinkedHashMap;
import java.util.Map;

/**
* <p>
* ProcessModel class.
* </p>
*
* Manages a collection of processes that can be run in steps or continuously.
*
* @author Even Solbraa
* @version $Id: $Id
*/
public class ProcessModel implements Runnable {
private final Map<String, ProcessSystem> processes = new LinkedHashMap<>();
private boolean runStep = false;

/**
* Checks if the model is running in step mode.
*
* @return true if running in step mode, false otherwise.
*/
public boolean isRunStep() {
return runStep;
}

/**
* Sets the step mode for the process.
*
* @param runStep true to enable step mode, false to disable.
*/
public void setRunStep(boolean runStep) {
this.runStep = runStep;
}

/**
* Adds a process to the model.
*
* @param name the name of the process.
* @param process the process to add.
* @return true if the process was added successfully.
*/
public boolean add(String name, ProcessSystem process) {
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("Name cannot be null or empty");
}
if (process == null) {
throw new IllegalArgumentException("Process cannot be null");
}
if (processes.containsKey(name)) {
throw new IllegalArgumentException("A process with the given name already exists");
}
processes.put(name, process);
return true;
}

/**
* Retrieves a process by its name.
*
* @param name the name of the process.
* @return the corresponding process, or null if not found.
*/
public ProcessSystem get(String name) {
return processes.get(name);
}

/**
* Removes a process by its name.
*
* @param name the name of the process to remove.
* @return true if the process was removed, false otherwise.
*/
public boolean remove(String name) {
return processes.remove(name) != null;
}

/**
* Executes all processes, either continuously or in steps based on mode.
*/
@Override
public void run() {
for (ProcessSystem process : processes.values()) {
try {
if (runStep) {
process.run_step();
} else {
process.run();
}
} catch (Exception e) {
System.err.println("Error running process: " + e.getMessage());
e.printStackTrace();
}
}
}

/**
* Executes all processes in a single step.
*/
public void runStep() {
for (ProcessSystem process : processes.values()) {
try {
process.run_step();
} catch (Exception e) {
System.err.println("Error in runStep: " + e.getMessage());
e.printStackTrace();
}
}
}

/**
* Runs the model as a separate thread.
*
* @return the thread running the model.
*/
public Thread runAsThread() {
Thread processThread = new Thread(this);
processThread.start();
return processThread;
}

}
23 changes: 21 additions & 2 deletions src/main/java/neqsim/process/processmodel/ProcessSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,34 @@ public void add(ProcessEquipmentInterface[] operations) {
getUnitOperations().addAll(Arrays.asList(operations));
}

/**
* <p>
* Replace a unitoperation
* </p>
*
* @param name Name of the object to replace
* @param newObject the object to replace it with
* @return a {@link java.lang.Boolean} object
*/
public boolean replaceUnit(String name, ProcessEquipmentInterface newObject) {
try {
ProcessEquipmentInterface unit = (ProcessEquipmentInterface) getUnit(name);
unit = newObject;
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return true;
}

/**
* <p>
* Get process equipmen by name.
* </p>
*
* @param name Name of
* @return a {@link java.lang.Object} object
* @return a {@link neqsim.process.equipment.ProcessEquipmentInterface} object
*/
public Object getUnit(String name) {
public ProcessEquipmentInterface getUnit(String name) {
for (int i = 0; i < getUnitOperations().size(); i++) {
if (getUnitOperations().get(i) instanceof ModuleInterface) {
for (int j = 0; j < ((ModuleInterface) getUnitOperations().get(i)).getOperations()
Expand Down
141 changes: 141 additions & 0 deletions src/test/java/neqsim/process/processmodel/CombinedModelsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package neqsim.process.processmodel;

import java.io.File;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import neqsim.process.equipment.compressor.Compressor;
import neqsim.process.equipment.separator.ThreePhaseSeparator;
import neqsim.process.equipment.stream.Stream;
import neqsim.thermo.system.SystemInterface;

/**
* CombinedModelsTest is a test class for validating the combined process model which includes an
* inlet model and a compressor process.
*
* <p>
* The class contains methods to set up individual process systems and combine them into a single
* process model. It also includes a test method to verify the behavior of the combined process
* model.
*
* <p>
* Methods:
* <ul>
* <li>{@link #getinletModel()}: Sets up the inlet process model including a well stream and a
* three-phase separator.</li>
* <li>{@link #getCompressorProcess()}: Sets up the compressor process model including a gas feed
* stream and a compressor.</li>
* <li>{@link #getCombinedModel()}: Combines the inlet process model and the compressor process
* model into a single process model.</li>
* <li>{@link #testCombinedProcess()}: Tests the combined process model by configuring the
* temperature and pressure for the well stream and the outlet pressure for the compressor, running
* the process, and asserting the expected outlet temperature of the compressor.</li>
* </ul>
*
* <p>
* Dependencies:
* <ul>
* <li>Logger: Used for logging debug information.</li>
* <li>ProcessSystem: Represents a process system containing various units.</li>
* <li>Stream: Represents a stream in the process system.</li>
* <li>ThreePhaseSeparator: Represents a three-phase separator unit in the process system.</li>
* <li>Compressor: Represents a compressor unit in the process system.</li>
* <li>ProcessModel: Represents the combined process model.</li>
* <li>Assertions: Used for asserting expected values in the test method.</li>
* </ul>
*/
public class CombinedModelsTest {
static Logger logger = LogManager.getLogger(CombinedModelsTest.class);

public ProcessSystem getinletModel() {
File file = new File("src/test/java/neqsim/process/processmodel");
String fileFluid1 = file.getAbsolutePath() + "/feedfluid.e300";
SystemInterface wellFluid = neqsim.thermo.util.readwrite.EclipseFluidReadWrite.read(fileFluid1);
// wellFluid.setMultiPhaseCheck(true);

Stream wellStreamHP = new neqsim.process.equipment.stream.Stream("HP well stream", wellFluid);
wellStreamHP.setFlowRate(10.0, "MSm3/day");

ThreePhaseSeparator firstStageSeparator =
new neqsim.process.equipment.separator.ThreePhaseSeparator("1st stage separator",
wellStreamHP);

ProcessSystem process1 = new ProcessSystem();
process1.add(wellStreamHP);
process1.add(firstStageSeparator);

return process1;
};

public ProcessSystem getCompressorProcess() {

neqsim.process.equipment.stream.Stream gasFeedStream =
new neqsim.process.equipment.stream.Stream("compressor feed stream");

neqsim.process.equipment.compressor.Compressor compressor1 =
new neqsim.process.equipment.compressor.Compressor("Compressor1", gasFeedStream);
compressor1.setPolytropicEfficiency(0.56);
compressor1.setUsePolytropicCalc(true);

ProcessSystem process1 = new ProcessSystem();
process1.add(gasFeedStream);
process1.add(compressor1);

return process1;
}

public ProcessModel getCombinedModel() {
ProcessSystem inletProcess = getinletModel();
ProcessSystem compressorProcess = getCompressorProcess();
((Compressor) compressorProcess.getUnit("Compressor1")).setInletStream(
((ThreePhaseSeparator) inletProcess.getUnit("1st stage separator")).getGasOutStream());


ProcessModel combinedProcess = new ProcessModel();
combinedProcess.add("feed process", inletProcess);
combinedProcess.add("compressor process", compressorProcess);

return combinedProcess;
}

/**
* Test method for the combined process model.
*
* This test sets up a combined process model, configures the temperature and pressure for the "HP
* well stream" in the "feed process", and sets the outlet pressure for "Compressor1" in the
* "compressor process". The process is then run, and the test asserts that the outlet temperature
* of "Compressor1" is as expected.
*
* The expected outlet temperature of "Compressor1" is 164.44139872 degrees Celsius with a
* tolerance of 0.1 degrees.
*/
@Test
public void testCombinedProcess() {
ProcessModel fullProcess = getCombinedModel();
fullProcess.setRunStep(true);

// Set fullProcess properties;
((Stream) (fullProcess.get("feed process")).getUnit("HP well stream")).setTemperature(80.0,
"C");
((Stream) (fullProcess.get("feed process")).getUnit("HP well stream")).setPressure(50.0,
"bara");

((Compressor) (fullProcess.get("compressor process")).getUnit("Compressor1"))
.setOutletPressure(100.0, "bara");


try {
fullProcess.run();
} catch (Exception ex) {
logger.debug(ex.getMessage(), ex);
}

Assertions.assertEquals(164.44139872,
((Compressor) fullProcess.get("compressor process").getUnit("Compressor1"))
.getOutletStream().getTemperature("C"),
0.1);

}

}

0 comments on commit 27bf800

Please sign in to comment.