diff --git a/src/main/java/neqsim/fluidmechanics/flownode/fluidboundary/heatmasstransfercalc/FluidBoundary.java b/src/main/java/neqsim/fluidmechanics/flownode/fluidboundary/heatmasstransfercalc/FluidBoundary.java index 372e73840..07f9ac500 100644 --- a/src/main/java/neqsim/fluidmechanics/flownode/fluidboundary/heatmasstransfercalc/FluidBoundary.java +++ b/src/main/java/neqsim/fluidmechanics/flownode/fluidboundary/heatmasstransfercalc/FluidBoundary.java @@ -83,7 +83,10 @@ public FluidBoundary(SystemInterface system) { jFlux = new Matrix(system.getPhases()[0].getNumberOfComponents() - 1, 1); nFlux = new Matrix(system.getPhases()[0].getNumberOfComponents(), 1); nFlux.set(0, 0, 0.0); - nFlux.set(1, 0, 0.0); + if (system.getPhases()[0].getNumberOfComponents() > 1) { + nFlux.set(1, 0, 0.0); + } + //nFlux.set(1, 0, 0.0); heatTransferCoefficient = new double[2]; heatTransferCorrection = new double[2]; thermodynamicCorrections = new boolean[2]; diff --git a/src/main/java/neqsim/physicalproperties/system/PhysicalProperties.java b/src/main/java/neqsim/physicalproperties/system/PhysicalProperties.java index b2318fe81..88f5371e9 100644 --- a/src/main/java/neqsim/physicalproperties/system/PhysicalProperties.java +++ b/src/main/java/neqsim/physicalproperties/system/PhysicalProperties.java @@ -341,15 +341,18 @@ public void init(PhaseInterface phase) { try { density = densityCalc.calcDensity(); viscosity = viscosityCalc.calcViscosity(); + System.out.println(density); kinematicViscosity = this.calcKinematicViscosity(); diffusivityCalc.calcDiffusionCoefficients(binaryDiffusionCoefficientMethod, multicomponentDiffusionMethod); // diffusivityCalc.calcEffectiveDiffusionCoefficients(); conductivity = conductivityCalc.calcConductivity(); } catch (Exception ex) { + viscosity = viscosityCalc.calcViscosity(); + // might be a chance that entering here ends in an infinite loop... - phase.resetPhysicalProperties(); - phase.initPhysicalProperties(); + //phase.resetPhysicalProperties(); + //phase.initPhysicalProperties(); } } diff --git a/src/main/java/neqsim/thermo/component/ComponentFundamentalEOS.java b/src/main/java/neqsim/thermo/component/ComponentFundamentalEOS.java new file mode 100644 index 000000000..caabdc9d5 --- /dev/null +++ b/src/main/java/neqsim/thermo/component/ComponentFundamentalEOS.java @@ -0,0 +1,216 @@ +package neqsim.thermo.component; + +import neqsim.thermo.phase.PhaseFundamentalEOS; +import neqsim.thermo.phase.PhaseInterface; + +/** + * Component class for use with fundamental Helmholtz equations of state. + */ +public abstract class ComponentFundamentalEOS extends Component implements ComponentFundamentalEOSInterface { + private static final long serialVersionUID = 1L; + + /** + *

+ * Constructor for ComponentFundamentalEos. + *

+ * + * @param name Name of component. + * @param moles Total number of moles of component. + * @param molesInPhase Number of moles in phase. + * @param compIndex Index number of component in phase object component array. + */ + public ComponentFundamentalEOS(String name, double moles, double molesInPhase, int compIndex) { + super(name, moles, molesInPhase, compIndex); + } + + + /** {@inheritDoc} */ + @Override + public void init(double temperature, double pressure, double totalNumberOfMoles, double beta, int initType) { + super.init(temperature, pressure, totalNumberOfMoles, beta, initType); + //For gerg get pure component contributions + + } + + /** {@inheritDoc} */ + @Override + public void Finit(PhaseInterface phase, double temp, double pres, double totMoles, double beta, + int numberOfComponents, int initType) { + //Multicomponent EOS + //double dPdN = phase.getDensity() * R * temp * (1.0 + phase.getalpharesMatrix()[0][1].val * (2 - 1 / rho_r * numberOfMolesInPhase * drhordn) + ) + //voli = - dPdN / phase.getdPdVTn(); + //Single component EOS + voli = phase.getVolume() / getNumberOfMolesInPhase(); + } + + + /** + * Get reduced temperature. + * + * @param temperature temperature of fluid + * @return double reduced temperature T/TC + */ + double reducedTemperature(double temperature) { + return temperature / criticalTemperature; + } + + /** + *

+ * Get reduced pressure. + *

+ * + * @param pressure pressure in unit bara + * @return double + */ + double reducedPressure(double pressure) { + return pressure / criticalPressure; + } + + /** {@inheritDoc} */ + @Override + public double dFdN(PhaseInterface phase, int numberOfComponents, double temperature, + double pressure) { + PhaseFundamentalEOS fundPhase = (PhaseFundamentalEOS) phase; + return fundPhase.getAlpharesMatrix()[0][0].val + ndAlphaResdN(phase, numberOfComponents, temperature, pressure); + } + + /** {@inheritDoc} */ + @Override + public double ndAlphaResdN(PhaseInterface phase, int numberOfComponents, double temperature, + double pressure) { + //MulticomponentEOS + //double rho_r = reducedDensity(phase.getDensity()); + //return + //single component EOS + PhaseFundamentalEOS fundPhase = (PhaseFundamentalEOS) phase; + return fundPhase.getAlpharesMatrix()[0][1].val; + } + + /** {@inheritDoc} */ + @Override + public double dFdNdT(PhaseInterface phase, int numberOfComponents, double temperature, + double pressure) { + PhaseFundamentalEOS fundPhase = (PhaseFundamentalEOS) phase; + return -(fundPhase.getAlpharesMatrix()[1][0].val + fundPhase.getAlpharesMatrix()[1][1].val) + / phase.getTemperature(); + } + + /** {@inheritDoc} */ + @Override + public double dFdNdV(PhaseInterface phase, int numberOfComponents, double temperature, + double pressure) { + PhaseFundamentalEOS fundPhase = (PhaseFundamentalEOS) phase; + + return -(2 * fundPhase.getAlpharesMatrix()[0][1].val + fundPhase.getAlpharesMatrix()[0][2].val) + / phase.getVolume(); + } + + + /** {@inheritDoc} */ + @Override + public double dFdNdN(int j, PhaseInterface phase, int numberOfComponents, double temperature, + double pressure) { + PhaseFundamentalEOS fundPhase = (PhaseFundamentalEOS) phase; + return (2 * fundPhase.getAlpharesMatrix()[0][1].val + fundPhase.getAlpharesMatrix()[0][2].val) + / phase.getNumberOfMolesInPhase(); //single component EOS + } + + + + + + + @Override + public double fugcoef(PhaseInterface phase) { + if (!(phase instanceof PhaseFundamentalEOS)) { + throw new IllegalArgumentException("Phase must be of type PhaseFundamentalEOS"); + } + PhaseFundamentalEOS fundPhase = (PhaseFundamentalEOS) phase; + double temperature = phase.getTemperature(); + double pressure = phase.getPressure(); + double Z = phase.getZ(); + double logFugacityCoefficient = dFdN(fundPhase, phase.getNumberOfComponents(), temperature, pressure) + - Math.log(Z); + + fugacityCoefficient = Math.exp(logFugacityCoefficient); + + return fugacityCoefficient; + } + + /** {@inheritDoc} */ + @Override + public double logfugcoefdP(PhaseInterface phase) { + double temperature = phase.getTemperature(); + double pressure = phase.getPressure(); + dfugdp = getVoli() / R / temperature - 1.0 / pressure; + return dfugdp; + } + + /** {@inheritDoc} */ + @Override + public double logfugcoefdT(PhaseInterface phase) { + double temperature = phase.getTemperature(); + double pressure = phase.getPressure(); + int numberOfComponents = phase.getNumberOfComponents(); + dfugdt = (this.dFdNdT(phase, numberOfComponents, temperature, pressure) + 1.0 / temperature + - getVoli() / R / temperature + * (-R * temperature * phase.dFdTdV() + pressure / temperature)); + return dfugdt; + } + + /** {@inheritDoc} */ + @Override + public double[] logfugcoefdN(PhaseInterface phase) { + double temperature = phase.getTemperature(); + double pressure = phase.getPressure(); + int numberOfComponents = phase.getNumberOfComponents(); + ComponentInterface[] compArray = phase.getComponents(); + for (int i = 0; i < numberOfComponents; i++) { + ComponentFundamentalEOSInterface comp = (ComponentFundamentalEOSInterface) compArray[i]; + dfugdn[i] = (this.dFdNdN(i, phase, numberOfComponents, temperature, pressure) + + 1.0 / phase.getNumberOfMolesInPhase() + - getVoli() / R / temperature + * (-R * temperature + * comp.dFdNdV(phase, numberOfComponents, temperature, pressure) + + R * temperature / phase.getTotalVolume())); + dfugdx[i] = dfugdn[i] * phase.getNumberOfMolesInPhase(); + } + // System.out.println("diffN: " + 1 + dfugdn[0]); + return dfugdn; + } + + // Method added by Neeraj + /* + * public double getdfugdn(int i){ double[] dfugdnv = this.logfugcoefdN(phase); //return 0.0001; + * return dfugdnv[i]; } + */ + // Added By Neeraj + /** {@inheritDoc} */ + @Override + public double logfugcoefdNi(PhaseInterface phase, int k) { + double temperature = phase.getTemperature(); + double pressure = phase.getPressure(); + int numberOfComponents = phase.getNumberOfComponents(); + double vol; + double voli; + ComponentEosInterface[] comp_Array = (ComponentEosInterface[]) phase.getcomponentArray(); + vol = phase.getMolarVolume(); + voli = getVoli(); + + dfugdn[k] = (this.dFdNdN(k, phase, numberOfComponents, temperature, pressure) + + 1.0 / phase.getNumberOfMolesInPhase() + - voli / R / temperature + * (-R * temperature + * comp_Array[k].dFdNdV(phase, numberOfComponents, temperature, pressure) + + R * temperature / (vol * phase.getNumberOfMolesInPhase()))); + dfugdx[k] = dfugdn[k] * (phase.getNumberOfMolesInPhase()); + // System.out.println("Main dfugdn "+dfugdn[k]); + return dfugdn[k]; + } + + + @Override + public ComponentFundamentalEOS clone() { + return (ComponentFundamentalEOS) super.clone(); + } +} diff --git a/src/main/java/neqsim/thermo/component/ComponentFundamentalEOSInterface.java b/src/main/java/neqsim/thermo/component/ComponentFundamentalEOSInterface.java new file mode 100644 index 000000000..f5c020514 --- /dev/null +++ b/src/main/java/neqsim/thermo/component/ComponentFundamentalEOSInterface.java @@ -0,0 +1,81 @@ +package neqsim.thermo.component; + +import neqsim.thermo.phase.PhaseInterface; + +public interface ComponentFundamentalEOSInterface { + + /** + *

+ * dFdN. + *

+ * + * @param phase a {@link neqsim.thermo.phase.PhaseInterface} object + * @param numberOfComponents a int + * @param temperature a double + * @param pressure a double + * @return a double + */ + public double dFdN(PhaseInterface phase, int numberOfComponents, double temperature, + double pressure); + + /** + *

+ * dFdNdT. + *

+ * + * @param phase a {@link neqsim.thermo.phase.PhaseInterface} object + * @param numberOfComponents a int + * @param temperature a double + * @param pressure a double + * @return a double + */ + public double dFdNdT(PhaseInterface phase, int numberOfComponents, double temperature, + double pressure); + + /** + *

+ * dFdNdV. + *

+ * + * @param phase a {@link neqsim.thermo.phase.PhaseInterface} object + * @param numberOfComponents a int + * @param temperature a double + * @param pressure a double + * @return a double + */ + public double dFdNdV(PhaseInterface phase, int numberOfComponents, double temperature, + double pressure); + + /** + *

+ * dFdNdN. + *

+ * + * @param j a int + * @param phase a {@link neqsim.thermo.phase.PhaseInterface} object + * @param numberOfComponents a int + * @param temperature a double + * @param pressure a double + * @return a double + */ + public double dFdNdN(int j, PhaseInterface phase, int numberOfComponents, double temperature, + double pressure); + + + + /** + * + *

+ * ndAlphaResdN. + *

+ * + * @param phase a {@link neqsim.thermo.phase.PhaseInterface} object + * @param numberOfComponents a int + * @param temperature a double + * @param pressure a double + * + */ + public double ndAlphaResdN(PhaseInterface phase, int numberOfComponents, double temperature, + double pressure); +} + diff --git a/src/main/java/neqsim/thermo/component/ComponentGERG2008.java b/src/main/java/neqsim/thermo/component/ComponentGERG2008.java new file mode 100644 index 000000000..e7d8af984 --- /dev/null +++ b/src/main/java/neqsim/thermo/component/ComponentGERG2008.java @@ -0,0 +1,96 @@ +package neqsim.thermo.component; + +import neqsim.thermo.phase.PhaseInterface; + +/** + * ComponentGERG2008 class. + * + *

This class implements a component for use with the GERG2008 equation of state. + * It is similar to the GERG2004 component class, but is provided as a separate + * class in case any modifications or additional properties specific to GERG2008 are required.

+ * + * @author YourName + * @version 1.0 + */ +public class ComponentGERG2008 extends ComponentEos { + private static final long serialVersionUID = 1000; + + /** + * Constructor for ComponentGERG2008. + * + * @param name Name of component. + * @param moles Total number of moles of component. + * @param molesInPhase Number of moles in phase. + * @param compIndex Index number of component in phase object component array. + */ + public ComponentGERG2008(String name, double moles, double molesInPhase, int compIndex) { + super(name, moles, molesInPhase, compIndex); + } + + /** + * Constructor for ComponentGERG2008. + * + * @param number Not used. + * @param TC Critical temperature. + * @param PC Critical pressure. + * @param M Molar mass. + * @param a Acentric factor. + * @param moles Total number of moles of component. + */ + public ComponentGERG2008(int number, double TC, double PC, double M, double a, double moles) { + super(number, TC, PC, M, a, moles); + } + + @Override + public ComponentGERG2008 clone() { + ComponentGERG2008 clonedComponent = null; + try { + clonedComponent = (ComponentGERG2008) super.clone(); + } catch (Exception ex) { + logger.error("Cloning failed.", ex); + } + return clonedComponent; + } + + @Override + public double getVolumeCorrection() { + // GERG2008 does not use a volume correction term. + return 0.0; + } + + @Override + public double calca() { + // Return zero if a calculation for "a" (attraction parameter) is not needed for GERG2008. + return 0; + } + + @Override + public double calcb() { + // Return zero if a calculation for "b" (repulsion parameter) is not needed for GERG2008. + return 0; + } + + @Override + public double fugcoef(PhaseInterface phase) { + // Return the already computed fugacity coefficient. + return fugacityCoefficient; + } + + @Override + public double alpha(double temperature) { + // GERG2008 may not need a temperature-dependent alpha function; return 1. + return 1; + } + + @Override + public double diffaT(double temperature) { + // Return unity unless a temperature derivative is required. + return 1; + } + +@Override +public double diffdiffaT(double temperature) { + // Return unity unless a second derivative is needed. + return 1; + } +} diff --git a/src/main/java/neqsim/thermo/component/ComponentLeachmanEos.java b/src/main/java/neqsim/thermo/component/ComponentLeachmanEos.java new file mode 100644 index 000000000..1f2edd297 --- /dev/null +++ b/src/main/java/neqsim/thermo/component/ComponentLeachmanEos.java @@ -0,0 +1,57 @@ +package neqsim.thermo.component; + +import neqsim.thermo.phase.PhaseInterface; + +/** + *

+ * ComponentLeachman class. + *

+ * + * @author Even Solbraa Leachman + * @version $Id: $Id + */ +public class ComponentLeachmanEos extends ComponentFundamentalEOS { + /** Serialization version UID. */ + private static final long serialVersionUID = 1000; + + /** + *

+ * Constructor for ComponentLeachman. + *

+ * + * @param name Name of component. + * @param moles Total number of moles of component. + * @param molesInPhase Number of moles in phase. + * @param compIndex Index number of component in phase object component array. + */ + public ComponentLeachmanEos(String name, double moles, double molesInPhase, int compIndex) { + super(name, moles, molesInPhase, compIndex); + } + + + + /** {@inheritDoc} */ + @Override + public ComponentLeachmanEos clone() { + ComponentLeachmanEos clonedComponent = null; + try { + clonedComponent = (ComponentLeachmanEos) super.clone(); + } catch (Exception ex) { + logger.error("Cloning failed.", ex); + } + + return clonedComponent; + } + + + + /** {@inheritDoc} */ + @Override + public double fugcoef(PhaseInterface phase) { + return fugacityCoefficient; + } + + + + +} diff --git a/src/main/java/neqsim/thermo/component/ComponentVegaEos.java2 b/src/main/java/neqsim/thermo/component/ComponentVegaEos.java2 new file mode 100644 index 000000000..f7598e8f1 --- /dev/null +++ b/src/main/java/neqsim/thermo/component/ComponentVegaEos.java2 @@ -0,0 +1,101 @@ +package neqsim.thermo.component; + +import neqsim.thermo.phase.PhaseInterface; + +/** + *

+ * ComponentVega class. + *

+ * + * @author Even Solbraa Vega + * @version $Id: $Id + */ +public class ComponentVegaEos extends ComponentEos { + /** Serialization version UID. */ + private static final long serialVersionUID = 1000; + + /** + *

+ * Constructor for ComponentVega + *

+ * + * @param name Name of component. + * @param moles Total number of moles of component. + * @param molesInPhase Number of moles in phase. + * @param compIndex Index number of component in phase object component array. + */ + public ComponentVegaEos(String name, double moles, double molesInPhase, int compIndex) { + super(name, moles, molesInPhase, compIndex); + } + + /** + *

+ * Constructor for ComponentVega + *

+ * + * @param number a int. Not used. + * @param TC Critical temperature + * @param PC Critical pressure + * @param M Molar mass + * @param a Acentric factor + * @param moles Total number of moles of component. + */ + public ComponentVegaEos(int number, double TC, double PC, double M, double a, double moles) { + super(number, TC, PC, M, a, moles); + } + + /** {@inheritDoc} */ + @Override + public ComponentVegaEos clone() { + ComponentVegaEos clonedComponent = null; + try { + clonedComponent = (ComponentVegaEos) super.clone(); + } catch (Exception ex) { + logger.error("Cloning failed.", ex); + } + + return clonedComponent; + } + + /** {@inheritDoc} */ + @Override + public double getVolumeCorrection() { + return 0.0; + } + + /** {@inheritDoc} */ + @Override + public double calca() { + return 0; + } + + /** {@inheritDoc} */ + @Override + public double calcb() { + return 0; + } + + /** {@inheritDoc} */ + @Override + public double fugcoef(PhaseInterface phase) { + return fugacityCoefficient; + } + + /** {@inheritDoc} */ + @Override + public double alpha(double temperature) { + return 1; + } + + /** {@inheritDoc} */ + @Override + public double diffaT(double temperature) { + return 1; + } + + /** {@inheritDoc} */ + @Override + public double diffdiffaT(double temperature) { + return 1; + } +} diff --git a/src/main/java/neqsim/thermo/phase/Phase.java b/src/main/java/neqsim/thermo/phase/Phase.java index e86d91c75..e2682466d 100644 --- a/src/main/java/neqsim/thermo/phase/Phase.java +++ b/src/main/java/neqsim/thermo/phase/Phase.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.netlib.util.doubleW; import neqsim.physicalproperties.PhysicalPropertyHandler; import neqsim.physicalproperties.PhysicalPropertyType; import neqsim.physicalproperties.system.PhysicalProperties; @@ -2320,8 +2321,95 @@ public double[] getProperties_Leachman() { throw new IllegalArgumentException("Leachman model only works for hydrogen. Found: " + compName); } } + + + /** {@inheritDoc} */ + @Override + public doubleW[] getAlpha0_Leachman(String hydrogenType) { + neqsim.thermo.util.leachman.NeqSimLeachman test = + new neqsim.thermo.util.leachman.NeqSimLeachman(this, hydrogenType); + return test.getAlpha0_Leachman(); + } + + /** + * If no hydrogentype is specified it checks the component name and chooses the correct hydrogen. + * Checks for other components in the phase and throws an exception if the phase is not pure + * + * @return a matrix of properties of type doubleW. + */ + public doubleW[] getAlpha0_Leachman() { + // Check that the phase contains exactly one component + if (this.getNumberOfComponents() != 1) { + StringBuilder compNames = new StringBuilder(); + for (int i = 0; i < this.getNumberOfComponents(); i++) { + compNames.append(this.getComponent(i).getComponentName()); + if (i < this.getNumberOfComponents() - 1) { + compNames.append(", "); + } + } + throw new IllegalArgumentException("Leachman model only works for pure hydrogen streams. Found components: " + + compNames.toString()); + } + + // Retrieve the component name from the current phase + String compName = this.getComponent(0).getComponentName(); + + // Check the component type and choose the correct hydrogen type + if (compName.equalsIgnoreCase("para-hydrogen")) { + return getAlpha0_Leachman("para"); + } else if (compName.equalsIgnoreCase("ortho-hydrogen")) { + return getAlpha0_Leachman("ortho"); + } else if (compName.equalsIgnoreCase("hydrogen")) { + return getAlpha0_Leachman("normal"); + } else { + throw new IllegalArgumentException("Leachman model only works for hydrogen. Found: " + compName); + } + } + /** {@inheritDoc} */ + @Override + public doubleW[][] getAlphares_Leachman(String hydrogenType) { + neqsim.thermo.util.leachman.NeqSimLeachman test = + new neqsim.thermo.util.leachman.NeqSimLeachman(this, hydrogenType); + return test.getAlphares_Leachman(); + } + + /** + * If no hydrogentype is specified it checks the component name and chooses the correct hydrogen. + * Checks for other components in the phase and throws an exception if the phase is not pure + * + * @return a matrix of properties of type doubleW. + */ + public doubleW[][] getAlphares_Leachman() { + // Check that the phase contains exactly one component + if (this.getNumberOfComponents() != 1) { + StringBuilder compNames = new StringBuilder(); + for (int i = 0; i < this.getNumberOfComponents(); i++) { + compNames.append(this.getComponent(i).getComponentName()); + if (i < this.getNumberOfComponents() - 1) { + compNames.append(", "); + } + } + throw new IllegalArgumentException("Leachman model only works for pure hydrogen streams. Found components: " + + compNames.toString()); + } + + // Retrieve the component name from the current phase + String compName = this.getComponent(0).getComponentName(); + + // Check the component type and choose the correct hydrogen type + if (compName.equalsIgnoreCase("para-hydrogen")) { + return getAlphares_Leachman("para"); + } else if (compName.equalsIgnoreCase("ortho-hydrogen")) { + return getAlphares_Leachman("ortho"); + } else if (compName.equalsIgnoreCase("hydrogen")) { + return getAlphares_Leachman("normal"); + } else { + throw new IllegalArgumentException("Leachman model only works for hydrogen. Found: " + compName); + } + } + /** {@inheritDoc} */ @Override public double getDensity_AGA8() { diff --git a/src/main/java/neqsim/thermo/phase/PhaseFundamentalEOS.java b/src/main/java/neqsim/thermo/phase/PhaseFundamentalEOS.java new file mode 100644 index 000000000..482b044c2 --- /dev/null +++ b/src/main/java/neqsim/thermo/phase/PhaseFundamentalEOS.java @@ -0,0 +1,325 @@ +package neqsim.thermo.phase; + +import org.netlib.util.doubleW; +import neqsim.thermo.component.ComponentFundamentalEOSInterface; +import neqsim.thermo.mixingrule.MixingRuleTypeInterface; +import neqsim.thermo.mixingrule.MixingRulesInterface; + +/** + * Abstract base class for Helmholtz-energy-based equations of state. + * Assumes subclasses use reduced Helmholtz energy (a/RT) and compute properties from it. + * + * @author victorigi + * @since 27.03.2025 + */ +public abstract class PhaseFundamentalEOS extends Phase implements PhaseFundamentalEOSInterface { + private static final long serialVersionUID = 1L; + + doubleW[][] ar; + doubleW[] a0; + double density; + double T; + double RT; + double dPdD; + double dPdT; + double d2PdTD; + double A; + double G; + double U; + double H; + double S; + double Cp; + double Cv; + double JT; + double W; + double Kappa; + double d2PdD2; + + + public PhaseFundamentalEOS() { + super(); + setType(PhaseType.GAS); // Default; subclasses can override after density calc + } + + /** + * Compute molar density [mol/m3] at specified T and P. + */ + public abstract double solveDensity(double temperature, double pressure); + + /** + * Compute reduced residual Helmholtz energy and its derivatives. + * /** + * Get reduced residual helmholtz free energy and its derivatives. + * The returned array has the following structure: + * + */ + public abstract doubleW[][] getAlpharesMatrix(); + + + public abstract doubleW[] getAlpha0Matrix(); + + /** {@inheritDoc} */ + @Override + public void init(double totalNumberOfMoles, int nComponents, int initType, PhaseType pt, double beta) { + super.init(totalNumberOfMoles, nComponents, initType, pt, beta); + T = getTemperature(); + this.pressure = getPressure(); + + + + + if (initType >= 1) { + density = solveDensity(temperature, pressure); //mol/m3 + ar = getAlpharesMatrix(); + a0 = getAlpha0Matrix(); + RT = R * temperature; + Z = 1 + ar[0][1].val; + dPdD = RT * (1 + 2 * ar[0][1].val + ar[0][2].val); + dPdT = density * R * (1 + ar[0][1].val - ar[1][1].val); + + d2PdTD = R * (1 + 2 * ar[0][1].val + ar[0][2].val - 2 * ar[1][1].val - ar[1][2].val); + A = RT * (a0[0].val + ar[0][0].val); // Helmholtz energy + G = RT * (1 + ar[0][1].val + a0[0].val + ar[0][0].val); + U = RT * (a0[1].val + ar[1][0].val); + H = RT * (1 + ar[0][1].val + a0[1].val + ar[1][0].val); + S = R * (a0[1].val + ar[1][0].val - a0[0].val - ar[0][0].val); + Cv = -R * (a0[2].val + ar[2][0].val); + if (density > 1e-15) { + Cp = Cv + T * (dPdT / density) * (dPdT / density) / dPdD; + d2PdD2 = RT * (2 * ar[0][1].val + 4 * ar[0][2].val + ar[0][3].val) / density; + JT = (T / density * dPdT / dPdD - 1) / Cp / density; + } else { + Cp = Cv + R; + d2PdD2 = 0; + JT = 1E+20; + } + W = 1000 * Cp / Cv * dPdD / getMolarMass(); + if (W < 0) { + W = 0; + } + W = Math.sqrt(W); + Kappa = Math.pow(W, 2) * getMolarMass() / (RT * 1000 * Z); + } + } + + + + // --- Thermodynamic framework methods --- + + + /** {@inheritDoc} */ + @Override + public double getZ() { + return Z; + } + + /** {@inheritDoc} */ + @Override + public double getDensity() { + return density; + } + + /** {@inheritDoc} */ + @Override + public double getPressure() { + return Z * R * temperature * density; + } + + /** + *

+ * Get the derivative of pressure with respect to density. + *

+ * + * @return double + */ + public double getDPdD() { + return dPdD; + } + + /** {@inheritDoc} */ + @Override + public double getGibbsEnergy() { + return G * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getJouleThomsonCoefficient() { + return JT * 1e3; // [K/bar] + } + + /** {@inheritDoc} */ + @Override + public double getEnthalpy() { + return H * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getEntropy() { + return S * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getInternalEnergy() { + return U * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getCp() { + return Cp * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getCv() { + return Cv * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getSoundSpeed() { + return W; + } + + /** {@inheritDoc} */ + @Override + public double getKappa() { + return Kappa; + } + + /** {@inheritDoc} */ + @Override + public double molarVolume(double pressure, double temperature, double A, double B, PhaseType pt) { + return 1 / density; + } + + + + + /** {@inheritDoc} */ + @Override + public double getdPdTVn() { + return density * R * (1 + ar[0][1].val - ar[1][1].val); + } + + /** {@inheritDoc} */ + @Override + public double getdPdVTn() { + return -density * density * R * T * (1 + 2 * ar[0][1].val + ar[0][2].val) / numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getdPdrho() { + return R * T * (1 + 2 * ar[0][1].val + ar[0][2].val); + } + + /** {@inheritDoc} */ + @Override + public double getdrhodP() { + return 1.0 / getdPdrho(); + } + + /** {@inheritDoc} */ + @Override + public double getdrhodT() { + return -getdPdTVn() / getdPdrho(); + } + + /** + *

+ * getF. + *

+ * + * @return a double + */ + public double getF() { + return numberOfMolesInPhase * ar[0][0].val; + } + + /** {@inheritDoc} */ + @Override + public double dFdTdV() { + return numberOfMolesInPhase * ar[1][1].val / (temperature * getVolume()); + } + + /** {@inheritDoc} */ + @Override + public double dFdN(int i) { + return ((ComponentFundamentalEOSInterface) getComponent(i)).dFdN(this, this.getNumberOfComponents(), + temperature, pressure); + } + + /** {@inheritDoc} */ + @Override + public double dFdNdN(int i, int j) { + return ((ComponentFundamentalEOSInterface) getComponent(i)).dFdNdN(j, this, this.getNumberOfComponents(), + temperature, pressure); + } + + /** {@inheritDoc} */ + @Override + public double dFdNdV(int i) { + return ((ComponentFundamentalEOSInterface) getComponent(i)).dFdNdV(this, this.getNumberOfComponents(), + temperature, pressure); + } + + /** {@inheritDoc} */ + @Override + public double dFdNdT(int i) { + return ((ComponentFundamentalEOSInterface) getComponent(i)).dFdNdT(this, this.getNumberOfComponents(), + temperature, pressure); + } + + + + // --- Provide defaults to avoid forcing subclass overrides if not needed --- + + @Override + public double getA() { + throw new UnsupportedOperationException("getA() not supported for fundamental EOS"); + } + + @Override + public double getB() { + throw new UnsupportedOperationException("getB() not supported for fundamental EOS"); + } + + @Override +public MixingRulesInterface getMixingRule() { + throw new UnsupportedOperationException("Mixing rule not implemented for PhaseFundamentalEos"); +} + + @Override + public MixingRuleTypeInterface getMixingRuleType() { + throw new UnsupportedOperationException("Mixing rule not implemented for PhaseFundamentalEos"); + } + + @Override + public void resetMixingRule(MixingRuleTypeInterface mixingRule) { + throw new UnsupportedOperationException("Mixing rule not implemented for PhaseFundamentalEos"); + } + + @Override + public void setMixingRule(MixingRuleTypeInterface mixingRule) { + throw new UnsupportedOperationException("Mixing rule not implemented for PhaseFundamentalEos"); + } + + @Override + public void setMixingRuleGEModel(String model) { + throw new UnsupportedOperationException("Mixing rule GE Model not implemented for PhaseFundamentalEos"); + } + + +} diff --git a/src/main/java/neqsim/thermo/phase/PhaseFundamentalEOSInterface.java b/src/main/java/neqsim/thermo/phase/PhaseFundamentalEOSInterface.java new file mode 100644 index 000000000..cb414cda4 --- /dev/null +++ b/src/main/java/neqsim/thermo/phase/PhaseFundamentalEOSInterface.java @@ -0,0 +1,244 @@ +package neqsim.thermo.phase; + +import org.netlib.util.doubleW; + +public interface PhaseFundamentalEOSInterface { + + + /** + * Compute molar density [mol/m3] at specified temperature and pressure. + * + * @param temperature Temperature in Kelvin. + * @param pressure Pressure (in the appropriate unit for your system). + * @return Molar density in [mol/m3]. + */ + double solveDensity(double temperature, double pressure); + + /** + * Get the reduced residual Helmholtz free energy and its derivatives. + * The returned 2D array has the following structure: + * + * + * @return A 2D array of {@code doubleW} objects containing the Helmholtz energy derivatives. + */ + doubleW[][] getAlpharesMatrix(); + + /** + * Get the matrix for the ideal-gas part of the Helmholtz free energy. + * + * @return An array of {@code doubleW} objects representing the ideal-gas contribution. + */ + doubleW[] getAlpha0Matrix(); + + /** + * Initialize the phase with the specified parameters. + * + * @param totalNumberOfMoles Total number of moles. + * @param nComponents Number of components. + * @param initType Initialization type flag. + * @param pt Phase type. + * @param beta Additional parameter (context-dependent). + */ + void init(double totalNumberOfMoles, int nComponents, int initType, PhaseType pt, double beta); + + /** + * Get the compressibility factor. + * + * @return Compressibility factor Z. + */ + double getZ(); + + /** + * Get the molar density [mol/m3]. + * + * @return Density in mol/m3. + */ + double getDensity(); + + /** + * Get the pressure calculated from the Helmholtz EOS. + * + * @return Pressure. + */ + double getPressure(); + + /** + * Get the derivative of pressure with respect to density. + * + * @return dP/dD. + */ + double getDPdD(); + + /** + * Get the Gibbs energy of the phase. + * + * @return Gibbs energy. + */ + double getGibbsEnergy(); + + /** + * Get the Joule-Thomson coefficient. + * + * @return Joule-Thomson coefficient. + */ + double getJouleThomsonCoefficient(); + + /** + * Get the enthalpy of the phase. + * + * @return Enthalpy. + */ + double getEnthalpy(); + + /** + * Get the entropy of the phase. + * + * @return Entropy. + */ + double getEntropy(); + + /** + * Get the internal energy of the phase. + * + * @return Internal energy. + */ + double getInternalEnergy(); + + /** + * Get the isobaric heat capacity. + * + * @return Cp. + */ + double getCp(); + + /** + * Get the isochoric heat capacity. + * + * @return Cv. + */ + double getCv(); + + /** + * Get the speed of sound in the phase. + * + * @return Speed of sound. + */ + double getSoundSpeed(); + + /** + * Get the isentropic exponent (kappa). + * + * @return kappa. + */ + double getKappa(); + + /** + * Compute the molar volume. + * + * @param pressure Pressure. + * @param temperature Temperature. + * @param A Parameter A. + * @param B Parameter B. + * @param pt Phase type. + * @return Molar volume. + */ + double molarVolume(double pressure, double temperature, double A, double B, PhaseType pt); + + /** + * Get the temperature derivative of pressure times the number of moles. + * + * @return dP/dT * n. + */ + double getdPdTVn(); + + /** + * Get the derivative of pressure with respect to volume times the number of moles. + * + * @return dP/dV * n. + */ + double getdPdVTn(); + + /** + * Get the derivative of pressure with respect to density. + * + * @return dP/drho. + */ + double getdPdrho(); + + /** + * Get the derivative of density with respect to pressure. + * + * @return drho/dP. + */ + double getdrhodP(); + + /** + * Get the derivative of density with respect to temperature. + * + * @return drho/dT. + */ + double getdrhodT(); + + /** + * Get the contribution to the Helmholtz energy from the residual part. + * + * @return Residual Helmholtz energy contribution. + */ + double getF(); + + + /** + * Get the derivative of the Helmholtz energy with respect to density. + * + * @param i Index for the derivative. + * @return Derivative of Helmholtz energy with respect to density. + */ + double dFdN(int i); + + /** + * Get the derivative of the Helmholtz energy with respect to temperature. + * + * @return Derivative of Helmholtz energy with respect to temperature. + */ + double dFdNdT(int i); + + /** + * Get the derivative of the Helmholtz energy with respect to volume. + * + * @return Derivative of Helmholtz energy with respect to volume. + */ + double dFdNdV(int i); + + /** + * Get the derivative of the Helmholtz energy with respect to moles. + * + * @param j Index for the derivative. + * @return Derivative of Helmholtz energy with respect to moles. + */ + double dFdNdN(int i, int j); + + /** + * Get parameter A. This method is not supported for fundamental EOS. + * + * @return Parameter A. + * @throws UnsupportedOperationException if not supported. + */ + double getA(); + + /** + * Get parameter B. This method is not supported for fundamental EOS. + * + * @return Parameter B. + * @throws UnsupportedOperationException if not supported. + */ + double getB(); + +} diff --git a/src/main/java/neqsim/thermo/phase/PhaseGERG2008Eos.java b/src/main/java/neqsim/thermo/phase/PhaseGERG2008Eos.java new file mode 100644 index 000000000..040710c50 --- /dev/null +++ b/src/main/java/neqsim/thermo/phase/PhaseGERG2008Eos.java @@ -0,0 +1,142 @@ +package neqsim.thermo.phase; + +import neqsim.thermo.component.ComponentGERG2008; + +/** + * PhaseGERG2008Eos class upgraded to use GERG2008. + * + *

This class upgrades the old GERG2004Eos by using the NeqSimGERG2008 routines to + * calculate thermodynamic properties. In addition, extensive properties are returned by + * multiplying the molar values by the number of moles in the phase. This version mimics the + * structure of the Leachman EOS implementation.

+ * + * @author YourName + * @version 1.1 + */ +public class PhaseGERG2008Eos extends PhaseEos { + private static final long serialVersionUID = 1000; + + int IPHASE = 0; + boolean okVolume = true; + double enthalpy = 0.0; + double entropy = 0.0; + double gibbsEnergy = 0.0; + double CpGERG = 0.0; + double CvGERG = 0.0; + double internalEnergy = 0.0; + double JTcoef = 0.0; + + // Helper for property calculations using GERG2008 + //NeqSimGERG2008 gerg2008 = new NeqSimGERG2008(); + + /** + * Constructor for PhaseGERG2008Eos. + */ + public PhaseGERG2008Eos() { + thermoPropertyModelName = "GERG-EoS 2008"; + } + + /** {@inheritDoc} */ + @Override + public PhaseGERG2008Eos clone() { + PhaseGERG2008Eos clonedPhase = null; + try { + clonedPhase = (PhaseGERG2008Eos) super.clone(); + } catch (Exception ex) { + logger.error("Cloning failed.", ex); + } + return clonedPhase; + } + + /** {@inheritDoc} */ + @Override + public void addComponent(String name, double moles, double molesInPhase, int compNumber) { + super.addComponent(name, molesInPhase, compNumber); + // Use the GERG2008-specific component. + componentArray[compNumber] = new ComponentGERG2008(name, moles, molesInPhase, compNumber); + } + + /** {@inheritDoc} */ + @Override + public void init(double totalNumberOfMoles, int numberOfComponents, int initType, PhaseType pt, double beta) { + IPHASE = pt == PhaseType.LIQUID ? -1 : -2; + super.init(totalNumberOfMoles, numberOfComponents, initType, pt, beta); + + if (!okVolume) { + IPHASE = pt == PhaseType.LIQUID ? -2 : -1; + super.init(totalNumberOfMoles, numberOfComponents, initType, pt, beta); + } + if (initType >= 1) { + // Let the GERG2008 helper map the phase composition + double[] properties = new double[18]; + properties = getProperties_GERG2008(); + // Retrieve the molar thermodynamic properties from GERG2008. + // Assumed mapping: + // properties[6]: internal energy (J/mol) + // properties[7]: enthalpy (J/mol) + // properties[8]: entropy (J/mol·K) + // properties[9]: Cv (J/mol·K) + // properties[10]: Cp (J/mol·K) + // properties[12]: Gibbs energy (J/mol) + // properties[13]: Joule-Thomson coefficient (K/kPa) + internalEnergy = properties[6]; + enthalpy = properties[7]; + entropy = properties[8]; + CvGERG = properties[9]; + CpGERG = properties[10]; + gibbsEnergy = properties[12]; + JTcoef = properties[13]; + } + super.init(totalNumberOfMoles, numberOfComponents, initType, pt, beta); + } + + @Override + public double getGibbsEnergy() { + return gibbsEnergy * numberOfMolesInPhase; + } + + @Override + public double getJouleThomsonCoefficient() { + return JTcoef * 1e3; // e.g., converting from K/kPa to K/bar + } + + @Override + public double getEnthalpy() { + return enthalpy * numberOfMolesInPhase; + } + + @Override + public double getEntropy() { + return entropy * numberOfMolesInPhase; + } + + @Override + public double getInternalEnergy() { + return internalEnergy * numberOfMolesInPhase; + } + + @Override + public double getCp() { + return CpGERG * numberOfMolesInPhase; + } + + @Override + public double getCv() { + return CvGERG * numberOfMolesInPhase; + } + + /** + * Computes the molar volume using the GERG2008 density routine. + *

+ * We assume that gerg2008.getMolarDensity(this) returns the molar density in [mol/m³]. + * Then, for consistency with the Leachman approach, we define: + * + * molarVolume = 1e5 / molarDensity. + *

+ */ + @Override + public double molarVolume(double pressure, double temperature, double A, double B, PhaseType pt) + throws neqsim.util.exception.IsNaNException, neqsim.util.exception.TooManyIterationsException { + return getMolarMass() * 1e5 / getDensity_GERG2008(); + } +} diff --git a/src/main/java/neqsim/thermo/phase/PhaseInterface.java b/src/main/java/neqsim/thermo/phase/PhaseInterface.java index 2278b7005..fe94e9bbc 100644 --- a/src/main/java/neqsim/thermo/phase/PhaseInterface.java +++ b/src/main/java/neqsim/thermo/phase/PhaseInterface.java @@ -6,6 +6,7 @@ package neqsim.thermo.phase; +import org.netlib.util.doubleW; import neqsim.physicalproperties.PhysicalPropertyType; import neqsim.physicalproperties.system.PhysicalProperties; import neqsim.physicalproperties.system.PhysicalPropertyModel; @@ -15,6 +16,7 @@ import neqsim.thermo.mixingrule.MixingRuleTypeInterface; import neqsim.thermo.mixingrule.MixingRulesInterface; import neqsim.thermo.system.SystemInterface; + /** *

@@ -453,6 +455,45 @@ public default void initPhysicalProperties(String name) { */ public double[] getProperties_Leachman(); + + + /** + *

+ * method to get Leachman alpha0 of a phase using the Leachman EoS. + *

+ * + * @param hydrogenType a {@link java.lang.String} object + * @return a matrix of the reduced ideal helmholtz free energy and its derivatives + */ + public doubleW[] getAlpha0_Leachman(String hydrogenType); + + + /** + * Overloaded method to get the Leachman a0matrix with default hydrogen type ('normal'). + * + * @return matrix of the reduced ideal helmholtz free energy and its derivatives + */ + public doubleW[] getAlpha0_Leachman(); + + /** + *

+ * method to get Leachman alphares of a phase using the Leachman EoS. + *

+ * + * @param hydrogenType a {@link java.lang.String} object + * @return a matrix of the reduced residual helmholtz free energy and its derivatives + */ + public doubleW[][] getAlphares_Leachman(String hydrogenType); + + + /** + * Overloaded method to get the Leachman armatrix with default hydrogen type ('normal'). + * + * @return matrix of the reduced residual helmholtz free energy and its derivatives + */ + public doubleW[][] getAlphares_Leachman(); + + /** * method to get helium density of a phase using the Vega EoS. * @@ -2088,4 +2129,5 @@ public default boolean hasComponent(String name) { * @return double Z volume corrected */ public double getZvolcorr(); + } diff --git a/src/main/java/neqsim/thermo/phase/PhaseLeachmanEos copy.java2 b/src/main/java/neqsim/thermo/phase/PhaseLeachmanEos copy.java2 new file mode 100644 index 000000000..f2185e596 --- /dev/null +++ b/src/main/java/neqsim/thermo/phase/PhaseLeachmanEos copy.java2 @@ -0,0 +1,213 @@ +package neqsim.thermo.phase; + +import org.netlib.util.doubleW; +import neqsim.thermo.component.ComponentEosInterface; +import neqsim.thermo.component.ComponentLeachmanEos; + +/** + *

+ * PhaseLeachmanEos class. + *

+ * + * @author Even Solbraa + * @version $Id: $Id + */ +public class PhaseLeachmanEosCopy extends PhaseEos { + /** Serialization version UID. */ + private static final long serialVersionUID = 1000; + + int IPHASE = 0; + boolean okVolume = true; + double enthalpy = 0.0; + + double entropy = 0.0; + + double gibbsEnergy = 0.0; + + double CpLeachman = 0.0; + + double CvLeachman = 0.0; + + double internalEnery = 0.0; + + double JTcoef = 0.0; + + doubleW[][] alpharesMatrix = null; + + /** + *

+ * Constructor for PhaseLeachmanEos. + *

+ */ + public PhaseLeachmanEos() { + thermoPropertyModelName = "Leachman Eos"; + } + + /** {@inheritDoc} */ + @Override + public PhaseLeachmanEos clone() { + PhaseLeachmanEos clonedPhase = null; + try { + clonedPhase = (PhaseLeachmanEos) super.clone(); + } catch (Exception ex) { + logger.error("Cloning failed.", ex); + } + + return clonedPhase; + } + + /** {@inheritDoc} */ + @Override + public void addComponent(String name, double moles, double molesInPhase, int compNumber) { + super.addComponent(name, molesInPhase, compNumber); + componentArray[compNumber] = new ComponentLeachmanEos(name, moles, molesInPhase, compNumber); + } + + /** {@inheritDoc} */ + @Override + public void init(double totalNumberOfMoles, int numberOfComponents, int initType, PhaseType pt, + double beta) { + + if (initType != 0) { + alpharesMatrix = getAlphares_Leachman(); // F = alpharesMatrix[0][0].val + } + super.init(totalNumberOfMoles, numberOfComponents, initType, pt, beta); + + + + + + if (!okVolume) { + IPHASE = pt == PhaseType.LIQUID ? -2 : -1; + super.init(totalNumberOfMoles, numberOfComponents, initType, pt, beta); + } + if (initType >= 1) { + double[] temp = new double[18]; + temp = getProperties_Leachman(); + + + gibbsEnergy = temp[12]; + internalEnery = temp[6]; // .UOTPX(temperature,pressure/10.0, + // xFracGERG[0],xFracGERG[1],xFracGERG[2],xFracGERG[3],xFracGERG[4],xFracGERG[5],xFracGERG[6],xFracGERG[7],xFracGERG[8],xFracGERG[9],xFracGERG[10],xFracGERG[11],xFracGERG[12],xFracGERG[13],xFracGERG[14],xFracGERG[15],xFracGERG[16],xFracGERG[17],IPHASE); + enthalpy = temp[7]; // gergEOS.HOTPX(temperature,pressure/10.0, + // xFracGERG[0],xFracGERG[1],xFracGERG[2],xFracGERG[3],xFracGERG[4],xFracGERG[5],xFracGERG[6],xFracGERG[7],xFracGERG[8],xFracGERG[9],xFracGERG[10],xFracGERG[11],xFracGERG[12],xFracGERG[13],xFracGERG[14],xFracGERG[15],xFracGERG[16],xFracGERG[17],IPHASE); + entropy = temp[8]; // gergEOS.SOTPX(temperature,pressure/10.0, + // xFracGERG[0],xFracGERG[1],xFracGERG[2],xFracGERG[3],xFracGERG[4],xFracGERG[5],xFracGERG[6],xFracGERG[7],xFracGERG[8],xFracGERG[9],xFracGERG[10],xFracGERG[11],xFracGERG[12],xFracGERG[13],xFracGERG[14],xFracGERG[15],xFracGERG[16],xFracGERG[17],IPHASE); + CpLeachman = temp[10]; // gergEOS.CPOTPX(temperature,pressure/10.0, + // xFracGERG[0],xFracGERG[1],xFracGERG[2],xFracGERG[3],xFracGERG[4],xFracGERG[5],xFracGERG[6],xFracGERG[7],xFracGERG[8],xFracGERG[9],xFracGERG[10],xFracGERG[11],xFracGERG[12],xFracGERG[13],xFracGERG[14],xFracGERG[15],xFracGERG[16],xFracGERG[17],IPHASE); + CvLeachman = temp[9]; // gergEOS.CPOTPX(temperature,pressure/10.0, + // xFracGERG[0],xFracGERG[1],xFracGERG[2],xFracGERG[3],xFracGERG[4],xFracGERG[5],xFracGERG[6],xFracGERG[7],xFracGERG[8],xFracGERG[9],xFracGERG[10],xFracGERG[11],xFracGERG[12],xFracGERG[13],xFracGERG[14],xFracGERG[15],xFracGERG[16],xFracGERG[17],IPHASE); + JTcoef = temp[13]; + + + super.init(totalNumberOfMoles, numberOfComponents, initType, pt, beta); + } + } + + /** {@inheritDoc} */ + @Override + public double getGibbsEnergy() { + return gibbsEnergy * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getJouleThomsonCoefficient() { + return JTcoef * 1e3; // [K/bar] + } + + /** {@inheritDoc} */ + @Override + public double getEnthalpy() { + return enthalpy * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getEntropy() { + return entropy * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getInternalEnergy() { + return internalEnery * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getCp() { + return CpLeachman * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getCv() { + return CvLeachman * numberOfMolesInPhase; + } + + + /** {@inheritDoc} */ + @Override + public double molarVolume(double pressure, double temperature, double A, double B, PhaseType pt) + throws neqsim.util.exception.IsNaNException, + neqsim.util.exception.TooManyIterationsException { + return getMolarMass() * 1e5 / getDensity_Leachman(); + } + + + + /** {@inheritDoc} */ + @Override + public double getF() { + return alpharesMatrix[0][0].val; + } + + /** {@inheritDoc} */ + @Override + public double dFdT() { + return - alpharesMatrix[1][0].val / getTemperature(); + } + + /** {@inheritDoc} */ + @Override + public double dFdTdT() { + return (2 * alpharesMatrix[1][0].val + alpharesMatrix[2][0].val) / (getTemperature() * getTemperature()); + } + + + /** {@inheritDoc} */ + @Override + public double dFdV() { + return - alpharesMatrix[0][1].val / getVolume(); + } + + /** {@inheritDoc} */ + @Override + public double dFdVdV() { + return (2 * alpharesMatrix[0][1].val + alpharesMatrix[0][2].val) / (getVolume() * getVolume()); + } + + /** {@inheritDoc} */ + @Override + public double dFdTdV() { + double T = getTemperature(); + double V = getVolume(); + return alpharesMatrix[1][1].val / (T * V); + } + + /** {@inheritDoc} */ + @Override + public double dFdN(int i) { + return ((ComponentEosInterface) getComponent(i)) + .dFdN(this, this.getNumberOfComponents(), temperature, pressure); + } + + /** {@inheritDoc} */ + @Override + public double dFdNdV(int i) { + return ((ComponentEosInterface) getComponent(i)) + .dFdNdV(this, this.getNumberOfComponents(), temperature, pressure); + } + +} diff --git a/src/main/java/neqsim/thermo/phase/PhaseLeachmanEos.java b/src/main/java/neqsim/thermo/phase/PhaseLeachmanEos.java new file mode 100644 index 000000000..6c93d357c --- /dev/null +++ b/src/main/java/neqsim/thermo/phase/PhaseLeachmanEos.java @@ -0,0 +1,118 @@ +package neqsim.thermo.phase; + +import org.netlib.util.doubleW; +import neqsim.thermo.component.ComponentLeachmanEos; + +/** + *

+ * PhaseLeachmanEos class. + *

+ * + * @author Even Solbraa + * @version $Id: $Id + */ +public class PhaseLeachmanEos extends PhaseFundamentalEOS implements PhaseFundamentalEOSInterface { + /** Serialization version UID. */ + private static final long serialVersionUID = 1000; + + int IPHASE = 0; + boolean okVolume = true; + double enthalpy = 0.0; + + double entropy = 0.0; + + double gibbsEnergy = 0.0; + + double CpLeachman = 0.0; + + double CvLeachman = 0.0; + + double internalEnery = 0.0; + + double JTcoef = 0.0; + + doubleW[][] alpharesMatrix = null; + + /** + *

+ * Constructor for PhaseLeachmanEos. + *

+ */ + public PhaseLeachmanEos() { + thermoPropertyModelName = "Leachman Eos"; + } + + /** {@inheritDoc} */ + @Override + public PhaseLeachmanEos clone() { + PhaseLeachmanEos clonedPhase = null; + try { + clonedPhase = (PhaseLeachmanEos) super.clone(); + } catch (Exception ex) { + logger.error("Cloning failed.", ex); + } + + return clonedPhase; + } + + /** {@inheritDoc} */ + @Override + public void addComponent(String name, double moles, double molesInPhase, int compNumber) { + super.addComponent(name, molesInPhase, compNumber); + componentArray[compNumber] = new ComponentLeachmanEos(name, moles, molesInPhase, compNumber); + } + + /** {@inheritDoc} */ + @Override + public void init(double totalNumberOfMoles, int numberOfComponents, int initType, PhaseType pt, + double beta) { + + if (initType != 0) { + + } + super.init(totalNumberOfMoles, numberOfComponents, initType, pt, beta); + + + + + + if (!okVolume) { + IPHASE = pt == PhaseType.LIQUID ? -2 : -1; + super.init(totalNumberOfMoles, numberOfComponents, initType, pt, beta); + } + if (initType >= 1) { + density = solveDensity(temperature, pressure);//mol/m3 + + + + super.init(totalNumberOfMoles, numberOfComponents, initType, pt, beta); + } + } + + + /** {@inheritDoc} */ + @Override + public double solveDensity(double temperature, double pressure) { + return getDensity_Leachman(); + } + + /** {@inheritDoc} */ + @Override + public double getDensity() { + return getDensity_Leachman(); + } + + + /** {@inheritDoc} */ + @Override + public doubleW[] getAlpha0Matrix() { + return getAlpha0_Leachman(); + } + + /** {@inheritDoc} */ + @Override + public doubleW[][] getAlpharesMatrix() { + return getAlphares_Leachman(); + } + +} diff --git a/src/main/java/neqsim/thermo/phase/PhaseVegaEos.java2 b/src/main/java/neqsim/thermo/phase/PhaseVegaEos.java2 new file mode 100644 index 000000000..769fe6c9a --- /dev/null +++ b/src/main/java/neqsim/thermo/phase/PhaseVegaEos.java2 @@ -0,0 +1,143 @@ +package neqsim.thermo.phase; + +import neqsim.thermo.component.ComponentVegaEos; + +/** + *

+ * PhaseVegaEos class. + *

+ * + * @author Even Solbraa + * @version $Id: $Id + */ +public class PhaseVegaEos extends PhaseFundamentalEOS { + /** Serialization version UID. */ + private static final long serialVersionUID = 1000; + + int IPHASE = 0; + boolean okVolume = true; + double enthalpy = 0.0; + + double entropy = 0.0; + + double gibbsEnergy = 0.0; + + double CpVega = 0.0; + + double CvVega = 0.0; + + double internalEnery = 0.0; + + double JTcoef = 0.0; + + /** + *

+ * Constructor for PhaseVegaEos. + *

+ */ + public PhaseVegaEos() { + thermoPropertyModelName = "Vega Eos"; + } + + /** {@inheritDoc} */ + @Override + public PhaseVegaEos clone() { + PhaseVegaEos clonedPhase = null; + try { + clonedPhase = (PhaseVegaEos) super.clone(); + } catch (Exception ex) { + logger.error("Cloning failed.", ex); + } + + return clonedPhase; + } + + /** {@inheritDoc} */ + @Override + public void addComponent(String name, double moles, double molesInPhase, int compNumber) { + super.addComponent(name, molesInPhase, compNumber); + componentArray[compNumber] = new ComponentVegaEos(name, moles, molesInPhase, compNumber); + } + + /** {@inheritDoc} */ + @Override + public void init(double totalNumberOfMoles, int numberOfComponents, int initType, PhaseType pt, + double beta) { + IPHASE = pt == PhaseType.LIQUID ? -1 : -2; + super.init(totalNumberOfMoles, numberOfComponents, initType, pt, beta); + + if (!okVolume) { + IPHASE = pt == PhaseType.LIQUID ? -2 : -1; + super.init(totalNumberOfMoles, numberOfComponents, initType, pt, beta); + } + if (initType >= 1) { + double[] temp = new double[18]; + temp = getProperties_Vega(); + + + gibbsEnergy = temp[12]; + internalEnery = temp[6]; // .UOTPX(temperature,pressure/10.0, + // xFracGERG[0],xFracGERG[1],xFracGERG[2],xFracGERG[3],xFracGERG[4],xFracGERG[5],xFracGERG[6],xFracGERG[7],xFracGERG[8],xFracGERG[9],xFracGERG[10],xFracGERG[11],xFracGERG[12],xFracGERG[13],xFracGERG[14],xFracGERG[15],xFracGERG[16],xFracGERG[17],IPHASE); + enthalpy = temp[7]; // gergEOS.HOTPX(temperature,pressure/10.0, + // xFracGERG[0],xFracGERG[1],xFracGERG[2],xFracGERG[3],xFracGERG[4],xFracGERG[5],xFracGERG[6],xFracGERG[7],xFracGERG[8],xFracGERG[9],xFracGERG[10],xFracGERG[11],xFracGERG[12],xFracGERG[13],xFracGERG[14],xFracGERG[15],xFracGERG[16],xFracGERG[17],IPHASE); + entropy = temp[8]; // gergEOS.SOTPX(temperature,pressure/10.0, + // xFracGERG[0],xFracGERG[1],xFracGERG[2],xFracGERG[3],xFracGERG[4],xFracGERG[5],xFracGERG[6],xFracGERG[7],xFracGERG[8],xFracGERG[9],xFracGERG[10],xFracGERG[11],xFracGERG[12],xFracGERG[13],xFracGERG[14],xFracGERG[15],xFracGERG[16],xFracGERG[17],IPHASE); + CpVega = temp[10]; // gergEOS.CPOTPX(temperature,pressure/10.0, + // xFracGERG[0],xFracGERG[1],xFracGERG[2],xFracGERG[3],xFracGERG[4],xFracGERG[5],xFracGERG[6],xFracGERG[7],xFracGERG[8],xFracGERG[9],xFracGERG[10],xFracGERG[11],xFracGERG[12],xFracGERG[13],xFracGERG[14],xFracGERG[15],xFracGERG[16],xFracGERG[17],IPHASE); + CvVega = temp[9]; // gergEOS.CPOTPX(temperature,pressure/10.0, + // xFracGERG[0],xFracGERG[1],xFracGERG[2],xFracGERG[3],xFracGERG[4],xFracGERG[5],xFracGERG[6],xFracGERG[7],xFracGERG[8],xFracGERG[9],xFracGERG[10],xFracGERG[11],xFracGERG[12],xFracGERG[13],xFracGERG[14],xFracGERG[15],xFracGERG[16],xFracGERG[17],IPHASE); + JTcoef = temp[13]; + super.init(totalNumberOfMoles, numberOfComponents, initType, pt, beta); + } + } + + /** {@inheritDoc} */ + @Override + public double getGibbsEnergy() { + return gibbsEnergy * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getJouleThomsonCoefficient() { + return JTcoef * 1e3; // [K/bar] + } + + /** {@inheritDoc} */ + @Override + public double getEnthalpy() { + return enthalpy * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getEntropy() { + return entropy * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getInternalEnergy() { + return internalEnery * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getCp() { + return CpVega * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double getCv() { + return CvVega * numberOfMolesInPhase; + } + + /** {@inheritDoc} */ + @Override + public double molarVolume(double pressure, double temperature, double A, double B, PhaseType pt) + throws neqsim.util.exception.IsNaNException, + neqsim.util.exception.TooManyIterationsException { + return getMolarMass() * 1e5 / getDensity_Vega(); + } +} diff --git a/src/main/java/neqsim/thermo/system/SystemGERG2008Eos.java b/src/main/java/neqsim/thermo/system/SystemGERG2008Eos.java new file mode 100644 index 000000000..8bf3d3208 --- /dev/null +++ b/src/main/java/neqsim/thermo/system/SystemGERG2008Eos.java @@ -0,0 +1,91 @@ +package neqsim.thermo.system; + +import neqsim.thermo.phase.PhaseGERG2008Eos; +import neqsim.thermo.phase.PhaseHydrate; +import neqsim.thermo.phase.PhasePureComponentSolid; + +/** + * This class defines a thermodynamic system using the GERG2008 equation of state. + * It is analogous to the GERG2004 system, but uses the upgraded GERG2008 model. + * + * @author YourName + * @version 1.0 + */ +public class SystemGERG2008Eos extends SystemEos { + private static final long serialVersionUID = 1000; + + /** + * Constructor for SystemGERG2008Eos. + */ + public SystemGERG2008Eos() { + this(298.15, 1.0, false); + } + + /** + * Constructor for SystemGERG2008Eos. + * + * @param T The temperature in Kelvin. + * @param P The pressure in bara (absolute pressure). + */ + public SystemGERG2008Eos(double T, double P) { + this(T, P, false); + } + + /** + * Constructor for SystemGERG2008Eos. + * + * @param T The temperature in Kelvin. + * @param P The pressure in bara (absolute pressure). + * @param checkForSolids Set true to enable solid phase check and calculations. + */ + public SystemGERG2008Eos(double T, double P, boolean checkForSolids) { + super(T, P, checkForSolids); + modelName = "GERG2008-EOS"; + + // Initialize the phase array with GERG2008 phases. + for (int i = 0; i < numberOfPhases; i++) { + phaseArray[i] = new PhaseGERG2008Eos(); + phaseArray[i].setTemperature(T); + phaseArray[i].setPressure(P); + } + + if (solidPhaseCheck) { + setNumberOfPhases(5); + phaseArray[numberOfPhases - 1] = new PhasePureComponentSolid(); + phaseArray[numberOfPhases - 1].setTemperature(T); + phaseArray[numberOfPhases - 1].setPressure(P); + phaseArray[numberOfPhases - 1].setRefPhase(phaseArray[1].getRefPhase()); + } + + // Hydrate check (if enabled) is handled similarly. + if (hydrateCheck) { + phaseArray[numberOfPhases - 1] = new PhaseHydrate(); + phaseArray[numberOfPhases - 1].setTemperature(T); + phaseArray[numberOfPhases - 1].setPressure(P); + phaseArray[numberOfPhases - 1].setRefPhase(phaseArray[1].getRefPhase()); + } + + this.useVolumeCorrection(false); + commonInitialization(); + } + + @Override + public SystemGERG2008Eos clone() { + SystemGERG2008Eos clonedSystem = null; + try { + clonedSystem = (SystemGERG2008Eos) super.clone(); + } catch (Exception ex) { + logger.error("Cloning failed.", ex); + } + return clonedSystem; + } + + /** + * Common initialization settings for the GERG2008 EOS system. + */ + public void commonInitialization() { + setImplementedCompositionDeriativesofFugacity(false); + setImplementedPressureDeriativesofFugacity(false); + setImplementedTemperatureDeriativesofFugacity(false); + } +} diff --git a/src/main/java/neqsim/thermo/system/SystemLeachmanEos.java b/src/main/java/neqsim/thermo/system/SystemLeachmanEos.java new file mode 100644 index 000000000..ed32c148b --- /dev/null +++ b/src/main/java/neqsim/thermo/system/SystemLeachmanEos.java @@ -0,0 +1,99 @@ +package neqsim.thermo.system; + +import neqsim.thermo.phase.PhaseHydrate; +import neqsim.thermo.phase.PhaseLeachmanEos; +import neqsim.thermo.phase.PhasePureComponentSolid; + +/** + * This class defines a thermodynamic system using the LeachmanEos equation of state. + * + * @author Even Solbraa + * @version $Id: $Id + */ +public class SystemLeachmanEos extends SystemEos { + /** Serialization version UID. */ + private static final long serialVersionUID = 1000; + + /** + *

+ * Constructor for SystemLeachmanEos. + *

+ */ + public SystemLeachmanEos() { + this(298.15, 1.0, false); + } + + /** + *

+ * Constructor for SystemLeachmanEos. + *

+ * + * @param T The temperature in unit Kelvin + * @param P The pressure in unit bara (absolute pressure) + */ + public SystemLeachmanEos(double T, double P) { + this(T, P, false); + } + + /** + *

+ * Constructor for SystemLeachmanEos. + *

+ * + * @param T The temperature in unit Kelvin + * @param P The pressure in unit bara (absolute pressure) + * @param checkForSolids Set true to do solid phase check and calculations + */ + public SystemLeachmanEos(double T, double P, boolean checkForSolids) { + super(T, P, checkForSolids); + modelName = "Leachman-EOS"; + + for (int i = 0; i < numberOfPhases; i++) { + phaseArray[i] = new PhaseLeachmanEos(); + phaseArray[i].setTemperature(T); + phaseArray[i].setPressure(P); + } + + if (solidPhaseCheck) { + setNumberOfPhases(5); + phaseArray[numberOfPhases - 1] = new PhasePureComponentSolid(); + phaseArray[numberOfPhases - 1].setTemperature(T); + phaseArray[numberOfPhases - 1].setPressure(P); + phaseArray[numberOfPhases - 1].setRefPhase(phaseArray[1].getRefPhase()); + } + + // What could set hydratecheck? Will never be true + if (hydrateCheck) { + phaseArray[numberOfPhases - 1] = new PhaseHydrate(); + phaseArray[numberOfPhases - 1].setTemperature(T); + phaseArray[numberOfPhases - 1].setPressure(P); + phaseArray[numberOfPhases - 1].setRefPhase(phaseArray[1].getRefPhase()); + } + this.useVolumeCorrection(false); + commonInitialization(); + } + + /** {@inheritDoc} */ + @Override + public SystemLeachmanEos clone() { + SystemLeachmanEos clonedSystem = null; + try { + clonedSystem = (SystemLeachmanEos) super.clone(); + } catch (Exception ex) { + logger.error("Cloning failed.", ex); + } + + return clonedSystem; + } + + /** + *

+ * commonInitialization. + *

+ */ + public void commonInitialization() { + setImplementedCompositionDeriativesofFugacity(false); + setImplementedPressureDeriativesofFugacity(false); + setImplementedTemperatureDeriativesofFugacity(false); + } +} diff --git a/src/main/java/neqsim/thermo/system/SystemVegaEos.java2 b/src/main/java/neqsim/thermo/system/SystemVegaEos.java2 new file mode 100644 index 000000000..953efa7af --- /dev/null +++ b/src/main/java/neqsim/thermo/system/SystemVegaEos.java2 @@ -0,0 +1,99 @@ +package neqsim.thermo.system; + +import neqsim.thermo.phase.PhaseHydrate; +import neqsim.thermo.phase.PhasePureComponentSolid; +import neqsim.thermo.phase.PhaseVegaEos; + +/** + * This class defines a thermodynamic system using the VegaEos equation of state. + * + * @author Even Solbraa + * @version $Id: $Id + */ +public class SystemVegaEos extends SystemEos { + /** Serialization version UID. */ + private static final long serialVersionUID = 1000; + + /** + *

+ * Constructor for SystemVegaEos. + *

+ */ + public SystemVegaEos() { + this(298.15, 1.0, false); + } + + /** + *

+ * Constructor for SystemVegaEos. + *

+ * + * @param T The temperature in unit Kelvin + * @param P The pressure in unit bara (absolute pressure) + */ + public SystemVegaEos(double T, double P) { + this(T, P, false); + } + + /** + *

+ * Constructor for SystemVegaEos. + *

+ * + * @param T The temperature in unit Kelvin + * @param P The pressure in unit bara (absolute pressure) + * @param checkForSolids Set true to do solid phase check and calculations + */ + public SystemVegaEos(double T, double P, boolean checkForSolids) { + super(T, P, checkForSolids); + modelName = "Vega-EOS"; + + for (int i = 0; i < numberOfPhases; i++) { + phaseArray[i] = new PhaseVegaEos(); + phaseArray[i].setTemperature(T); + phaseArray[i].setPressure(P); + } + + if (solidPhaseCheck) { + setNumberOfPhases(5); + phaseArray[numberOfPhases - 1] = new PhasePureComponentSolid(); + phaseArray[numberOfPhases - 1].setTemperature(T); + phaseArray[numberOfPhases - 1].setPressure(P); + phaseArray[numberOfPhases - 1].setRefPhase(phaseArray[1].getRefPhase()); + } + + // What could set hydratecheck? Will never be true + if (hydrateCheck) { + phaseArray[numberOfPhases - 1] = new PhaseHydrate(); + phaseArray[numberOfPhases - 1].setTemperature(T); + phaseArray[numberOfPhases - 1].setPressure(P); + phaseArray[numberOfPhases - 1].setRefPhase(phaseArray[1].getRefPhase()); + } + this.useVolumeCorrection(false); + commonInitialization(); + } + + /** {@inheritDoc} */ + @Override + public SystemVegaEos clone() { + SystemVegaEos clonedSystem = null; + try { + clonedSystem = (SystemVegaEos) super.clone(); + } catch (Exception ex) { + logger.error("Cloning failed.", ex); + } + + return clonedSystem; + } + + /** + *

+ * commonInitialization. + *

+ */ + public void commonInitialization() { + setImplementedCompositionDeriativesofFugacity(false); + setImplementedPressureDeriativesofFugacity(false); + setImplementedTemperatureDeriativesofFugacity(false); + } +} diff --git a/src/main/java/neqsim/thermo/util/leachman/NeqSimLeachman.java b/src/main/java/neqsim/thermo/util/leachman/NeqSimLeachman.java index 4545ca9a2..4501e531c 100644 --- a/src/main/java/neqsim/thermo/util/leachman/NeqSimLeachman.java +++ b/src/main/java/neqsim/thermo/util/leachman/NeqSimLeachman.java @@ -106,6 +106,69 @@ public double getMolarDensity() { return D.val; } + public doubleW[] getAlpha0_Leachman() { + // Get temperature and molar density from the phase object + double temperature = phase.getTemperature(); + double molarDensity = getMolarDensity(phase); + + // Create and initialize a 4x4 array for the derivatives. + // Assuming doubleW is a simple wrapper with a public field 'val'. + int rows = 4; + int cols = 4; + doubleW[] a0 = new doubleW[rows]; + for (int i = 0; i < rows; i++) { + a0[i] = new doubleW(0.0); + } + + // Call the Leachman function to fill in the ar array. + // The first two parameters (itau and idelta) are set to 0. + Leachman.Alpha0Leachman(temperature, molarDensity, a0); + + // Return the computed dimensionless residual Helmholtz free energy. + // This is equivalent to alpha_res = A^r/(RT) + return a0; + } + + /** + * Get reduced residual helmholtz free energy and its derivatives. + * The returned array has the following structure: + * + * @param phase + * @return a doubleW[][] representing the reduced residual helmholtz free energy + */ + public doubleW[][] getAlphares_Leachman() { + // Get temperature and molar density from the phase object + double temperature = phase.getTemperature(); + double molarDensity = getMolarDensity(phase); + + // Create and initialize a 4x4 array for the derivatives. + // Assuming doubleW is a simple wrapper with a public field 'val'. + int rows = 4; + int cols = 4; + doubleW[][] ar = new doubleW[rows][cols]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + ar[i][j] = new doubleW(0.0); + } + } + + // Call the Leachman function to fill in the ar array. + // The first two parameters (itau and idelta) are set to 0. + Leachman.AlpharLeachman(0, 0, temperature, molarDensity, ar); + + // Return the computed dimensionless residual Helmholtz free energy. + // This is equivalent to alpha_res = A^r/(RT) + return ar; + } + /** * Get various thermodynamic properties of the specified phase. * diff --git a/src/test/java/neqsim/process/equipment/pipeline/PipelineTest.java b/src/test/java/neqsim/process/equipment/pipeline/PipelineTest.java index dc5894509..37212a7c2 100644 --- a/src/test/java/neqsim/process/equipment/pipeline/PipelineTest.java +++ b/src/test/java/neqsim/process/equipment/pipeline/PipelineTest.java @@ -17,9 +17,9 @@ public void testMain() { double wallroughness = 5e-6; neqsim.thermo.system.SystemInterface testSystem = - new neqsim.thermo.system.SystemSrkEos((273.15 + temperature), pressure); - testSystem.addComponent("methane", 0.9); - testSystem.addComponent("ethane", 0.1); + new neqsim.thermo.system.SystemLeachmanEos((273.15 + temperature), pressure); + testSystem.addComponent("hydrogen", 1.0); + //testSystem.addComponent("ethane", 0.1); testSystem.setMixingRule("classic"); Stream stream_1 = new Stream("Stream1", testSystem); diff --git a/src/test/java/neqsim/thermo/util/Vega/VegaTest.java b/src/test/java/neqsim/thermo/util/Vega/VegaTest.java deleted file mode 100644 index 6dcc2c858..000000000 --- a/src/test/java/neqsim/thermo/util/Vega/VegaTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package neqsim.thermo.util.Vega; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.netlib.util.StringW; -import org.netlib.util.doubleW; -import org.netlib.util.intW; - -public class VegaTest { - private Vega Vega; - - @BeforeEach - void setUp() { - Vega = new Vega(); - Vega.SetupVega(); - } - - @Test - void testDensityVega() { - int iFlag = 0; - double T = 273.15; - double P = 1000.0; - doubleW D = new doubleW(0.0); - intW ierr = new intW(0); - StringW herr = new StringW(""); - Vega.DensityVega(iFlag, T, P, D, ierr, herr); - assertEquals(0, ierr.val); - assertTrue(D.val > 0); - assertEquals(0.43802, D.val, 1e-5); - } - - @Test - void testPropertiesVega() { - double T = 273.15; - int iFlag = 0; - intW ierr = new intW(0); - StringW herr = new StringW(""); - doubleW D = new doubleW(30); - doubleW P = new doubleW(1000.0d); - doubleW Z = new doubleW(0.0); - doubleW dPdD = new doubleW(0.0); - doubleW d2PdD2 = new doubleW(0.0); - doubleW d2PdTD = new doubleW(0.0); - doubleW dPdT = new doubleW(0.0); - doubleW U = new doubleW(0.0); - doubleW H = new doubleW(0.0); - doubleW S = new doubleW(0.0); - doubleW Cv = new doubleW(0.0); - doubleW Cp = new doubleW(0.0); - doubleW W = new doubleW(0.0); - doubleW G = new doubleW(0.0); - doubleW JT = new doubleW(0.0); - doubleW Kappa = new doubleW(0.0); - doubleW A = new doubleW(0.0); - - Vega.DensityVega(iFlag, T, P.val, D, ierr, herr); - - Vega.propertiesVega(T, D.val, P, Z, dPdD, d2PdD2, d2PdTD, dPdT, U, H, S, Cv, Cp, W, G, JT, - Kappa, A); - assertTrue(P.val > 0); - assertTrue(Z.val > 0); - assertTrue(U.val != 0); - assertTrue(H.val != 0); - assertTrue(S.val != 0); - assertTrue(Cv.val != 0); - assertTrue(Cp.val != 0); - assertTrue(W.val != 0); - assertTrue(G.val != 0); - assertTrue(JT.val != 0); - assertTrue(Kappa.val != 0); - assertTrue(A.val != 0); - assertEquals(1.005253888311987, Z.val, 1e-5); - - } -} diff --git a/src/test/java/neqsim/thermo/util/Vega/VegaTest.java2 b/src/test/java/neqsim/thermo/util/Vega/VegaTest.java2 new file mode 100644 index 000000000..1184e409f --- /dev/null +++ b/src/test/java/neqsim/thermo/util/Vega/VegaTest.java2 @@ -0,0 +1,216 @@ +package neqsim.thermo.util.Vega; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.netlib.util.StringW; +import org.netlib.util.doubleW; +import org.netlib.util.intW; +import neqsim.thermo.system.SystemInterface; + +public class VegaTest { + private Vega Vega; + + @BeforeEach + void setUp() { + Vega = new Vega(); + Vega.SetupVega(); + } + + @Test + void testDensityVega() { + int iFlag = 0; + double T = 273.15; + double P = 1000.0; + doubleW D = new doubleW(0.0); + intW ierr = new intW(0); + StringW herr = new StringW(""); + Vega.DensityVega(iFlag, T, P, D, ierr, herr); + assertEquals(0, ierr.val); + assertTrue(D.val > 0); + assertEquals(0.43802, D.val, 1e-5); + } + + @Test + void testPropertiesVega() { + double T = 273.15; + int iFlag = 0; + intW ierr = new intW(0); + StringW herr = new StringW(""); + doubleW D = new doubleW(30); + doubleW P = new doubleW(1000.0d); + doubleW Z = new doubleW(0.0); + doubleW dPdD = new doubleW(0.0); + doubleW d2PdD2 = new doubleW(0.0); + doubleW d2PdTD = new doubleW(0.0); + doubleW dPdT = new doubleW(0.0); + doubleW U = new doubleW(0.0); + doubleW H = new doubleW(0.0); + doubleW S = new doubleW(0.0); + doubleW Cv = new doubleW(0.0); + doubleW Cp = new doubleW(0.0); + doubleW W = new doubleW(0.0); + doubleW G = new doubleW(0.0); + doubleW JT = new doubleW(0.0); + doubleW Kappa = new doubleW(0.0); + doubleW A = new doubleW(0.0); + + Vega.DensityVega(iFlag, T, P.val, D, ierr, herr); + + Vega.propertiesVega(T, D.val, P, Z, dPdD, d2PdD2, d2PdTD, dPdT, U, H, S, Cv, Cp, W, G, JT, + Kappa, A); + assertTrue(P.val > 0); + assertTrue(Z.val > 0); + assertTrue(U.val != 0); + assertTrue(H.val != 0); + assertTrue(S.val != 0); + assertTrue(Cv.val != 0); + assertTrue(Cp.val != 0); + assertTrue(W.val != 0); + assertTrue(G.val != 0); + assertTrue(JT.val != 0); + assertTrue(Kappa.val != 0); + assertTrue(A.val != 0); + assertEquals(1.005253888311987, Z.val, 1e-5); + + } + + @Test + void testThermoVega() { + + SystemInterface vegafluid = new neqsim.thermo.system.SystemVegaEos(298.15, 10.0); + SystemInterface vegafluid_KTA = new neqsim.thermo.system.SystemVegaEos(298.15, 10.0); + + vegafluid.addComponent("helium", 1.0); + vegafluid.init(0); + vegafluid.init(1); + + vegafluid_KTA.addComponent("helium", 1.0); + vegafluid_KTA.init(0); + vegafluid_KTA.init(1); + // ThermodynamicOperations ops = new ThermodynamicOperations(vegafluid); + // ops.TPflash(); + // double densitygas = vegafluid.getPhase("gas").getDensity("kg/m3"); + // assertEquals(1.607, densitygas, 1e-3); + // vegafluid.init(2); + + // vegafluid.setP + + // double enthalpgas = vegafluid.getPhase("gas").getEnthalpy("J/mol"); + // assertEquals(6230.66, enthalpgas, 1e-2); + + + vegafluid.setNumberOfPhases(1); + vegafluid.setMaxNumberOfPhases(1); + vegafluid.setForcePhaseTypes(true); + vegafluid.setPhaseType(0, "GAS"); + vegafluid.getPhase("gas").getPhysicalProperties().setViscosityModel("FT"); + vegafluid.getPhase("gas").initPhysicalProperties(); + //vegafluid.getPhase("gas").getPhysicalProperties().setViscosityModel("KTA_mod"); + //vegafluid.getPhase("gas").initPhysicalProperties(); + + + vegafluid_KTA.setNumberOfPhases(1); + vegafluid_KTA.setMaxNumberOfPhases(1); + vegafluid_KTA.setForcePhaseTypes(true); + vegafluid_KTA.setPhaseType(0, "GAS"); + vegafluid_KTA.getPhase("gas").getPhysicalProperties().setViscosityModel("KTA_mod"); + vegafluid_KTA.getPhase("gas").initPhysicalProperties(); + + neqsim.process.equipment.stream.Stream gasstream = + new neqsim.process.equipment.stream.Stream("gas", vegafluid); + gasstream.setFlowRate(10000.0, "kg/hr"); + gasstream.run(); + + neqsim.process.equipment.stream.Stream gasstream_KTA = + new neqsim.process.equipment.stream.Stream("gas", vegafluid_KTA); + gasstream_KTA.setFlowRate(10000.0, "kg/hr"); + gasstream_KTA.run(); + + neqsim.process.equipment.compressor.Compressor compressor = + new neqsim.process.equipment.compressor.Compressor("compressor 1", gasstream); + // compressor.setUseVega(true); + compressor.setOutletPressure(20.0); + compressor.run(); + + + neqsim.process.equipment.compressor.Compressor compressor_KTA = + new neqsim.process.equipment.compressor.Compressor("compressor 2", gasstream_KTA); + // compressor.setUseVega(true); + compressor_KTA.setOutletPressure(20.0); + compressor_KTA.run(); + + assertEquals(compressor_KTA.getOutletStream().getTemperature("C"), compressor.getOutletStream().getTemperature("C"), 1e-5); + + neqsim.process.equipment.pipeline.PipeBeggsAndBrills pipeline = + new neqsim.process.equipment.pipeline.PipeBeggsAndBrills("pipe 1", + compressor.getOutletStream()); + pipeline.setLength(5000.0); + pipeline.setDiameter(0.2); + pipeline.setElevation(0); + pipeline.run(); + + assertEquals(pipeline.getOutletPressure(), 13.749556023043809, 1e-5); + + + + } + + @Test + void testVegaCompressor() { + SystemInterface vegafluid = new neqsim.thermo.system.SystemVegaEos(298.15, 10.0); + + vegafluid.addComponent("helium", 1.0); + vegafluid.init(0); + vegafluid.init(1); + + vegafluid.setNumberOfPhases(1); + vegafluid.setMaxNumberOfPhases(1); + vegafluid.setForcePhaseTypes(true); + vegafluid.setPhaseType(0, "GAS"); + vegafluid.getPhase("gas").getPhysicalProperties().setViscosityModel("KTA_mod"); + + SystemInterface SRKfluid = new neqsim.thermo.system.SystemSrkEos(298.15, 10.0); + + SRKfluid.addComponent("helium", 1.0); + SRKfluid.init(0); + SRKfluid.init(1); + + SRKfluid.setNumberOfPhases(1); + SRKfluid.setMaxNumberOfPhases(1); + SRKfluid.setForcePhaseTypes(true); + SRKfluid.setPhaseType(0, "GAS"); + SRKfluid.getPhase("gas").getPhysicalProperties().setViscosityModel("KTA_mod"); + + neqsim.process.equipment.stream.Stream Vegastream = + new neqsim.process.equipment.stream.Stream("gas", vegafluid); + Vegastream.setFlowRate(130.0, "MSm3/day"); + Vegastream.run(); + + neqsim.process.equipment.stream.Stream SRKstream = + new neqsim.process.equipment.stream.Stream("gas", SRKfluid); + SRKstream.setFlowRate(130.0, "MSm3/day"); + SRKstream.run(); + + neqsim.process.equipment.compressor.Compressor Vegacompressor = + new neqsim.process.equipment.compressor.Compressor("compressor 1", Vegastream); + Vegacompressor.setOutletPressure(20.0, "bara"); + Vegacompressor.setPolytropicEfficiency(0.75); + Vegacompressor.run(); + + neqsim.process.equipment.compressor.Compressor SRKcompressor = + new neqsim.process.equipment.compressor.Compressor("compressor 2", SRKstream); + SRKcompressor.setOutletPressure(20.0, "bara"); + SRKcompressor.setPolytropicEfficiency(0.75); + SRKcompressor.setUseVega(true); + SRKcompressor.run(); + + assertEquals(Vegacompressor.getOutletStream().getTemperature("C"), SRKcompressor.getOutletStream().getTemperature("C"), 1e-5); + assertEquals(Vegacompressor.getPower("MW"), SRKcompressor.getPower("MW"), 1e-5); + assertEquals(Vegacompressor.getPolytropicHead(), SRKcompressor.getPolytropicHead(), 1e-5); + } + + + +} diff --git a/src/test/java/neqsim/thermo/util/gerg/GERG2008Test.java b/src/test/java/neqsim/thermo/util/gerg/GERG2008Test.java index 896eac018..16e1f6f3f 100644 --- a/src/test/java/neqsim/thermo/util/gerg/GERG2008Test.java +++ b/src/test/java/neqsim/thermo/util/gerg/GERG2008Test.java @@ -7,6 +7,7 @@ import org.netlib.util.StringW; import org.netlib.util.doubleW; import org.netlib.util.intW; +import neqsim.thermo.system.SystemInterface; public class GERG2008Test { private GERG2008 gerg; @@ -93,4 +94,61 @@ public void testPropertiesGERG() { assertTrue(A.val != 0); assertEquals(0.83232372466, Z.val, 1e-5); } + + @Test + void testVegaCompressor() { + SystemInterface GERGfluid = new neqsim.thermo.system.SystemGERG2008Eos(298.15, 10.0); + + GERGfluid.addComponent("methane", 0.8); + GERGfluid.addComponent("ethane", 0.1); + GERGfluid.addComponent("hydrogen", 0.1); + GERGfluid.init(0); + GERGfluid.init(1); + + GERGfluid.setNumberOfPhases(1); + GERGfluid.setMaxNumberOfPhases(1); + GERGfluid.setForcePhaseTypes(true); + GERGfluid.setPhaseType(0, "GAS"); + //GERGfluid.getPhase("gas").getPhysicalProperties().setViscosityModel("KTA_mod"); + + SystemInterface SRKfluid = new neqsim.thermo.system.SystemSrkEos(298.15, 10.0); + + SRKfluid.addComponent("methane", 0.8); + SRKfluid.addComponent("ethane", 0.1); + SRKfluid.addComponent("hydrogen", 0.1); SRKfluid.init(0); + SRKfluid.init(1); + + SRKfluid.setNumberOfPhases(1); + SRKfluid.setMaxNumberOfPhases(1); + SRKfluid.setForcePhaseTypes(true); + SRKfluid.setPhaseType(0, "GAS"); + //SRKfluid.getPhase("gas").getPhysicalProperties().setViscosityModel("KTA_mod"); + + neqsim.process.equipment.stream.Stream GERGstream = + new neqsim.process.equipment.stream.Stream("gas", GERGfluid); + GERGstream.setFlowRate(130.0, "MSm3/day"); + GERGstream.run(); + + neqsim.process.equipment.stream.Stream SRKstream = + new neqsim.process.equipment.stream.Stream("gas", SRKfluid); + SRKstream.setFlowRate(130.0, "MSm3/day"); + SRKstream.run(); + + neqsim.process.equipment.compressor.Compressor GERGcompressor = + new neqsim.process.equipment.compressor.Compressor("compressor 1", GERGstream); + GERGcompressor.setOutletPressure(20.0, "bara"); + GERGcompressor.setPolytropicEfficiency(0.75); + GERGcompressor.run(); + + neqsim.process.equipment.compressor.Compressor SRKcompressor = + new neqsim.process.equipment.compressor.Compressor("compressor 2", SRKstream); + SRKcompressor.setOutletPressure(20.0, "bara"); + SRKcompressor.setPolytropicEfficiency(0.75); + SRKcompressor.setUseGERG2008(true); + SRKcompressor.run(); + + assertEquals(GERGcompressor.getOutletStream().getTemperature("C"), SRKcompressor.getOutletStream().getTemperature("C"), 1e-8); + assertEquals(GERGcompressor.getPower("MW"), SRKcompressor.getPower("MW"), 1e-5); + assertEquals(GERGcompressor.getPolytropicHead(), SRKcompressor.getPolytropicHead(), 1e-5); + } } diff --git a/src/test/java/neqsim/thermo/util/leachman/Compressor_H2_test.java b/src/test/java/neqsim/thermo/util/leachman/Compressor_H2_test.java new file mode 100644 index 000000000..082beb783 --- /dev/null +++ b/src/test/java/neqsim/thermo/util/leachman/Compressor_H2_test.java @@ -0,0 +1,146 @@ +package neqsim.thermo.util.leachman; + +import org.junit.jupiter.api.Test; +import neqsim.process.equipment.pipeline.OnePhasePipeLine; +import neqsim.process.equipment.pipeline.PipeBeggsAndBrills; +import neqsim.thermo.system.SystemInterface; + + +public class Compressor_H2_test { + + @Test + void Leachman_compr_pipe_test() { + + SystemInterface Leachmanfluid = new neqsim.thermo.system.SystemGERG2008Eos(293.15, 90); + + double length = 20000.0; + double elevation = 0.0; + double diameter = 0.98; + System.out.println("-----------GERG2008 EOS-----------"); + + + //Leachmanfluid.addComponent("hydrogen", 0.5); + Leachmanfluid.addComponent("methane", 0.9); + //Leachmanfluid.addComponent("ethane", 0.1); + Leachmanfluid.init(0); + Leachmanfluid.init(1); + + + Leachmanfluid.setNumberOfPhases(1); + Leachmanfluid.setMaxNumberOfPhases(1); + Leachmanfluid.setForcePhaseTypes(true); + Leachmanfluid.setPhaseType(0, "GAS"); + Leachmanfluid.getPhase("gas").getPhysicalProperties().setViscosityModel("PFCT"); + Leachmanfluid.getPhase("gas").initPhysicalProperties(); + + + neqsim.process.equipment.stream.Stream gasstream_leachman = + new neqsim.process.equipment.stream.Stream("gas", Leachmanfluid); + gasstream_leachman.setFlowRate(60.0, "MSm3/day"); + gasstream_leachman.run(); + + neqsim.process.equipment.compressor.Compressor compressor_leachman_1 = + new neqsim.process.equipment.compressor.Compressor("compressor 1", gasstream_leachman); + // compressor.setUseLeachman(true); + compressor_leachman_1.setOutletPressure(120.0, "bara"); + compressor_leachman_1.setIsentropicEfficiency(0.77); + //compressor_leachman_1.setUseLeachman(true); + compressor_leachman_1.run(); + + neqsim.process.equipment.heatexchanger.Cooler cooler_1 = + new neqsim.process.equipment.heatexchanger.Cooler("cooler_1", compressor_leachman_1.getOutletStream()); + cooler_1.setOutTemperature(273.15+20.0); + cooler_1.run(); + + neqsim.process.equipment.compressor.Compressor compressor_leachman_2 = + new neqsim.process.equipment.compressor.Compressor("compressor 2", cooler_1.getOutStream()); + // compressor.setUseLeachman(true); + compressor_leachman_2.setOutletPressure(150.0); + compressor_leachman_2.setIsentropicEfficiency(0.77); + compressor_leachman_2.run(); + + neqsim.process.equipment.heatexchanger.Cooler cooler_2 = + new neqsim.process.equipment.heatexchanger.Cooler("cooler_2", compressor_leachman_2.getOutletStream()); + cooler_2.setOutTemperature(273.15+35.0); + cooler_2.run(); + + + System.out.println("Inital temperature " + gasstream_leachman.getTemperature("C")); + System.out.println("Initial pressure " + gasstream_leachman.getPressure("bara")); + System.out.println("Initial Volume flow " + gasstream_leachman.getFlowRate("MSm3/day") + " MSm3/day"); + + System.out.println("-------Compressor 1-------"); + System.out.println("Temperature out of Compr. 1: " + compressor_leachman_1.getOutletStream().getTemperature("C") + " C"); + System.out.println("Pressure out of Compr. 1: " + compressor_leachman_1.getOutletStream().getPressure("bara") + " bara"); + System.out.println("Volume flow out of Compr. 1: " + compressor_leachman_1.getOutletStream().getFlowRate("MSm3/day") + " MSm3/day"); + System.out.println("Compressor 1 power: " + compressor_leachman_1.getPower("kW") + " kW"); + System.out.println("Compressor 1 Polytropic head: " + compressor_leachman_1.getPolytropicHead("kJ/kg") + " kJ/kg"); + + System.out.println("-------Cooler 1-------"); + System.out.println("Temperature out of Cooler 1: " + (cooler_1.getOutletTemperature() - 273.15) + " C"); + System.out.println("Pressure out of Cooler 1: " + cooler_1.getOutletPressure() + " bara"); + System.out.println("Volume flow out of Cooler 1: " + cooler_1.getOutletStream().getFlowRate("MSm3/day") + " MSm3/day"); + System.out.println("Cooler 1 duty: " + cooler_1.getDuty()); + + System.out.println("-------Compressor 2-------"); + System.out.println("Temperature out of Compr. 2: " + compressor_leachman_2.getOutletStream().getTemperature("C") + " C"); + System.out.println("Pressure out of Compr. 2: " + compressor_leachman_2.getOutletStream().getPressure("bara") + " bara"); + System.out.println("Volume flow out of Compr. 2: " + compressor_leachman_2.getOutletStream().getFlowRate("MSm3/day") + " MSm3/day"); + System.out.println("Compressor 2 power: " + compressor_leachman_2.getPower("kW") + " kW"); + System.out.println("Compressor 2 Polytropic head: " + compressor_leachman_2.getPolytropicHead("kJ/kg") + "kJ/kg"); + + System.out.println("-------Cooler 2-------"); + System.out.println("Temperature out of Cooler 2: " + (cooler_2.getOutletTemperature() - 273.15) + " C"); + System.out.println("Pressure out of Cooler 2: " + cooler_2.getOutletPressure() + " bara"); + System.out.println("Volume flow out of Cooler 2: " + cooler_2.getOutletStream().getFlowRate("MSm3/day") + " MSm3/day"); + System.out.println("Cooler 2 duty: " + cooler_2.getDuty()); + + PipeBeggsAndBrills beggsBrilsPipe = new PipeBeggsAndBrills("simplePipeline 1", cooler_2.getOutStream()); + beggsBrilsPipe.setPipeWallRoughness(5.0e-6); + + beggsBrilsPipe.setLength(length); + beggsBrilsPipe.setElevation(elevation); + beggsBrilsPipe.setDiameter(diameter); + beggsBrilsPipe.setRunIsothermal(false); + //beggsBrilsPipe.setOuterTemperatures(new double[]{278.15, 278.15}); + beggsBrilsPipe.run(); + + System.out.println("-------Beggs and Brills-------"); + System.out.println("Pipe length: " + beggsBrilsPipe.getLength()/1000 + " km"); + System.out.println("Temperature out of Pipeline: " + beggsBrilsPipe.getOutletStream().getTemperature("C") + " C"); + System.out.println("Pressure out of Pipeline: " + beggsBrilsPipe.getOutletStream().getPressure("bara") + " bara"); + System.out.println("Volume flow out of Pipeline: " + beggsBrilsPipe.getOutletStream().getFlowRate("MSm3/day") + " MSm3/day"); + + + + + // Define the arrays for pipeline properties + double[] diameters = new double[]{0.98, 0.98}; // in meters + double[] roughness = new double[]{5.0e-6, 5.0e-6}; // in meters + double[] positions = new double[]{0.0, 600000.0}; // in meters (start and end positions) + double[] heights = new double[]{0.0, 0.0}; // in meters + double[] outerTemperatures = new double[]{278.15, 278.15}; // in Kelvin + double[] outHeatU = new double[]{25.0, 25.0}; // W/m2K for outer heat transfer + double[] wallHeatU = new double[]{35.0, 35.0}; // W/m2K for wall heat transfer + + + // Create and configure the pipeline + OnePhasePipeLine pipe1 = new OnePhasePipeLine("pipeline", cooler_2.getOutStream()); + pipe1.setLegPositions(positions); + pipe1.setPipeDiameters(diameters); + pipe1.setHeightProfile(heights); + pipe1.setOuterTemperatures(outerTemperatures); + pipe1.setPipeWallRoughness(roughness); + pipe1.setPipeOuterHeatTransferCoefficients(outHeatU); + pipe1.setPipeWallHeatTransferCoefficients(wallHeatU); + pipe1.setNumberOfNodesInLeg(100); + + + // Run the pipeline simulation + pipe1.run(); + + //System.out.println("Number of nodes " + pipeline.get()); + System.out.println("pressure " + pipe1.getOutletStream().getPressure()); + System.out.println("temperature out of pipe " + pipe1.getOutletStream().getTemperature("C")); + } +} \ No newline at end of file diff --git a/src/test/java/neqsim/thermo/util/leachman/LeachmanTest.java b/src/test/java/neqsim/thermo/util/leachman/LeachmanTest.java index 12e76e609..2b298c1bf 100644 --- a/src/test/java/neqsim/thermo/util/leachman/LeachmanTest.java +++ b/src/test/java/neqsim/thermo/util/leachman/LeachmanTest.java @@ -7,6 +7,7 @@ import org.netlib.util.StringW; import org.netlib.util.doubleW; import org.netlib.util.intW; +import neqsim.thermo.system.SystemInterface; /** * @author victorigi99 @@ -108,4 +109,139 @@ void testPropertiesLeachman() { assertTrue(A.val != 0); assertEquals(1.0058554805933522, Z.val, 1e-5); } + + @Test + void testThermoLeachman() { + + SystemInterface Leachmanfluid = new neqsim.thermo.system.SystemLeachmanEos(298.15, 10.0); + SystemInterface SRKfluid = new neqsim.thermo.system.SystemSrkEos(298.15, 10.0); + + Leachmanfluid.addComponent("hydrogen", 1.0); + Leachmanfluid.init(0); + Leachmanfluid.init(1); + + SRKfluid.addComponent("hydrogen", 1.0); + SRKfluid.init(0); + SRKfluid.init(1); + // ThermodynamicOperations ops = new ThermodynamicOperations(Leachmanfluid); + // ops.TPflash(); + // double densitygas = Leachmanfluid.getPhase("gas").getDensity("kg/m3"); + // assertEquals(1.607, densitygas, 1e-3); + // Leachmanfluid.init(2); + + // Leachmanfluid.setP + + // double enthalpgas = Leachmanfluid.getPhase("gas").getEnthalpy("J/mol"); + // assertEquals(6230.66, enthalpgas, 1e-2); + + + Leachmanfluid.setNumberOfPhases(1); + Leachmanfluid.setMaxNumberOfPhases(1); + Leachmanfluid.setForcePhaseTypes(true); + Leachmanfluid.setPhaseType(0, "GAS"); + Leachmanfluid.getPhase("gas").getPhysicalProperties().setViscosityModel("PFCT"); + Leachmanfluid.getPhase("gas").initPhysicalProperties(); + + SRKfluid.setNumberOfPhases(1); + SRKfluid.setMaxNumberOfPhases(1); + SRKfluid.setForcePhaseTypes(true); + SRKfluid.setPhaseType(0, "GAS"); + + neqsim.process.equipment.stream.Stream gasstream_leachman = + new neqsim.process.equipment.stream.Stream("gas", Leachmanfluid); + gasstream_leachman.setFlowRate(10000.0, "kg/hr"); + gasstream_leachman.run(); + + neqsim.process.equipment.stream.Stream gasstream_SRK = + new neqsim.process.equipment.stream.Stream("gas", SRKfluid); + gasstream_SRK.setFlowRate(10000.0, "kg/hr"); + gasstream_SRK.run(); + + neqsim.process.equipment.compressor.Compressor compressor_leachman = + new neqsim.process.equipment.compressor.Compressor("compressor 1", gasstream_leachman); + // compressor.setUseLeachman(true); + compressor_leachman.setOutletPressure(20.0); + compressor_leachman.run(); + + System.out.println("Temperature out of Compr." + compressor_leachman.getOutletStream().getTemperature("C")); + + neqsim.process.equipment.compressor.Compressor compressor_SRK = + new neqsim.process.equipment.compressor.Compressor("compressor 2", gasstream_SRK); + compressor_SRK.setUseLeachman(true); + compressor_SRK.setOutletPressure(20.0); + compressor_SRK.run(); + + assertEquals(compressor_leachman.getOutletStream().getTemperature("C"), compressor_SRK.getOutletStream().getTemperature("C"), 1e-5); + assertEquals(compressor_leachman.getPower(), compressor_SRK.getPower(), 1e-2); + assertEquals(compressor_leachman.getPolytropicHead("kJ/kg"), compressor_SRK.getPolytropicHead("kJ/kg"), 1e-5); + + neqsim.process.equipment.pipeline.PipeBeggsAndBrills pipeline = + new neqsim.process.equipment.pipeline.PipeBeggsAndBrills("pipe 1", + compressor_leachman.getOutletStream()); + pipeline.setLength(1000.0); + pipeline.setDiameter(0.2); + pipeline.setElevation(0); + pipeline.run(); + + System.out.println("pressure " + pipeline.getOutletStream().getPressure()); + System.out.println("temperature out of pipe " + pipeline.getOutletStream().getTemperature("C")); + assertEquals(17.91015516796876, pipeline.getOutletStream().getPressure(), 1e-5); + + + // assertEquals(0.43802, D.val, 1e-5); + } + + @Test + void CompressorSchultz() { + SystemInterface Leachmanfluid = new neqsim.thermo.system.SystemLeachmanEos(298.15, 90.0); + + + Leachmanfluid.addComponent("hydrogen", 1.0); + Leachmanfluid.init(0); + + + Leachmanfluid.setNumberOfPhases(1); + Leachmanfluid.setMaxNumberOfPhases(1); + Leachmanfluid.setForcePhaseTypes(true); + Leachmanfluid.setPhaseType(0, "GAS"); + Leachmanfluid.getPhase("gas").getPhysicalProperties().setViscosityModel("PFCT"); + + Leachmanfluid.init(1); + Leachmanfluid.init(2); + Leachmanfluid.init(3); + Leachmanfluid.getPhase("gas").initPhysicalProperties(); + + neqsim.process.equipment.stream.Stream gasstream_leachman = + new neqsim.process.equipment.stream.Stream("gas", Leachmanfluid); + gasstream_leachman.setFlowRate(60.0, "MSm3/day"); + gasstream_leachman.run(); + + neqsim.process.equipment.compressor.Compressor compressor_leachman = + new neqsim.process.equipment.compressor.Compressor("compressor 1", gasstream_leachman); + compressor_leachman.setOutletPressure(120.0); + compressor_leachman.setPolytropicEfficiency(0.77); + compressor_leachman.run(); + + neqsim.process.equipment.compressor.Compressor compressor_Schultz = + new neqsim.process.equipment.compressor.Compressor("compressor 2", gasstream_leachman); + compressor_Schultz.setOutletPressure(120.0); + compressor_Schultz.setPolytropicEfficiency(0.77); + compressor_Schultz.setUsePolytropicCalc(true); + compressor_Schultz.setPolytropicMethod("schultz"); + compressor_Schultz.run(); + + System.out.println("Density before compressor " + Leachmanfluid.getDensity("kg/m3")); + System.out.println("-----------------Normal-----------------"); + System.out.println("Temperature out of Compr." + compressor_leachman.getOutletStream().getTemperature("C")); + System.out.println("Power out of Compr." + compressor_leachman.getPower("MW")); + System.out.println("Polytropic Head out of Compr." + compressor_leachman.getPolytropicHead("kJ/kg")); + + System.out.println("-----------------Schultz-----------------"); + System.out.println("Temperature out of Compr." + compressor_Schultz.getOutletStream().getTemperature("C")); + System.out.println("Power out of Compr." + compressor_Schultz.getPower("MW")); + System.out.println("Polytropic Head out of Compr." + compressor_Schultz.getPolytropicHead("kJ/kg")); + + } + + } diff --git a/src/test/java/neqsim/thermo/util/leachman/PipeLine_error.java b/src/test/java/neqsim/thermo/util/leachman/PipeLine_error.java new file mode 100644 index 000000000..828d2ed26 --- /dev/null +++ b/src/test/java/neqsim/thermo/util/leachman/PipeLine_error.java @@ -0,0 +1,150 @@ +package neqsim.thermo.util.leachman; + +import org.junit.jupiter.api.Test; +import neqsim.process.equipment.pipeline.OnePhasePipeLine; +import neqsim.process.equipment.pipeline.PipeBeggsAndBrills; +import neqsim.thermo.system.SystemInterface; + + +public class PipeLine_error { + + + + + + @Test + void Leachman_compr_pipe_test() { + + SystemInterface Leachmanfluid = new neqsim.thermo.system.SystemSrkEos(293.15, 90); + + double length = 20000.0; + double elevation = 0.0; + double diameter = 0.98; + System.out.println("-----------SRK EOS-----------"); + + + //Leachmanfluid.addComponent("hydrogen", 0.5); + Leachmanfluid.addComponent("methane", 1.0); + //Leachmanfluid.addComponent("ethane", 0.1); + Leachmanfluid.init(0); + Leachmanfluid.init(1); + + + Leachmanfluid.setNumberOfPhases(1); + Leachmanfluid.setMaxNumberOfPhases(1); + Leachmanfluid.setForcePhaseTypes(true); + Leachmanfluid.setPhaseType(0, "GAS"); + Leachmanfluid.getPhase("gas").getPhysicalProperties().setViscosityModel("PFCT"); + Leachmanfluid.getPhase("gas").initPhysicalProperties(); + + + neqsim.process.equipment.stream.Stream gasstream_leachman = + new neqsim.process.equipment.stream.Stream("gas", Leachmanfluid); + gasstream_leachman.setFlowRate(60.0, "MSm3/day");//Went over max itterations for 130 MSm3/day + gasstream_leachman.run(); + + neqsim.process.equipment.compressor.Compressor compressor_leachman_1 = + new neqsim.process.equipment.compressor.Compressor("compressor 1", gasstream_leachman); + // compressor.setUseLeachman(true); + compressor_leachman_1.setOutletPressure(120.0, "bara"); + compressor_leachman_1.setIsentropicEfficiency(0.77); + //compressor_leachman_1.setUseLeachman(true); + compressor_leachman_1.run(); + + neqsim.process.equipment.heatexchanger.Cooler cooler_1 = + new neqsim.process.equipment.heatexchanger.Cooler("cooler_1", compressor_leachman_1.getOutletStream()); + cooler_1.setOutTemperature(273.15+20.0); + cooler_1.run(); + + neqsim.process.equipment.compressor.Compressor compressor_leachman_2 = + new neqsim.process.equipment.compressor.Compressor("compressor 2", cooler_1.getOutStream()); + // compressor.setUseLeachman(true); + compressor_leachman_2.setOutletPressure(150.0); + compressor_leachman_2.setIsentropicEfficiency(0.77); + compressor_leachman_2.run(); + + neqsim.process.equipment.heatexchanger.Cooler cooler_2 = + new neqsim.process.equipment.heatexchanger.Cooler("cooler_2", compressor_leachman_2.getOutletStream()); + cooler_2.setOutTemperature(273.15+35.0); + cooler_2.run(); + + + System.out.println("Inital temperature " + gasstream_leachman.getTemperature("C")); + System.out.println("Initial pressure " + gasstream_leachman.getPressure("bara")); + System.out.println("Initial Volume flow " + gasstream_leachman.getFlowRate("MSm3/day") + " MSm3/day"); + + System.out.println("-------Compressor 1-------"); + System.out.println("Temperature out of Compr. 1: " + compressor_leachman_1.getOutletStream().getTemperature("C") + " C"); + System.out.println("Pressure out of Compr. 1: " + compressor_leachman_1.getOutletStream().getPressure("bara") + " bara"); + System.out.println("Volume flow out of Compr. 1: " + compressor_leachman_1.getOutletStream().getFlowRate("MSm3/day") + " MSm3/day"); + System.out.println("Compressor 1 power: " + compressor_leachman_1.getPower("kW") + " kW"); + System.out.println("Compressor 1 Polytropic head: " + compressor_leachman_1.getPolytropicHead("kJ/kg") + " kJ/kg"); + + System.out.println("-------Cooler 1-------"); + System.out.println("Temperature out of Cooler 1: " + (cooler_1.getOutletTemperature() - 273.15) + " C"); + System.out.println("Pressure out of Cooler 1: " + cooler_1.getOutletPressure() + " bara"); + System.out.println("Volume flow out of Cooler 1: " + cooler_1.getOutletStream().getFlowRate("MSm3/day") + " MSm3/day"); + System.out.println("Cooler 1 duty: " + cooler_1.getDuty()); + + System.out.println("-------Compressor 2-------"); + System.out.println("Temperature out of Compr. 2: " + compressor_leachman_2.getOutletStream().getTemperature("C") + " C"); + System.out.println("Pressure out of Compr. 2: " + compressor_leachman_2.getOutletStream().getPressure("bara") + " bara"); + System.out.println("Volume flow out of Compr. 2: " + compressor_leachman_2.getOutletStream().getFlowRate("MSm3/day") + " MSm3/day"); + System.out.println("Compressor 2 power: " + compressor_leachman_2.getPower("kW") + " kW"); + System.out.println("Compressor 2 Polytropic head: " + compressor_leachman_2.getPolytropicHead("kJ/kg") + "kJ/kg"); + + System.out.println("-------Cooler 2-------"); + System.out.println("Temperature out of Cooler 2: " + (cooler_2.getOutletTemperature() - 273.15) + " C"); + System.out.println("Pressure out of Cooler 2: " + cooler_2.getOutletPressure() + " bara"); + System.out.println("Volume flow out of Cooler 2: " + cooler_2.getOutletStream().getFlowRate("MSm3/day") + " MSm3/day"); + System.out.println("Cooler 2 duty: " + cooler_2.getDuty()); + + PipeBeggsAndBrills beggsBrilsPipe = new PipeBeggsAndBrills("simplePipeline 1", cooler_2.getOutStream()); + beggsBrilsPipe.setPipeWallRoughness(5.0e-6); + + beggsBrilsPipe.setLength(length); + beggsBrilsPipe.setElevation(elevation); + beggsBrilsPipe.setDiameter(diameter); + beggsBrilsPipe.setRunIsothermal(false); + //beggsBrilsPipe.setOuterTemperatures(new double[]{278.15, 278.15}); + beggsBrilsPipe.run(); + + System.out.println("-------Beggs and Brills-------"); + System.out.println("Pipe length: " + beggsBrilsPipe.getLength()/1000 + " km"); + System.out.println("Temperature out of Pipeline: " + beggsBrilsPipe.getOutletStream().getTemperature("C") + " C"); + System.out.println("Pressure out of Pipeline: " + beggsBrilsPipe.getOutletStream().getPressure("bara") + " bara"); + System.out.println("Volume flow out of Pipeline: " + beggsBrilsPipe.getOutletStream().getFlowRate("MSm3/day") + " MSm3/day"); + + + + + // Define the arrays for pipeline properties + double[] diameters = new double[]{0.98, 0.98}; // in meters + double[] roughness = new double[]{5.0e-6, 5.0e-6}; // in meters + double[] positions = new double[]{0.0, 600000.0}; // in meters (start and end positions) + double[] heights = new double[]{0.0, 0.0}; // in meters + double[] outerTemperatures = new double[]{278.15, 278.15}; // in Kelvin + double[] outHeatU = new double[]{25.0, 25.0}; // W/m2K for outer heat transfer + double[] wallHeatU = new double[]{35.0, 35.0}; // W/m2K for wall heat transfer + + + // Create and configure the pipeline + OnePhasePipeLine pipe1 = new OnePhasePipeLine("pipeline", cooler_2.getOutStream()); + pipe1.setLegPositions(positions); + pipe1.setPipeDiameters(diameters); + pipe1.setHeightProfile(heights); + pipe1.setOuterTemperatures(outerTemperatures); + pipe1.setPipeWallRoughness(roughness); + pipe1.setPipeOuterHeatTransferCoefficients(outHeatU); + pipe1.setPipeWallHeatTransferCoefficients(wallHeatU); + pipe1.setNumberOfNodesInLeg(100); + + + // Run the pipeline simulation + pipe1.run(); + + //System.out.println("Number of nodes " + pipeline.get()); + System.out.println("pressure " + pipe1.getOutletStream().getPressure()); + System.out.println("temperature out of pipe " + pipe1.getOutletStream().getTemperature("C")); + } +} \ No newline at end of file