Skip to content

Commit

Permalink
update model
Browse files Browse the repository at this point in the history
  • Loading branch information
EvenSol committed Jan 4, 2025
1 parent 114d147 commit 36bfcb5
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public class MultiStreamHeatExchanger extends Heater implements MultiStreamHeatE
protected double temperatureOut = 0;

protected double dT = 0.0;
private double temperatureApproach = 0.0;


private double UAvalue = 500.0; // Overall heat transfer coefficient times area
private double duty = 0.0;
Expand Down Expand Up @@ -455,94 +457,183 @@ public void setDeltaT(double deltaT) {
*/
@Override
public void run(UUID id) {
if (useDeltaT) {
runDeltaT(id);
return;
}

if (getSpecification().equals("out stream")) {
runSpecifiedStream(id);
} else if (firstTime) {
if (firstTime) {
firstTime = false;
// Initialize all outStreams with guessed temperatures
for (StreamInterface outStream : outStreams) {
SystemInterface systemOut =
inStreams.get(outStreams.indexOf(outStream)).getThermoSystem().clone();
outStream.setThermoSystem(systemOut);
outStream.getThermoSystem().setTemperature(guessOutTemperature, guessOutTemperatureUnit);
outStream.run(id);
}
run(id);
} else {
// Ensure all input streams are run
for (StreamInterface inStream : inStreams) {

// 1. Identify the hottest and coldest inlet streams
double hottestTemperature = Double.NEGATIVE_INFINITY;
double coldestTemperature = Double.POSITIVE_INFINITY;
int hottestIndex = -1;
int coldestIndex = -1;

for (int i = 0; i < inStreams.size(); i++) {
StreamInterface inStream = inStreams.get(i);
// Ensure the inlet stream is run to get the latest temperature
inStream.run();
double currentTemp = inStream.getThermoSystem().getTemperature("K");

if (currentTemp > hottestTemperature) {
hottestTemperature = currentTemp;
hottestIndex = i;
}

if (currentTemp < coldestTemperature) {
coldestTemperature = currentTemp;
coldestIndex = i;
}
}

// Clone thermo systems for all out streams
List<SystemInterface> systemsOut = new ArrayList<>();
for (StreamInterface inStream : inStreams) {
systemsOut.add(inStream.getThermoSystem().clone());
// Check if valid indices were found
if (hottestIndex == -1 || coldestIndex == -1) {
throw new IllegalStateException("Unable to determine hottest or coldest inlet streams.");
}

// Set thermo systems to out streams
// 2. Set the outlet temperatures accordingly
for (int i = 0; i < outStreams.size(); i++) {
outStreams.get(i).setThermoSystem(systemsOut.get(i));
// Set temperature based on some logic, e.g., maintaining a certain delta T
outStreams.get(i).setTemperature(inStreams.get(i).getTemperature() + 10, "K");
if (!outStreams.get(i).getSpecification().equals("TP")) {
outStreams.get(i).runTPflash();
StreamInterface outStream = outStreams.get(i);
SystemInterface systemOut = inStreams.get(i).getThermoSystem().clone();
outStream.setThermoSystem(systemOut);

if (i == hottestIndex) {
// Set the outlet temperature of the hottest inlet stream to the coldest inlet temperature
outStream.getThermoSystem().setTemperature(coldestTemperature + temperatureApproach, "K");
} else if (i == coldestIndex) {
// Set the outlet temperature of the coldest inlet stream to the hottest inlet temperature
outStream.getThermoSystem().setTemperature(hottestTemperature - temperatureApproach, "K");
} else {
// Set the outlet temperature of other streams to the hottest inlet temperature
outStream.getThermoSystem().setTemperature(hottestTemperature - temperatureApproach, "K");
}
outStreams.get(i).run(id);

// Run the outlet stream with the given ID
outStream.run(id);
}

// Calculate enthalpy changes and capacity rates
List<Double> deltaEnthalpies = new ArrayList<>();
List<Double> capacities = new ArrayList<>();
for (int i = 0; i < inStreams.size(); i++) {
double deltaH = outStreams.get(i).getThermoSystem().getEnthalpy()
- inStreams.get(i).getThermoSystem().getEnthalpy();
deltaEnthalpies.add(deltaH);
double C = Math.abs(deltaH) / Math.abs(outStreams.get(i).getThermoSystem().getTemperature()
- inStreams.get(i).getThermoSystem().getTemperature());
capacities.add(C);
// Finalize the setup
run();
return;
}

else {
// Run all input and output streams to ensure they are up-to-date
for (StreamInterface inStream : inStreams) {
inStream.run(id);
}
for (StreamInterface outStream : outStreams) {
outStream.run(id);
}

// Determine Cmin and Cmax among all streams
double Cmin = capacities.stream().min(Double::compare).orElse(1.0);
double Cmax = capacities.stream().max(Double::compare).orElse(1.0);
double Cr = Cmin / Cmax;
// Identify heated and cooled streams
List<Integer> heatedStreamIndices = new ArrayList<>();
List<Integer> cooledStreamIndices = new ArrayList<>();
double totalHeatGained = 0.0; // Total Q for heated streams
double totalHeatLost = 0.0; // Total Q for cooled streams

// Calculate NTU and thermal effectiveness
NTU = UAvalue / Cmin;
thermalEffectiveness = calcThermalEffectiveness(NTU, Cr);
for (int i = 0; i < inStreams.size(); i++) {
double enthalpyIn = inStreams.get(i).getThermoSystem().getEnthalpy();
double enthalpyOut = outStreams.get(i).getThermoSystem().getEnthalpy();
double deltaH = enthalpyOut - enthalpyIn;

if (deltaH > 0) {
// Stream is being heated
heatedStreamIndices.add(i);
totalHeatGained += deltaH;
} else if (deltaH < 0) {
// Stream is being cooled
cooledStreamIndices.add(i);
totalHeatLost += Math.abs(deltaH);
}
// Streams with deltaH == 0 are neither heated nor cooled
}

// Adjust enthalpies based on effectiveness
duty = 0.0;
for (int i = 0; i < deltaEnthalpies.size(); i++) {
deltaEnthalpies.set(i, thermalEffectiveness * deltaEnthalpies.get(i));
duty += deltaEnthalpies.get(i);
logger.debug(": Total Heat Gained = " + totalHeatGained + " J");
logger.debug(": Total Heat Lost = " + totalHeatLost + " J");

// Determine the limiting side
double limitingHeat;
boolean heatingIsLimiting;

if (totalHeatGained < totalHeatLost) {
limitingHeat = totalHeatGained;
heatingIsLimiting = true;
logger.debug("Limiting side: Heating");
} else {
limitingHeat = totalHeatLost;
heatingIsLimiting = false;
logger.debug("Limiting side: Cooling");
}

// Update thermo systems based on adjusted enthalpies
for (int i = 0; i < outStreams.size(); i++) {
ThermodynamicOperations thermoOps =
new ThermodynamicOperations(outStreams.get(i).getThermoSystem());
thermoOps.PHflash(inStreams.get(i).getThermoSystem().getEnthalpy() - deltaEnthalpies.get(i),
0);
if (Math.abs(thermalEffectiveness - 1.0) > 1e-10) {
thermoOps = new ThermodynamicOperations(outStreams.get(i).getThermoSystem());
thermoOps.PHflash(
inStreams.get(i).getThermoSystem().getEnthalpy() + deltaEnthalpies.get(i), 0);
// Calculate scaling factors for each side
double scalingFactor = 1.0;

if (heatingIsLimiting) {
// Scale down the heat lost by cooled streams
scalingFactor = limitingHeat / totalHeatLost;
logger.debug("Scaling factor for cooled streams: " + scalingFactor);
} else {
// Scale down the heat gained by heated streams
scalingFactor = limitingHeat / totalHeatGained;
logger.debug("Scaling factor for heated streams: " + scalingFactor);
}

// Apply scaling factors to adjust outlet enthalpies
double maxTemperatureChange = 0.0;

for (int i : cooledStreamIndices) {
StreamInterface inStream = inStreams.get(i);
StreamInterface outStream = outStreams.get(i);

double enthalpyIn = inStream.getThermoSystem().getEnthalpy();
double targetDeltaH =
-(outStream.getThermoSystem().getEnthalpy() - enthalpyIn) * scalingFactor;

// Adjust the outlet enthalpy
double adjustedEnthalpyOut = enthalpyIn - (Math.abs(targetDeltaH));
ThermodynamicOperations ops = new ThermodynamicOperations(outStream.getThermoSystem());
ops.PHflash(adjustedEnthalpyOut);

// Calculate temperature change for convergence check
double oldTemp = outStream.getThermoSystem().getTemperature("K");
outStream.run(id); // Re-run to update temperature based on adjusted enthalpy
double newTemp = outStream.getThermoSystem().getTemperature("K");
double tempChange = Math.abs(newTemp - oldTemp);
if (tempChange > maxTemperatureChange) {
maxTemperatureChange = tempChange;
}

logger.debug("Adjusted cooled stream " + i + ": ΔH = " + targetDeltaH);
}

hotColdDutyBalance = 1.0; // Adjust as needed for specific applications
}
scalingFactor = 1.0;
for (int i : heatedStreamIndices) {
StreamInterface inStream = inStreams.get(i);
StreamInterface outStream = outStreams.get(i);

double enthalpyIn = inStream.getThermoSystem().getEnthalpy();
double targetDeltaH =
(outStream.getThermoSystem().getEnthalpy() - enthalpyIn) * scalingFactor;

// Adjust the outlet enthalpy
double adjustedEnthalpyOut = enthalpyIn + (Math.abs(targetDeltaH));
ThermodynamicOperations ops = new ThermodynamicOperations(outStream.getThermoSystem());
ops.PHflash(adjustedEnthalpyOut);

// Calculate temperature change for convergence check
double oldTemp = outStream.getThermoSystem().getTemperature("K");
outStream.run(id); // Re-run to update temperature based on adjusted enthalpy
double newTemp = outStream.getThermoSystem().getTemperature("K");
double tempChange = Math.abs(newTemp - oldTemp);
if (tempChange > maxTemperatureChange) {
maxTemperatureChange = tempChange;
}

logger.debug("Adjusted heated stream " + i + ": ΔH = " + targetDeltaH);
}
}
setCalculationIdentifier(id);
}


/**
* Runs the heat exchanger simulation using a specified stream approach.
*
Expand All @@ -553,13 +644,12 @@ public void runSpecifiedStream(UUID id) {
// This method needs to be defined based on specific requirements
}

/**
* Runs the heat exchanger simulation using a delta T approach.
*
* @param id Unique identifier for the run
*/
public void runDeltaT(UUID id) {
// Implementation similar to the two-stream case but generalized for multiple streams
// This method needs to be defined based on specific requirements

public double getTemperatureApproach() {
return temperatureApproach;
}

public void setTemperatureApproach(double temperatureApproach) {
this.temperatureApproach = temperatureApproach;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package neqsim.process.equipment.heatexchanger;

import static org.junit.jupiter.api.Assertions.assertEquals;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -44,8 +45,7 @@ void testRun1() {
heatEx.addInStream(stream_Hot);
heatEx.addInStream(stream_Cold);
heatEx.addInStream(stream_Cold2);
heatEx.setGuessOutTemperature(20.0, "C");
heatEx.setUAvalue(1000);
heatEx.setTemperatureApproach(5.0);


neqsim.process.processmodel.ProcessSystem operations =
Expand All @@ -57,11 +57,10 @@ void testRun1() {

operations.run();

heatEx.getOutStream(0).getFluid().prettyPrint();
heatEx.getOutStream(1).getFluid().prettyPrint();
heatEx.getOutStream(2).getFluid().prettyPrint();
logger.debug("duty " + heatEx.getDuty());
// resyc.getOutStream().displayResult();
assertEquals(95, heatEx.getOutStream(1).getTemperature("C"), 1e-3);
assertEquals(95, heatEx.getOutStream(2).getTemperature("C"), 1e-3);
assertEquals(70.5921794735, heatEx.getOutStream(0).getTemperature("C"), 1e-3);

}


Expand Down

0 comments on commit 36bfcb5

Please sign in to comment.