diff --git a/Examples.mo b/Examples.mo new file mode 100644 index 0000000..a40086b --- /dev/null +++ b/Examples.mo @@ -0,0 +1,7 @@ +within REFPROP2Modelica; +package Examples "Demonstration of the usage of the library" +extends Modelica.Icons.ExamplesPackage; +annotation(preferedView="info", + __Dymola_classOrder={"PumpingSystem", "HeatingSystem", "DrumBoiler", "Tanks", "ControlledTankSystem", "AST_BatchPlant", + "IncompressibleFluidNetwork", "BranchingDynamicPipes", "HeatExchanger", "TraceSubstances", "InverseParameterization", "Explanatory", "*"}); +end Examples; diff --git a/Examples/package.mo b/Examples/package.mo index f55d44b..c332612 100644 --- a/Examples/package.mo +++ b/Examples/package.mo @@ -1,3 +1,7 @@ -within MediaTwoPhaseMixture; -package Examples -end Examples; +within REFPROP2Modelica; +package Examples "Demonstration of the usage of the library" + extends Modelica.Icons.ExamplesPackage; + + + annotation(preferedView = "info", __Dymola_classOrder = {"PumpingSystem","HeatingSystem","DrumBoiler","Tanks","ControlledTankSystem","AST_BatchPlant","IncompressibleFluidNetwork","BranchingDynamicPipes","HeatExchanger","TraceSubstances","InverseParameterization","Explanatory","*"}); +end Examples; diff --git a/Examples/package.order b/Examples/package.order index f8a6ea5..e69de29 100644 --- a/Examples/package.order +++ b/Examples/package.order @@ -1,2 +0,0 @@ -PropsMixture -PropsPureSubstance diff --git a/Interfaces/MixtureInputChoice.mo b/Interfaces/MixtureInputChoice.mo new file mode 100644 index 0000000..4a0ded6 --- /dev/null +++ b/Interfaces/MixtureInputChoice.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Interfaces; +type MixtureInputChoice = enumeration( + dTX "(d,T,X) as inputs", + phX "(p,h,X) as inputs", + psX "(p,s,X) as inputs", + pTX "(p,T,X) as inputs"); diff --git a/Interfaces/PartialMixtureTwoPhaseMedium.mo b/Interfaces/PartialMixtureTwoPhaseMedium.mo new file mode 100644 index 0000000..fa177b5 --- /dev/null +++ b/Interfaces/PartialMixtureTwoPhaseMedium.mo @@ -0,0 +1,990 @@ +within REFPROP2Modelica.Interfaces; +partial package PartialMixtureTwoPhaseMedium + "Template class for two phase medium of a mixture of substances " + extends Modelica.Media.Interfaces.PartialMixtureMedium(ThermoStates=inputChoice); + constant Boolean smoothModel = false + "true if the (derived) model should not generate state events"; + constant Boolean onePhase = false + "true if the (derived) model should never be called with two-phase inputs"; + + //constant Real minValue = 1e-6; + + constant FluidConstants mixtureFluidConstants( + iupacName = "mixture", + casRegistryNumber = "mixture", + chemicalFormula = "mixture", + structureFormula = "mixture", + molarMass = 0.001, + criticalTemperature = 0, + criticalPressure = 0, + criticalMolarVolume = 0, + acentricFactor = 0, + triplePointTemperature = 0, + triplePointPressure = 0, + meltingPoint = 0, + normalBoilingPoint = 0, + dipoleMoment = 0); + // The following values are not constant! + + import InputChoice = REFPROP2Modelica.Interfaces.MixtureInputChoice; + +constant InputChoice inputChoice=MixtureInputChoice.phX + "Default choice of input variables for property computations"; + + type FixedPhase = Integer(min=0,max=2) + "phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g. interactive use"; + record FluidLimits "validity limits for fluid model" + extends Modelica.Icons.Record; + Temperature TMIN "minimum temperature"; + Temperature TMAX "maximum temperature"; + Density DMIN "minimum density"; + Density DMAX "maximum density"; + AbsolutePressure PMIN "minimum pressure"; + AbsolutePressure PMAX "maximum pressure"; + SpecificEnthalpy HMIN "minimum enthalpy"; + SpecificEnthalpy HMAX "maximum enthalpy"; + SpecificEntropy SMIN "minimum entropy"; + SpecificEntropy SMAX "maximum entropy"; + annotation(Documentation( + info=" +

The minimum pressure mostly applies to the liquid state only. + The minimum density is also arbitrary, but is reasonable for techical + applications to limit iterations in non-linear systems. The limits in + enthalpy and entropy are used as safeguards in inverse iterations.

+ ")); + end FluidLimits; + +redeclare replaceable record extends ThermodynamicState + "Thermodynamic state of two phase medium" + MolarMass molarMass "Molar mass of bulk mixture"; + FixedPhase phase(min=0, max=2) + "phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g. interactive use"; + + //PrandtlNumber Pr "prandtl number"; + //Temperature T "temperature"; + VelocityOfSound w(min=1e-8) "velocity of sound"; + //Modelica.SIunits.CubicExpansionCoefficient beta + //"isobaric expansion coefficient"; + SpecificHeatCapacity cp(min=1e-8) "specific heat capacity cp"; + SpecificHeatCapacity cv(min=1e-8) "specific heat capacity cv"; + Density d(min=1e-8) "density"; + //DynamicViscosity eta "dynamic viscosity"; + SpecificEnthalpy h "specific enthalpy"; + //Modelica.SIunits.Compressibility kappa "compressibility"; + //ThermalConductivity lambda "thermal conductivity"; + //AbsolutePressure p "pressure"; + SpecificEntropy s "specific entropy"; + //MassFraction X[nX] "Mass fraction of components in kg/kg"; + MassFraction q "vapor quality"; + annotation(Documentation(info="")); +end ThermodynamicState; + + replaceable record SaturationProperties + "Saturation properties of two phase medium" + extends Modelica.Icons.Record; + + Temperature Tsat; + AbsolutePressure psat; + MassFraction X[nX] "Mass fraction of bulk"; + // Real dTp "derivative of Ts wrt pressure"; + // DerDensityByPressure ddldp "derivative of dls wrt pressure"; + // DerDensityByPressure ddvdp "derivative of dvs wrt pressure"; + // DerEnthalpyByPressure dhldp "derivative of hls wrt pressure"; + // DerEnthalpyByPressure dhvdp "derivative of hvs wrt pressure"; + Density dl "density at bubble line (for pressure ps)"; + Density dv "density at dew line (for pressure ps)"; + SpecificEnthalpy hl "specific enthalpy at bubble line (for pressure ps)"; + SpecificEnthalpy hv "specific enthalpy at dew line (for pressure ps)"; + SpecificEntropy sl "specific entropy at bubble line (for pressure ps)"; + SpecificEntropy sv "specific entropy at dew line (for pressure ps)"; + SurfaceTension sigma "surface tension"; + // MassFraction X[nX] "Bulk mass fractions"; + // MolarMass MMl "molar mass bubble line (for pressure ps)"; + // MolarMass MMv "molar mass at dew line (for pressure ps)"; + MassFraction Xl[nX] "Mass fractions of liquid phase"; + MassFraction Xv[nX] "Mass fractions of gaseous phase"; + end SaturationProperties; + +redeclare replaceable model extends BaseProperties( + p(min=1e-8,stateSelect = if preferredMediumStates and + (basePropertiesInputChoice == InputChoice.phX or + basePropertiesInputChoice == InputChoice.pTX or + basePropertiesInputChoice == InputChoice.psX) then + StateSelect.prefer else StateSelect.default), + T(min=1e-8,stateSelect = if preferredMediumStates and + (basePropertiesInputChoice == InputChoice.pTX or + basePropertiesInputChoice == InputChoice.dTX) then + StateSelect.prefer else StateSelect.default), + h(stateSelect = if preferredMediumStates and + basePropertiesInputChoice == InputChoice.phX then + StateSelect.prefer else StateSelect.default), + d(min=1e-8,stateSelect = if preferredMediumStates and + basePropertiesInputChoice == InputChoice.dTX then + StateSelect.prefer else StateSelect.default)) + import REFPROP2Modelica.Interfaces.MixtureInputChoice; + parameter MixtureInputChoice basePropertiesInputChoice = inputChoice + "Choice of input variables for property computations"; + FixedPhase phaseInput + "Phase input for property computation functions, 2 for two-phase, 1 for one-phase, 0 if not known"; + Integer phaseOutput + "Phase output for medium, 2 for two-phase, 1 for one-phase"; + SpecificEntropy s( + stateSelect = if basePropertiesInputChoice == InputChoice.psX then + StateSelect.prefer else StateSelect.default) + "Specific entropy"; + SaturationProperties sat "saturation property record"; +equation + MM = state.molarMass; + R = Modelica.Constants.R/max(1e-8,MM); + if (onePhase or (basePropertiesInputChoice == InputChoice.pTX)) then + phaseInput = 1 "Force one-phase property computation"; + else + phaseInput = 0 "Unknown phase"; + end if; + if (basePropertiesInputChoice == InputChoice.phX) then + // Compute the state record (including the unique ID) + state = + setState_phX( + p, + h, + X, + phaseInput); + d = density(state); + s = specificEntropy(state); + T = temperature(state); + elseif (basePropertiesInputChoice == InputChoice.dTX) then + state = + setState_dTX( + d, + T, + X, + phaseInput); + h = specificEnthalpy(state); + p = pressure(state); + s = specificEntropy(state); + elseif (basePropertiesInputChoice == InputChoice.pTX) then + state = + setState_pTX( + p, + T, + X, + phaseInput); + d = density(state); + h = specificEnthalpy(state); + s = specificEntropy(state); + elseif (basePropertiesInputChoice == InputChoice.psX) then + state = + setState_psX( + p, + s, + X, + phaseInput); + d = density(state); + h = specificEnthalpy(state); + T = temperature(state); + end if; + // Compute the internal energy + u = h - p/max(1e-8,d); + // Compute the saturation properties record + sat = setSat_pX(state.p,state.X); + // Event generation for phase boundary crossing + if smoothModel then + // No event generation + phaseOutput = state.phase; + else + // Event generation at phase boundary crossing + if basePropertiesInputChoice == InputChoice.phX then + phaseOutput = if ((h > bubbleEnthalpy(sat) and h < dewEnthalpy(sat)) and + p < fluidConstants[1].criticalPressure) then 2 else 1; + elseif basePropertiesInputChoice == InputChoice.dTX then + phaseOutput = if ((d < bubbleDensity(sat) and d > dewDensity(sat)) and + T < fluidConstants[1].criticalTemperature) then 2 else 1; + elseif basePropertiesInputChoice == InputChoice.psX then + phaseOutput = if ((s > bubbleEntropy(sat) and s < dewEntropy(sat)) and + p < fluidConstants[1].criticalPressure) then 2 else 1; + else + // basePropertiesInputChoice == pTX + phaseOutput = 1; + end if; + end if; +end BaseProperties; + +// redeclare replaceable partial model extends BaseProperties +// "Base properties (p, d, T, h, s, u, R, MM, sat) of two phase medium" +// // Temperature T(start=300); +// Modelica.SIunits.SpecificEntropy s; +// SaturationProperties sat "Saturation properties at the medium pressure"; +// annotation(Documentation(info="")); +// end BaseProperties; + + replaceable partial function getMolarMass + extends Modelica.Icons.Function; + output MolarMass MM "Molar mass of the mixture"; + annotation (Documentation(info="")); + end getMolarMass; + + replaceable partial function getCriticalTemperature + extends Modelica.Icons.Function; + output Temperature Tcrit "Molar mass of the mixture"; + annotation (Documentation(info="")); + end getCriticalTemperature; + + replaceable partial function getCriticalPressure + extends Modelica.Icons.Function; + output AbsolutePressure Pcrit "Molar mass of the mixture"; + annotation (Documentation(info="")); + end getCriticalPressure; + + replaceable partial function getCriticalMolarVolume + extends Modelica.Icons.Function; + output MolarVolume v "Molar mass of the mixture"; + annotation (Documentation(info="")); + end getCriticalMolarVolume; + + replaceable partial function setDewState + "Return the thermodynamic state on the dew line" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation point"; + input FixedPhase phase(min = 1, max = 2) = 1 "phase: default is one phase"; + output ThermodynamicState state "complete thermodynamic state info"; + annotation(Documentation(info="")); + end setDewState; + + replaceable partial function setBubbleState + "Return the thermodynamic state on the bubble line" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation point"; + input FixedPhase phase(min = 1, max = 2) = 1 "phase: default is one phase"; + output ThermodynamicState state "complete thermodynamic state info"; + annotation(Documentation(info="")); + end setBubbleState; + + redeclare replaceable partial function extends setState_dTX + "Return thermodynamic state as function of d, T and composition X or Xi" + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + annotation(Documentation(info="")); + end setState_dTX; + + redeclare replaceable partial function extends setState_phX + "Return thermodynamic state as function of p, h and composition X or Xi" + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + annotation(Documentation(info="")); + end setState_phX; + + redeclare replaceable partial function extends setState_psX + "Return thermodynamic state as function of p, s and composition X or Xi" + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + annotation(Documentation(info="")); + end setState_psX; + + redeclare replaceable partial function extends setState_pTX + "Return thermodynamic state as function of p, T and composition X or Xi" + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + annotation(Documentation(info="")); + end setState_pTX; + + replaceable function setSat_TX + "Return saturation property record from temperature" + extends Modelica.Icons.Function; + input Temperature T "temperature"; + input MassFraction X[nX] "Mass fractions"; + output SaturationProperties sat "saturation property record"; + algorithm + sat.Tsat := T; + sat.psat := saturationPressure(T,X); + sat.X := X; + annotation(Documentation(info="")); + end setSat_TX; + + replaceable function setSat_pX + "Return saturation property record from pressure" + extends Modelica.Icons.Function; + input AbsolutePressure p "pressure"; + input MassFraction X[nX] "Mass fractions"; + output SaturationProperties sat "saturation property record"; + algorithm + sat.psat := p; + sat.Tsat := saturationTemperature(p,X); + sat.X := X; + annotation(Documentation(info="")); + end setSat_pX; + +/* +Functions to obtain fluid properties from the currently active state. +*/ + + replaceable partial function bubbleEnthalpy + "Return bubble point specific enthalpy" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output SpecificEnthalpy hl "boiling curve specific enthalpy"; + annotation(Documentation(info="")); + end bubbleEnthalpy; + + replaceable partial function dewEnthalpy "Return dew point specific enthalpy" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output SpecificEnthalpy hv "dew curve specific enthalpy"; + annotation(Documentation(info="")); + end dewEnthalpy; + + replaceable partial function bubbleEntropy + "Return bubble point specific entropy" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output SpecificEntropy sl "boiling curve specific entropy"; + annotation(Documentation(info="")); + end bubbleEntropy; + + replaceable partial function dewEntropy "Return dew point specific entropy" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output SpecificEntropy sv "dew curve specific entropy"; + annotation(Documentation(info="")); + end dewEntropy; + + replaceable partial function bubbleDensity "Return bubble point density" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output Density dl "boiling curve density"; + annotation(Documentation(info="")); + end bubbleDensity; + + replaceable partial function dewDensity "Return dew point density" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output Density dv "dew curve density"; + annotation(Documentation(info="")); + end dewDensity; + + replaceable partial function saturationPressure "Return saturation pressure" + extends Modelica.Icons.Function; + input Temperature T "temperature"; + input MassFraction X[:]={1} "fluid composition as mass fractions"; + output AbsolutePressure p "saturation pressure"; + annotation(Documentation(info="")); + end saturationPressure; + + function saturationPressure_der "Return saturation pressure time derivative" + extends Modelica.Icons.Function; + input Temperature T "temperature"; + input MassFraction X[:]={1} "fluid composition as mass fractions"; + input Real T_der "Temperature derivative"; + output Real p_der "saturation pressure derivative"; + // Standard definition + algorithm + p_der :=T_der/saturationTemperature_derp_sat(setSat_TX(T,X)); + annotation(Inline = true); + end saturationPressure_der; + + replaceable function saturationPressure_sat "Return saturation temperature" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output AbsolutePressure p "saturation pressure"; + algorithm + p := sat.psat; + annotation(Documentation(info="")); + end saturationPressure_sat; + + replaceable partial function saturationTemperature + "Return saturation temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "pressure"; + input MassFraction X[:]={1} "fluid composition as mass fractions"; + output Temperature T "saturation temperature"; + annotation(Documentation(info="")); + end saturationTemperature; + + replaceable function saturationTemperature_sat + "Return saturation temperature" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output Temperature T "saturation temperature"; + algorithm + T := sat.Tsat; + annotation(Documentation(info="")); + end saturationTemperature_sat; + + replaceable partial function saturationTemperature_derp + "Return derivative of saturation temperature w.r.t. pressure" + extends Modelica.Icons.Function; + input AbsolutePressure p "pressure"; + output Real dTp "derivative of saturation temperature w.r.t. pressure"; + annotation(Documentation(info="")); + end saturationTemperature_derp; + + replaceable function saturationTemperature_derp_sat + "Return derivative of saturation temperature w.r.t. pressure" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output Real dTp "derivative of saturation temperature w.r.t. pressure"; + algorithm + dTp := saturationTemperature_derp(sat.psat); + annotation(Documentation(info="")); + end saturationTemperature_derp_sat; + + /* redeclare replaceable partial function extends molarMass + "Return the molar mass of the medium" + algorithm + MM := fluidConstants[1].molarMass; + end molarMass;*/ + + replaceable partial function dBubbleDensity_dPressure + "Return bubble point density derivative" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output DerDensityByPressure ddldp "boiling curve density derivative"; + annotation(Documentation(info="")); + end dBubbleDensity_dPressure; + + replaceable partial function dDewDensity_dPressure + "Return dew point density derivative" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output DerDensityByPressure ddvdp "saturated steam density derivative"; + annotation(Documentation(info="")); + end dDewDensity_dPressure; + + replaceable partial function dBubbleEnthalpy_dPressure + "Return bubble point specific enthalpy derivative" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output DerEnthalpyByPressure dhldp + "boiling curve specific enthalpy derivative"; + annotation(Documentation(info="")); + end dBubbleEnthalpy_dPressure; + + replaceable partial function dDewEnthalpy_dPressure + "Return dew point specific enthalpy derivative" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output DerEnthalpyByPressure dhvdp + "saturated steam specific enthalpy derivative"; + annotation(Documentation(info="")); + end dDewEnthalpy_dPressure; + + redeclare replaceable function density_phX + "Return density from p, h, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEnthalpy h "Specific enthalpy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output Density d "density"; + algorithm + d := density( + setState_phX( + p, + h, + X, + phase)); + annotation(Documentation(info="")); + end density_phX; + + redeclare replaceable function density_psX + "Return density from p, s, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output Density d "Density"; + algorithm + d := density( + setState_psX( + p, + s, + X, + phase)); + annotation(Documentation(info="")); + end density_psX; + + redeclare replaceable function density_pTX + "Return density from p, T, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Temperature T "Temperature"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output Density d "Density"; + algorithm + d := density( + setState_pTX( + p, + T, + X, + phase)); + annotation(Documentation(info="")); + end density_pTX; + +replaceable function pressure_dTX "Return pressure from d, T, and X or Xi" + extends Modelica.Icons.Function; + input Density d "Density"; + input Temperature T "Temperature"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output AbsolutePressure p "Pressure"; +algorithm + p := pressure( + setState_dTX( + d, + T, + X, + phase)); +annotation(Documentation(info="")); +end pressure_dTX; + +replaceable function specificEnthalpy_dTX + "Return specific enthalpy from d, T, and X or Xi" + extends Modelica.Icons.Function; + input Density d "Pressure"; + input Temperature T "Specific entropy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; +algorithm + h := specificEnthalpy( + setState_dTX( + d, + T, + X, + phase)); +annotation(Documentation(info="")); +end specificEnthalpy_dTX; + + redeclare replaceable function specificEnthalpy_psX + "Return specific enthalpy from p, s, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; + algorithm + h := specificEnthalpy( + setState_psX( + p, + s, + X, + phase)); + annotation(Documentation(info="")); + end specificEnthalpy_psX; + + redeclare replaceable function specificEnthalpy_pTX + "Return specific enthalpy from pressure, temperature and mass fraction" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Temperature T "Temperature"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "Specific enthalpy at p, T, X"; + algorithm + h := specificEnthalpy( + setState_pTX( + p, + T, + X, + phase)); + annotation(Documentation(info="")); + end specificEnthalpy_pTX; + +replaceable function specificEntropy_dTX + "Return specific entropy from d, T, and X or Xi" + extends Modelica.Icons.Function; + input Density d "Density"; + input Temperature T "Temperature"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEntropy s "specific enthalpy"; +algorithm + s := specificEntropy( + setState_dTX( + d, + T, + X, + phase)); +annotation(Documentation(info="")); +end specificEntropy_dTX; + +replaceable function specificEntropy_phX + "Return specific entropy from p, h, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEnthalpy h "Specific enthalpy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEntropy s "specific enthalpy"; +algorithm + s := specificEntropy( + setState_phX( + p, + h, + X, + phase)); +annotation(Documentation(info="")); +end specificEntropy_phX; + +replaceable function specificEntropy_pTX + "Return specific entropy from p, T, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Temperature T "Temperature"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEntropy s "specific enthalpy"; +algorithm + s := specificEntropy( + setState_pTX( + p, + T, + X, + phase)); +annotation(Documentation(info="")); +end specificEntropy_pTX; + + redeclare replaceable function temperature_phX + "Return temperature from p, h, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEnthalpy h "Specific enthalpy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output Temperature T "Temperature"; + algorithm + T := temperature( + setState_phX( + p, + h, + X, + phase)); + annotation(Documentation(info="")); + end temperature_phX; + + redeclare replaceable function temperature_psX + "Return temperature from p, s, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output Temperature T "Temperature"; + algorithm + T := temperature( + setState_psX( + p, + s, + X, + phase)); + annotation(Documentation(info="")); + end temperature_psX; + + replaceable function setState_dT "Return thermodynamic state from d and T" + extends Modelica.Icons.Function; + input Density d "density"; + input Temperature T "Temperature"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output ThermodynamicState state "thermodynamic state record"; + algorithm + assert(nX==1,"This function is not allowed for mixtures."); + state := + setState_dTX( + d, + T, + fill(0, 0), + phase); + annotation(Documentation(info="")); + end setState_dT; + + replaceable function setState_ph "Return thermodynamic state from p and h" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEnthalpy h "Specific enthalpy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output ThermodynamicState state "thermodynamic state record"; + algorithm + assert(nX==1,"This function is not allowed for mixtures."); + state := + setState_phX( + p, + h, + fill(0, 0), + phase); + annotation(Documentation(info="")); + end setState_ph; + + replaceable function setState_ps "Return thermodynamic state from p and s" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output ThermodynamicState state "thermodynamic state record"; + algorithm + assert(nX==1,"This function is not allowed for mixtures."); + state := + setState_psX( + p, + s, + fill(0, 0), + phase); + annotation(Documentation(info="")); + end setState_ps; + + replaceable function setState_pT "Return thermodynamic state from p and T" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Temperature T "Temperature"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output ThermodynamicState state "thermodynamic state record"; + algorithm + assert(nX==1,"This function is not allowed for mixtures."); + state := + setState_pTX( + p, + T, + fill(0, 0), + phase); + annotation(Documentation(info="")); + end setState_pT; + + replaceable function setState_px + "Return thermodynamic state from pressure and vapour quality" + input AbsolutePressure p "Pressure"; + input MassFraction x "Vapour quality"; + output ThermodynamicState state "Thermodynamic state record"; + algorithm + assert(nX==1,"This function is not allowed for mixtures."); + state := setState_ph( + p, + (1 - x)*bubbleEnthalpy( + setSat_pX(p,{1})) + + x*dewEnthalpy( + setSat_pX(p,{1})), + 2); + annotation(Documentation(info="")); + end setState_px; + + replaceable function setState_Tx + "Return thermodynamic state from temperature and vapour quality" + input Temperature T "Temperature"; + input MassFraction x "Vapour quality"; + output ThermodynamicState state "thermodynamic state record"; + algorithm + assert(nX==1,"This function is not allowed for mixtures."); + state := setState_ph( + saturationPressure_sat( + setSat_TX(T,{1})), + (1 - x)*bubbleEnthalpy( + setSat_TX(T,{1})) + + x*dewEnthalpy( + setSat_TX(T,{1})), + 2); + annotation(Documentation(info="")); + end setState_Tx; + + replaceable function density_ph "Return density from p and h" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEnthalpy h "Specific enthalpy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Density d "Density"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use density_phX() instead!"); + d := density_phX(p, h, fill(0,0), phase); + annotation(Documentation(info="")); + end density_ph; + + replaceable function specificEnthalpy_dT + "Return specific enthalpy from d and T" + extends Modelica.Icons.Function; + input Density d "Density"; + input Temperature T "Temperature"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use specificEnthalpy_dX() instead!"); + h := specificEnthalpy(setState_dTX( + d, + T, + fill(0, 0), + phase)); + annotation(Documentation(info="")); + end specificEnthalpy_dT; + + replaceable function temperature_ph "Return temperature from p and h" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEnthalpy h "Specific enthalpy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Temperature T "Temperature"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use temperature_phX() instead!"); + T := temperature_phX(p, h, fill(0,0),phase); + annotation(Documentation(info="")); + end temperature_ph; + + replaceable function pressure_dT "Return pressure from d and T" + extends Modelica.Icons.Function; + input Density d "Density"; + input Temperature T "Temperature"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output AbsolutePressure p "Pressure"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use pressure_dTX() instead!"); + p := pressure(setState_dTX( + d, + T, + fill(0, 0), + phase)); + annotation(Documentation(info="")); + end pressure_dT; + + replaceable function specificEnthalpy_ps + "Return specific enthalpy from p and s" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use specificEnthalpy_psX() instead!"); + h := specificEnthalpy_psX(p,s,reference_X); + annotation(Documentation(info="")); + end specificEnthalpy_ps; + + replaceable function temperature_ps "Return temperature from p and s" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Temperature T "Temperature"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use temperature_psX() instead!"); + T := temperature_psX(p,s,fill(0,0),phase); + annotation(Documentation(info="")); + end temperature_ps; + + replaceable function density_ps "Return density from p and s" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Density d "Density"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use density_psX() instead!"); + d := density_psX(p, s, fill(0,0), phase); + annotation(Documentation(info="")); + end density_ps; + + replaceable function specificEnthalpy_pT + "Return specific enthalpy from p and T" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Temperature T "Temperature"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use specificEnthalpy_pTx() instead!"); + h := specificEnthalpy_pTX(p, T, fill(0,0),phase); + annotation(Documentation(info="")); + end specificEnthalpy_pT; + + replaceable function density_pT "Return density from p and T" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Temperature T "Temperature"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Density d "Density"; + algorithm + d := density( + setState_pTX( + p, + T, + fill(0, 0), + phase)); + annotation(Documentation(info="")); + end density_pT; + +redeclare replaceable function density + input ThermodynamicState state "Thermodynamic state record"; + output Density d; +algorithm + d:=state.d; +end density; + +redeclare replaceable function pressure + input ThermodynamicState state "Thermodynamic state record"; + output AbsolutePressure p; +algorithm + p:=state.p; +end pressure; + +redeclare replaceable function specificEnthalpy + input ThermodynamicState state "Thermodynamic state record"; + output SpecificEnthalpy h; +algorithm + h:=state.h; +end specificEnthalpy; + +redeclare replaceable function specificEntropy + input ThermodynamicState state "Thermodynamic state record"; + output SpecificEntropy s; +algorithm + s:=state.s; +end specificEntropy; + +redeclare replaceable function temperature + input ThermodynamicState state "Thermodynamic state record"; + output Temperature T; +algorithm + T:=state.T; +end temperature; + + replaceable function vapourQuality "Return vapour quality" + input ThermodynamicState state "Thermodynamic state record"; + output MassFraction x "Vapour quality"; + protected + constant SpecificEnthalpy eps = 1e-8; + algorithm + // x := min(max((specificEnthalpy(state) - bubbleEnthalpy( + // setSat_pX( + // pressure(state), state.X)))/(dewEnthalpy( + // setSat_pX( + // pressure(state), state.X)) - bubbleEnthalpy( + // setSat_pX( + // pressure(state), state.X)) + eps), 0), 1); + x := state.q; + annotation(Documentation(info="")); + end vapourQuality; + + replaceable partial function surfaceTension + "Return surface tension sigma in the two phase region" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output SurfaceTension sigma "Surface tension sigma in the two phase region"; + annotation(Documentation(info="")); + end surfaceTension; + +type DerPressureByDensity = Real (unit="m2/s2"); +type DerDerPressureByDensityByDensity = Real (unit="(m5)/(kg.s2)"); +type DerPressureByTemperature = Real (unit="kg/(K.m.s2)"); +//type DerDensityByTemperature = Real (unit="kg/(m3.K)"); +//type DerDensityByPressure = Real (unit="s2/m2"); +type DerDerPressureByTemperatureByTemperature = Real (unit="kg/(m.s2.K2)"); +type DerDerPressureByTemperatureByDensity = Real (unit="(m2)/(s2.K)"); + +type DerEnthalpyByDensity = Real (unit="J.m3/kg"); +//type DerEnthalpyByPressure = Real (unit="J.m.s2/kg"); +type DerEnthalpyByTemperature = Real (unit="J/(kg.K)"); + + annotation(Documentation(info=" +

PartialMixtureTwoPhaseMedium

+ +")); +end PartialMixtureTwoPhaseMedium; diff --git a/Interfaces/PureSubstanceInputChoice.mo b/Interfaces/PureSubstanceInputChoice.mo new file mode 100644 index 0000000..56a5514 --- /dev/null +++ b/Interfaces/PureSubstanceInputChoice.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Interfaces; +type PureSubstanceInputChoice = enumeration( + dT "(d,T) as inputs", + ph "(p,h) as inputs", + ps "(p,s) as inputs", + pT "(p,T) as inputs"); diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo new file mode 100644 index 0000000..d1ece26 --- /dev/null +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -0,0 +1,2187 @@ +within REFPROP2Modelica.Interfaces; +partial package REFPROPMixtureTwoPhaseMedium + "Two-phase mixture medium (properties supplied by REFPROP library)" + extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMedium( + mediumName="REFPROP Medium", + final reducedX=true, + final singleState=false, + final smoothModel=true, + reference_X=cat( + 1, + fill(0, nX - 1), + {1}), + fluidConstants=rpConstants); + + final constant String fluidnames=StrJoin(substanceNames, "|") + "Merge all substance names to one string for refprop library"; + constant Boolean debugmode=false + "print messages in functions and wrapper library if run from command line"; + + type PartialDersInputChoice = enumeration( + none "no partial derivatives is computed", + phX_numeric + "Numerical derivatives of density wrt. pressure, enthalpy and mass fraction is computed", + + phX_pseudoanalytic + "Pseudo analytical derivatives of density wrt. pressure, enthalpy and mass fraction is computed (not exact, but faster)", + + pTX_numeric + "Numerical derivatives of density and enthalpy wrt. pressure, temperature and mass fraction is computed"); + + constant FluidConstants[nS] rpConstants( + each chemicalFormula="REFPROP Medium", + each structureFormula="REFPROP Medium", + each casRegistryNumber="007", + each iupacName="REFPROP Medium", + each molarMass=0.1, + each criticalTemperature=600, + each criticalPressure=300e5, + each criticalMolarVolume=1, + each acentricFactor=1, + each triplePointTemperature=273.15, + each triplePointPressure=1e5, + each meltingPoint=1, + each normalBoilingPoint=1, + each dipoleMoment=1); + +//import REFPROP2Modelica.Interfaces.MixtureInputChoice; +//constant MixtureInputChoice explicitVars = InputChoice.phX +// "set of variables the model is explicit for, may be set to all combinations of p,h,T,d,s,d, REFPROP works internally with dT"; +// inputChoice = explicitVars, +//"mediumName is being checked for consistency at flowports" + + partial function partialREFPROP "Declaration of array props" + //used by getSatProp_REFPROP_check() and getProp_REFPROP_check() + extends Modelica.Icons.Function; + protected + Real[21+ 2*nX] props; + Real[12] ders; + Real[4] trns; + String errormsg=StrJoin(fill("xxxx", 64), "") + "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; + end partialREFPROP; + + function getProp_REFPROP + "calls C function with property identifier & returns single property" + input String what2calc; + input String statevars; + input String fluidnames; + input Real[:] ders; + input Real[:] trns; + input Real[:] props; + input Real statevar1; + input Real statevar2; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; + input String errormsg; + // input Integer debug=1; + output Real val; + external "C" val= props_REFPROP( + what2calc, + statevars, + fluidnames, + ders, + trns, + props, + statevar1, + statevar2, + X, + phase, + REFPROP_PATH, + errormsg, + debugmode, + calcTransport, + partialDersInputChoice); + annotation (Include="#include ", Library="refprop_wrapper"); + end getProp_REFPROP; + + function getProp_REFPROP_check + "wrapper for getProp_REFPROP returning 1 property value with error check" + extends partialREFPROP; + input String what2calc; + input String statevars; + // input String fluidnames; + input Real statevar1; + input Real statevar2; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Real val; + algorithm + assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); + // Modelica.Utilities.Streams.print("Calc "+what2calc); + + val := getProp_REFPROP( + what2calc, + statevars, + fluidnames, + ders, + trns, + props, + statevar1, + statevar2, + X, + phase, + errormsg) "just passing through"; + + // Modelica.Utilities.Streams.print("ERR("+String(props[1])+"):"+errormsg); + assert(props[1] == 0, "Errorcode " + String(props[1]) + " in REFPROP wrapper function:\n" + + errormsg + "\n"); + end getProp_REFPROP_check; + + partial function partialSatREFPROP "Declaration of array props" + //used by getSatProp_REFPROP_check() and getProp_REFPROP_check() + extends Modelica.Icons.Function; + protected + Real[11 + 2*nX] satprops; + String errormsg=StrJoin(fill("xxxx", 64), "") + "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; + // initial algorithm + // props :=fill(1, (16 + 2*nX)); + // ders :=fill(1, 19); + // trns :=fill(1, 3); + + end partialSatREFPROP; + + function getSatProp_REFPROP + "calls C function with property identifier & returns single property" + input String what2calc; + input String statevar; + input String fluidnames; + input Real[:] satprops; + input Real statevarval; + input Integer kph(min=1,max=2) + "phase specification, 1=>X is liquid, 2=>X is vapor"; + input Boolean calcTransport=false; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input String errormsg; + output Real val; + // input Integer debugmode=1; + external"C" val= satprops_REFPROP( + what2calc, + statevar, + fluidnames, + satprops, + statevarval, + X, + kph, + REFPROP_PATH, + errormsg, + debugmode, + calcTransport); + annotation (Include="#include ", Library="refprop_wrapper"); + end getSatProp_REFPROP; + + function getSatProp_REFPROP_check + "wrapper for getSatProp_REFPROP returning 1 property value with error check" + extends partialSatREFPROP; + input String what2calc; + input String statevar; + // input String fluidnames; + input Real statevarval; + input Integer kph(min=1,max=2) + "phase specification, 1=>X is liquid, 2=>X is vapor"; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + output Real val; + algorithm + assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); + val := getSatProp_REFPROP( + what2calc, + statevar, + fluidnames, + satprops, + statevarval, + X, + kph, + errormsg) "just passing through"; + //Error string decoding in wrapper-c-function + assert(satprops[1] == 0 or satprops[1] == 141, "Errorcode " + String(satprops[1]) + " in REFPROP wrapper function:\n" + + errormsg + "\n"); + if satprops[1] == 141 then + Modelica.Utilities.Streams.print("Saturation properties cannot be calculated, because P > p_crit!..."); + val := -999; + end if; + end getSatProp_REFPROP_check; + +redeclare record extends SaturationProperties + "Saturation properties in two-phase region" +end SaturationProperties; + +redeclare record extends ThermodynamicState + "Adapt this record to the returned values from one REFPROP call." + + SaturationProperties sat "saturation properties"; + +// Density d_l "density of liquid phase"; +// Density d_g "density of gaseous phase"; +// MassFraction x "void fraction"; +// SpecificInternalEnergy u "Specific energy"; + +// MolarMass MM_l "Molar Mass of liquid phase"; +// MolarMass MM_g "Molar Mass of gas phase"; +// MassFraction X_l[nX] "Composition of liquid phase (Mass fractions in kg/kg)"; +// MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; +// DerDensityByEnthalpy ddhp +// "derivative of density wrt enthalpy at constant pressure"; +// DerDensityByPressure ddph +// "derivative of density wrt pressure at constant enthalpy"; + +// Real hjt "isenthalpic Joule-Thompson coefficient [K/Pa]"; +// Modelica.SIunits.SpecificHelmholtzFreeEnergy a "Helmholtz energy"; +// Modelica.SIunits.SpecificGibbsFreeEnergy f "Gibbs free energy"; + Modelica.SIunits.IsothermalCompressibility kappa "isothermal compressibility"; + IsobaricExpansionCoefficient beta + "volume expansivity (= 1/V dV/dT = -1/rho dD/dT)"; + +// DerPressureByDensity dpdrho_T; +// DerDerPressureByDensityByDensity d2pdrho2_T; +// DerPressureByTemperature dpdT_rho; +// DerDensityByTemperature drhodT_p; +// DerDensityByPressure drhodp_T; +// DerDerPressureByTemperatureByTemperature d2pdT2_rho; +// DerDerPressureByTemperatureByDensity d2pdTdrho; +// DerEnthalpyByTemperature dhdT_rho "dH/dT at constant density"; +// DerEnthalpyByTemperature dhdT_p "dH/dT at constant pressure"; +// DerEnthalpyByDensity dhdrho_T "dH/drho at constant temperature"; +// DerEnthalpyByDensity dhdrho_p "dH/drho at constant pressure"; +// DerEnthalpyByPressure dhdp_T "dH/dP at constant temperature"; +// DerEnthalpyByPressure dhdp_rho "dH/dP at constant density"; + + Real dddX_ph; + DerDensityByEnthalpy dddh_pX "drho/dh at constant pressure"; + DerDensityByPressure dddp_hX "drho/dp at constant enthalpy"; + + DynamicViscosity eta "dynamic viscosity"; + ThermalConductivity lambda "thermal conductivity"; + + DerDensityByTemperature dddT_pX; + DerDensityByPressure dddp_TX; + DerEnthalpyByPressure dhdp_TX; + DerEnthalpyByTemperature dhdT_pX; + Real dddX_pT; + Real dhdX_pT; + +end ThermodynamicState; + +// redeclare model extends BaseProperties "Base properties of medium" +// equation +// u = h - p/d +// "state.u - calculated anyway by REFPROP, but this way the expression can be derived symbolically"; +// MM = state.molarMass; +// R = Modelica.Constants.R/MM; +// //ph-explicit +// if explicitVars=="ph" or explicitVars=="hp" then +// state = setState_phX(p,h,X,0) " ,fluidnames)"; +// T = temperature_phX(p,h,X) +// "double calculation, but necessary if T is given"; +// // T = state.T "can be used instead"; +// s = specificEntropy_phX(p,h,X) +// "double calculation, but necessary if s is given"; +// // s = state.s "can be used instead"; +// d = density_phX(p,h,X) "double calculation, but necessary if d is given"; +// //d = state.d "can be used instead"; +// elseif explicitVars=="pT" or explicitVars=="Tp" then +// //pT-explicit +// state = setState_pTX(p,T,X,0) ",fluidnames)"; +// h = specificEnthalpy_pTX(p,T,X) +// "double calculation, but necessary if s is given"; +// //h = state.h "can be used instead"; +// s = specificEntropy_pTX(p,T,X) +// "state.s double calculation, but necessary if s is given"; +// // s = state.s "can be used instead"; +// d = density_pTX(p,T,X) +// "state.d double calculation, but necessary if d is given"; +// //d = state.d "can be used instead"; +// elseif explicitVars=="dT" or explicitVars=="Td" then +// //Td-explicit +// state = setState_dTX(d,T,X,0) ",fluidnames)"; +// h = specificEnthalpy_dTX(d,T,X) +// "double calculation, but necessary if s is given"; +// //h = state.h "can be used instead"; +// s = specificEntropy_dTX(d,T,X) +// "state.s double calculation, but necessary if s is given"; +// // s = state.s "can be used instead"; +// p = pressure_dTX(d,T,X) +// "state.d double calculation, but necessary if d is given"; +// // p = state.p "can be used instead"; +// elseif explicitVars=="ps" or explicitVars=="ps" then +// state = setState_psX(p,s,X,0) ",fluidnames)"; +// T = temperature_psX(p,s,X); +// h = specificEnthalpy_psX(p,s,X); +// d = density_psX(p,s,X); +// elseif explicitVars=="pd" or explicitVars=="pd" then +// state = setState_pdX(p,d,X,0) ",fluidnames)"; +// T = temperature_pdX(p,d,X); +// h = specificEnthalpy_pdX(p,d,X); +// s = specificEntropy_pdX(p,d,X); +// elseif explicitVars=="hT" or explicitVars=="Th" then +// state = setState_ThX(T,h,X,0) ",fluidnames)"; +// p = pressure_ThX(T,h,X); +// s = specificEntropy_ThX(T,h,X); +// d = density_ThX(T,h,X); +// elseif explicitVars=="sT" or explicitVars=="Ts" then +// state = setState_TsX(T,s,X,0) ",fluidnames)"; +// p = pressure_TsX(T,s,X); +// h = specificEnthalpy_TsX(T,s,X); +// d = density_TsX(T,s,X); +// elseif explicitVars=="hd" or explicitVars=="hd" then +// state = setState_hdX(h,d,X,0) ",fluidnames)"; +// p = pressure_hdX(h,d,X); +// s = specificEntropy_hdX(h,d,X); +// T = temperature_hdX(h,d,X); +// elseif explicitVars=="hs" or explicitVars=="sh" then +// state = setState_hsX(h,s,X,0) ",fluidnames)"; +// p = pressure_hsX(h,s,X); +// T = temperature_hsX(h,s,X); +// d = density_hsX(h,s,X); +// elseif explicitVars=="sd" or explicitVars=="ds" then +// state = setState_dsX(d,s,X,0) ",fluidnames)"; +// p = pressure_dsX(d,s,X); +// h = specificEnthalpy_dsX(d,s,X); +// T = temperature_dsX(d,s,X); +// end if; +// sat.psat = p; +// sat.Tsat = saturationTemperature(p,X); +// sat.X = X; +// annotation (Documentation(info=" +// +// The baseproperties model is explicit for one set of 2 variables, which can be chosen to be ph, pT, ps, pd, Th, dT, Ts, hd, hs, ds (set explicitVars when calling this package or in package).
+// That means, that if only one of these variables is explicitly given, the other one is calculated by inverting its property function.
+// Then alle state variables are calculated using the corresponding setstate_XX function.
+// In order to avoid numerical inversion by the solver, 3 state variables are set explicitly using their respective property function, which has its inverses defined.
+// Example: So for p and h as explicit variables a state given by p and T is calculated by first calculating h with specificEnthalpy_pTX (inverse function of temperature_phX), +// then calculating the other variables using setState_phX. s and d, however, are then calculated, although they are already known in the state variable.
+// Knowing this, the baseproperty model can be adapted to your calculation needs to decrease computation time: +// +// ")); +// end BaseProperties; + + function setState "Calculates medium properties" + extends partialREFPROP; + input String statevars; + input Real statevar1; + input Real statevar2; + input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase "2 for two-phase, 1 for one-phase, 0 if not known"; + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; + output ThermodynamicState state "thermodynamic state record"; + algorithm + assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", + statevars, + fluidnames, + ders, + trns, + props, + statevar1, + statevar2, + X, + phase, + partialDersInputChoice, + calcTransport, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + /* If q = 990 Then Modelica.Utilities.Streams.print(msg+String(z)) end if; + + If q = 998 Then Quality = Trim2("Superheated vapor with T>Tc") + If q = 999 Then Quality = Trim2("Supercritical state (T>Tc, p>pc)") + If q = -998 Then Quality = Trim2("Subcooled liquid with p>pc")*/ + state := ThermodynamicState( + sat=SaturationProperties( + Tsat=props[21], + psat=props[2], + X=X, + dl=props[6], + dv=props[7], + hl=props[17], + hv=props[18], + sl=props[19], + sv=props[20], + sigma=trns[4], + Xl={props[21+i] for i in 1:nX}, + Xv={props[21+nX+i] for i in 1:nX}), + p=props[2], + T=props[3], + X=X, + molarMass=props[4], + d=props[5], + h=props[10], + s=props[11], + cv=props[12], + cp=props[13], + w=props[14], + phase=if (props[8] > 0 and props[8] < 1) then 2 else 1, + q= props[8], + kappa=ders[2], + beta=ders[3], + dddX_ph=ders[4], + dddh_pX=ders[5], + dddp_hX=ders[6], + dddp_TX=ders[7], + dddT_pX=ders[8], + dddX_pT=ders[9], + dhdp_TX=ders[10], + dhdT_pX=ders[11], + dhdX_pT=ders[12], + eta=trns[2], + lambda=trns[3]); + //q=if (props[8] < 0) then 0 elseif (props[8] > 1) then 1 else props[8], + // q=if (props[8] < 0) then 0 elseif (props[8] > 1) then 1 else props[8], + + if debugmode then + Modelica.Utilities.Streams.print("Running state set to p,T,d,h,s (" + + String(state.p) + "," + String(state.T) + "," + String(state.d) + "," + String(state.h) + "," + String(state.s) + ")"); + end if; + + end setState; + + function setState_dsX "Calculates medium properties from d,s,X" + extends Modelica.Icons.Function; + input Density d "Temperature"; + input SpecificEntropy s "Entropy"; + input MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_dsX(" + String(d) + "," + + String(s) + ",X)..."); + end if; + state := setState( + "ds", + d, + s, + X, + phase) ",fluidnames)"; + end setState_dsX; + + redeclare replaceable function extends setState_dTX + // input String fluidnames; + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_dTX(" + String(d) + "," + + String(T) + ",X)..."); + end if; + state := setState( + "dT", + d, + T, + X, + phase, + partialDersInputChoice, + calcTransport) ",fluidnames)"; + end setState_dTX; + + function setState_hsX "Calculates medium properties from h,s,X" + extends Modelica.Icons.Function; + input SpecificEnthalpy h "Enthalpy"; + input SpecificEntropy s "Entropy"; + input MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running (" + String(h) + "," + String(s) + + ",X)..."); + end if; + state := setState( + "hs", + h, + s, + X, + phase) ",fluidnames)"; + end setState_hsX; + + function setState_hdX "Calculates medium properties from h,d,X" + extends Modelica.Icons.Function; + input SpecificEnthalpy h "Enthalpy"; + input Density d "Temperature"; + input MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_hdX(" + String(h) + "," + + String(d) + ",X)..."); + end if; + state := setState( + "hd", + h, + d, + X, + phase) ",fluidnames)"; + end setState_hdX; + + function setState_pdX "Calculates medium properties from p,d,X" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Density d "Density"; + input MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_pdX(" + String(p) + "," + + String(d) + ",X)..."); + end if; + state := setState( + "pd", + p, + d, + X, + phase) ",fluidnames)"; + end setState_pdX; + + redeclare replaceable function extends setState_phX + "Calculates medium properties from p,h,X" + // input String fluidnames; + + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_phX(" + String(p) + "," + + String(h) + ",X)..."); + end if; + state := setState( + "ph", + p, + h, + X, + phase, + partialDersInputChoice, + calcTransport) ",fluidnames)"; + end setState_phX; + + redeclare function extends setBubbleState + "set the thermodynamic state on the bubble line" + algorithm + // if debugmode then + // Modelica.Utilities.Streams.print("Running setState_dTX(" + String(sat.dl) + "," + // + String(sat.Tsat) + ",X)..."); + // end if; + // state := setState_dTX( + // sat.dl, + // sat.Tsat, + // sat.Xl, + // phase); + + state := setState_pqX( + sat.psat, + 0, + sat.X); + + end setBubbleState; + + redeclare function extends setDewState + "set the thermodynamic state on the bubble line" + //input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + //input Boolean calcTransport=false; + algorithm + // if debugmode then + // Modelica.Utilities.Streams.print("Running setState_dTX(" + String(sat.dv) + "," + // + String(sat.Tsat) + ",X)..."); + // end if; + // state := setState_dTX( + // sat.dv, + // sat.Tsat, + // sat.Xv, + // phase); + + state := setState_pqX( + sat.psat, + 1, + sat.X); + + end setDewState; + + function setState_pqX "Calculates medium properties from p,q,X" + extends Modelica.Icons.Function; + input Modelica.SIunits.AbsolutePressure p "Pressure"; + input Modelica.SIunits.MassFraction q "quality (vapor mass fraction)"; + input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_pqX(" + String(p) + "," + + String(q) + ",X)..."); + end if; + state := setState( + "pq", + p, + q, + X, + phase, + partialDersInputChoice, + calcTransport) ",fluidnames)"; + end setState_pqX; + + function setState_TqX "Calculates medium properties from p,q,X" + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T "Temperature"; + input Modelica.SIunits.MassFraction q "quality (vapor mass fraction)"; + input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_tqX(" + String(T) + "," + + String(q) + ",X)..."); + end if; + state := setState( + "tq", + T, + q, + X, + phase, + partialDersInputChoice, + calcTransport) ",fluidnames)"; + end setState_TqX; + + redeclare replaceable partial function extends setState_psX + "Calculates medium properties from p,s,X" + // input String fluidnames; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_psX(" + String(p) + "," + + String(s) + ",X)..."); + end if; + state := setState( + "ps", + p, + s, + X, + phase) ",fluidnames)"; + end setState_psX; + + redeclare replaceable partial function extends setState_pTX + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; + + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_pTX(" + String(p) + "," + + String(T) + ",X)..."); + end if; + state := setState( + "pT", + p, + T, + X, + phase, + partialDersInputChoice, + calcTransport); //",fluidnames)"; + end setState_pTX; + + function setState_ThX "Calculates medium properties from T,h,X" + extends Modelica.Icons.Function; + input Temperature T "Temperature"; + input SpecificEnthalpy h "Enthalpy"; + input MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_ThX(" + String(T) + "," + + String(h) + ",X)..."); + end if; + state := setState( + "Th", + T, + h, + X, + phase) ",fluidnames)"; + end setState_ThX; + + function setState_TsX "Calculates medium properties from T,s,X" + extends Modelica.Icons.Function; + input Temperature T "Temperature"; + input SpecificEntropy s "Entropy"; + input MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_TsX(" + String(T) + "," + + String(s) + ",X)..."); + end if; + state := setState( + "Ts", + T, + s, + X, + phase) ",fluidnames)"; + end setState_TsX; + + function setSat "calculate saturation property record" + extends partialSatREFPROP; + input String statevar; + input Real statevarval; + input Modelica.SIunits.MassFraction X[:] "Mass fractions"; + input Integer kph(min=1,max=2) + "phase specification, 1=>X is liquid, 2=>X is vapor"; + input Boolean calcTransport=false; + output SaturationProperties sat "saturation property record"; + algorithm + assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getSatProp_REFPROP( + "p", + statevar, + fluidnames, + satprops, + statevarval, + kph, + calcTransport, + X, + errormsg); + assert(satprops[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + sat := SaturationProperties( + Tsat=satprops[2], + psat=satprops[3], + X=X, + dl=satprops[4], + dv=satprops[5], + hl=satprops[6], + hv=satprops[7], + sl=satprops[8], + sv=satprops[9], + sigma=satprops[10], + Xl= satprops[11:11+nX-1], + Xv= satprops[11+nX:11+2*nX-1]); + end setSat; + + redeclare replaceable function setSat_pX + "Return saturation property record from pressure" + extends Modelica.Icons.Function; + input AbsolutePressure p "pressure"; + input MassFraction X[nX] "Mass fractions"; + input Integer kph(min=1,max=2)=1 + "phase specification, 1=>X is liquid, 2=>X is vapor"; + input Boolean calcTransport=false; + output SaturationProperties sat "saturation property record"; + algorithm + sat := setSat( + "p", + p, + X, + kph, + calcTransport); + end setSat_pX; + + redeclare replaceable function setSat_TX + "Return saturation property record from temperature" + extends Modelica.Icons.Function; + input Temperature T "temperature"; + input MassFraction X[nX] "Mass fractions"; + input Integer kph(min=1,max=2)=1 + "phase specification, 1=>X is liquid, 2=>X is vapor"; + input Boolean calcTransport=false; + output SaturationProperties sat "saturation property record"; + algorithm + sat := setSat( + "t", + T, + X, + kph, + calcTransport=calcTransport); + end setSat_TX; + +// redeclare function extends specificEntropy +// "Return specific entropy - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" +// algorithm +// s := state.s; +// end specificEntropy; + +// redeclare replaceable function extends density +// "returns density from state - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" +// algorithm +// d := state.d; +// end density; + + redeclare function extends dewEnthalpy "dew curve specific enthalpy" + extends Modelica.Icons.Function; + algorithm + hv:=sat.hv; + end dewEnthalpy; + + redeclare function extends dewEntropy "dew curve specific entropy" + extends Modelica.Icons.Function; + algorithm + sv:=sat.sv; + end dewEntropy; + + redeclare function extends dewDensity "dew curve specific density" + extends Modelica.Icons.Function; + algorithm + dv:=sat.dv; + end dewDensity; + + redeclare function extends bubbleEnthalpy "boiling curve specific enthalpy" + extends Modelica.Icons.Function; + algorithm + hl:=sat.hl; + end bubbleEnthalpy; + + redeclare function extends bubbleEntropy "boiling curve specific entropy" + extends Modelica.Icons.Function; + algorithm + sl:=sat.sl; + end bubbleEntropy; + + redeclare function extends bubbleDensity "boiling curve specific density" + extends Modelica.Icons.Function; + algorithm + dl:=sat.dl; + end bubbleDensity; + + redeclare replaceable function extends molarMass + "Return the molar mass of the mixture" + extends Modelica.Icons.Function; + algorithm + MM := state.molarMass; + end molarMass; + +// redeclare function density_phX +// "calls REFPROP-Wrapper, returns density" +// extends Modelica.Icons.Function; +// input Modelica.SIunits.Pressure p; +// input Modelica.SIunits.SpecificEnthalpy h; +// input MassFraction X[:]=reference_X +// "composition defined by mass fractions"; +// input FixedPhase phase=0 +// "2 for two-phase, 1 for one-phase, 0 if not known"; +// output Modelica.SIunits.Density d; +// algorithm +// if debugmode then +// Modelica.Utilities.Streams.print("Running density_phX("+String(p)+","+String(h)+",X)"); +// end if; +// // p="+String(p)+",h="+String(h)+", X={"+String(X[1])+","+String(X[2])+"}"); +// d :=getProp_REFPROP_check("d", "ph",p,h,X,phase); +// annotation(LateInline=true,inverse(h=specificEnthalpy_pdX(p,d,X,phase), +// p=pressure_hdX(h,d,X,phase))); +// end density_phX; + +// redeclare function temperature_phX +// "calls REFPROP-Wrapper, returns temperature" +// extends Modelica.Icons.Function; +// input Modelica.SIunits.Pressure p; +// input Modelica.SIunits.SpecificEnthalpy h; +// input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; +// input FixedPhase phase=0 +// "2 for two-phase, 1 for one-phase, 0 if not known"; +// output Modelica.SIunits.Temperature T; +// algorithm +// if debugmode then +// Modelica.Utilities.Streams.print("Running temperature_phX("+String(p)+","+String(h)+",X)"); +// end if; +// T :=getProp_REFPROP_check("T", "ph",p,h,X,phase); +// annotation(LateInline=true,inverse(h=specificEnthalpy_pTX(p,T,X,phase), +// p=pressure_ThX(T,h,X,phase))); +// end temperature_phX; + + function density_hsX "calls REFPROP-Wrapper, returns density" + extends Modelica.Icons.Function; + input Modelica.SIunits.SpecificEnthalpy h; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Density d; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running density_hsX(" + String(h) + "," + + String(s) + ",X)"); + end if; + d := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "d", + "hs", + h, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_hdX( + h, + d, + X, + phase), h=specificEnthalpy_dsX( + d, + s, + X, + phase))); + end density_hsX; + + function density_pqX "calls REFPROP-Wrapper, returns specific density" + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Real q; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Density d; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running density_pqX(" + String(p) + "," + + String(q) + ",X)"); + end if; + d := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "d", + "pq", + p, + q, + X, + phase); + /* annotation(LateInline=true,inverse(p=pressure_dqX(d,q,X,phase), + q=quality_pdX(p,d,X,phase)));*/ + end density_pqX; + + redeclare function density_psX "calls REFPROP-Wrapper, returns density" + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Density d; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running density_psX(" + String(p) + "," + + String(s) + ",X)"); + end if; + d := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "d", + "ps", + p, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_pdX( + p, + d, + X, + phase), p=pressure_dsX( + d, + s, + X, + phase))); + end density_psX; + + redeclare function density_pTX "calls REFPROP-Wrapper, returns density" + extends Modelica.Icons.Function; + // input String fluidnames; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temperature T; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Density d; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running density_pTX(" + String(p) + "," + + String(T) + ",X)..."); + end if; + d := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "d", + "pT", + p, + T, + X, + phase); + annotation (LateInline=true, inverse(T=temperature_pdX( + p, + d, + X, + phase), p=pressure_dTX( + d, + T, + X, + phase))); + end density_pTX; + + function density_ThX "calls REFPROP-Wrapper, returns density" + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Density d; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running density_ThX(" + String(T) + "," + + String(h) + ",X)"); + end if; + d := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "d", + "Th", + T, + h, + X, + phase); + annotation (LateInline=true, inverse(h=specificEnthalpy_dTX( + d, + T, + X, + phase), T=temperature_hdX( + h, + d, + X, + phase))); + end density_ThX; + + function density_TsX "calls REFPROP-Wrapper, returns density" + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Density d; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running density_TsX(" + String(T) + "," + + String(s) + ",X)"); + end if; + d := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "d", + "Ts", + T, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_dTX( + d, + T, + X, + phase), T=temperature_dsX( + d, + s, + X, + phase))); + end density_TsX; + + // explicit derivative functions for finite element models + redeclare function density_derp_h + "Return density derivative w.r.t. pressure at const specific enthalpy" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DerDensityByPressure ddph "Density derivative w.r.t. pressure"; + algorithm + ddph := state.dddp_hX; + end density_derp_h; + + redeclare function density_derh_p + "Return density derivative w.r.t. specific enthalpy at constant pressure" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DerDensityByEnthalpy ddhp + "Density derivative w.r.t. specific enthalpy"; + algorithm + ddhp := state.dddh_pX; + end density_derh_p; + + redeclare function density_derp_T + "Return density derivative w.r.t. pressure at const temperature" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DerDensityByPressure ddpT "Density derivative w.r.t. pressure"; + algorithm + ddpT := state.dddp_TX; + end density_derp_T; + + redeclare function density_derT_p + "Return density derivative w.r.t. temperature at constant pressure" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DerDensityByTemperature ddTp "Density derivative w.r.t. temperature"; + algorithm + ddTp := state.dddT_pX; + end density_derT_p; + + redeclare function density_derX + "Return density derivative w.r.t. mass fraction" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output Density[nX] dddX "Derivative of density w.r.t. mass fraction"; + algorithm + dddX[1] := state.dddX_ph; + dddX[2:nX] := fill(0,nX-1); + end density_derX; + + function pressure_dsX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_dsX(" + String(d) + "," + + String(s) + ",X)"); + end if; + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "p", + "ds", + d, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_pdX( + p, + d, + X, + phase), d=density_psX( + p, + s, + X, + phase))); + end pressure_dsX; + + function pressure_dTX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d; + input Modelica.SIunits.Temperature T; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_dTX(" + String(d) + "," + + String(T) + ",X)"); + end if; + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "p", + "dT", + d, + T, + X, + phase); + annotation (LateInline=true, inverse(d=density_pTX( + p, + T, + X, + phase), T=temperature_pdX( + p, + d, + X, + phase))); + end pressure_dTX; + + function pressure_hdX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.SpecificEnthalpy h; + input Modelica.SIunits.Density d; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_hdX(" + String(h) + "," + + String(d) + ",X)"); + end if; + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "p", + "hd", + h, + d, + X, + phase); + annotation (LateInline=true, inverse(h=specificEnthalpy_pdX( + p, + d, + X, + phase),d=density_phX( + p, + h, + X, + phase))); + end pressure_hdX; + + function pressure_hsX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.SpecificEnthalpy h; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_hsX(" + String(h) + "," + + String(s) + ",X)"); + end if; + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "p", + "hs", + h, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_phX( + p, + h, + X, + phase), h=specificEnthalpy_psX( + p, + s, + X, + phase))); + end pressure_hsX; + + function pressure_ThX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_ThX(" + String(T) + "," + + String(h) + ",X)..."); + end if; + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "p", + "Th", + T, + h, + X, + phase); + annotation (LateInline=true, inverse(h=specificEnthalpy_pTX( + p, + T, + X, + phase), T=temperature_phX( + p, + h, + X, + phase))); + end pressure_ThX; + + function pressure_TqX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Real q; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + //T=quality_pTX(p,T,X,phase) + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_TqX(" + String(T) + "," + + String(q) + ",X)"); + end if; + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "p", + "Tq", + T, + q, + X, + phase); + annotation (LateInline=true, inverse(T=temperature_pqX( + p, + q, + X, + phase))); + end pressure_TqX; + + function pressure_TsX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_TsX(" + String(T) + "," + + String(s) + ",X)..."); + end if; + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "p", + "Ts", + T, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_pTX( + p, + T, + X, + phase), T=temperature_psX( + p, + s, + X, + phase))); + end pressure_TsX; + + function specificEnthalpy_dsX + "calls REFPROP-Wrapper, returns specific enthalpy" + //does not extend existing function from PartialMedium because there the algorithm is already defined + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + /*protected + Real[14+2*nX] props; + String errormsg=StrJoin(fill("xxxx",10),"");*/ + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_dsX(" + String( + d) + "," + String(s) + ",X)"); + end if; + // h :=getProp_REFPROP_check("h", "ds", fluidnames,d,s,X,phase); + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "h", + "ds", + d, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_hdX( + h, + d, + X, + phase), d=density_hsX( + h, + s, + X, + phase))); + end specificEnthalpy_dsX; + + redeclare function specificEnthalpy_dTX + "calls REFPROP-Wrapper, returns specific enthalpy" + //does not extend existing function from PartialMedium because there the algorithm is already defined + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d; + input Modelica.SIunits.Temperature T; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_dTX(" + String( + d) + "," + String(T) + ",X)"); + end if; + // h :=getProp_REFPROP_check("h", "dT", fluidnames,d,T,X,phase); + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "h", + "dT", + d, + T, + X, + phase); + annotation (LateInline=true, inverse(d=density_ThX( + T, + h, + X, + phase), T=temperature_hdX( + h, + d, + X, + phase))); + end specificEnthalpy_dTX; + + function specificEnthalpy_pdX + "calls REFPROP-Wrapper, returns specific enthalpy" + //does not extend existing function from PartialMedium because there the algorithm is already defined + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Density d; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_pdX(" + String( + p) + "," + String(d) + ",X)..."); + end if; + // h :=getProp_REFPROP_check("h", "pd", fluidnames,p,d,X,phase); + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "h", + "pd", + p, + d, + X, + phase); + annotation (LateInline=true, inverse(d=density_phX( + p, + h, + X, + phase), p=pressure_hdX( + h, + d, + X, + phase))); + end specificEnthalpy_pdX; + + function specificEnthalpy_pqX + "calls REFPROP-Wrapper, returns specific enthalpy" + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Real q; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + // annotation(LateInline=true,inverse(p = pressure_hqX(h,q,X,phase),quality_phX(p,h,X,phase))); + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_pqX(" + String( + p) + "," + String(q) + ",X)"); + end if; + // h :=getProp_REFPROP_check("h", "pq", fluidnames,p,q,X,phase); + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "h", + "pq", + p, + q, + X, + phase); + end specificEnthalpy_pqX; + + redeclare function specificEnthalpy_psX + "calls REFPROP-Wrapper, returns specific enthalpy" + //does not extend existing function from PartialMedium because there the algorithm is already defined + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + /*protected + Real[14+2*nX] props; + String errormsg=StrJoin(fill("xxxx",10),"");*/ + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_psX(" + String( + p) + "," + String(s) + ",X)..."); + end if; + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "h", + "ps", + p, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_phX( + p, + h, + X, + phase), p=pressure_hsX( + h, + s, + X, + phase))); + end specificEnthalpy_psX; + + redeclare function specificEnthalpy_pTX + "calls REFPROP-Wrapper, returns specific enthalpy" + //does not extend existing function from PartialMedium because there the algorithm is already defined + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temp_K T; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + /*protected + Real[14+2*nX] props; + String errormsg=StrJoin(fill("xxxx",10),"");*/ + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_pTX(" + String( + p) + "," + String(T) + ",X)..."); + end if; + // p="+String(p)+",T="+String(T)+", X={"+String(X[1])+","+String(X[2])+"}"); + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "h", + "pT", + p, + T, + X, + phase); + annotation (LateInline=true, inverse(T=temperature_phX( + p, + h, + X, + phase), p=pressure_ThX( + T, + h, + X, + phase))); + end specificEnthalpy_pTX; + + function specificEnthalpy_TsX + "calls REFPROP-Wrapper, returns specific enthalpy" + //does not extend existing function from PartialMedium because there the algorithm is already defined + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_TsX(" + String( + T) + "," + String(s) + ",X)"); + end if; + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "h", + "Ts", + T, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_ThX( + T, + h, + X, + phase), T=temperature_hsX( + h, + s, + X, + phase))); + end specificEnthalpy_TsX; + + function specificEntropy_dTX + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d; + input Modelica.SIunits.Temperature T; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEntropy s; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEntropy_dTX(" + String( + d) + "," + String(T) + ",X)"); + end if; + s := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "s", + "dT", + d, + T, + X, + phase); + annotation (LateInline=true, inverse(d=density_TsX( + T, + s, + X, + phase), T=temperature_dsX( + d, + s, + X, + phase))); + end specificEntropy_dTX; + + function specificEntropy_hdX + extends Modelica.Icons.Function; + input Modelica.SIunits.SpecificEnthalpy h; + input Modelica.SIunits.Density d; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEntropy s; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEntropy_hdX(" + String( + h) + "," + String(d) + ",X)"); + end if; + s := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "s", + "hd", + h, + d, + X, + phase); + annotation (LateInline=true, inverse(d=density_hsX( + h, + s, + X, + phase), h=specificEnthalpy_dsX( + d, + s, + X, + phase))); + end specificEntropy_hdX; + + function specificEntropy_pdX + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Density d; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEntropy s; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEntropy_pdX(" + String( + p) + "," + String(d) + ",X)"); + end if; + s := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "s", + "pd", + p, + d, + X, + phase); + annotation (LateInline=true, inverse(d=density_psX( + p, + s, + X, + phase), p=pressure_dsX( + d, + s, + X, + phase))); + end specificEntropy_pdX; + +// function specificEntropy_phX +// extends Modelica.Icons.Function; +// input Modelica.SIunits.Pressure p; +// input Modelica.SIunits.SpecificEnthalpy h; +// input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; +// // input String fluidnames; +// input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; +// output Modelica.SIunits.SpecificEntropy s; +// /*protected +// Real[14+2*nX] props; +// String errormsg=StrJoin(fill("xxxx",10),"");*/ +// algorithm +// if debugmode then +// Modelica.Utilities.Streams.print("Running specificEntropy_phX(" + String( +// p) + "," + String(h) + ",X)..."); +// // p="+String(p)+",h="+String(h)+", X={"+String(X[1])+","+String(X[2])+"}"); +// end if; +// s := getProp_REFPROP_check( +// "s", +// "ph", +// p, +// h, +// X, +// phase); +// annotation (LateInline=true, inverse(h=specificEnthalpy_psX( +// p, +// s, +// X, +// phase), p=pressure_hsX( +// h, +// s, +// X, +// phase))); +// end specificEntropy_phX; + + function specificEntropy_pqX + "calls REFPROP-Wrapper, returns specific entropy" + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Real q; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEntropy s; + // annotation(LateInline=true,inverse(p = pressure_sqX(s,q,X,phase),q=quality_psX(p,s,X,phase)); + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEntropy_pqX(" + String( + p) + "," + String(q) + ",X)"); + end if; + s := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "s", + "pq", + p, + q, + X, + phase); + end specificEntropy_pqX; + + redeclare function specificEntropy_pTX + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temp_K T; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEntropy s; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEntropy_pTX(" + String( + p) + "," + String(T) + ",X)"); + end if; + s := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "s", + "pT", + p, + T, + X, + phase); + annotation (LateInline=true, inverse(T=temperature_psX( + p, + s, + X, + phase), p=pressure_TsX( + T, + s, + X, + phase))); + end specificEntropy_pTX; + + function specificEntropy_ThX + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEntropy s; + /*protected + Real[14+2*nX] props; + String errormsg=StrJoin(fill("xxxx",10),"");*/ + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEntropy_ThX(" + String( + T) + "," + String(h) + ",X)"); + end if; + s := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "s", + "Th", + T, + h, + X, + phase); + annotation (LateInline=true, inverse(h=specificEnthalpy_TsX( + T, + s, + X, + phase), T=temperature_hsX( + h, + s, + X, + phase))); + end specificEntropy_ThX; + + function temperature_dsX "calls REFPROP-Wrapper, returns temperature" + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temperature T; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running temperature_dsX(" + String(d) + "," + + String(s) + ",X)"); + end if; + T := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "T", + "ds", + d, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_dTX( + d, + T, + X, + phase), d=density_TsX( + T, + s, + X, + phase))); + end temperature_dsX; + + function temperature_hdX "calls REFPROP-Wrapper, returns temperature" + extends Modelica.Icons.Function; + input Modelica.SIunits.SpecificEnthalpy h; + input Modelica.SIunits.Density d; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temperature T; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running temperature_hdX(" + String(h) + "," + + String(d) + ",X)"); + end if; + T := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "T", + "hd", + h, + d, + X, + phase); + annotation (LateInline=true, inverse(d=density_ThX( + T, + h, + X, + phase), h=specificEnthalpy_dTX( + d, + T, + X, + phase))); + end temperature_hdX; + + function temperature_hsX "calls REFPROP-Wrapper, returns temperature" + extends Modelica.Icons.Function; + input Modelica.SIunits.SpecificEnthalpy h; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temperature T; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running temperature_hsX(" + String(h) + "," + + String(s) + ",X)"); + end if; + T := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "T", + "hs", + h, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_ThX( + T, + h, + X, + phase), h=specificEnthalpy_TsX( + T, + s, + X, + phase))); + end temperature_hsX; + + function temperature_pdX "calls REFPROP-Wrapper, returns temperature" + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Density d; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temperature T; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running temperature_psX(" + String(p) + "," + + String(d) + ",X)..."); + end if; + T := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "T", + "pd", + p, + d, + X, + phase); + annotation (LateInline=true, inverse(d=density_pTX( + p, + T, + X, + phase), p=pressure_dTX( + d, + T, + X, + phase))); + end temperature_pdX; + + function temperature_pqX + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input MassFraction q; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temperature T; + // annotation(LateInline=true,inverse(p = pressure_TqX(T,q,X,phase),q=quality_pTX(p,T,X,phase)); + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running temperature_pqX(" + String(p) + "," + + String(q) + ",X)"); + end if; + T := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "T", + "pq", + p, + q, + X, + phase); + end temperature_pqX; + + redeclare function temperature_psX + "calls REFPROP-Wrapper, returns temperature" + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temperature T; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running temperature_psX(" + String(p) + "," + + String(s) + ",X)..."); + end if; + T := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( + "T", + "ps", + p, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_pTX( + p, + T, + X, + phase), p=pressure_TsX( + T, + s, + X, + phase))); + end temperature_psX; + +// redeclare function vapourQuality "Return vapour quality" +// input ThermodynamicState state "Thermodynamic state record"; +// output MassFraction x "Vapour quality"; +// algorithm +// x := state.x; +// annotation (Documentation(info="")); +// end vapourQuality; + + redeclare function extends specificHeatCapacityCp + algorithm + cp := state.cp; + end specificHeatCapacityCp; + + redeclare function extends specificHeatCapacityCv + algorithm + cv := state.cv; + end specificHeatCapacityCv; + + redeclare replaceable function extends thermalConductivity + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running thermalConductivity"); + end if; + lambda := state.lambda; + end thermalConductivity; + + redeclare replaceable function extends dynamicViscosity + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running dynamicViscosity"); + end if; + eta := state.eta; + end dynamicViscosity; + + function StrJoin "Converts an Array of Strings into a string separated by |" + input String[:] s_in; + input String delimiter; + output String s_out; + algorithm + s_out := s_in[1]; + for i in 2:size(s_in, 1) loop + s_out := s_out + delimiter + s_in[i]; + end for; + end StrJoin; + + replaceable function setSat_p + "Return saturation property record from pressure" + extends Modelica.Icons.Function; + input AbsolutePressure p "pressure"; + input MassFraction X[nX] "Mass fractions"; + input Real Tsurft=0 + "additional temperature for surface tension function, in case of setSat_pX"; + input Boolean calcTransport=false; + output SaturationProperties sat "saturation property record"; + algorithm + sat := setSat( + "p", + p, + X, + Tsurft, + calcTransport); + end setSat_p; + + replaceable function setSat_T + "Return saturation property record from temperature" + extends Modelica.Icons.Function; + input Temperature T "temperature"; + input MassFraction X[nX] "Mass fractions"; + input Boolean calcTransport=false; + output SaturationProperties sat "saturation property record"; + algorithm + sat := setSat( + "t", + T, + X, + calcTransport=calcTransport); + end setSat_T; + + partial function partialCritREFPROP "Declaration of array props" + extends Modelica.Icons.Function; + protected + Real[1] critprops; + String errormsg=StrJoin(fill("xxxx", 64), ""); + + end partialCritREFPROP; + + function getCritProp_REFPROP + input String fluidnames; + input Real[:] critprops; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input String errormsg; + output Real val; + external"C" val= critprops_REFPROP( + fluidnames, + critprops, + X, + REFPROP_PATH, + errormsg, + debugmode); + annotation (Include="#include ", Library="refprop_wrapper"); + end getCritProp_REFPROP; + + function setCrit + extends partialCritREFPROP; + input Modelica.SIunits.MassFraction X[:] "Mass fractions"; + output Real Tc(unit="K") "critical temperature K"; + // output Real pc(unit="kPa") "critical pressure, kPa"; + // output Real dc(unit="mol/l") "critical molar density, mol/L"; + // output MoleFraction[nX] Z "mole fraction"; + + algorithm + getCritProp_REFPROP( + fluidnames, + critprops, + X, + errormsg); + assert(critprops[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + Tc:=critprops[1]; + // pc:=critprops[2]; + // dc:=critprops[3]; + // Z:=critprops[4:4+nX-1]; + + end setCrit; + + function setState_dqX "Calculates medium properties from d,q,X" + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d "Pressure"; + input Modelica.SIunits.MassFraction q "quality (vapor mass fraction)"; + input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_dqX(" + String(d) + "," + + String(q) + ",X)..."); + end if; + state := setState( + "dq", + d, + q, + X, + phase, + partialDersInputChoice, + calcTransport) ",fluidnames)"; + end setState_dqX; + annotation (Documentation(info=" +

+REFPROPMedium is a package that delivers REFPROP data to a model based on and largely compatible to the Modelica.Media library. +It can be used to model two-phase mixtures of all fluids whose data is delivered with REFPROP. It has been developed and tested only in Dymola up to 2012 FD01. +

+

+All files in this library, including the C source files are released under the Modelica License 2. +

+

Installation

+The installation basically consists in copying 2 files and changing one line in this package: +
    +
  • We need access to the REFPROP.DLL and to the Fluid-Data directory in the REFPROP directory. + So you need to set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of this parent package). + Make sure you mask the backslashes. It should look something like +
    constant String REFPROP_PATH = \"C:\\\\Program Files\\\\REFPROP\\\\\";
  • +
  • We need REFPROP_WRAPPER.LIB in %DYMOLADIR%\\BIN\\LIB\ and REFPROP_WRAPPER.H in %DYMOLADIR%\\SOURCE\\ (%DYMOLADIR% is DYMOLA's program directory)
  • +
+This package needs the package PartialMixtureMediumTwoPhase which should be included in the parent package. + +

+

Usage

+As it is based on Modelica.Media, the usage is little different from the usage of the two-phase water model:
+Create an instance of REFPROPMedium and specify the mixture by passing the names of the medium components (medium names are the names of the .fld files in the +%REFPROP%\\fluids directory): +
+  package Medium = REFPROPMedium (final substanceNames={\"nitrogen\",\"argon\"});
+
+Create an Instance of REFPROPMedium.Baseproperties: +
+  Medium.BaseProperties props;
+
+You can then use the BaseProperties model to define the actual medium composition (via Xi or X), to define the thermodynamic state and calculate the corresponding properties. +
+  props.p = 1e5;
+  props.T = 300;
+  props.Xi = {.8};
+  d = props.d;
+  h = props.h;
+
+

Any combination of the pressure, temperature, specific enthalpy, specific entropy and density (p,T,h,s,d) can be used to define a +thermodynamic state. Explicit functions for all combinations exist in REFPROP and likewise in the REFPROPMedium package. +The calculation of all variables of a thermodynamic state, however, is by default done by setState_phX, so p and h have to be +calculated from the given combination of two variables first. Actually, by doing this, REFPROP already calculates all variables +of the thermodynamic state, but they cannot be used directly. This is a limitation of DYMOLA, as it is not able to invert a function +returning an array. +You can change the set of variables the property model is explicit for by setting the string variable explicitVars e.g. to \"pT\" or \"dT\": +

+package Medium = REFPROPMedium(final substanceNames={\"water\"}, final explicitVars = \"pT\");
+
+

+

All calculated values are returned in SI-Units and are mass based. +

+

Verbose mode can be switched on globally by setting the variable debugmode to true. This leads to many status messages from the modelica functions + as well as from the compiled library. The latter only appear are only seen in only seen when the dymola.exe is run directly in the command window. + + +

Details

+ In order to take advantage of REFPROP's capability of calculating two-phase mixtures a new Medium template had to be created by merging + Modelica.Media.Interfaces.PartialMixtureMedium and Modelica.Media.Interfaces.PartialTwoPhaseMedium of the Modelica Standard Library 3.1. + Alternatively, there is a version of this package limited to single-substance fluids (REFPROPMediumPureSubstance) which uses the standard + template Modelica.Media.Interfaces.PartialTwoPhaseMedium. + All property functions contain a definition of their inverses. So, in many cases no numerical inversion by the solver is needed because + explicit REFPROP functions are used (meaning, numerical inversion happens in REFPROP instead).
+ Example: When explicitVars are set to \"ph\" and p and T are given, the specificEnthalpy is calculated first using the inverse function of + Temperature_phX --> specificEnthalpy_pTX. With p and h known all other variables are calculated by setstate_phX. +

+ +

+

    +
+

+ + +

Created by

+Henning Francke
+Helmholtz Centre Potsdam
+GFZ German Research Centre for Geosciences
+Telegrafenberg, D-14473 Potsdam
+Germany +

+francke@gfz-potsdam.de + +", revisions=" + +")); +end REFPROPMixtureTwoPhaseMedium; diff --git a/Interfaces/package.mo b/Interfaces/package.mo new file mode 100644 index 0000000..85f5c15 --- /dev/null +++ b/Interfaces/package.mo @@ -0,0 +1,4 @@ +within REFPROP2Modelica; +package Interfaces "Interfaces for dummy implementations" + extends Modelica.Icons.InterfacesPackage; +end Interfaces; diff --git a/Interfaces/package.order b/Interfaces/package.order new file mode 100644 index 0000000..4f06915 --- /dev/null +++ b/Interfaces/package.order @@ -0,0 +1,4 @@ +MixtureInputChoice +PartialMixtureTwoPhaseMedium +PureSubstanceInputChoice +REFPROPMixtureTwoPhaseMedium diff --git a/Media/MethaneEthane.mo b/Media/MethaneEthane.mo new file mode 100644 index 0000000..ddf76cd --- /dev/null +++ b/Media/MethaneEthane.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Media; +package MethaneEthane "MethaneEthane mixture by REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"methane","ethane"}, + final debugmode=false); +end MethaneEthane; diff --git a/Media/NH3_Water.mo b/Media/NH3_Water.mo new file mode 100644 index 0000000..911aed9 --- /dev/null +++ b/Media/NH3_Water.mo @@ -0,0 +1,1922 @@ +within REFPROP2Modelica.Media; +package NH3_Water "Ammonia and water mixture by REFPROP library" + + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"ammoniaL","water"}, + final debugmode=false); + + replaceable function DynamicViscosityLiquid = dynamicViscosity_LIQconde constrainedby + partialDynamicViscosityLiquid; + replaceable function DynamicViscosityVapor = dynamicViscosity_VAPWilke constrainedby + partialDynamicViscosityVapor; + replaceable function ThermalConductivityLiquid = thermalConductivity_LIQConde + constrainedby + partialThermalConductivityLiquid; + replaceable function ThermalConductivityVapor = thermalConductivity_VAPWilke constrainedby + partialThermalConductivityVapor; + +/* + type ViscLiq = enumeration( + Conde "Conde 2006", + ElSayed "El-Sayed 1988", + HdbKaltetechnik "Handbuch der Kältetechnik", + SteccoDesideri "Stecco and Desideri 1991", + TejaRice "Teja and Rice (in Poling 2001)", + TejaRiceSassen "Teja and Rice using Sassen critical props", + TejaRiceFit "Teja and Rice (fit others with psi=1.6)") + "Liquid viscosity methods"; + constant ViscLiq viscLiq = ViscLiq.Conde annotation(evaluate=true); + + type ViscVap = enumeration( + Wilke "Wilke (in Poling 2001)", + Reichenberg "Reichenberg (in Poling 2001)", + Chung "Chung et al. (in Poling 2001)", + ChungErrorWeight + "Chung et al. incl. mole-fraction avg. error correction (in Poling 2001)") + "Vapor viscosity methods"; + constant ViscVap viscVap = ViscVap.Wilke; + + type CondLiq = enumeration( + Conde "Conde 2006", + ElSayed "El-Sayed 1988", + Filippov "Filippov (in Poling 2001)", + Jamieson "(in Poling 2001)") "Liquid conductivity methods"; + constant CondLiq condLiq = CondLiq.Conde; + + type CondVap = enumeration( + Average "Mole-fraction average (suggested in Poling 2001)", + MasonSaxena "Mason and Saxena (in Poling 2001)", + Chung "Chung et al. (in Poling 2001)", + ChungErrorWeight + "Chung et al. incl. mole-fraction avg. error correction (in Poling 2001)") + "Vapor conductivity methods"; + constant CondVap condVap = CondVap.Average; +*/ + + function criticalProperties + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + output Modelica.SIunits.Temperature Tc "critical temperature"; + output Modelica.SIunits.Pressure pc "critical pressure"; + output Modelica.SIunits.Density dc "critical density"; + output MoleFraction[nX] Z "mole fraction"; + + protected + Real[3 + 1*nX] critprops; + String errormsg=StrJoin(fill("xxxx", 64), ""); + + package Internal + function InternalFunction + input String fluidnames; + input Real[:] critprops; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input String errormsg; + output Real val; + + external "C" val= critprops_REFPROP( + fluidnames, + critprops, + X, + REFPROP_PATH, + errormsg, + debugmode) annotation (Include="#include ", Library="refprop_wrapper"); + annotation(Inline=true); + end InternalFunction; + end Internal; + + algorithm + Internal.InternalFunction( + fluidnames, + critprops, + X, + errormsg); + + Tc:=critprops[1]; + pc:=critprops[2]; + dc:=critprops[3]; + Z:=critprops[4:4+nX-1]; + + annotation(Inline=true,LateInline=true); + end criticalProperties; + + redeclare function dynamicViscosity + "Return dynamic viscosity, LIQ=CONDE, VAP=WILKE" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + algorithm + if state.q<=0.01 then // liquid + eta := DynamicViscosityLiquid(state); + elseif state.q>=0.99 then // vapor + eta := DynamicViscosityVapor(state); + else // twophase + eta:=1e-6; + end if; + + end dynamicViscosity; + + redeclare function thermalConductivity + "Return thermal conductivity, LIQ=Jamison, VAP=MOLE FRACTION AVG" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda "thermal conductivity"; + + algorithm + if state.q <= 0.01 then + // liquid + lambda :=ThermalConductivityLiquid(state); + elseif state.q >= 0.99 then + // vapor + lambda :=ThermalConductivityVapor(state); + else + // twophase + lambda := 1e-6; + end if; + + end thermalConductivity; + + function criticalProperties_sassen1990 + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + output Modelica.SIunits.Temperature Tc "critical temperature"; + output Modelica.SIunits.Pressure pc "critical pressure"; + // output Modelica.SIunits.Density dc "critical density"; + output MoleFraction[nX] Z "mole fraction"; + + protected + constant Real Mw=18.0153; // Molar mass of water, g/mol + constant Real Ma=17.0305; // Molar mass of ammonia, g/mol + + algorithm + Z[1] :=X[1]/(X[1] + (Ma*(1 - X[1])/Mw)); + Z[2] :=(1 - X[1])/((1 - X[1]) + ((X[1]*Mw)/Ma)); + + Tc :=647.14 - 199.822371*Z[1] + 109.035522*Z[1]^2 - 239.626217*Z[1]^3 + 88.689691*Z[1]^4; + pc :=220.64*1e5 - 37.923795*1e5*Z[1] + 36.424739*1e5*Z[1]^2 -41.851597*1e5*Z[1]^3 -63.805617*1e5*Z[1]^4; + + annotation(Inline=true,LateInline=true); + end criticalProperties_sassen1990; + + partial function partialDynamicViscosityLiquid + end partialDynamicViscosityLiquid; + + function dynamicViscosity_LIQconde "Conde 2006" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a = 405.560; + constant Modelica.SIunits.Temperature Tc_w = 647.096; + Modelica.SIunits.Temperature Tcorr_a "Corresponding temp. for ammonia, K"; + Modelica.SIunits.Temperature Tcorr_w "Corresponding temp. for water, K"; + + Modelica.SIunits.DynamicViscosity mu_a; + Modelica.SIunits.DynamicViscosity mu_w; + + Real F1; + Real F2; + Real F12; + Real F21; + + Real F_x; + Real DELTAeta; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + Tcorr_a := max(195.5,state.T*Tc_a/Tc) "Corresponding temp. for ammonia, K"; + Tcorr_w := max(273.16,state.T*Tc_w/Tc) "Corresponding temp. for water, K"; + + if debugmode then + Modelica.Utilities.Streams.print("got (Tc,pc,Tcorr_a,Tcorr_w), (" + String(Tc) + "," + String(pc) + "," + String(Tcorr_a) + "," + String(Tcorr_w) + ")"); + end if; + + state_a :=setState_TqX( + min(Tc_a-1,Tcorr_a), + 0, + {1,0}, + calcTransport=true); + state_w :=setState_TqX( + min(Tcorr_w,Tc_w-1), + 0, + {0,1}, + calcTransport=true); + + mu_a :=state_a.eta; + mu_w :=state_w.eta; + + if debugmode then + Modelica.Utilities.Streams.print("got (mu_a,mu_w,lambda_a,lambda_w), (" + String(mu_a) + "," + String(mu_w) + ")"); + end if; + + mu_a := mu_a*1e6; //convert to (1e-6 Pa.s) + mu_w := mu_w*1e6; //convert to (1e-6 Pa.s) + + F_x :=6.38*((1 - Z[1])^(1.125*Z[1]))*(1 - exp(-0.585*Z[1]*(1 - Z[1])^0.18))* + log((mu_a^0.5)*(mu_w^0.5)); + DELTAeta:=(0.534 - 0.815*(state.T/Tc_w))*F_x; + eta :=exp(Z[1]*log(mu_a) + (1 - Z[1])*log(mu_w) + DELTAeta); + eta := eta/1e6; // convert to Pa.s + + end dynamicViscosity_LIQconde; + + function dynamicViscosity_LIQelsayed + "El-Sayed 1988 (correct equations by Thorin 2001)" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a = 405.560; + constant Modelica.SIunits.Temperature Tc_w = 647.096; + Modelica.SIunits.Temperature Tcorr_a "Corresponding temp. for ammonia, K"; + Modelica.SIunits.Temperature Tcorr_w "Corresponding temp. for water, K"; + + Modelica.SIunits.DynamicViscosity mu_a; + Modelica.SIunits.DynamicViscosity mu_w; + + Real F1; + Real F2; + Real F12; + Real F21; + + Real F_x; + Real F_t; + Real DELTAeta; + + algorithm + (Tc,pc,Z) :=criticalProperties_sassen1990(state.X); + + Tcorr_a := max(195.5,state.T*Tc_a/Tc) "Corresponding temp. for ammonia, K"; + Tcorr_w := max(273.16,state.T*Tc_w/Tc) "Corresponding temp. for water, K"; + + if debugmode then + Modelica.Utilities.Streams.print("got (Tc,pc,Tcorr_a,Tcorr_w), (" + String(Tc) + "," + String(pc) + "," + String(Tcorr_a) + "," + String(Tcorr_w) + ")"); + end if; + + state_a :=setState_TqX( + min(Tc_a-1,Tcorr_a), + 0, + {1,0}, + calcTransport=true); + state_w :=setState_TqX( + min(Tcorr_w,Tc_w-1), + 0, + {0,1}, + calcTransport=true); + + mu_a :=state_a.eta; + mu_w :=state_w.eta; + + if debugmode then + Modelica.Utilities.Streams.print("got (mu_a,mu_w,lambda_a,lambda_w), (" + String(mu_a) + "," + String(mu_w) + ")"); + end if; + + mu_a := mu_a*1e6; //convert to (1e-6 Pa.s) + mu_w := mu_w*1e6; //convert to (1e-6 Pa.s) + + F_x:=(Z[1]*Z[2] - 0.125*(Z[1]^2)*Z[2])*((log(mu_a*mu_w))^0.5); + F_t:=4.219 - 3.7996*(state.T*(9/5)/492) + 0.842*(state.T*(9/5)/492)^2; + F12:=F_t*F_x; + eta :=(exp(Z[1]*log(mu_a) + Z[2]*log(mu_w) + F12)); + eta := eta/1e6; // convert to Pa.s + + end dynamicViscosity_LIQelsayed; + + function dynamicViscosity_LIQHDK "Handbuch der Kältetechnik" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + algorithm + eta :=(10^(10^((2000/(500 + state.T - 273.15)) - 4.41 + 0.925*state.X[1] - 1.743* + state.X[1]^2 + 0.021*state.X[1]^3)) - 1)*1e-3; + + end dynamicViscosity_LIQHDK; + + function dynamicViscosity_LIQTejeRice "Teja and Rice (in Poling 2001)" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState states[2]; + + Modelica.SIunits.Temperature Tc_actual "critical temperature"; + Modelica.SIunits.Pressure pc_actual "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + + Modelica.SIunits.DynamicViscosity etas[2]; + + Real yi,yj,psi_ij,epsilon_i,epsilon_j,Vc_ij,Vcm, Tc_ij, Tcm, T_i, T_j, M_m, epsilon_m; + + algorithm + (Tc_actual,pc_actual,Z) :=criticalProperties_sassen1990(state.X); + + yi := Z[1]; + yj := Z[2]; + + psi_ij := 1;// 8 as suggested by el-sayed??? + + epsilon_i := Vc[1]^(2/3)/(Tc[1]*MM[1])^0.5; // "9-13.18" + epsilon_j := Vc[2]^(2/3)/(Tc[2]*MM[2])^0.5; // "9-13.18" + + Vc_ij := (Vc[1]^(1/3) + Vc[2]^(1/3))^3/8; + // "9-13.23" + Vcm := yi*yi*Vc[1] + yj*yj*Vc[2] + 2*yi*yj*Vc_ij; // "9-13.19" + + Tc_ij := psi_ij*(Tc[1]*Tc[2]*Vc[1]*Vc[2])^0.5/Vc_ij; // "9-13.24" + Tcm := (yi*yi*Tc[1]*Vc[1] + yj*yj*Tc[2]*Vc[2] + 2*yi*yj*Tc_ij*Vc_ij)/Vcm; // "9-13.19" + + T_i := max(195.5,Tc[1]/Tcm*state.T); + T_j := max(273.16,Tc[2]/Tcm*state.T); + + states[1] := setState_TqX( + min(Tc[1]-1,T_i), + 0, + {1,0}, + calcTransport=true); + states[2] := setState_TqX( + min(T_j,Tc[2]-1), + 0, + {0,1}, + calcTransport=true); + etas[1] := states[1].eta; + etas[2] := states[2].eta; + + M_m :=yi*MM[1] + yj*MM[2]; // "9-13.21" + epsilon_m :=Vcm^(2/3)/(Tcm*M_m)^0.5; // "9-13.18" + + eta :=exp(yi*log(etas[1]*epsilon_i) + yj*log(etas[2]*epsilon_j))/epsilon_m; // "9-13.25" + + end dynamicViscosity_LIQTejeRice; + + function dynamicViscosity_LIQTejeRiceSteccoWay "Stecco and Desideri 1991" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState states[2]; + + Modelica.SIunits.Temperature Tc_actual "critical temperature"; + Modelica.SIunits.Pressure pc_actual "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + + Modelica.SIunits.DynamicViscosity etas[2]; + + Real yi,yj,psi_ij,epsilon_i,epsilon_j,Vc_ij,Vcm, Tc_ij, Tcm, T_i, T_j, M_m, epsilon_m; + + algorithm + (Tc_actual,pc_actual,Z) :=criticalProperties_sassen1990(state.X); + + yi := Z[1]; + yj := Z[2]; + + psi_ij := 8;// 8 as suggested by el-sayed??? + + epsilon_i := Vc[1]^(2/3)/(Tc[1]*MM[1])^0.5; // "9-13.18" + epsilon_j := Vc[2]^(2/3)/(Tc[2]*MM[2])^0.5; // "9-13.18" + + Vc_ij := (Vc[1]^(1/3) + Vc[2]^(1/3))^3/8; + // "9-13.23" + Vcm := yi*yi*Vc[1] + yj*yj*Vc[2] + 2*yi*yj*Vc_ij; // "9-13.19" + + Tc_ij := psi_ij*(Tc[1]*Tc[2]*Vc[1]*Vc[2])^0.5/Vc_ij; // "9-13.24" + Tcm := (yi*yi*Tc[1]*Vc[1] + yj*yj*Tc[2]*Vc[2] + 2*yi*yj*Tc_ij*Vc_ij)/Vcm; // "9-13.19" + + T_i := max(195.5,state.T); + T_j := max(273.16,state.T); + + states[1] := setState_TqX( + min(Tc[1]-1,T_i), + 0, + {1,0}, + calcTransport=true); + states[2] := setState_TqX( + min(T_j,Tc[2]-1), + 0, + {0,1}, + calcTransport=true); + etas[1] := states[1].eta; + etas[2] := states[2].eta; + + M_m :=yi*MM[1] + yj*MM[2]; // "9-13.21" + epsilon_m :=Vcm^(2/3)/(Tcm*M_m)^0.5; // "9-13.18" + + eta :=exp(yi*log(etas[1]*epsilon_i) + yj*log(etas[2]*epsilon_j))/epsilon_m; // "9-13.25" + + end dynamicViscosity_LIQTejeRiceSteccoWay; + + function dynamicViscosity_LIQTejeRiceSassensTcrit + "Teja and Rice using Sassen critical props" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + protected + ThermodynamicState states[2]; + + Modelica.SIunits.Temperature Tc_actual "critical temperature"; + Modelica.SIunits.Pressure pc_actual "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + + Modelica.SIunits.DynamicViscosity etas[2]; + + Real yi,yj,psi_ij,epsilon_i,epsilon_j,Vc_ij,Vcm, Tc_ij, Tcm, T_i, T_j, M_m, epsilon_m; + + algorithm + (Tc_actual,pc_actual,Z) :=criticalProperties_sassen1990(state.X); + + yi := Z[1]; + yj := Z[2]; + + epsilon_i := Vc[1]^(2/3)/(Tc[1]*MM[1])^0.5; // "9-13.18" + epsilon_j := Vc[2]^(2/3)/(Tc[2]*MM[2])^0.5; // "9-13.18" + + Vc_ij := (Vc[1]^(1/3) + Vc[2]^(1/3))^3/8; // "9-13.23" + Vcm := yi*yi*Vc[1] + yj*yj*Vc[2] + 2*yi*yj*Vc_ij; // "9-13.19" + + Tcm:=Tc_actual; + T_i := max(195.5,state.T*Tc[1]/Tc_actual) + "Corresponding temp. for ammonia, K"; + T_j := max(273.16,state.T*Tc[2]/Tc_actual) + "Corresponding temp. for water, K"; + + states[1] := setState_TqX( + min(Tc[1]-1,T_i), + 0, + {1,0}, + calcTransport=true); + states[2] := setState_TqX( + min(T_j,Tc[2]-1), + 0, + {0,1}, + calcTransport=true); + etas[1] := states[1].eta; + etas[2] := states[2].eta; + + M_m :=yi*MM[1] + yj*MM[2]; // "9-13.21" + epsilon_m :=Vcm^(2/3)/(Tcm*M_m)^0.5; // "9-13.18" + + eta :=exp(yi*log(etas[1]*epsilon_i) + yj*log(etas[2]*epsilon_j))/epsilon_m; // "9-13.25" + + end dynamicViscosity_LIQTejeRiceSassensTcrit; + + function dynamicViscosity_LIQTejeRiceFit + "Teja and Rice (fit others with psi=1.6)" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState states[2]; + + Modelica.SIunits.Temperature Tc_actual "critical temperature"; + Modelica.SIunits.Pressure pc_actual "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + + Modelica.SIunits.DynamicViscosity etas[2]; + + Real yi,yj,psi_ij,epsilon_i,epsilon_j,Vc_ij,Vcm, Tc_ij, Tcm, T_i, T_j, M_m, epsilon_m; + + algorithm + (Tc_actual,pc_actual,Z) :=criticalProperties_sassen1990(state.X); + + yi := Z[1]; + yj := Z[2]; + + psi_ij := 1.6;// 8 as suggested by el-sayed??? + + epsilon_i := Vc[1]^(2/3)/(Tc[1]*MM[1])^0.5; // "9-13.18" + epsilon_j := Vc[2]^(2/3)/(Tc[2]*MM[2])^0.5; // "9-13.18" + + Vc_ij := (Vc[1]^(1/3) + Vc[2]^(1/3))^3/8; + // "9-13.23" + Vcm := yi*yi*Vc[1] + yj*yj*Vc[2] + 2*yi*yj*Vc_ij; // "9-13.19" + + Tc_ij := psi_ij*(Tc[1]*Tc[2]*Vc[1]*Vc[2])^0.5/Vc_ij; // "9-13.24" + Tcm := (yi*yi*Tc[1]*Vc[1] + yj*yj*Tc[2]*Vc[2] + 2*yi*yj*Tc_ij*Vc_ij)/Vcm; // "9-13.19" + + T_i := max(195.5,Tc[1]/Tcm*state.T); + T_j := max(273.16,Tc[2]/Tcm*state.T); + + states[1] := setState_TqX( + min(Tc[1]-1,T_i), + 0, + {1,0}, + calcTransport=true); + states[2] := setState_TqX( + min(T_j,Tc[2]-1), + 0, + {0,1}, + calcTransport=true); + etas[1] := states[1].eta; + etas[2] := states[2].eta; + + M_m :=yi*MM[1] + yj*MM[2]; // "9-13.21" + epsilon_m :=Vcm^(2/3)/(Tcm*M_m)^0.5; // "9-13.18" + + eta :=exp(yi*log(etas[1]*epsilon_i) + yj*log(etas[2]*epsilon_j))/epsilon_m; // "9-13.25" + + end dynamicViscosity_LIQTejeRiceFit; + + partial function partialDynamicViscosityVapor + end partialDynamicViscosityVapor; + + function dynamicViscosity_VAPReichenberg "Reichenberg (in Poling 2001)" + extends partialDynamicViscosityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + SaturationProperties sat_w; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a = 405.560; + constant Modelica.SIunits.Temperature Tc_w = 647.096; + constant Modelica.SIunits.Pressure pc_a = 11333000; + constant Modelica.SIunits.Pressure pc_w = 22064000; + constant Real Mw=18.0153; // Molar mass of water, g/mol + constant Real Ma=17.0305; // Molar mass of ammonia, g/mol + constant Real mu_1 = 1.470; // dipole moment + constant Real mu_2 = 1.855; // dipole moment + + Modelica.SIunits.DynamicViscosity eta_a; + Modelica.SIunits.DynamicViscosity eta_w; + + Real Tr_1; + Real Tr_2; + Real Tr_12; + Real mu_r1; + Real mu_r2; + Real mu_r12; + Real U_1; + Real U_2; + Real C_1; + Real C_2; + Real H_12; + Real K_1; + Real K_2; + + algorithm + (Tc,pc,Z) :=criticalProperties_sassen1990(state.X); + + // it will always be vapor or supercritical! + state_a :=setState_pTX( + state.p, + state.T, + {1,0}, + calcTransport=true); + + if state.T < Tc_w-1 then // + sat_w := setSat_TX(state.T, {0,1}); + state_w :=setState_pTX( + min(state.p,sat_w.psat-1), + state.T, + {0,1}, + calcTransport=true); + else + state_w :=setState_pTX( + state.p, + state.T, + {0,1}, + calcTransport=true); + end if; + + eta_a :=state_a.eta; + eta_w :=state_w.eta; + + eta_a:=eta_a*1e6; //convert to (1e-6 Pa.s) + eta_w:=eta_w*1e6; //convert to (1e-6 Pa.s) + + Tr_1 := state.T/Tc_a "Reduced temperature of ammonia"; + Tr_2 := state.T/Tc_w "Reduced temperature of water"; + Tr_12 := state.T/(sqrt(Tc_a*Tc_w)); + mu_r1:=52.46*(((mu_1^2)*pc_a)/Tc_a^2); + mu_r2:=52.46*(((mu_2^2)*pc_w)/Tc_w^2); + mu_r12:=sqrt(mu_r1*mu_r2); + U_1:=(((1 + 0.36*Tr_1*(Tr_1 - 1))^(1/6))/sqrt(Tr_1))*(((Tr_1^3.5) + (10* + mu_r1)^7)/((Tr_1^3.5)*(1 + (10*mu_r1)^7))); + U_2:=(((1 + 0.36*Tr_2*(Tr_2 - 1))^(1/6))/sqrt(Tr_2))*(((Tr_2^3.5) + (10* + mu_r2)^7)/((Tr_2^3.5)*(1 + (10*mu_r2)^7))); + C_1:=(Ma^(1/4))/sqrt(eta_a*U_1); + C_2:=(Mw^(1/4))/sqrt(eta_w*U_2); + H_12:= (sqrt((Ma*Mw)/32)/((Ma+Mw)^(3/2)))*(((1+0.36*Tr_12*(Tr_12-1))^(1/6))/sqrt(Tr_12))*((C_1+C_2)^2)*(((Tr_12^3.5)+(10*mu_r12)^7)/((Tr_12^3.5)*(1+(10*mu_r12)^7))); + K_1:=(Z[1]*eta_a)/(Z[1]+eta_a*(Z[2]*H_12*(3+2*(Mw/Ma)))); + K_2:=(Z[2]*eta_w)/(Z[2]+eta_w*(Z[1]*H_12*(3+(2*Ma/Mw)))); + eta:=(K_1*(1+H_12^2*K_2^2)+K_2*(1+2*H_12*K_1+H_12^2*K_1^2)); + + eta := eta/1e6; // convert to Pa.s + + end dynamicViscosity_VAPReichenberg; + + function dynamicViscosity_VAPWilke "Wilke (in Poling 2001)" + extends partialDynamicViscosityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + SaturationProperties sat_w; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a = 405.560; + constant Modelica.SIunits.Temperature Tc_w = 647.096; + constant Modelica.SIunits.Pressure pc_a = 11333000; + constant Modelica.SIunits.Pressure pc_w = 22064000; + constant Real Mw=18.0153; // Molar mass of water, g/mol + constant Real Ma=17.0305; // Molar mass of ammonia, g/mol + + Real F12,F21; + + Modelica.SIunits.DynamicViscosity mu_a; + Modelica.SIunits.DynamicViscosity mu_w; + + algorithm + (Tc,pc,Z) :=criticalProperties_sassen1990(state.X); + + // it will always be vapor or supercritical! + state_a :=setState_pTX( + state.p, + state.T, + {1,0}, + calcTransport=true); + + if state.T < Tc_w-1 then // + sat_w := setSat_TX(state.T, {0,1}); + state_w :=setState_pTX( + min(state.p,sat_w.psat-1), + state.T, + {0,1}, + calcTransport=true); + else + state_w :=setState_pTX( + state.p, + state.T, + {0,1}, + calcTransport=true); + end if; + + mu_a :=state_a.eta; + mu_w :=state_w.eta; + + mu_a:=mu_a*1e6; //convert to (1e-6 Pa.s) + mu_w:=mu_w*1e6; //convert to (1e-6 Pa.s) + + F12 := ((1 + (sqrt(mu_a/mu_w)*((Mw/Ma)^0.25)))^2)/sqrt(8*(1 + (Ma/Mw))); + F21 := F12*(mu_w/mu_a)*(Ma/Mw); + eta:= ((mu_a*Z[1])/(Z[1] + (F12*Z[2]))) + ((mu_w*Z[2])/(Z[2] + (F21*Z[1]))); // Mixture vapour dynamic visc., microPa s, Thorin, 2001 + eta := eta/1e6; // convert to Pa.s + + end dynamicViscosity_VAPWilke; + + function dynamicViscosity_VAPChung "Chung et al. (in Poling 2001)" + extends partialDynamicViscosityVapor; + + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + // constant Real DM[2] = {1.470,1.855}; // dipole moment, debye + constant Real DM[2] = {1.5,1.8}; // dipole moment, debye + constant Real omega[2] = {0.2558,0.3443}; // accentric factor + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + constant Real kappa[2] = {0.0,0.076}; // hydrogen bonding or hydrogen association factor + + Modelica.SIunits.Temperature Tc_dum "critical temperature"; + Modelica.SIunits.Pressure pc_dum "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + Real yi,yj; + + Real sigma_i,sigma_j,sigma_ij,sigma_m; + Real epsilon_i_K,epsilon_j_K,epsilon_ij_K,epsilon_m_K; + Real M_ij,M_m,omega_ij,omega_m; + Real DM_m, Vcm, Tcm, DM_rm, kappa_m, F_cm, T_star_m, OMEGA_v; + Real MMm, rho, y, G1, G2, eta_star_star, eta_star; + Real E[10]; + + constant Real a[10] = {6.324,1.210e-3,5.283,6.623,19.745,-1.900,24.275,0.7972,-0.2382,0.06863}; + constant Real b[10] = {50.412,-1.154e-3,254.209,38.096,7.630,-12.537,3.450,1.117,0.06770,0.3479}; + constant Real c[10] = {-51.680,-6.257e-3,-168.48,-8.464,-14.354,4.985,-11.291,0.01235,-0.8163,0.5926}; + constant Real d[10] = {1189.0,0.03728,3898.0,31.42,31.53,-18.15,69.35,-4.117,4.025,-0.727}; + + algorithm + (Tc_dum,pc_dum,Z) :=criticalProperties_sassen1990(state.X); + + yi :=Z[1]; + yj :=Z[2]; + + sigma_i:=0.809*Vc[1]^(1/3); // "9-5.32"; + sigma_j:=0.809*Vc[2]^(1/3); // "9-5.32" + sigma_ij:=(sigma_i*sigma_j)^0.5; // "9-5.33" + sigma_m :=(yi*yi*sigma_i^3 + yj*yj*sigma_j^3 + 2*yi*yj*sigma_ij^3)^(1/3); // "9-5.24" + + epsilon_i_K :=Tc[1]/1.2593; // "9-5.34" + epsilon_j_K :=Tc[2]/1.2593; // "9-5.34" + epsilon_ij_K :=(epsilon_i_K*epsilon_j_K)^0.5; // "9-5.35" + epsilon_m_K :=(yi*yi*epsilon_i_K*sigma_i^3 + yj*yj*epsilon_j_K*sigma_j^3 + 2* + yi*yj*epsilon_ij_K*sigma_ij^3)/sigma_m^3; // "9-5.27" + + M_ij :=2*MM[1]*MM[2]/(MM[1] + MM[2]); // "9-5.40" + M_m :=((yi*yi*epsilon_i_K*sigma_i^2*MM[1]^0.5 + yj*yj*epsilon_j_K*sigma_j^2* + MM[2]^0.5 + 2*yi*yj*epsilon_ij_K*sigma_ij^2*M_ij^0.5)/(epsilon_m_K*sigma_m^2)) + ^2; // "9-5.28" + + omega_ij:=(omega[1] + omega[2])/2; + omega_m :=(yi*yi*omega[1]*sigma_i^3 + yj*yj*omega[2]*sigma_j^3 + 2*yi*yj* + omega_ij*sigma_ij^3)/sigma_m^3; // "9-5.29" + + DM_m :=(sigma_m^3*(yi*yi*DM[1]^4/sigma_i^3 + yj*yj*DM[2]^4/sigma_j^3 + 2*yi* + yj*DM[1]^2*DM[2]^2/sigma_ij^3))^(1/4); // "9-5.30" + Vcm :=(sigma_m/0.809)^3; // "9-5.44" + Tcm :=1.2593*epsilon_m_K; // "9-5.42" + DM_rm :=131.3*DM_m/(Vcm*Tcm)^0.5; // "9-5.43" + kappa_m :=yi*yi*kappa[1] + yj*yj*kappa[2] + 2*yi*yj*(kappa[1]*kappa[2])^0.5; // "9-5.31" + F_cm :=1 - 0.275*omega_m + 0.059035*DM_rm^4 + kappa_m; // "9-5.41" + + T_star_m := state.T/epsilon_m_K; + OMEGA_v:=1.16145*T_star_m^(-0.14874) + 0.52487*exp(-0.77320*T_star_m) + 2.16178 + *exp(-2.43787*T_star_m); // "9-4.3" + + // eta :=26.69*F_cm*(M_m*state.T)^0.5/(sigma_m^2*OMEGA_v); // "1e-6 poise unit = 1-7 " "9-5.24" + // eta := eta/10^7; // from "mu poise" to "Pa s" + + // Modelica.Utilities.Streams.print("got OMEGA_v = " + String(OMEGA_v)); + // Modelica.Utilities.Streams.print("got sigma_m = " + String(sigma_m)); + // Modelica.Utilities.Streams.print("got epsilon_m_K = " + String(epsilon_m_K)); + // Modelica.Utilities.Streams.print("got M_m = " + String(M_m)); + // Modelica.Utilities.Streams.print("got omega_m = " + String(omega_m)); + // Modelica.Utilities.Streams.print("got DM_rm = " + String(DM_rm)); + + // "extention to dense (high pressure)" + + MMm :=yi*MM[1] + yj*MM[2]; + + // we always have liquid or vapor, no two-phase + + // if state.q <= 1 and state.q>=0 then // two-phase state + // rho :=state.sat.dv/(MMm*1e-3)/(1e6); // from kg/m3 to mol/cm3 + // //rho = state.dv / (MMm * 1e-3 [kmol/mol]) / (1e6 [cm^3/m^3]) + // //{rho=0.000001} + // else + rho:=state.d/(MMm*1e-3)/(1e6);// from kg/m3 to mol/cm3 + // end if; + y :=rho*Vcm/6; // "9-6.20" + G1 :=(1 - 0.5*y)/(1 - y)^3; // "9-6.21" + for i in 1:10 loop + E[i] :=a[i] + b[i]*omega_m + c[i]*DM_rm^4 + d[i]*kappa_m; + end for; + G2 :=(E[1]*((1 - exp(-E[4]*y))/y) + E[2]*G1*exp(E[5]*y) + E[3]*G1)/(E[1]*E[4] + + E[2] + E[3]); // "9-6.22" + eta_star_star :=E[7]*y^2*G2*exp(E[8] + E[9]*T_star_m^(-1) + E[10]*T_star_m^(-2)); // "9-6.23" + eta_star :=T_star_m^0.5/OMEGA_v*F_cm*(G2^(-1) + E[6]*y) + eta_star_star; // "9-6.19" + eta := eta_star*36.344*(M_m*Tcm)^0.5/Vcm^(2/3); // "9-6.18" + eta := eta/10^7; // from "mu poise" to "Pa s" + + end dynamicViscosity_VAPChung; + + function dynamicViscosity_VAPChungPureErrorWeight + "Chung et al. incl. mole-fraction avg. error correction (in Poling 2001)" + extends partialDynamicViscosityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + // constant Real DM[2] = {1.470,1.855}; // dipole moment, debye + constant Real DM[2] = {1.5,1.8}; // dipole moment, debye + constant Real omega[2] = {0.2558,0.3443}; // accentric factor + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + constant Real kappa[2] = {0.0,0.076}; // hydrogen bonding or hydrogen association factor + + Modelica.SIunits.Temperature Tc_dum "critical temperature"; + Modelica.SIunits.Pressure pc_dum "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + Real yi,yj; + + Real sigma_i,sigma_j,sigma_ij,sigma_m; + Real epsilon_i_K,epsilon_j_K,epsilon_ij_K,epsilon_m_K; + Real M_ij,M_m,omega_ij,omega_m; + Real DM_m, Vcm, Tcm, DM_rm, kappa_m, F_cm, T_star_m, OMEGA_v; + Real MMm, rho, y, G1, G2, eta_star_star, eta_star; + Real E[10]; + + constant Real a[10] = {6.324,1.210e-3,5.283,6.623,19.745,-1.900,24.275,0.7972,-0.2382,0.06863}; + constant Real b[10] = {50.412,-1.154e-3,254.209,38.096,7.630,-12.537,3.450,1.117,0.06770,0.3479}; + constant Real c[10] = {-51.680,-6.257e-3,-168.48,-8.464,-14.354,4.985,-11.291,0.01235,-0.8163,0.5926}; + constant Real d[10] = {1189.0,0.03728,3898.0,31.42,31.53,-18.15,69.35,-4.117,4.025,-0.727}; + + ThermodynamicState state_2,state_1; + SaturationProperties sat_2; + Real eta_1,eta_2, eta_1actual,eta_2actual; + + package Pure + function eta + + input Real DM; + input Real Vc; + input Real Tc; + input Real omega; + input Real kappa; + input Real MM; + input Real T; + input Real rho; + + output Real eta; + + protected + Real DM_r,F_c,T_star, y, G1, G2, eta_star_star, eta_star, OMEGA_v; + Real E[10]; + + constant Real a[10] = {6.324,1.210e-3,5.283,6.623,19.745,-1.900,24.275,0.7972,-0.2382,0.06863}; + constant Real b[10] = {50.412,-1.154e-3,254.209,38.096,7.630,-12.537,3.450,1.117,0.06770,0.3479}; + constant Real c[10] = {-51.680,-6.257e-3,-168.48,-8.464,-14.354,4.985,-11.291,0.01235,-0.8163,0.5926}; + constant Real d[10] = {1189.0,0.03728,3898.0,31.42,31.53,-18.15,69.35,-4.117,4.025,-0.727}; + + algorithm + // "! pure values used for error weighting" + DM_r :=131.3*DM/(Vc*Tc)^0.5; // "9-4.12" + F_c :=1 - 0.2756*omega + 0.059035*DM_r^4 + kappa; // "9-4.11" + T_star :=1.2593*T/Tc; // "9-4.9" + OMEGA_v:=1.16145*T_star^(-0.14874) + 0.52487*exp(-0.77320*T_star) + 2.16178 + *exp(-2.43787*T_star); // "9-4.3" + + y :=rho*Vc/6; // "9-6.20" + G1 :=(1 - 0.5*y)/(1 - y)^3; // "9-6.21" + for i in 1:10 loop + E[i] :=a[i] + b[i]*omega + c[i]*DM_r^4 + d[i]*kappa; + end for; + G2 :=(E[1]*((1 - exp(-E[4]*y))/y) + E[2]*G1*exp(E[5]*y) + E[3]*G1)/(E[1]*E[4] + + E[2] + E[3]); //"9-6.22" + eta_star_star :=E[7]*y^2*G2*exp(E[8] + E[9]*T_star^(-1) + E[10]*T_star^(-2)); // "9-6.23" + eta_star :=T_star^0.5/OMEGA_v*F_c*(G2^(-1) + E[6]*y) + eta_star_star; // "9-6.19" + eta :=eta_star*36.344*(MM*Tc)^0.5/Vc^(2/3); // "9-6.18" + eta := eta/10^7; // from "mu poise" to "Pa s" + end eta; + + end Pure; + + algorithm + (Tc_dum,pc_dum,Z) :=criticalProperties_sassen1990(state.X); + + yi :=Z[1]; + yj :=Z[2]; + + sigma_i:=0.809*Vc[1]^(1/3); // "9-5.32"; + sigma_j:=0.809*Vc[2]^(1/3); // "9-5.32" + sigma_ij:=(sigma_i*sigma_j)^0.5; // "9-5.33" + sigma_m :=(yi*yi*sigma_i^3 + yj*yj*sigma_j^3 + 2*yi*yj*sigma_ij^3)^(1/3); // "9-5.24" + + epsilon_i_K :=Tc[1]/1.2593; // "9-5.34" + epsilon_j_K :=Tc[2]/1.2593; // "9-5.34" + epsilon_ij_K :=(epsilon_i_K*epsilon_j_K)^0.5; // "9-5.35" + epsilon_m_K :=(yi*yi*epsilon_i_K*sigma_i^3 + yj*yj*epsilon_j_K*sigma_j^3 + 2* + yi*yj*epsilon_ij_K*sigma_ij^3)/sigma_m^3; // "9-5.27" + + M_ij :=2*MM[1]*MM[2]/(MM[1] + MM[2]); // "9-5.40" + M_m :=((yi*yi*epsilon_i_K*sigma_i^2*MM[1]^0.5 + yj*yj*epsilon_j_K*sigma_j^2* + MM[2]^0.5 + 2*yi*yj*epsilon_ij_K*sigma_ij^2*M_ij^0.5)/(epsilon_m_K*sigma_m^2)) + ^2; // "9-5.28" + + omega_ij:=(omega[1] + omega[2])/2; + omega_m :=(yi*yi*omega[1]*sigma_i^3 + yj*yj*omega[2]*sigma_j^3 + 2*yi*yj* + omega_ij*sigma_ij^3)/sigma_m^3; // "9-5.29" + + DM_m :=(sigma_m^3*(yi*yi*DM[1]^4/sigma_i^3 + yj*yj*DM[2]^4/sigma_j^3 + 2*yi* + yj*DM[1]^2*DM[2]^2/sigma_ij^3))^(1/4); // "9-5.30" + Vcm :=(sigma_m/0.809)^3; // "9-5.44" + Tcm :=1.2593*epsilon_m_K; // "9-5.42" + DM_rm :=131.3*DM_m/(Vcm*Tcm)^0.5; // "9-5.43" + kappa_m :=yi*yi*kappa[1] + yj*yj*kappa[2] + 2*yi*yj*(kappa[1]*kappa[2])^0.5; // "9-5.31" + F_cm :=1 - 0.275*omega_m + 0.059035*DM_rm^4 + kappa_m; // "9-5.41" + + T_star_m := state.T/epsilon_m_K; + OMEGA_v:=1.16145*T_star_m^(-0.14874) + 0.52487*exp(-0.77320*T_star_m) + 2.16178 + *exp(-2.43787*T_star_m); // "9-4.3" + + // eta :=26.69*F_cm*(M_m*state.T)^0.5/(sigma_m^2*OMEGA_v); // "1e-6 poise unit = 1-7 " "9-5.24" + // eta := eta/10^7; // from "mu poise" to "Pa s" + + // Modelica.Utilities.Streams.print("got OMEGA_v = " + String(OMEGA_v)); + // Modelica.Utilities.Streams.print("got sigma_m = " + String(sigma_m)); + // Modelica.Utilities.Streams.print("got epsilon_m_K = " + String(epsilon_m_K)); + // Modelica.Utilities.Streams.print("got M_m = " + String(M_m)); + // Modelica.Utilities.Streams.print("got omega_m = " + String(omega_m)); + // Modelica.Utilities.Streams.print("got DM_rm = " + String(DM_rm)); + + // "extention to dense (high pressure)" + + MMm :=yi*MM[1] + yj*MM[2]; + + // we always have liquid or vapor, no two-phase + + // if state.q <= 1 and state.q>=0 then // two-phase state + // rho :=state.sat.dv/(MMm*1e-3)/(1e6); // from kg/m3 to mol/cm3 + // //rho = state.dv / (MMm * 1e-3 [kmol/mol]) / (1e6 [cm^3/m^3]) + // //{rho=0.000001} + // else + rho:=state.d/(MMm*1e-3)/(1e6);// from kg/m3 to mol/cm3 + // end if; + y :=rho*Vcm/6; // "9-6.20" + G1 :=(1 - 0.5*y)/(1 - y)^3; // "9-6.21" + for i in 1:10 loop + E[i] :=a[i] + b[i]*omega_m + c[i]*DM_rm^4 + d[i]*kappa_m; + end for; + G2 :=(E[1]*((1 - exp(-E[4]*y))/y) + E[2]*G1*exp(E[5]*y) + E[3]*G1)/(E[1]*E[4] + + E[2] + E[3]); // "9-6.22" + eta_star_star :=E[7]*y^2*G2*exp(E[8] + E[9]*T_star_m^(-1) + E[10]*T_star_m^(-2)); // "9-6.23" + eta_star :=T_star_m^0.5/OMEGA_v*F_cm*(G2^(-1) + E[6]*y) + eta_star_star; // "9-6.19" + eta := eta_star*36.344*(M_m*Tcm)^0.5/Vcm^(2/3); // "9-6.18" + eta := eta/10^7; // from "mu poise" to "Pa s" + + // error weighting + // get corresponding values of pure components + + state_1 :=setState_pTX( + state.p, + state.T, + {1,0}, + calcTransport=true); + if state.T < Tc[2]-1 then // + sat_2 := setSat_TX(state.T, {0,1}); + state_2 :=setState_pTX( + min(state.p,sat_2.psat-1), + state.T, + {0,1}, + calcTransport=true); + else + state_2 :=setState_pTX( + state.p, + state.T, + {0,1}, + calcTransport=true); + end if; + // if state.p < 22064000 then + // sat_2 := setSat_pX(state.p, {0,1}); + // state_2 :=setState_pTX( + // state.p, + // max(state.T,sat_2.Tsat+0.1), + // {0,1}, + // calcTransport=true); + // else + // state_2 :=setState_pTX( + // state.p, + // state.T, + // {0,1}, + // calcTransport=true); + // end if; + + eta_1 :=Pure.eta( + DM[1], + Vc[1], + Tc[1], + omega[1], + kappa[1], + MM[1], + state.T, + rho); // using mixture rho to do the averaging + eta_2 :=Pure.eta( + DM[2], + Vc[2], + Tc[2], + omega[2], + kappa[2], + MM[2], + state.T, + rho); // using mixture rho to do the averaging + + // Modelica.Utilities.Streams.print("got eta_1 = " + String(eta_1)); + // Modelica.Utilities.Streams.print("got state_1.eta = " + String(state_1.eta)); + // Modelica.Utilities.Streams.print("got eta_2 = " + String(eta_2)); + // Modelica.Utilities.Streams.print("got state_2.eta = " + String(state_2.eta)); + + eta := eta + (state_1.eta-eta_1)*yi + (state_2.eta-eta_2)*yj; + + end dynamicViscosity_VAPChungPureErrorWeight; + + partial function partialThermalConductivityVapor + end partialThermalConductivityVapor; + + function thermalConductivity_VAPWilke "Mason and Saxena (in Poling 2001)" + extends partialThermalConductivityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + SaturationProperties sat_w; + ThermodynamicState state_w; + ThermodynamicState state_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + constant Real Mw=18.0153; + // Molar mass of water, g/mol + constant Real Ma=17.0305; + // Molar mass of ammonia, g/mol + + Modelica.SIunits.DynamicViscosity mu_a; + Modelica.SIunits.ThermalConductivity lambda_a; + Modelica.SIunits.DynamicViscosity mu_w; + Modelica.SIunits.ThermalConductivity lambda_w; + + Real F12; + Real F21; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + // it will always be vapor or supercritical! + state_a := setState_pTX( + state.p, + state.T, + {1,0}, + calcTransport=true); + + if state.T < Tc_w - 1 then + // + sat_w := setSat_TX(state.T, {0,1}); + state_w := setState_pTX( + min(state.p, sat_w.psat - 1), + state.T, + {0,1}, + calcTransport=true); + else + state_w := setState_pTX( + state.p, + state.T, + {0,1}, + calcTransport=true); + end if; + + mu_a := state_a.eta; + mu_w := state_w.eta; + + mu_a := mu_a*1e6; + //convert to (1e-6 Pa.s) + mu_w := mu_w*1e6; + //convert to (1e-6 Pa.s) + + F12 := ((1 + (sqrt(mu_a/mu_w)*((Mw/Ma)^0.25)))^2)/sqrt(8*(1 + (Ma/Mw))); + F21 := F12*(mu_w/mu_a)*(Ma/Mw); + + lambda_a := state_a.lambda; + lambda_w := state_w.lambda; + + lambda := ((lambda_a*Z[1])/(Z[1] + (F12*Z[2]))) + ((lambda_w*Z[2])/(Z[2] + ( + F21*Z[1]))); + + // Mixture vapour th. cond., W/(m K), Thorin, 2001 + + end thermalConductivity_VAPWilke; + + function thermalConductivity_VAPLinearMolePoling + "Mole-fraction average (suggested in Poling 2001)" + extends partialThermalConductivityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + SaturationProperties sat_w; + ThermodynamicState state_w; + ThermodynamicState state_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + + Modelica.SIunits.ThermalConductivity lambda_a; + Modelica.SIunits.ThermalConductivity lambda_w; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + // it will always be vapor or supercritical! + state_a := setState_pTX( + state.p, + state.T, + {1,0}, + calcTransport=true); + + if state.T < Tc_w - 1 then + // + sat_w := setSat_TX(state.T, {0,1}); + state_w := setState_pTX( + min(state.p, sat_w.psat - 1), + state.T, + {0,1}, + calcTransport=true); + else + state_w := setState_pTX( + state.p, + state.T, + {0,1}, + calcTransport=true); + end if; + + lambda_a := state_a.lambda; + lambda_w := state_w.lambda; + + lambda := lambda_a*Z[1] + lambda_w*Z[2]; + + end thermalConductivity_VAPLinearMolePoling; + + function thermalConductivity_VAPChung "Chung et al. (in Poling 2001)" + extends partialThermalConductivityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + // constant Real DM[2] = {1.470,1.855}; // dipole moment, debye + constant Real DM[2] = {1.5,1.8}; // dipole moment, debye + constant Real omega[2] = {0.2558,0.3443}; // accentric factor + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + constant Real kappa[2] = {0.0,0.076}; // hydrogen bonding or hydrogen association factor + Real Cv[2]; // ideal gas specfic volume + constant Real beta[2] = {1.08^(-1),0.78^(-1)}; // hydrogen bonding or hydrogen association factor + + Modelica.SIunits.Temperature Tc_dum "critical temperature"; + Modelica.SIunits.Pressure pc_dum "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + Real yi,yj; + + Real sigma_i,sigma_j,sigma_ij,sigma_m; + Real epsilon_i_K,epsilon_j_K,epsilon_ij_K,epsilon_m_K; + Real M_ij,M_m,omega_ij,omega_m; + Real DM_m, Vcm, Tcm, DM_rm, kappa_m, F_cm, T_star_m, OMEGA_v; + Real MMm, rho, y_m, G1, G2, q, PSI_m, alpha_m, beta_m, Z_m, C_vm; + Real B[7]; + Real eta_m0, lambda_m0; + + constant Real a[7] = {2.4166,-0.50924,6.6107,14.543,0.79274,-5.8634,91.089}; + constant Real b[7] = {0.74824,-1.5094,5.6207,-8.9139,0.82019,12.801,128.11}; + constant Real c[7] = {-0.91858,-49.991,64.76,-5.6379,-0.69369,9.5893,-54.217}; + constant Real d[7] = {121.72,69.983,27.039,74.344,6.3173,65.529,523.81}; + + algorithm + (Tc_dum,pc_dum,Z) :=criticalProperties_sassen1990(state.X); + + yi :=Z[1]; + yj :=Z[2]; + + // first mix visc + sigma_i:=0.809*Vc[1]^(1/3); // "9-5.32"; + sigma_j:=0.809*Vc[2]^(1/3); // "9-5.32" + sigma_ij:=(sigma_i*sigma_j)^0.5; // "9-5.33" + sigma_m :=(yi*yi*sigma_i^3 + yj*yj*sigma_j^3 + 2*yi*yj*sigma_ij^3)^(1/3); // "9-5.24" + + epsilon_i_K :=Tc[1]/1.2593; // "9-5.34" + epsilon_j_K :=Tc[2]/1.2593; // "9-5.34" + epsilon_ij_K :=(epsilon_i_K*epsilon_j_K)^0.5; // "9-5.35" + epsilon_m_K :=(yi*yi*epsilon_i_K*sigma_i^3 + yj*yj*epsilon_j_K*sigma_j^3 + 2* + yi*yj*epsilon_ij_K*sigma_ij^3)/sigma_m^3; // "9-5.27" + + M_ij :=2*MM[1]*MM[2]/(MM[1] + MM[2]); // "9-5.40" + M_m :=((yi*yi*epsilon_i_K*sigma_i^2*MM[1]^0.5 + yj*yj*epsilon_j_K*sigma_j^2* + MM[2]^0.5 + 2*yi*yj*epsilon_ij_K*sigma_ij^2*M_ij^0.5)/(epsilon_m_K*sigma_m^2)) + ^2; // "9-5.28" + + omega_ij:=(omega[1] + omega[2])/2; + omega_m :=(yi*yi*omega[1]*sigma_i^3 + yj*yj*omega[2]*sigma_j^3 + 2*yi*yj* + omega_ij*sigma_ij^3)/sigma_m^3; // "9-5.29" + + DM_m :=(sigma_m^3*(yi*yi*DM[1]^4/sigma_i^3 + yj*yj*DM[2]^4/sigma_j^3 + 2*yi* + yj*DM[1]^2*DM[2]^2/sigma_ij^3))^(1/4); // "9-5.30" + Vcm :=(sigma_m/0.809)^3; // "9-5.44" + Tcm :=1.2593*epsilon_m_K; // "9-5.42" + DM_rm :=131.3*DM_m/(Vcm*Tcm)^0.5; // "9-5.43" + kappa_m :=yi*yi*kappa[1] + yj*yj*kappa[2] + 2*yi*yj*(kappa[1]*kappa[2])^0.5; // "9-5.31" + F_cm :=1 - 0.275*omega_m + 0.059035*DM_rm^4 + kappa_m; // "9-5.41" + + T_star_m := state.T/epsilon_m_K; + OMEGA_v:=1.16145*T_star_m^(-0.14874) + 0.52487*exp(-0.77320*T_star_m) + 2.16178 + *exp(-2.43787*T_star_m); // "9-4.3" + + eta_m0 := 26.69*F_cm*(M_m*state.T)^0.5/(sigma_m^2*OMEGA_v) * 1e-7; // "1e-6 poise unit = 1-7 " "9-5.24" + + // second mix cond + + Cv[1] :=(4.238 - 4.215e-3*state.T + 2.041e-5*state.T^2 - 2.126*1e-8*state.T^3 + + 0.761e-11*state.T^4)*8.314 - 8.314; + Cv[2] :=(4.395 - 4.186e-3*state.T + 1.405e-5*state.T^2 - 1.564*1e-8*state.T^3 + + 0.632e-11*state.T^4)*8.314 - 8.314; + C_vm :=yi*Cv[1] + yj*Cv[2]; // "10-6.6" + alpha_m :=C_vm/8.314 - 1.5;// "10-3.14" + //beta_m = 0.7862 - 0.7109*omega_m + 1.3168*omega_m^2 "10-3.14" + /* + For polar materials beta is specific for each compound; Chung, et al. (1984) list values for a few materials. If the compound is polar and + is not available,use a default value of (1.32)^(-1)=0.758 + "! how to deal with beta_m for polar mixtures???????" + "! I would choose similar mixture rules as for sigma, epsilon and kappa how to deal with beta_m for polar mixtures???????" + */ + beta_m :=yi*yi*beta[1] + yj*yj*beta[2] + 2*yi*yj*(beta[1]*beta[2])^0.5; + Z_m :=2 + 10.5*(state.T/Tcm)^2; // "10-3.14" + PSI_m :=1 + alpha_m*(0.215 + 0.28288*alpha_m - 1.061*beta_m + 0.26665*Z_m)/(0.6366 + + beta_m*Z_m + 1.061*alpha_m*beta_m); // "10-3.14" + lambda_m0 :=3.75*PSI_m/(C_vm/8.314)*eta_m0*C_vm/(M_m*1e-3); // "10-3.14" + + // Modelica.Utilities.Streams.print("got OMEGA_v = " + String(OMEGA_v)); + // Modelica.Utilities.Streams.print("got sigma_m = " + String(sigma_m)); + // Modelica.Utilities.Streams.print("got epsilon_m_K = " + String(epsilon_m_K)); + // Modelica.Utilities.Streams.print("got M_m = " + String(M_m)); + // Modelica.Utilities.Streams.print("got omega_m = " + String(omega_m)); + // Modelica.Utilities.Streams.print("got DM_rm = " + String(DM_rm)); + + // "extention to dense (high pressure)" + + MMm :=yi*MM[1] + yj*MM[2]; + + // //this is just to make sure calculation is done right (is gas) if two-phase.. + // if state.q <= 1 and state.q>=0 then // two-phase state + // rho :=state.sat.dv/(MMm*1e-3)/(1e6); // from kg/m3 to mol/cm3 + // //rho = state.dv / (MMm * 1e-3 [kmol/mol]) / (1e6 [cm^3/m^3]) + // //{rho=0.000001} + // else + rho:=state.d/(MMm*1e-3)/(1e6);// from kg/m3 to mol/cm3 + // end if; + + y_m :=rho*Vcm/6; // "9-6.20" + G1 :=(1 - 0.5*y_m)/(1 - y_m)^3; // "9-6.21" + for i in 1:7 loop + B[i] :=a[i] + b[i]*omega_m + c[i]*DM_rm^4 + d[i]*kappa_m; + end for; + G2 :=(B[1]*((1 - exp(-B[4]*y_m))/y_m) + B[2]*G1*exp(B[5]*y_m) + B[3]*G1)/(B[1]*B[4] + + B[2] + B[3]); // "9-6.22" + + q :=3.586e-3*(Tcm/(M_m*1e-3))^0.5/Vcm^(2/3); + lambda :=31.2*eta_m0*PSI_m/(M_m*1e-3)*(G2^(-1) + B[6]*y_m) + q*B[7]*y_m^2*(state.T/ + Tcm)^0.5*G2; // "10-5.5" + + end thermalConductivity_VAPChung; + + function thermalConductivity_VAPChungPureErrorWeight + "Chung et al. incl. mole-fraction avg. error correction (in Poling 2001)" + extends partialThermalConductivityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + // constant Real DM[2] = {1.470,1.855}; // dipole moment, debye + constant Real DM[2] = {1.5,1.8}; // dipole moment, debye + constant Real omega[2] = {0.2558,0.3443}; // accentric factor + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + constant Real kappa[2] = {0.0,0.076}; // hydrogen bonding or hydrogen association factor + Real Cv[2]; // ideal gas specfic volume + constant Real beta[2] = {1.08^(-1),0.78^(-1)}; // hydrogen bonding or hydrogen association factor + + Modelica.SIunits.Temperature Tc_dum "critical temperature"; + Modelica.SIunits.Pressure pc_dum "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + Real yi,yj; + + Real sigma_i,sigma_j,sigma_ij,sigma_m; + Real epsilon_i_K,epsilon_j_K,epsilon_ij_K,epsilon_m_K; + Real M_ij,M_m,omega_ij,omega_m; + Real DM_m, Vcm, Tcm, DM_rm, kappa_m, F_cm, T_star_m, OMEGA_v; + Real MMm, rho, y_m, G1, G2, q, PSI_m, alpha_m, beta_m, Z_m, C_vm; + Real B[7]; + Real eta_m0, lambda_m0; + + constant Real a[7] = {2.4166,-0.50924,6.6107,14.543,0.79274,-5.8634,91.089}; + constant Real b[7] = {0.74824,-1.5094,5.6207,-8.9139,0.82019,12.801,128.11}; + constant Real c[7] = {-0.91858,-49.991,64.76,-5.6379,-0.69369,9.5893,-54.217}; + constant Real d[7] = {121.72,69.983,27.039,74.344,6.3173,65.529,523.81}; + + ThermodynamicState state_1,state_2; + SaturationProperties sat_2; + Real lambda_1,lambda_2,lambda_1actual,lambda_2actual; + + package Pure + function lambda + + input Real DM; + input Real Vc; + input Real Tc; + input Real omega; + input Real kappa; + input Real MM; + input Real T; + input Real rho; + input Real Cv; + input Real beta; + + output Real lambda; + + protected + Real DM_r,F_c,T_star, y, G1, G2, eta_star_star, eta_star, OMEGA_v; + Real B[7]; + + Real eta_0,lambda_0,PSI,Z,alpha,q; + + constant Real a[7] = {2.4166,-0.50924,6.6107,14.543,0.79274,-5.8634,91.089}; + constant Real b[7] = {0.74824,-1.5094,5.6207,-8.9139,0.82019,12.801,128.11}; + constant Real c[7] = {-0.91858,-49.991,64.76,-5.6379,-0.69369,9.5893,-54.217}; + constant Real d[7] = {121.72,69.983,27.039,74.344,6.3173,65.529,523.81}; + algorithm + // "! pure values used for error weighting" + DM_r :=131.3*DM/(Vc*Tc)^0.5; // "9-4.12" + F_c :=1 - 0.2756*omega + 0.059035*DM_r^4 + kappa; // "9-4.11" + T_star :=1.2593*T/Tc; // "9-4.9" + OMEGA_v:=1.16145*T_star^(-0.14874) + 0.52487*exp(-0.77320*T_star) + 2.16178 + *exp(-2.43787*T_star); // "9-4.3" + + eta_0 :=(40.785*F_c*(MM*T)^0.5/(Vc^(2/3)*OMEGA_v))*1e-7; // "1e-6 poise unit = 1-7 " "9-4.10" + + //"! Then thermal conductivity by Chung" + alpha :=Cv/8.314 - 1.5; + Z :=2 + 10.5*(T/Tc)^2; + PSI:=1 + alpha*(0.215 + 0.28288*alpha - 1.061*beta + 0.26665*Z)/(0.6366 + + beta*Z + 1.061*alpha*beta); + lambda_0 :=3.75*PSI/(Cv/8.314)*eta_0*Cv/(MM*1e-3); // "10-3.14" + + /* +For polar materials beta is specific for each compound; Chung, et al. (1984) list values for a few materials. If the compound is polar and +is not available,use a default value of (1.32)^(-1)=0.758 +*/ + y :=rho*Vc/6; // "9-6.20" + G1 :=(1 - 0.5*y)/(1 - y)^3; // "9-6.21" + for i in 1:7 loop + B[i] :=a[i] + b[i]*omega + c[i]*DM_r^4 + d[i]*kappa; + end for; + G2 :=(B[1]*((1 - exp(-B[4]*y))/y) + B[2]*G1*exp(B[5]*y) + B[3]*G1)/(B[1]*B[4] + + B[2] + B[3]); //"9-6.22" + + q :=3.586e-3*(Tc/(MM*1e-3))^0.5/Vc^(2/3); + lambda :=31.2*eta_0*PSI/(MM*1e-3)*(G2^(-1) + B[6]*y) + q*B[7]*y^2*(T/Tc)^0.5* + G2; // "10-5.5" + + end lambda; + + end Pure; + + algorithm + (Tc_dum,pc_dum,Z) :=criticalProperties_sassen1990(state.X); + + yi :=Z[1]; + yj :=Z[2]; + + // first mix visc + sigma_i:=0.809*Vc[1]^(1/3); // "9-5.32"; + sigma_j:=0.809*Vc[2]^(1/3); // "9-5.32" + sigma_ij:=(sigma_i*sigma_j)^0.5; // "9-5.33" + sigma_m :=(yi*yi*sigma_i^3 + yj*yj*sigma_j^3 + 2*yi*yj*sigma_ij^3)^(1/3); // "9-5.24" + + epsilon_i_K :=Tc[1]/1.2593; // "9-5.34" + epsilon_j_K :=Tc[2]/1.2593; // "9-5.34" + epsilon_ij_K :=(epsilon_i_K*epsilon_j_K)^0.5; // "9-5.35" + epsilon_m_K :=(yi*yi*epsilon_i_K*sigma_i^3 + yj*yj*epsilon_j_K*sigma_j^3 + 2* + yi*yj*epsilon_ij_K*sigma_ij^3)/sigma_m^3; // "9-5.27" + + M_ij :=2*MM[1]*MM[2]/(MM[1] + MM[2]); // "9-5.40" + M_m :=((yi*yi*epsilon_i_K*sigma_i^2*MM[1]^0.5 + yj*yj*epsilon_j_K*sigma_j^2* + MM[2]^0.5 + 2*yi*yj*epsilon_ij_K*sigma_ij^2*M_ij^0.5)/(epsilon_m_K*sigma_m^2)) + ^2; // "9-5.28" + + omega_ij:=(omega[1] + omega[2])/2; + omega_m :=(yi*yi*omega[1]*sigma_i^3 + yj*yj*omega[2]*sigma_j^3 + 2*yi*yj* + omega_ij*sigma_ij^3)/sigma_m^3; // "9-5.29" + + DM_m :=(sigma_m^3*(yi*yi*DM[1]^4/sigma_i^3 + yj*yj*DM[2]^4/sigma_j^3 + 2*yi* + yj*DM[1]^2*DM[2]^2/sigma_ij^3))^(1/4); // "9-5.30" + Vcm :=(sigma_m/0.809)^3; // "9-5.44" + Tcm :=1.2593*epsilon_m_K; // "9-5.42" + DM_rm :=131.3*DM_m/(Vcm*Tcm)^0.5; // "9-5.43" + kappa_m :=yi*yi*kappa[1] + yj*yj*kappa[2] + 2*yi*yj*(kappa[1]*kappa[2])^0.5; // "9-5.31" + F_cm :=1 - 0.275*omega_m + 0.059035*DM_rm^4 + kappa_m; // "9-5.41" + + T_star_m := state.T/epsilon_m_K; + OMEGA_v:=1.16145*T_star_m^(-0.14874) + 0.52487*exp(-0.77320*T_star_m) + 2.16178 + *exp(-2.43787*T_star_m); // "9-4.3" + + eta_m0 := 26.69*F_cm*(M_m*state.T)^0.5/(sigma_m^2*OMEGA_v) * 1e-7; // "1e-6 poise unit = 1-7 " "9-5.24" + + // second mix cond + + Cv[1] :=(4.238 - 4.215e-3*state.T + 2.041e-5*state.T^2 - 2.126*1e-8*state.T^3 + + 0.761e-11*state.T^4)*8.314 - 8.314; + Cv[2] :=(4.395 - 4.186e-3*state.T + 1.405e-5*state.T^2 - 1.564*1e-8*state.T^3 + + 0.632e-11*state.T^4)*8.314 - 8.314; + C_vm :=yi*Cv[1] + yj*Cv[2]; // "10-6.6" + alpha_m :=C_vm/8.314 - 1.5;// "10-3.14" + //beta_m = 0.7862 - 0.7109*omega_m + 1.3168*omega_m^2 "10-3.14" + /* + For polar materials beta is specific for each compound; Chung, et al. (1984) list values for a few materials. If the compound is polar and + is not available,use a default value of (1.32)^(-1)=0.758 + "! how to deal with beta_m for polar mixtures???????" + "! I would choose similar mixture rules as for sigma, epsilon and kappa how to deal with beta_m for polar mixtures???????" + */ + beta_m :=yi*yi*beta[1] + yj*yj*beta[2] + 2*yi*yj*(beta[1]*beta[2])^0.5; + Z_m :=2 + 10.5*(state.T/Tcm)^2; // "10-3.14" + PSI_m :=1 + alpha_m*(0.215 + 0.28288*alpha_m - 1.061*beta_m + 0.26665*Z_m)/(0.6366 + + beta_m*Z_m + 1.061*alpha_m*beta_m); // "10-3.14" + lambda_m0 :=3.75*PSI_m/(C_vm/8.314)*eta_m0*C_vm/(M_m*1e-3); // "10-3.14" + + // Modelica.Utilities.Streams.print("got OMEGA_v = " + String(OMEGA_v)); + // Modelica.Utilities.Streams.print("got sigma_m = " + String(sigma_m)); + // Modelica.Utilities.Streams.print("got epsilon_m_K = " + String(epsilon_m_K)); + // Modelica.Utilities.Streams.print("got M_m = " + String(M_m)); + // Modelica.Utilities.Streams.print("got omega_m = " + String(omega_m)); + // Modelica.Utilities.Streams.print("got DM_rm = " + String(DM_rm)); + + // "extention to dense (high pressure)" + + MMm :=yi*MM[1] + yj*MM[2]; + + // this is just to make sure calculation is done right (is gas) if two-phase.. + // if state.q <= 1 and state.q>=0 then // two-phase state + // rho :=state.sat.dv/(MMm*1e-3)/(1e6); // from kg/m3 to mol/cm3 + // //rho = state.dv / (MMm * 1e-3 [kmol/mol]) / (1e6 [cm^3/m^3]) + // //{rho=0.000001} + // else + rho:=state.d/(MMm*1e-3)/(1e6);// from kg/m3 to mol/cm3 + // end if; + + y_m :=rho*Vcm/6; // "9-6.20" + G1 :=(1 - 0.5*y_m)/(1 - y_m)^3; // "9-6.21" + for i in 1:7 loop + B[i] :=a[i] + b[i]*omega_m + c[i]*DM_rm^4 + d[i]*kappa_m; + end for; + G2 :=(B[1]*((1 - exp(-B[4]*y_m))/y_m) + B[2]*G1*exp(B[5]*y_m) + B[3]*G1)/(B[1]*B[4] + + B[2] + B[3]); // "9-6.22" + + q :=3.586e-3*(Tcm/(M_m*1e-3))^0.5/Vcm^(2/3); + lambda :=31.2*eta_m0*PSI_m/(M_m*1e-3)*(G2^(-1) + B[6]*y_m) + q*B[7]*y_m^2*(state.T/ + Tcm)^0.5*G2; // "10-5.5" + + // error weighting + // get corresponding values of pure components + + state_1 :=setState_pTX( + state.p, + state.T, + {1,0}, + calcTransport=true); + if state.T < Tc[2]-1 then // + sat_2 := setSat_TX(state.T, {0,1}); + state_2 :=setState_pTX( + min(state.p,sat_2.psat-1), + state.T, + {0,1}, + calcTransport=true); + else + state_2 :=setState_pTX( + state.p, + state.T, + {0,1}, + calcTransport=true); + end if; + + lambda_1 :=Pure.lambda( + DM[1], + Vc[1], + Tc[1], + omega[1], + kappa[1], + MM[1], + state.T, + rho, + Cv[1], + beta[1]); + lambda_2 :=Pure.lambda( + DM[2], + Vc[2], + Tc[2], + omega[2], + kappa[2], + MM[2], + state.T, + rho, + Cv[2], + beta[2]); + + // Modelica.Utilities.Streams.print("got eta_1 = " + String(eta_1)); + // Modelica.Utilities.Streams.print("got state_1.eta = " + String(state_1.eta)); + // Modelica.Utilities.Streams.print("got eta_2 = " + String(eta_2)); + // Modelica.Utilities.Streams.print("got state_2.eta = " + String(state_2.eta)); + + lambda_1actual:=state_1.lambda; + lambda_2actual:=state_2.lambda; + + lambda := lambda + (state_1.lambda-lambda_1)*yi + (state_2.lambda-lambda_2)*yj; + + end thermalConductivity_VAPChungPureErrorWeight; + + partial function partialThermalConductivityLiquid + end partialThermalConductivityLiquid; + + function thermalConductivity_LIQLinearMoleElsayed "El-Sayed 1988" + + extends partialThermalConductivityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + Modelica.SIunits.Temperature Tcorr_a "Corresponding temp. for ammonia, K"; + Modelica.SIunits.Temperature Tcorr_w "Corresponding temp. for water, K"; + + Modelica.SIunits.ThermalConductivity lambda_a; + Modelica.SIunits.ThermalConductivity lambda_w; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + Tcorr_a := state.T*Tc_a/Tc "Corresponding temp. for ammonia, K"; + Tcorr_w := state.T*Tc_w/Tc "Corresponding temp. for water, K"; + + if debugmode then + Modelica.Utilities.Streams.print("got (Tc,pc,Tcorr_a,Tcorr_w), (" + + String(Tc) + "," + String(pc) + "," + String(Tcorr_a) + "," + String( + Tcorr_w) + ")"); + end if; + + state_a := setState_TqX( + min(Tc_a - 1, Tcorr_a), + 0, + {1,0}, + calcTransport=true); + state_w := setState_TqX( + min(Tcorr_w, Tc_w - 1), + 0, + {0,1}, + calcTransport=true); + + lambda_a := state_a.lambda; + lambda_w := state_w.lambda; + + lambda := lambda_a*Z[1] + lambda_w*Z[2]; + + end thermalConductivity_LIQLinearMoleElsayed; + + function thermalConductivity_LIQConde "Conde 2006" + + extends partialThermalConductivityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + Modelica.SIunits.Temperature Tcorr_a "Corresponding temp. for ammonia, K"; + Modelica.SIunits.Temperature Tcorr_w "Corresponding temp. for water, K"; + + Modelica.SIunits.ThermalConductivity lambda_a; + Modelica.SIunits.ThermalConductivity lambda_w; + + Real rho_p1; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + Tcorr_a := state.T*Tc_a/Tc "Corresponding temp. for ammonia, K"; + Tcorr_w := state.T*Tc_w/Tc "Corresponding temp. for water, K"; + + if debugmode then + Modelica.Utilities.Streams.print("got (Tc,pc,Tcorr_a,Tcorr_w), (" + + String(Tc) + "," + String(pc) + "," + String(Tcorr_a) + "," + String( + Tcorr_w) + ")"); + end if; + + state_a := setState_TqX( + min(Tc_a - 1, Tcorr_a), + 0, + {1,0}, + calcTransport=true); + state_w := setState_TqX( + min(Tcorr_w, Tc_w - 1), + 0, + {0,1}, + calcTransport=true); + + lambda_a := state_a.lambda; + lambda_w := state_w.lambda; + + // Modelica.Utilities.Streams.print("got first lambda = " + String(lambda_a)); + + rho_p1 := state_a.d*Z[1]^0.425; + state_a := setState_dqX( + max(rho_p1, 225), + 0, + {1,0}, + calcTransport=true); + + lambda_a := state_a.lambda; + + // Modelica.Utilities.Streams.print("got second lambda = " + String(lambda_a)); + + lambda := lambda_a*Z[1] + lambda_w*Z[2]; + + end thermalConductivity_LIQConde; + + function thermalConductivity_LIQFilipov "Filippov (in Poling 2001)" + + extends partialThermalConductivityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + SaturationProperties sat_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + constant Modelica.SIunits.Pressure pc_a=11333000; + constant Modelica.SIunits.Pressure pc_w=22064000; + + Modelica.SIunits.ThermalConductivity lambda_a; + Modelica.SIunits.ThermalConductivity lambda_w; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + if state.T < Tc_a - 2 then + // + sat_a := setSat_TX(state.T, {1,0}); + state_a := setState_pTX( + max(state.p, sat_a.psat + 10), + state.T, + {1,0}, + calcTransport=true); + else + state_a := setState_pTX( + max(pc_a + 10, state.p), + Tc_a - 2, + {1,0}, + calcTransport=true); + end if; + + // the water will always be liquid + state_w := setState_pTX( + state.p, + min(state.T, Tc_w - 2), + {0,1}, + calcTransport=true); + + lambda_a := state_a.lambda; + lambda_w := state_w.lambda; + + lambda := state.X[1]*lambda_a + state.X[2]*lambda_w - 0.72*state.X[1]*state.X[ + 2]*max(lambda_a - lambda_w, lambda_w - lambda_a); + + end thermalConductivity_LIQFilipov; + + function thermalConductivity_LIQJamie "Jamieson (in Poling 2001)" + + extends partialThermalConductivityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + SaturationProperties sat_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + constant Modelica.SIunits.Pressure pc_a=11333000; + constant Modelica.SIunits.Pressure pc_w=22064000; + + Modelica.SIunits.ThermalConductivity lambda_a; + Modelica.SIunits.ThermalConductivity lambda_w; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + if state.T < Tc_a - 2 then + // + sat_a := setSat_TX(state.T, {1,0}); + state_a := setState_pTX( + max(state.p, sat_a.psat + 10), + state.T, + {1,0}, + calcTransport=true); + else + state_a := setState_pTX( + max(pc_a + 10, state.p), + Tc_a - 2, + {1,0}, + calcTransport=true); + end if; + + // the water will always be liquid + state_w := setState_pTX( + state.p, + min(state.T, Tc_w - 2), + {0,1}, + calcTransport=true); + + lambda_a := state_a.lambda; + lambda_w := state_w.lambda; + + if lambda_a > lambda_w then + lambda := state.X[1]*lambda_a + state.X[2]*lambda_w - (lambda_a - + lambda_w)*(1 - sqrt(state.X[1]))*state.X[1]; + else + lambda := state.X[1]*lambda_a + state.X[2]*lambda_w - (lambda_w - + lambda_a)*(1 - sqrt(state.X[2]))*state.X[2]; + end if; + + end thermalConductivity_LIQJamie; + + function surfaceTensionTX + "Return surface tension, ideal solution based on corresponding temperature" + extends Modelica.Icons.Function; + input Temperature T; + input MassFraction X[nX] + "bulk mass fraction to determine critical T and p"; + output SurfaceTension sigma "Dynamic viscosity"; + + protected + SaturationProperties sat_w; + SaturationProperties sat_a; + + SurfaceTension sigma_w; + SurfaceTension sigma_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a = 405.560; + constant Modelica.SIunits.Temperature Tc_w = 647.096; + Modelica.SIunits.Temperature Tcorr_a "Corresponding temp. for ammonia, K"; + Modelica.SIunits.Temperature Tcorr_w "Corresponding temp. for water, K"; + + constant Modelica.SIunits.Temperature TNH3min=195.5; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(X); + + Tcorr_a := T*Tc_a/Tc "Corresponding temp. for ammonia, K"; + Tcorr_w := T*Tc_w/Tc "Corresponding temp. for water, K"; + + if debugmode then + Modelica.Utilities.Streams.print("got (Tc,pc,Tcorr_a,Tcorr_w), (" + String(Tc) + "," + String(pc) + "," + String(Tcorr_a) + "," + String(Tcorr_w) + ")"); + end if; + + sat_a := setSat_TX( + max(TNH3min,Tcorr_a), + {1,0}, + calcTransport=true); + sat_w := setSat_TX( + Tcorr_w, + {0,1}, + calcTransport=true); + + sigma_a :=sat_a.sigma; + sigma_w :=sat_w.sigma; + + sigma:= sigma_a*Z[1] + sigma_w*Z[2]; + + end surfaceTensionTX; + + redeclare function surfaceTension + "Return surface tension, ideal solution based on corresponding temperature" + extends Modelica.Icons.Function; + input SaturationProperties sat; + output SurfaceTension sigma "Dynamic viscosity"; + + protected + SaturationProperties sat_w; + SaturationProperties sat_a; + + SurfaceTension sigma_w; + SurfaceTension sigma_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + Modelica.SIunits.Temperature Tcorr_a "Corresponding temp. for ammonia, K"; + Modelica.SIunits.Temperature Tcorr_w "Corresponding temp. for water, K"; + + constant Modelica.SIunits.Temperature TNH3min=195.5; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(sat.X); + + Tcorr_a := sat.Tsat*Tc_a/Tc "Corresponding temp. for ammonia, K"; + Tcorr_w := sat.Tsat*Tc_w/Tc "Corresponding temp. for water, K"; + + if debugmode then + Modelica.Utilities.Streams.print("got (Tc,pc,Tcorr_a,Tcorr_w), (" + + String(Tc) + "," + String(pc) + "," + String(Tcorr_a) + "," + String( + Tcorr_w) + ")"); + end if; + + sat_a := setSat_TX( + min(Tc_a - 1, max(TNH3min, Tcorr_a)), + {1,0}, + calcTransport=true); + sat_w := setSat_TX( + min(Tcorr_w, Tc_w - 1), + {0,1}, + calcTransport=true); + + sigma_a := sat_a.sigma; + sigma_w := sat_w.sigma; + + sigma := sigma_a*Z[1] + sigma_w*Z[2]; + + end surfaceTension; + + + +end NH3_Water; diff --git a/Media/Pentane/package.mo b/Media/Pentane/package.mo new file mode 100644 index 0000000..c1a94c4 --- /dev/null +++ b/Media/Pentane/package.mo @@ -0,0 +1,4 @@ +within REFPROP2Modelica.Media; +package Pentane "Pentane from REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames = {"pentane"}); +end Pentane; diff --git a/Media/Pentane/package.order b/Media/Pentane/package.order new file mode 100644 index 0000000..e69de29 diff --git a/Media/R410.mo b/Media/R410.mo new file mode 100644 index 0000000..102fd49 --- /dev/null +++ b/Media/R410.mo @@ -0,0 +1,4 @@ +within REFPROP2Modelica.Media; +package R410 "R410 defined as pseudo pure in REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames = {"R410"}); +end R410; diff --git a/Media/R410mix/package.mo b/Media/R410mix/package.mo new file mode 100644 index 0000000..b6965ed --- /dev/null +++ b/Media/R410mix/package.mo @@ -0,0 +1,4 @@ +within REFPROP2Modelica.Media; +package R410mix "R410 defined as mixture in REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames = {"R32","R125"}, reference_X = {0.697615,0.302385}); +end R410mix; diff --git a/Media/R410mix/package.order b/Media/R410mix/package.order new file mode 100644 index 0000000..e69de29 diff --git a/Media/Water/package.mo b/Media/Water/package.mo new file mode 100644 index 0000000..2242ce3 --- /dev/null +++ b/Media/Water/package.mo @@ -0,0 +1,4 @@ +within REFPROP2Modelica.Media; +package Water "Water from REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames = {"water"}); +end Water; diff --git a/Media/Water/package.order b/Media/Water/package.order new file mode 100644 index 0000000..e69de29 diff --git a/Media/package.mo b/Media/package.mo new file mode 100644 index 0000000..b0947ed --- /dev/null +++ b/Media/package.mo @@ -0,0 +1,3 @@ +within REFPROP2Modelica; +package Media +end Media; diff --git a/Media/package.order b/Media/package.order new file mode 100644 index 0000000..1cee419 --- /dev/null +++ b/Media/package.order @@ -0,0 +1,6 @@ +Pentane +R410mix +Water +NH3_Water +R410 +MethaneEthane diff --git a/PartialMixtureTwoPhaseMedium/FixedPhase.mo b/PartialMixtureTwoPhaseMedium/FixedPhase.mo deleted file mode 100644 index 3d17485..0000000 --- a/PartialMixtureTwoPhaseMedium/FixedPhase.mo +++ /dev/null @@ -1,3 +0,0 @@ -within MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium; -type FixedPhase = Integer(min=0,max=2) - "phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g. interactive use"; diff --git a/PartialMixtureTwoPhaseMedium/FluidLimits.mo b/PartialMixtureTwoPhaseMedium/FluidLimits.mo deleted file mode 100644 index 5e3532b..0000000 --- a/PartialMixtureTwoPhaseMedium/FluidLimits.mo +++ /dev/null @@ -1,21 +0,0 @@ -within MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium; -record FluidLimits "validity limits for fluid model" - extends Modelica.Icons.Record; - Temperature TMIN "minimum temperature"; - Temperature TMAX "maximum temperature"; - Density DMIN "minimum density"; - Density DMAX "maximum density"; - AbsolutePressure PMIN "minimum pressure"; - AbsolutePressure PMAX "maximum pressure"; - SpecificEnthalpy HMIN "minimum enthalpy"; - SpecificEnthalpy HMAX "maximum enthalpy"; - SpecificEntropy SMIN "minimum entropy"; - SpecificEntropy SMAX "maximum entropy"; - annotation(Documentation( - info=" -

The minimum pressure mostly applies to the liquid state only. - The minimum density is also arbitrary, but is reasonable for techical - applications to limit iterations in non-linear systems. The limits in - enthalpy and entropy are used as safeguards in inverse iterations.

- ")); -end FluidLimits; diff --git a/PartialMixtureTwoPhaseMedium/package.mo b/PartialMixtureTwoPhaseMedium/package.mo deleted file mode 100644 index 0b703e1..0000000 --- a/PartialMixtureTwoPhaseMedium/package.mo +++ /dev/null @@ -1,728 +0,0 @@ -within MediaTwoPhaseMixture; -partial package PartialMixtureTwoPhaseMedium "Template class for two phase medium of a mixture of substances " - - - extends Modelica.Media.Interfaces.PartialMixtureMedium; -// constant Boolean smoothModel "true if the (derived) model should not generate state events"; - constant Boolean onePhase = false - "true if the (derived) model should never be called with two-phase inputs"; - - - redeclare replaceable record extends FluidConstants - "extended fluid constants" - /* Temperature criticalTemperature "critical temperature"; - AbsolutePressure criticalPressure "critical pressure"; - MolarVolume criticalMolarVolume "critical molar Volume"; - Real acentricFactor "Pitzer acentric factor"; - Temperature triplePointTemperature "triple point temperature"; - AbsolutePressure triplePointPressure "triple point pressure"; - Temperature meltingPoint "melting point at 101325 Pa"; - Temperature normalBoilingPoint "normal boiling point (at 101325 Pa)"; - DipoleMoment dipoleMoment - "dipole moment of molecule in Debye (1 debye = 3.33564e10-30 C.m)"; - Boolean hasIdealGasHeatCapacity=false - "true if ideal gas heat capacity is available"; - Boolean hasCriticalData=false "true if critical data are known"; - Boolean hasDipoleMoment=false "true if a dipole moment known"; - Boolean hasFundamentalEquation=false "true if a fundamental equation"; - Boolean hasLiquidHeatCapacity=false - "true if liquid heat capacity is available"; - Boolean hasSolidHeatCapacity=false - "true if solid heat capacity is available"; - Boolean hasAccurateViscosityData=false - "true if accurate data for a viscosity function is available"; - Boolean hasAccurateConductivityData=false - "true if accurate data for thermal conductivity is available"; - Boolean hasVapourPressureCurve=false - "true if vapour pressure data, e.g. Antoine coefficents are known"; - Boolean hasAcentricFactor=false "true if Pitzer accentric factor is known"; - SpecificEnthalpy HCRIT0=0.0 - "Critical specific enthalpy of the fundamental equation"; - SpecificEntropy SCRIT0=0.0 - "Critical specific entropy of the fundamental equation"; - SpecificEnthalpy deltah=0.0 - "Difference between specific enthalpy model (h_m) and f.eq. (h_f) (h_m - h_f)"; - SpecificEntropy deltas=0.0 - "Difference between specific enthalpy model (s_m) and f.eq. (s_f) (s_m - s_f)"; - */ - annotation(Documentation(info="")); - end FluidConstants; - -constant FluidConstants[nS] fluidConstants "constant data for the fluid"; - - -redeclare replaceable record extends ThermodynamicState - "Thermodynamic state of two phase medium" - FixedPhase phase(min=0, max=2) - "phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g. interactive use"; - Density d_l(start=300) "density liquid phase"; - Density d_g(start=300) "density gas phase"; - MassFraction X_l[nX] "Mass fraction of NaCl in kg/kg"; - annotation(Documentation(info="")); -//MassFraction X[nX] "Mass fraction of NaCl in kg/kg" -end ThermodynamicState; - - - replaceable record SaturationProperties - "Saturation properties of two phase medium" - extends Modelica.Icons.Record; - AbsolutePressure psat "saturation pressure"; - Temperature Tsat "saturation temperature"; - MassFraction X[nX] "Mass fractions"; - annotation(Documentation(info="")); - end SaturationProperties; - - - redeclare replaceable partial model extends BaseProperties - "Base properties (p, d, T, h, s, u, R, MM, sat) of two phase medium" - // Temperature T(start=300); - Modelica.SIunits.SpecificEntropy s; - SaturationProperties sat "Saturation properties at the medium pressure"; - annotation(Documentation(info="")); - end BaseProperties; - - - replaceable partial function setDewState - "Return the thermodynamic state on the dew line" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation point"; - input FixedPhase phase(min = 1, max = 2) = 1 "phase: default is one phase"; - output ThermodynamicState state "complete thermodynamic state info"; - annotation(Documentation(info="")); - end setDewState; - - - replaceable partial function setBubbleState - "Return the thermodynamic state on the bubble line" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation point"; - input FixedPhase phase(min = 1, max = 2) = 1 "phase: default is one phase"; - output ThermodynamicState state "complete thermodynamic state info"; - annotation(Documentation(info="")); - end setBubbleState; - - - redeclare replaceable partial function extends setState_dTX - "Return thermodynamic state as function of d, T and composition X or Xi" - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - annotation(Documentation(info="")); - end setState_dTX; - - - redeclare replaceable partial function extends setState_phX - "Return thermodynamic state as function of p, h and composition X or Xi" - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - annotation(Documentation(info="")); - end setState_phX; - - - redeclare replaceable partial function extends setState_psX - "Return thermodynamic state as function of p, s and composition X or Xi" - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - annotation(Documentation(info="")); - end setState_psX; - - - redeclare replaceable partial function extends setState_pTX - "Return thermodynamic state as function of p, T and composition X or Xi" - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - annotation(Documentation(info="")); - end setState_pTX; - - - replaceable function setSat_TX - "Return saturation property record from temperature" - extends Modelica.Icons.Function; - input Temperature T "temperature"; - input MassFraction X[nX] "Mass fractions"; - output SaturationProperties sat "saturation property record"; - algorithm - sat.Tsat := T; - sat.psat := saturationPressure(T,X); - sat.X := X; - annotation(Documentation(info="")); - end setSat_TX; - - - replaceable function setSat_pX - "Return saturation property record from pressure" - extends Modelica.Icons.Function; - input AbsolutePressure p "pressure"; - input MassFraction X[nX] "Mass fractions"; - output SaturationProperties sat "saturation property record"; - algorithm - sat.psat := p; - sat.Tsat := saturationTemperature(p,X); - sat.X := X; - annotation(Documentation(info="")); - end setSat_pX; - - - replaceable partial function bubbleEnthalpy - "Return bubble point specific enthalpy" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Modelica.SIunits.SpecificEnthalpy hl - "boiling curve specific enthalpy"; - annotation(Documentation(info="")); - end bubbleEnthalpy; - - - replaceable partial function dewEnthalpy - "Return dew point specific enthalpy" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Modelica.SIunits.SpecificEnthalpy hv "dew curve specific enthalpy"; - annotation(Documentation(info="")); - end dewEnthalpy; - - - replaceable partial function bubbleEntropy - "Return bubble point specific entropy" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Modelica.SIunits.SpecificEntropy sl "boiling curve specific entropy"; - annotation(Documentation(info="")); - end bubbleEntropy; - - - replaceable partial function dewEntropy "Return dew point specific entropy" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Modelica.SIunits.SpecificEntropy sv "dew curve specific entropy"; - annotation(Documentation(info="")); - end dewEntropy; - - - replaceable partial function bubbleDensity "Return bubble point density" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Density dl "boiling curve density"; - annotation(Documentation(info="")); - end bubbleDensity; - - - replaceable partial function dewDensity "Return dew point density" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Density dv "dew curve density"; - annotation(Documentation(info="")); - end dewDensity; - - - replaceable partial function saturationPressure - "Return saturation pressure" - extends Modelica.Icons.Function; - input Temperature T "temperature"; - input MassFraction X[:]={1} "fluid composition as mass fractions"; - output AbsolutePressure p "saturation pressure"; - - annotation(Documentation(info="")); - end saturationPressure; - - - replaceable partial function saturationTemperature - "Return saturation temperature" - extends Modelica.Icons.Function; - input AbsolutePressure p "pressure"; - input MassFraction X[:]={1} "fluid composition as mass fractions"; - output Temperature T "saturation temperature"; - - annotation(Documentation(info="")); - end saturationTemperature; - - - replaceable function saturationPressure_sat "Return saturation temperature" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output AbsolutePressure p "saturation pressure"; - algorithm - p := sat.psat; - annotation(Documentation(info="")); - end saturationPressure_sat; - - - replaceable function saturationTemperature_sat - "Return saturation temperature" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Temperature T "saturation temperature"; - algorithm - T := sat.Tsat; - annotation(Documentation(info="")); - end saturationTemperature_sat; - - - replaceable partial function saturationTemperature_derp - "Return derivative of saturation temperature w.r.t. pressure" - extends Modelica.Icons.Function; - input AbsolutePressure p "pressure"; - output Real dTp "derivative of saturation temperature w.r.t. pressure"; - annotation(Documentation(info="")); - end saturationTemperature_derp; - - - replaceable function saturationTemperature_derp_sat - "Return derivative of saturation temperature w.r.t. pressure" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Real dTp "derivative of saturation temperature w.r.t. pressure"; - algorithm - dTp := saturationTemperature_derp(sat.psat); - annotation(Documentation(info="")); - end saturationTemperature_derp_sat; - - - replaceable partial function surfaceTension - "Return surface tension sigma in the two phase region" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output SurfaceTension sigma "Surface tension sigma in the two phase region"; - annotation(Documentation(info="")); - end surfaceTension; - - /* redeclare replaceable partial function extends molarMass - "Return the molar mass of the medium" - algorithm - MM := fluidConstants[1].molarMass; - end molarMass;*/ - - - replaceable partial function dBubbleDensity_dPressure - "Return bubble point density derivative" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output DerDensityByPressure ddldp "boiling curve density derivative"; - annotation(Documentation(info="")); - end dBubbleDensity_dPressure; - - - replaceable partial function dDewDensity_dPressure - "Return dew point density derivative" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output DerDensityByPressure ddvdp "saturated steam density derivative"; - annotation(Documentation(info="")); - end dDewDensity_dPressure; - - - replaceable partial function dBubbleEnthalpy_dPressure - "Return bubble point specific enthalpy derivative" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output DerEnthalpyByPressure dhldp - "boiling curve specific enthalpy derivative"; - annotation(Documentation(info="")); - end dBubbleEnthalpy_dPressure; - - - replaceable partial function dDewEnthalpy_dPressure - "Return dew point specific enthalpy derivative" - extends Modelica.Icons.Function; - - input SaturationProperties sat "saturation property record"; - output DerEnthalpyByPressure dhvdp - "saturated steam specific enthalpy derivative"; - annotation(Documentation(info="")); - end dDewEnthalpy_dPressure; - - - redeclare replaceable function specificEnthalpy_pTX - "Return specific enthalpy from pressure, temperature and mass fraction" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Temperature T "Temperature"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "Specific enthalpy at p, T, X"; - algorithm - h := specificEnthalpy(setState_pTX(p,T,X,phase)); - annotation(Documentation(info="")); - end specificEnthalpy_pTX; - - - redeclare replaceable function temperature_phX - "Return temperature from p, h, and X or Xi" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEnthalpy h "Specific enthalpy"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Temperature T "Temperature"; - algorithm - T := temperature(setState_phX(p,h,X,phase)); - annotation(Documentation(info="")); - end temperature_phX; - - - redeclare replaceable function density_phX - "Return density from p, h, and X or Xi" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEnthalpy h "Specific enthalpy"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Density d "density"; - algorithm - d := density(setState_phX(p,h,X,phase)); - annotation(Documentation(info="")); - end density_phX; - - - redeclare replaceable function temperature_psX - "Return temperature from p, s, and X or Xi" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Temperature T "Temperature"; - algorithm - T := temperature(setState_psX(p,s,X,phase)); - annotation(Documentation(info="")); - end temperature_psX; - - - redeclare replaceable function density_psX - "Return density from p, s, and X or Xi" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Density d "Density"; - algorithm - d := density(setState_psX(p,s,X,phase)); - annotation(Documentation(info="")); - end density_psX; - - - redeclare replaceable function specificEnthalpy_psX - "Return specific enthalpy from p, s, and X or Xi" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; - algorithm - h := specificEnthalpy(setState_psX(p,s,X,phase)); - annotation(Documentation(info="")); - end specificEnthalpy_psX; - - - replaceable function setState_pT "Return thermodynamic state from p and T" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Temperature T "Temperature"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output ThermodynamicState state "thermodynamic state record"; - algorithm - assert(nX==1,"This function is not allowed for mixtures."); - state := setState_pTX(p,T,fill(0,0),phase); - annotation(Documentation(info="")); - end setState_pT; - - - replaceable function setState_ph "Return thermodynamic state from p and h" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEnthalpy h "Specific enthalpy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output ThermodynamicState state "thermodynamic state record"; - algorithm - assert(nX==1,"This function is not allowed for mixtures."); - state := setState_phX(p,h,fill(0, 0),phase); - annotation(Documentation(info="")); - end setState_ph; - - - replaceable function setState_ps "Return thermodynamic state from p and s" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output ThermodynamicState state "thermodynamic state record"; - algorithm - assert(nX==1,"This function is not allowed for mixtures."); - state := setState_psX(p,s,fill(0,0),phase); - annotation(Documentation(info="")); - end setState_ps; - - - replaceable function setState_dT "Return thermodynamic state from d and T" - extends Modelica.Icons.Function; - input Density d "density"; - input Temperature T "Temperature"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output ThermodynamicState state "thermodynamic state record"; - algorithm - assert(nX==1,"This function is not allowed for mixtures."); - state := setState_dTX(d,T,fill(0,0),phase); - annotation(Documentation(info="")); - end setState_dT; - - - replaceable function setState_px - "Return thermodynamic state from pressure and vapour quality" - input AbsolutePressure p "Pressure"; - input MassFraction x "Vapour quality"; - output ThermodynamicState state "Thermodynamic state record"; - algorithm - assert(nX==1,"This function is not allowed for mixtures."); - state := setState_ph( - p, - (1 - x)*bubbleEnthalpy( - MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium.setSat_pX(p)) + x* - dewEnthalpy(MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium.setSat_pX(p)), - 2); - annotation(Documentation(info="")); - end setState_px; - - - replaceable function setState_Tx - "Return thermodynamic state from temperature and vapour quality" - input Temperature T "Temperature"; - input MassFraction x "Vapour quality"; - output ThermodynamicState state "thermodynamic state record"; - algorithm - assert(nX==1,"This function is not allowed for mixtures."); - state := setState_ph( - saturationPressure_sat( - MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium.setSat_TX(T)), - (1 - x)*bubbleEnthalpy( - MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium.setSat_TX(T)) + x* - dewEnthalpy(MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium.setSat_TX(T)), - 2); - annotation(Documentation(info="")); - end setState_Tx; - - - replaceable function vapourQuality "Return vapour quality" - input ThermodynamicState state "Thermodynamic state record"; - output MassFraction x "Vapour quality"; -protected - constant SpecificEnthalpy eps = 1e-8; - algorithm - x := min(max((specificEnthalpy(state) - bubbleEnthalpy(setSat_pX(pressure(state),state.X))) - /(dewEnthalpy(setSat_pX(pressure(state),state.X)) - bubbleEnthalpy(setSat_pX(pressure(state),state.X)) - + eps), 0), 1); - annotation(Documentation(info="")); - end vapourQuality; - - - replaceable function density_ph "Return density from p and h" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEnthalpy h "Specific enthalpy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Density d "Density"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use density_phX() instead!"); - d := density_phX(p, h, fill(0,0), phase); - annotation(Documentation(info="")); - end density_ph; - - - replaceable function temperature_ph "Return temperature from p and h" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEnthalpy h "Specific enthalpy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Temperature T "Temperature"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use temperature_phX() instead!"); - T := temperature_phX(p, h, fill(0,0),phase); - annotation(Documentation(info="")); - end temperature_ph; - - - replaceable function pressure_dT "Return pressure from d and T" - extends Modelica.Icons.Function; - input Density d "Density"; - input Temperature T "Temperature"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output AbsolutePressure p "Pressure"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use pressure_dTX() instead!"); - p := pressure(setState_dTX(d, T, fill(0,0),phase)); - annotation(Documentation(info="")); - end pressure_dT; - - - replaceable function specificEnthalpy_dT - "Return specific enthalpy from d and T" - extends Modelica.Icons.Function; - input Density d "Density"; - input Temperature T "Temperature"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use specificEnthalpy_dX() instead!"); - h := specificEnthalpy(setState_dTX(d, T, fill(0,0),phase)); - annotation(Documentation(info="")); - end specificEnthalpy_dT; - - - replaceable function specificEnthalpy_ps - "Return specific enthalpy from p and s" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use specificEnthalpy_psX() instead!"); - h := specificEnthalpy_psX(p,s,reference_X); - annotation(Documentation(info="")); - end specificEnthalpy_ps; - - - replaceable function temperature_ps "Return temperature from p and s" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Temperature T "Temperature"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use temperature_psX() instead!"); - T := temperature_psX(p,s,fill(0,0),phase); - annotation(Documentation(info="")); - end temperature_ps; - - - replaceable function density_ps "Return density from p and s" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Density d "Density"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use density_psX() instead!"); - d := density_psX(p, s, fill(0,0), phase); - annotation(Documentation(info="")); - end density_ps; - - - replaceable function specificEnthalpy_pT - "Return specific enthalpy from p and T" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Temperature T "Temperature"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use specificEnthalpy_pTx() instead!"); - h := specificEnthalpy_pTX(p, T, fill(0,0),phase); - annotation(Documentation(info="")); - end specificEnthalpy_pT; - - - replaceable function density_pT "Return density from p and T" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Temperature T "Temperature"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Density d "Density"; - algorithm - d := density(setState_pTX(p, T, fill(0,0),phase)); - annotation(Documentation(info="")); - end density_pT; - - -replaceable function specificEnthalpy_dTX - "Return specific enthalpy from d, T, and X or Xi" - extends Modelica.Icons.Function; - input Density d "Pressure"; - input Temperature T "Specific entropy"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; -algorithm - h := specificEnthalpy(setState_dTX(d,T,X,phase)); - -annotation(Documentation(info="")); -end specificEnthalpy_dTX; - - -redeclare replaceable function pressure - input ThermodynamicState state "Thermodynamic state record"; - output Modelica.SIunits.Pressure p; -algorithm - p:=state.p; -end pressure; - - -redeclare replaceable function specificEnthalpy - input ThermodynamicState state "Thermodynamic state record"; - output Modelica.SIunits.SpecificEnthalpy h; -algorithm - h:=state.h; -end specificEnthalpy; - - -replaceable function density_liq - input ThermodynamicState state "Thermodynamic state record"; - output Modelica.SIunits.Density d_l; -algorithm - d_l:=state.d_l; -end density_liq; - - - replaceable function dynamicViscosity_liq "Viscosity of liquid phase" - // extends dynamicViscosity; Warum funzt das nicht? Er sagt "multiple algorithms" - extends Modelica.Icons.Function; - input ThermodynamicState state "thermodynamic state record"; - output DynamicViscosity eta "Dynamic viscosity"; - /*protected - Modelica.SIunits.Pressure p_sat = max(state.p,saturationPressure(state.T, {1})); - ThermodynamicState state_l=state "liquid state"; -algorithm - state_l.d:=state.d_l; - state_l.p:=p_sat; - eta := dynamicViscosity(state_l); -// eta := Modelica.Media.Water.IF97_Utilities.dynamicViscosity(state.d_l, state.T, p_sat, 1); -// Modelica.Utilities.Streams.print(String(p_sat)); -*/ - end dynamicViscosity_liq; - - - replaceable function dynamicViscosity_gas "Viscosity of liquid phase" - // extends dynamicViscosity; Warum funzt das nicht? Er sagt "multiple algorithms" - extends Modelica.Icons.Function; - input ThermodynamicState state "thermodynamic state record"; - output DynamicViscosity eta "Dynamic viscosity"; - /*protected - Modelica.SIunits.Pressure p_sat = min(state.p,saturationPressure(state.T, {1})); - ThermodynamicState state_g=state "gaseous state"; -algorithm - state_g.d:=state.d_g; - state_g.p:=p_sat; - eta := dynamicViscosity(state_g); - */ - // eta := Modelica.Media.Water.IF97_Utilities.dynamicViscosity(state.d_g, state.T, p_sat, 1); - end dynamicViscosity_gas; - - - annotation (Documentation(info=" -

PartialMixtureTwoPhaseMedium

- This is a template for two phase medium of a mixture of substances and is used by REFPROPMedium.
- It has been created by merging PartialMixtureMedium and PartialTwoPhaseMedium from Modelica.Media.Interfaces.
- -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -"), uses(Modelica(version="3.1"))); -end PartialMixtureTwoPhaseMedium; diff --git a/PartialMixtureTwoPhaseMedium/package.order b/PartialMixtureTwoPhaseMedium/package.order deleted file mode 100644 index 6ccc947..0000000 --- a/PartialMixtureTwoPhaseMedium/package.order +++ /dev/null @@ -1,61 +0,0 @@ -onePhase -FluidLimits -FluidConstants -fluidConstants -ThermodynamicState -SaturationProperties -FixedPhase -BaseProperties -setDewState -setBubbleState -setState_dTX -setState_phX -setState_psX -setState_pTX -setSat_TX -setSat_pX -bubbleEnthalpy -dewEnthalpy -bubbleEntropy -dewEntropy -bubbleDensity -dewDensity -saturationPressure -saturationTemperature -saturationPressure_sat -saturationTemperature_sat -saturationTemperature_derp -saturationTemperature_derp_sat -surfaceTension -dBubbleDensity_dPressure -dDewDensity_dPressure -dBubbleEnthalpy_dPressure -dDewEnthalpy_dPressure -specificEnthalpy_pTX -temperature_phX -density_phX -temperature_psX -density_psX -specificEnthalpy_psX -setState_pT -setState_ph -setState_ps -setState_dT -setState_px -setState_Tx -vapourQuality -density_ph -temperature_ph -pressure_dT -specificEnthalpy_dT -specificEnthalpy_ps -temperature_ps -density_ps -specificEnthalpy_pT -density_pT -specificEnthalpy_dTX -pressure -specificEnthalpy -density_liq -dynamicViscosity_liq -dynamicViscosity_gas diff --git a/REFPROPMedium/StrJoin.mo b/REFPROPMedium/StrJoin.mo deleted file mode 100644 index f44713b..0000000 --- a/REFPROPMedium/StrJoin.mo +++ /dev/null @@ -1,11 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function StrJoin "Converts an Array of Strings into a string separated by |" - input String[:] s_in; - input String delimiter; - output String s_out; -algorithm - s_out :=s_in[1]; - for i in 2:size(s_in,1) loop - s_out :=s_out + delimiter + s_in[i]; - end for; -end StrJoin; diff --git a/REFPROPMedium/density_ThX.mo b/REFPROPMedium/density_ThX.mo deleted file mode 100644 index ccfa89b..0000000 --- a/REFPROPMedium/density_ThX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function density_ThX "calls REFPROP-Wrapper, returns density" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_ThX("+String(T)+","+String(h)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "Th",T,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_dTX(d,T,X,phase), - T=temperature_hdX(h,d,X,phase))); -end density_ThX; diff --git a/REFPROPMedium/density_TsX.mo b/REFPROPMedium/density_TsX.mo deleted file mode 100644 index 5b9267e..0000000 --- a/REFPROPMedium/density_TsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function density_TsX "calls REFPROP-Wrapper, returns density" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_TsX("+String(T)+","+String(s)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "Ts",T,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_dTX(d,T,X,phase), - T=temperature_dsX(d,s,X,phase))); -end density_TsX; diff --git a/REFPROPMedium/density_hsX.mo b/REFPROPMedium/density_hsX.mo deleted file mode 100644 index 54ac0a2..0000000 --- a/REFPROPMedium/density_hsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function density_hsX "calls REFPROP-Wrapper, returns density" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_hsX("+String(h)+","+String(s)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "hs",h,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_hdX(h,d,X,phase), - h=specificEnthalpy_dsX(d,s,X,phase))); -end density_hsX; diff --git a/REFPROPMedium/density_pqX.mo b/REFPROPMedium/density_pqX.mo deleted file mode 100644 index 2d4338d..0000000 --- a/REFPROPMedium/density_pqX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function density_pqX "calls REFPROP-Wrapper, returns specific density" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_pqX("+String(p)+","+String(q)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "pq",p,q,X,phase); -/* annotation(LateInline=true,inverse(p=pressure_dqX(d,q,X,phase), - q=quality_pdX(p,d,X,phase)));*/ -end density_pqX; diff --git a/REFPROPMedium/getProp_REFPROP.mo b/REFPROPMedium/getProp_REFPROP.mo deleted file mode 100644 index ecdb4dc..0000000 --- a/REFPROPMedium/getProp_REFPROP.mo +++ /dev/null @@ -1,19 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function getProp_REFPROP - "calls C function with property identifier & returns single property" - input String what2calc; - input String statevars; - input String fluidnames; - input Real[:] props; - input Real statevar1; - input Real statevar2; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - input String errormsg; -// input Integer debug=1; - output Real val; - - external "C" val = props_REFPROP(what2calc, statevars, fluidnames, props, statevar1, statevar2, X, phase, REFPROP_PATH, errormsg, debugmode); - -annotation (Include="#include ", Library="REFPROP_wrapper"); -end getProp_REFPROP; diff --git a/REFPROPMedium/getProp_REFPROP_check.mo b/REFPROPMedium/getProp_REFPROP_check.mo deleted file mode 100644 index 35a2e02..0000000 --- a/REFPROPMedium/getProp_REFPROP_check.mo +++ /dev/null @@ -1,23 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function getProp_REFPROP_check - "wrapper for getProp_REFPROP returning 1 property value with error check" - extends partialREFPROP; - input String what2calc; - input String statevars; -// input String fluidnames; - input Real statevar1; - input Real statevar2; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Real val; -algorithm - assert(size(X,1)>0,"The mass fraction vector must have at least 1 element."); - -// Modelica.Utilities.Streams.print("Calc "+what2calc); - val :=getProp_REFPROP(what2calc,statevars,fluidnames,props,statevar1,statevar2,X,phase,errormsg) - "just passing through"; - -// Modelica.Utilities.Streams.print("ERR("+String(props[1])+"):"+errormsg); - assert(props[1]==0,"Errorcode "+String(props[1])+" in REFPROP wrapper function:\n"+errormsg +"\n"); - -end getProp_REFPROP_check; diff --git a/REFPROPMedium/getSatProp_REFPROP.mo b/REFPROPMedium/getSatProp_REFPROP.mo deleted file mode 100644 index 3849893..0000000 --- a/REFPROPMedium/getSatProp_REFPROP.mo +++ /dev/null @@ -1,17 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function getSatProp_REFPROP - "calls C function with property identifier & returns single property" - input String what2calc; - input String statevar; - input String fluidnames; - input Real[:] props; - input Real statevarval; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input String errormsg; - output Real val; -// input Integer debugmode=1; - - external "C" val = satprops_REFPROP(what2calc, statevar, fluidnames, props, statevarval, X, REFPROP_PATH, errormsg, debugmode); - - annotation (Include="#include ", Library="REFPROP_wrapper"); -end getSatProp_REFPROP; diff --git a/REFPROPMedium/getSatProp_REFPROP_check.mo b/REFPROPMedium/getSatProp_REFPROP_check.mo deleted file mode 100644 index d3f6441..0000000 --- a/REFPROPMedium/getSatProp_REFPROP_check.mo +++ /dev/null @@ -1,21 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function getSatProp_REFPROP_check - "wrapper for getSatProp_REFPROP returning 1 property value with error check" - extends partialREFPROP; - input String what2calc; - input String statevar; -// input String fluidnames; - input Real statevarval; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - output Real val; -algorithm - assert(size(X,1)>0,"The mass fraction vector must have at least 1 element."); - val :=getSatProp_REFPROP(what2calc,statevar,fluidnames,props,statevarval,X,errormsg) - "just passing through"; -//Error string decoding in wrapper-c-function - assert(props[1]==0 or props[1]==141,"Errorcode "+String(props[1])+" in REFPROP wrapper function:\n"+errormsg +"\n"); - if props[1]==141 then - Modelica.Utilities.Streams.print("Saturation properties cannot be calculated, because P > p_crit!..."); - val :=-999; - end if; -end getSatProp_REFPROP_check; diff --git a/REFPROPMedium/package.mo b/REFPROPMedium/package.mo deleted file mode 100644 index 6c88db5..0000000 --- a/REFPROPMedium/package.mo +++ /dev/null @@ -1,597 +0,0 @@ -within MediaTwoPhaseMixture; -package REFPROPMedium "Two Phase Mixture Medium whose property functions are supplied by REFPROPR (via wrapper for refprop.dll)" -constant Boolean debugmode = false - "print messages in functions and in refpropwrapper.lib (to see the latter, start dymosim.exe in command window)"; - -constant String explicitVars = "ph" - "set of variables the model is explicit for, may be set to all combinations of p,h,T,d,s,d, REFPROP works internally with dT"; -final constant String fluidnames= StrJoin(substanceNames,"|"); - - -extends PartialMixtureTwoPhaseMedium( - mediumName="REFPROP Medium", - final reducedX = true, - final singleState=false, - reference_X=cat(1,fill(0,nX-1),{1}), - fluidConstants = rpConstants); -//"mediumName is being checked for consistency at flowports" - - constant FluidConstants[nS] rpConstants( - each chemicalFormula = "REFPROP Medium", - each structureFormula="REFPROP Medium", - each casRegistryNumber="007", - each iupacName="REFPROP Medium", - each molarMass=0.1, - each criticalTemperature = 600, - each criticalPressure = 300e5, - each criticalMolarVolume = 1, - each acentricFactor = 1, - each triplePointTemperature = 273.15, - each triplePointPressure = 1e5, - each meltingPoint = 1, - each normalBoilingPoint = 1, - each dipoleMoment = 1); - - -redeclare record extends ThermodynamicState - "a selection of variables that uniquely defines the thermodynamic state" -/* AbsolutePressure p "Absolute pressure of medium"; - Temperature T "Temperature of medium"; - MassFraction X[nX] "Composition (Mass fractions in kg/kg)";*/ - MolarMass MM "Molar Mass of the whole mixture"; - Density d(start=300) "density"; - Density d_l(start=300) "density liquid phase"; - Density d_g(start=300) "density gas phase"; - Real x "vapor quality on a mass basis [mass vapor/total mass]"; - SpecificEnergy u "Specific energy"; - SpecificEnthalpy h "Specific enthalpy"; - SpecificEntropy s "Specific entropy"; - Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; - Modelica.SIunits.SpecificHeatCapacityAtConstantVolume cv; - VelocityOfSound c; - MolarMass MM_l "Molar Mass of liquid phase"; - MolarMass MM_g "Molar Mass of gas phase"; - MassFraction X_l[nX] "Composition of liquid phase (Mass fractions in kg/kg)"; - MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; -// Real GVF "Gas Void Fraction"; -end ThermodynamicState; - - - redeclare model extends BaseProperties "Base properties of medium" - - equation - u = h - p/d - "state.u - calculated anyway by REFPROP, but this way the expression can be derived symbolically"; - MM = state.MM; - R = 1 "Modelica.Constants.R/MM"; - - //ph-explicit - if explicitVars=="ph" or explicitVars=="hp" then - state = setState_phX(p,h,X,0) " ,fluidnames)"; - T = temperature_phX(p,h,X) - "double calculation, but necessary if T is given"; - // T = state.T "can be used instead"; - - s = specificEntropy_phX(p,h,X) - "double calculation, but necessary if s is given"; - // s = state.s "can be used instead"; - - d = density_phX(p,h,X) "double calculation, but necessary if d is given"; - //d = state.d "can be used instead"; - elseif explicitVars=="pT" or explicitVars=="Tp" then - //pT-explicit - state = setState_pTX(p,T,X,0) ",fluidnames)"; - h = specificEnthalpy_pTX(p,T,X) - "double calculation, but necessary if s is given"; - //h = state.h "can be used instead"; - - s = specificEntropy_pTX(p,T,X) - "state.s double calculation, but necessary if s is given"; - // s = state.s "can be used instead"; - - d = density_pTX(p,T,X) - "state.d double calculation, but necessary if d is given"; - //d = state.d "can be used instead"; - elseif explicitVars=="dT" or explicitVars=="Td" then - //Td-explicit - state = setState_dTX(d,T,X,0) ",fluidnames)"; - h = specificEnthalpy_dTX(d,T,X) - "double calculation, but necessary if s is given"; - //h = state.h "can be used instead"; - - s = specificEntropy_dTX(d,T,X) - "state.s double calculation, but necessary if s is given"; - // s = state.s "can be used instead"; - p = pressure_dTX(d,T,X) - "state.d double calculation, but necessary if d is given"; - // p = state.p "can be used instead"; - elseif explicitVars=="ps" or explicitVars=="ps" then - state = setState_psX(p,s,X,0) ",fluidnames)"; - T = temperature_psX(p,s,X); - h = specificEnthalpy_psX(p,s,X); - d = density_psX(p,s,X); - elseif explicitVars=="pd" or explicitVars=="pd" then - state = setState_pdX(p,d,X,0) ",fluidnames)"; - T = temperature_pdX(p,d,X); - h = specificEnthalpy_pdX(p,d,X); - s = specificEntropy_pdX(p,d,X); - elseif explicitVars=="hT" or explicitVars=="Th" then - state = setState_ThX(T,h,X,0) ",fluidnames)"; - p = pressure_ThX(T,h,X); - s = specificEntropy_ThX(T,h,X); - d = density_ThX(T,h,X); - elseif explicitVars=="sT" or explicitVars=="Ts" then - state = setState_TsX(T,s,X,0) ",fluidnames)"; - p = pressure_TsX(T,s,X); - h = specificEnthalpy_TsX(T,s,X); - d = density_TsX(T,s,X); - elseif explicitVars=="hd" or explicitVars=="hd" then - state = setState_hdX(h,d,X,0) ",fluidnames)"; - p = pressure_hdX(h,d,X); - s = specificEntropy_hdX(h,d,X); - T = temperature_hdX(h,d,X); - elseif explicitVars=="hs" or explicitVars=="sh" then - state = setState_hsX(h,s,X,0) ",fluidnames)"; - p = pressure_hsX(h,s,X); - T = temperature_hsX(h,s,X); - d = density_hsX(h,s,X); - elseif explicitVars=="sd" or explicitVars=="ds" then - state = setState_dsX(d,s,X,0) ",fluidnames)"; - p = pressure_dsX(d,s,X); - h = specificEnthalpy_dsX(d,s,X); - T = temperature_dsX(d,s,X); - end if; - - sat.psat = p; - sat.Tsat = saturationTemperature(p,X); - sat.X = X; - annotation (Documentation(info=" - - The baseproperties model is explicit for one set of 2 variables, which can be chosen to be ph, pT, ps, pd, Th, dT, Ts, hd, hs, ds (set explicitVars when calling this package or in package).
- That means, that if only one of these variables is explicitly given, the other one is calculated by inverting its property function.
- Then alle state variables are calculated using the corresponding setstate_XX function.
- In order to avoid numerical inversion by the solver, 3 state variables are set explicitly using their respective property function, which has its inverses defined.
- Example: So for p and h as explicit variables a state given by p and T is calculated by first calculating h with specificEnthalpy_pTX (inverse function of temperature_phX), - then calculating the other variables using setState_phX. s and d, however, are then calculated, although they are already known in the state variable.
- Knowing this, the baseproperty model can be adapted to your calculation needs to decrease computation time: -

    -
  • Choose the explicitVars to the combination occurring most often in your model. (The combination dT might be favorable, because it is used by REFPROP's internal algorithm.)
  • -
  • if you are sure, that it won't be needed, in BaseProperties replace explicit calculation of T/s/d/h with definition as state (commented line)
  • -
- ")); - end BaseProperties; - - -redeclare function extends saturationPressure -// extends Modelica.Icons.Function; -algorithm -// p := getSatProp_REFPROP_check("p", "T", fluidnames,T,X); - p := getSatProp_REFPROP_check("p", "T", T,X); -end saturationPressure; - - -redeclare function extends saturationTemperature -// extends Modelica.Icons.Function; -algorithm -// T := getSatProp_REFPROP_check("T", "p", fluidnames,p,X); - T := getSatProp_REFPROP_check("T", "p", p,X); -end saturationTemperature; - - - redeclare function extends specificEntropy - "Return specific entropy - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" - algorithm - s := state.s; - end specificEntropy; - - - redeclare replaceable function extends density - "returns density from state - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" - algorithm - d := state.d; - end density; - - -redeclare function extends dewEnthalpy "dew curve specific enthalpy" - extends Modelica.Icons.Function; -algorithm - hv := getProp_REFPROP_check("h", "pq", sat.psat,1,sat.X,1); -end dewEnthalpy; - - - redeclare function extends dewEntropy "dew curve specific entropy of water" - extends Modelica.Icons.Function; - algorithm - sv := getProp_REFPROP_check("s", "pq", sat.psat,1,sat.X,1); - end dewEntropy; - - - redeclare function extends dewDensity "dew curve specific density of water" - extends Modelica.Icons.Function; - algorithm - dv := getProp_REFPROP_check("d", "pq", sat.psat,1,sat.X,1); - end dewDensity; - - - redeclare function extends bubbleEnthalpy - "boiling curve specific enthalpy of water" - extends Modelica.Icons.Function; - algorithm - hl := getProp_REFPROP_check("h", "pq", sat.psat,0,sat.X,1); - end bubbleEnthalpy; - - - redeclare function extends bubbleEntropy - "boiling curve specific entropy of water" - extends Modelica.Icons.Function; - algorithm - sl := getProp_REFPROP_check("s", "pq", sat.psat,0,sat.X,1); - end bubbleEntropy; - - - redeclare function extends bubbleDensity - "boiling curve specific density of water" - extends Modelica.Icons.Function; - algorithm - dl := getProp_REFPROP_check("d", "pq", sat.psat,0,sat.X,1); - end bubbleDensity; - - -redeclare replaceable partial function extends molarMass - "Return the molar mass of the medium" - extends Modelica.Icons.Function; -algorithm - MM:=state.MM; -end molarMass; - - -redeclare replaceable partial function extends setState_phX - "Calculates medium properties from p,h,X" -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_phX("+String(p)+","+String(h)+",X)..."); - end if; - state := setState("ph",p,h,X,phase) ",fluidnames)"; -end setState_phX; - - - redeclare function density_phX "calls REFPROP-Wrapper, returns density" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X - "composition defined by mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_phX("+String(p)+","+String(h)+",X)"); - end if; - // p="+String(p)+",h="+String(h)+", X={"+String(X[1])+","+String(X[2])+"}"); - d :=getProp_REFPROP_check("d", "ph",p,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_pdX(p,d,X,phase), - p=pressure_hdX(h,d,X,phase))); - end density_phX; - - - redeclare function temperature_phX - "calls REFPROP-Wrapper, returns temperature" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_phX("+String(p)+","+String(h)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "ph",p,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_pTX(p,T,X,phase), - p=pressure_ThX(T,h,X,phase))); - end temperature_phX; - - -redeclare replaceable partial function extends setState_pTX -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_pTX("+String(p)+","+String(T)+",X)..."); - end if; - state := setState("pT",p,T,X,phase) ",fluidnames)"; -end setState_pTX; - - - redeclare function density_pTX "calls REFPROP-Wrapper, returns density" - extends Modelica.Icons.Function; - // input String fluidnames; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_pTX("+String(p)+","+String(T)+",X)..."); - end if; - d :=getProp_REFPROP_check("d", "pT",p,T,X,phase); - annotation(LateInline=true,inverse(T=temperature_pdX(p,d,X,phase), - p=pressure_dTX(d,T,X,phase))); - end density_pTX; - - - redeclare function specificEnthalpy_pTX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - // input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; - /*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_pTX("+String(p)+","+String(T)+",X)..."); - end if; - // p="+String(p)+",T="+String(T)+", X={"+String(X[1])+","+String(X[2])+"}"); - h :=getProp_REFPROP_check("h", "pT",p,T,X,phase); - annotation(LateInline=true,inverse(T=temperature_phX(p,h,X,phase), - p=pressure_ThX(T,h,X,phase))); - end specificEnthalpy_pTX; - - - redeclare function specificEntropy_pTX - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_pTX("+String(p)+","+String(T)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "pT",p,T,X,phase); - annotation(LateInline=true,inverse(T=temperature_psX(p,s,X,phase), - p=pressure_TsX(T,s,X,phase))); - end specificEntropy_pTX; - - -redeclare replaceable partial function extends setState_psX - "Calculates medium properties from p,s,X" -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_psX("+String(p)+","+String(s)+",X)..."); - end if; - state := setState("ps",p,s,X,phase) ",fluidnames)"; -end setState_psX; - - - redeclare function temperature_psX - "calls REFPROP-Wrapper, returns temperature" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_psX("+String(p)+","+String(s)+",X)..."); - end if; - T :=getProp_REFPROP_check("T", "ps",p,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_pTX(p,T,X,phase), - p=pressure_TsX(T,s,X,phase))); - end temperature_psX; - - - redeclare function specificEnthalpy_psX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - // input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; - /*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_psX("+String(p)+","+String(s)+",X)..."); - end if; - h :=getProp_REFPROP_check("h", "ps",p,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_phX(p,h,X,phase), - p=pressure_hsX(h,s,X,phase))); - end specificEnthalpy_psX; - - - redeclare function density_psX "calls REFPROP-Wrapper, returns density" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_psX("+String(p)+","+String(s)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "ps",p,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_pdX(p,d,X,phase), - p=pressure_dsX(d,s,X,phase))); - end density_psX; - - -redeclare replaceable partial function extends setState_dTX -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_dTX("+String(d)+","+String(T)+",X)..."); - end if; - state := setState("dT",d,T,X,phase) ",fluidnames)"; -end setState_dTX; - - - redeclare function specificEnthalpy_dTX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - // input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_dTX("+String(d)+","+String(T)+",X)"); - end if; - // h :=getProp_REFPROP_check("h", "dT", fluidnames,d,T,X,phase); - h :=getProp_REFPROP_check("h", "dT", d,T,X,phase); - annotation(LateInline=true,inverse(d=density_ThX(T,h,X,phase), - T=temperature_hdX(h,d,X,phase))); - end specificEnthalpy_dTX; - - -redeclare function extends dynamicViscosity -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running dynamicViscosity"); - end if; - eta := getProp_REFPROP_check("v", "Td",state.T,state.d,state.X,state.phase); -end dynamicViscosity; - - -redeclare function extends thermalConductivity -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running thermalConductivity"); - end if; - lambda := getProp_REFPROP_check("l", "Td",state.T,state.d,state.X,state.phase); -end thermalConductivity; - - - redeclare function vapourQuality "Return vapour quality" - input ThermodynamicState state "Thermodynamic state record"; - output MassFraction x "Vapour quality"; - algorithm - x := state.x; - annotation(Documentation(info="")); - end vapourQuality; - - - redeclare function extends specificHeatCapacityCp - - algorithm - cp:=state.cp; - end specificHeatCapacityCp; - - - redeclare function extends specificHeatCapacityCv - - algorithm - cv:=state.cv; - end specificHeatCapacityCv; - - - annotation (Documentation(info=" -

-REFPROPMedium is a package that delivers REFPROP data to a model based on and largely compatible to the Modelica.Media library. -It can be used to model two-phase mixtures of all fluids whose data is delivered with REFPROP. It has been developed and tested only in Dymola up to 2012 FD01. -

-

-All files in this library, including the C source files are released under the Modelica License 2. -

-

Installation

-The installation basically consists in copying 2 files and changing one line in this package: -
    -
  • We need access to the REFPROP.DLL and to the Fluid-Data directory in the REFPROP directory. - So you need to set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of this parent package). - Make sure you mask the backslashes. It should look something like -
    constant String REFPROP_PATH = \"C:\\\\Program Files\\\\REFPROP\\\\\";
  • -
  • We need REFPROP_WRAPPER.LIB in %DYMOLADIR%\\BIN\\LIB\ and REFPROP_WRAPPER.H in %DYMOLADIR%\\SOURCE\\ (%DYMOLADIR% is DYMOLA's program directory)
  • -
-This package needs the package PartialMixtureMediumTwoPhase which should be included in the parent package. - -

-

Usage

-As it is based on Modelica.Media, the usage is little different from the usage of the two-phase water model:
-Create an instance of REFPROPMedium and specify the mixture by passing the names of the medium components (medium names are the names of the .fld files in the -%REFPROP%\\fluids directory): -
-  package Medium = REFPROPMedium (final substanceNames={\"nitrogen\",\"argon\"});
-
-Create an Instance of REFPROPMedium.Baseproperties: -
-  Medium.BaseProperties props;
-
-You can then use the BaseProperties model to define the actual medium composition (via Xi or X), to define the thermodynamic state and calculate the corresponding properties. -
-  props.p = 1e5;
-  props.T = 300;
-  props.Xi = {.8};
-  d = props.d;
-  h = props.h;
-
-

Any combination of the pressure, temperature, specific enthalpy, specific entropy and density (p,T,h,s,d) can be used to define a -thermodynamic state. Explicit functions for all combinations exist in REFPROP and likewise in the REFPROPMedium package. -The calculation of all variables of a thermodynamic state, however, is by default done by setState_phX, so p and h have to be -calculated from the given combination of two variables first. Actually, by doing this, REFPROP already calculates all variables -of the thermodynamic state, but they cannot be used directly. This is a limitation of DYMOLA, as it is not able to invert a function -returning an array. -You can change the set of variables the property model is explicit for by setting the string variable explicitVars e.g. to \"pT\" or \"dT\": -

-package Medium = REFPROPMedium(final substanceNames={\"water\"}, final explicitVars = \"pT\");
-
-

-

All calculated values are returned in SI-Units and are mass based. -

-

Verbose mode can be switched on globally by setting the variable debugmode to true. This leads to many status messages from the modelica functions - as well as from the compiled library. The latter only appear are only seen in only seen when the dymola.exe is run directly in the command window. - - -

Details

- In order to take advantage of REFPROP's capability of calculating two-phase mixtures a new Medium template had to be created by merging - Modelica.Media.Interfaces.PartialMixtureMedium and Modelica.Media.Interfaces.PartialTwoPhaseMedium of the Modelica Standard Library 3.1. - Alternatively, there is a version of this package limited to single-substance fluids (REFPROPMediumPureSubstance) which uses the standard - template Modelica.Media.Interfaces.PartialTwoPhaseMedium. - All property functions contain a definition of their inverses. So, in many cases no numerical inversion by the solver is needed because - explicit REFPROP functions are used (meaning, numerical inversion happens in REFPROP instead).
- Example: When explicitVars are set to \"ph\" and p and T are given, the specificEnthalpy is calculated first using the inverse function of - Temperature_phX --> specificEnthalpy_pTX. With p and h known all other variables are calculated by setstate_phX. -

- -

-

    -
-

- - -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -", - revisions=" - -"), uses(Modelica(version="3.2"))); -end REFPROPMedium; diff --git a/REFPROPMedium/package.order b/REFPROPMedium/package.order deleted file mode 100644 index 95f6c45..0000000 --- a/REFPROPMedium/package.order +++ /dev/null @@ -1,75 +0,0 @@ -debugmode -explicitVars -fluidnames -rpConstants -ThermodynamicState -BaseProperties -StrJoin -partialREFPROP -getSatProp_REFPROP_check -getSatProp_REFPROP -saturationPressure -saturationTemperature -getProp_REFPROP_check -getProp_REFPROP -setState -specificEntropy -density -dewEnthalpy -dewEntropy -dewDensity -bubbleEnthalpy -bubbleEntropy -bubbleDensity -molarMass -setState_phX -density_phX -temperature_phX -specificEntropy_phX -setState_pTX -density_pTX -specificEnthalpy_pTX -specificEntropy_pTX -setState_psX -temperature_psX -specificEnthalpy_psX -density_psX -setState_pdX -temperature_pdX -specificEnthalpy_pdX -specificEntropy_pdX -setState_ThX -pressure_ThX -density_ThX -specificEntropy_ThX -setState_dTX -pressure_dTX -specificEnthalpy_dTX -specificEntropy_dTX -setState_TsX -pressure_TsX -specificEnthalpy_TsX -density_TsX -setState_hdX -pressure_hdX -temperature_hdX -specificEntropy_hdX -setState_hsX -pressure_hsX -temperature_hsX -density_hsX -setState_dsX -pressure_dsX -temperature_dsX -specificEnthalpy_dsX -setState_pqX -density_pqX -pressure_TqX -specificEnthalpy_pqX -specificEntropy_pqX -temperature_pqX -dynamicViscosity -thermalConductivity -vapourQuality -specificHeatCapacityCp -specificHeatCapacityCv diff --git a/REFPROPMedium/partialREFPROP.mo b/REFPROPMedium/partialREFPROP.mo deleted file mode 100644 index e63fed0..0000000 --- a/REFPROPMedium/partialREFPROP.mo +++ /dev/null @@ -1,9 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -partial function partialREFPROP "Declaration of array props" -//used by getSatProp_REFPROP_check() and getProp_REFPROP_check() - extends Modelica.Icons.Function; -protected - Real[16+2*nX] props; - String errormsg=StrJoin(fill("xxxx",64),"") - "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; -end partialREFPROP; diff --git a/REFPROPMedium/pressure_ThX.mo b/REFPROPMedium/pressure_ThX.mo deleted file mode 100644 index 110c086..0000000 --- a/REFPROPMedium/pressure_ThX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_ThX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_ThX("+String(T)+","+String(h)+",X)..."); - end if; - p :=getProp_REFPROP_check("p", "Th",T,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_pTX(p,T,X,phase), - T=temperature_phX(p,h,X,phase))); -end pressure_ThX; diff --git a/REFPROPMedium/pressure_TqX.mo b/REFPROPMedium/pressure_TqX.mo deleted file mode 100644 index 0493d86..0000000 --- a/REFPROPMedium/pressure_TqX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_TqX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; - //T=quality_pTX(p,T,X,phase) -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_TqX("+String(T)+","+String(q)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "Tq",T,q,X,phase); - annotation(LateInline=true,inverse(T=temperature_pqX(p,q,X,phase))); -end pressure_TqX; diff --git a/REFPROPMedium/pressure_TsX.mo b/REFPROPMedium/pressure_TsX.mo deleted file mode 100644 index 22b56a2..0000000 --- a/REFPROPMedium/pressure_TsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_TsX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_TsX("+String(T)+","+String(s)+",X)..."); - end if; - p :=getProp_REFPROP_check("p", "Ts",T,s,X,phase); - annotation(LateInline=true,inverse(s = specificEntropy_pTX(p,T,X,phase), - T=temperature_psX(p,s,X,phase))); -end pressure_TsX; diff --git a/REFPROPMedium/pressure_dTX.mo b/REFPROPMedium/pressure_dTX.mo deleted file mode 100644 index e8664f0..0000000 --- a/REFPROPMedium/pressure_dTX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_dTX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_dTX("+String(d)+","+String(T)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "dT",d,T,X,phase); - annotation(LateInline=true,inverse(d = density_pTX(p,T,X,phase), - T=temperature_pdX(p,d,X,phase))); -end pressure_dTX; diff --git a/REFPROPMedium/pressure_dsX.mo b/REFPROPMedium/pressure_dsX.mo deleted file mode 100644 index c02f8b5..0000000 --- a/REFPROPMedium/pressure_dsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_dsX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_dsX("+String(d)+","+String(s)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "ds",d,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_pdX(p,d,X,phase), - d=density_psX(p,s,X,phase))); -end pressure_dsX; diff --git a/REFPROPMedium/pressure_hdX.mo b/REFPROPMedium/pressure_hdX.mo deleted file mode 100644 index e35dba0..0000000 --- a/REFPROPMedium/pressure_hdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_hdX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_hdX("+String(h)+","+String(d)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "hd",h,d,X,phase); - annotation(LateInline=true,inverse(d=density_phX(p,h,X,phase), - h=specificEnthalpy_pdX(p,d,X,phase))); -end pressure_hdX; diff --git a/REFPROPMedium/pressure_hsX.mo b/REFPROPMedium/pressure_hsX.mo deleted file mode 100644 index d7b5ad2..0000000 --- a/REFPROPMedium/pressure_hsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_hsX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_hsX("+String(h)+","+String(s)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "hs",h,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_phX(p,h,X,phase), - h=specificEnthalpy_psX(p,s,X,phase))); -end pressure_hsX; diff --git a/REFPROPMedium/setState.mo b/REFPROPMedium/setState.mo deleted file mode 100644 index 487ee63..0000000 --- a/REFPROPMedium/setState.mo +++ /dev/null @@ -1,45 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState "Calculates medium properties" - extends partialREFPROP; - input String statevars; - input Real statevar1; - input Real statevar2; - input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -// Real[:] props=getProps_REFPROP_check(statevars, fluidnames,statevar1, statevar2, X, phase); -/*protected - Real[16+2*nX] props; - String errormsg=StrJoin(fill("xxxx",64),"") - "Allocating memory, string will be written by C function";*/ - -algorithm - assert(size(X,1)>0,"The mass fraction vector must have at least 1 element."); - getProp_REFPROP("",statevars,fluidnames,props,statevar1,statevar2,X,phase,errormsg); - assert(props[1]==0,"Error in REFPROP wrapper function: "+errormsg +"\n"); -/* If q = 990 Then Modelica.Utilities.Streams.print(msg+String(z)) end if; - - If q = 998 Then Quality = Trim2("Superheated vapor with T>Tc") - If q = 999 Then Quality = Trim2("Supercritical state (T>Tc, p>pc)") - If q = -998 Then Quality = Trim2("Subcooled liquid with p>pc")*/ - state := ThermodynamicState( p= props[2], - T= props[3], - X= X, - MM= props[4], - d=props[5], - d_l=props[6], - d_g=props[7], - x=min(max(props[8],0),1), - u=props[9], - h=props[10], - s=props[11], - cv=props[12], - cp=props[13], - c=props[14], - MM_l=props[15], - MM_g=props[16], - X_l=props[17:16+nX], - X_g=props[17+nX:16+2*nX], - phase=if (props[8]>0 and props[8]<1) then 2 else 1); -end setState; diff --git a/REFPROPMedium/setState_ThX.mo b/REFPROPMedium/setState_ThX.mo deleted file mode 100644 index 1d180d0..0000000 --- a/REFPROPMedium/setState_ThX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_ThX "Calculates medium properties from T,h,X" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - input SpecificEnthalpy h "Enthalpy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_ThX("+String(T)+","+String(h)+",X)..."); - end if; - state := setState("Th",T,h,X,phase) ",fluidnames)"; -end setState_ThX; diff --git a/REFPROPMedium/setState_TsX.mo b/REFPROPMedium/setState_TsX.mo deleted file mode 100644 index eca8fb9..0000000 --- a/REFPROPMedium/setState_TsX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_TsX "Calculates medium properties from T,s,X" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - input SpecificEntropy s "Entropy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_TsX("+String(T)+","+String(s)+",X)..."); - end if; - state := setState("Ts",T,s,X,phase) ",fluidnames)"; -end setState_TsX; diff --git a/REFPROPMedium/setState_dsX.mo b/REFPROPMedium/setState_dsX.mo deleted file mode 100644 index 83781be..0000000 --- a/REFPROPMedium/setState_dsX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_dsX "Calculates medium properties from d,s,X" - extends Modelica.Icons.Function; - input Density d "Temperature"; - input SpecificEntropy s "Entropy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_dsX("+String(d)+","+String(s)+",X)..."); - end if; - state := setState("ds",d,s,X,phase) ",fluidnames)"; -end setState_dsX; diff --git a/REFPROPMedium/setState_hdX.mo b/REFPROPMedium/setState_hdX.mo deleted file mode 100644 index bcadcf4..0000000 --- a/REFPROPMedium/setState_hdX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_hdX "Calculates medium properties from h,d,X" - extends Modelica.Icons.Function; - input SpecificEnthalpy h "Enthalpy"; - input Density d "Temperature"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_hdX("+String(h)+","+String(d)+",X)..."); - end if; - state := setState("hd",h,d,X,phase) ",fluidnames)"; -end setState_hdX; diff --git a/REFPROPMedium/setState_hsX.mo b/REFPROPMedium/setState_hsX.mo deleted file mode 100644 index 0fa1127..0000000 --- a/REFPROPMedium/setState_hsX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_hsX "Calculates medium properties from h,s,X" - extends Modelica.Icons.Function; - input SpecificEnthalpy h "Enthalpy"; - input SpecificEntropy s "Entropy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running ("+String(h)+","+String(s)+",X)..."); - end if; - state := setState("hs",h,s,X,phase) ",fluidnames)"; -end setState_hsX; diff --git a/REFPROPMedium/setState_pdX.mo b/REFPROPMedium/setState_pdX.mo deleted file mode 100644 index 0dafcda..0000000 --- a/REFPROPMedium/setState_pdX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_pdX "Calculates medium properties from p,d,X" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Density d "Density"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_pdX("+String(p)+","+String(d)+",X)..."); - end if; - state := setState("pd",p,d,X,phase) ",fluidnames)"; -end setState_pdX; diff --git a/REFPROPMedium/setState_pqX.mo b/REFPROPMedium/setState_pqX.mo deleted file mode 100644 index 5199d57..0000000 --- a/REFPROPMedium/setState_pqX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_pqX "Calculates medium properties from p,q,X" - extends Modelica.Icons.Function; - input Modelica.SIunits.AbsolutePressure p "Pressure"; - input Modelica.SIunits.MassFraction q "quality (vapor mass fraction)"; - input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_pqX("+String(p)+","+String(q)+",X)..."); - end if; - state := setState("pq",p,q,X,phase) ",fluidnames)"; -end setState_pqX; diff --git a/REFPROPMedium/specificEnthalpy_TsX.mo b/REFPROPMedium/specificEnthalpy_TsX.mo deleted file mode 100644 index 171e0c7..0000000 --- a/REFPROPMedium/specificEnthalpy_TsX.mo +++ /dev/null @@ -1,19 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEnthalpy_TsX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_TsX("+String(T)+","+String(s)+",X)"); - end if; - h :=getProp_REFPROP_check("h", "Ts",T,s,X,phase); - annotation(LateInline=true,inverse(s = specificEntropy_ThX(T,h,X,phase), - T=temperature_hsX(h,s,X,phase))); -end specificEnthalpy_TsX; diff --git a/REFPROPMedium/specificEnthalpy_dsX.mo b/REFPROPMedium/specificEnthalpy_dsX.mo deleted file mode 100644 index 548cd1b..0000000 --- a/REFPROPMedium/specificEnthalpy_dsX.mo +++ /dev/null @@ -1,23 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEnthalpy_dsX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -/*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_dsX("+String(d)+","+String(s)+",X)"); - end if; -// h :=getProp_REFPROP_check("h", "ds", fluidnames,d,s,X,phase); - h :=getProp_REFPROP_check("h", "ds", d,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_hdX(h,d,X,phase), - d=density_hsX(h,s,X,phase))); -end specificEnthalpy_dsX; diff --git a/REFPROPMedium/specificEnthalpy_pdX.mo b/REFPROPMedium/specificEnthalpy_pdX.mo deleted file mode 100644 index abb5bb6..0000000 --- a/REFPROPMedium/specificEnthalpy_pdX.mo +++ /dev/null @@ -1,19 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEnthalpy_pdX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_pdX("+String(p)+","+String(d)+",X)..."); - end if; -// h :=getProp_REFPROP_check("h", "pd", fluidnames,p,d,X,phase); - h :=getProp_REFPROP_check("h", "pd", p,d,X,phase); - annotation(LateInline=true,inverse(d = density_phX(p,h,X,phase), - p=pressure_hdX(h,d,X,phase))); -end specificEnthalpy_pdX; diff --git a/REFPROPMedium/specificEnthalpy_pqX.mo b/REFPROPMedium/specificEnthalpy_pqX.mo deleted file mode 100644 index 4b6abfc..0000000 --- a/REFPROPMedium/specificEnthalpy_pqX.mo +++ /dev/null @@ -1,17 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEnthalpy_pqX - "calls REFPROP-Wrapper, returns specific enthalpy" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -// annotation(LateInline=true,inverse(p = pressure_hqX(h,q,X,phase),quality_phX(p,h,X,phase))); -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_pqX("+String(p)+","+String(q)+",X)"); - end if; -// h :=getProp_REFPROP_check("h", "pq", fluidnames,p,q,X,phase); - h :=getProp_REFPROP_check("h", "pq", p,q,X,phase); -end specificEnthalpy_pqX; diff --git a/REFPROPMedium/specificEntropy_ThX.mo b/REFPROPMedium/specificEntropy_ThX.mo deleted file mode 100644 index 168b2a8..0000000 --- a/REFPROPMedium/specificEntropy_ThX.mo +++ /dev/null @@ -1,20 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEntropy_ThX - extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -/*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_ThX("+String(T)+","+String(h)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "Th",T,h,X,phase); - annotation(LateInline=true,inverse(h = specificEnthalpy_TsX(T,s,X,phase), - T=temperature_hsX(h,s,X,phase))); -end specificEntropy_ThX; diff --git a/REFPROPMedium/specificEntropy_dTX.mo b/REFPROPMedium/specificEntropy_dTX.mo deleted file mode 100644 index f18a891..0000000 --- a/REFPROPMedium/specificEntropy_dTX.mo +++ /dev/null @@ -1,17 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEntropy_dTX - extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_dTX("+String(d)+","+String(T)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "dT",d,T,X,phase); - annotation(LateInline=true,inverse(d = density_TsX(T,s,X,phase), - T=temperature_dsX(d,s,X,phase))); -end specificEntropy_dTX; diff --git a/REFPROPMedium/specificEntropy_hdX.mo b/REFPROPMedium/specificEntropy_hdX.mo deleted file mode 100644 index bd4de6f..0000000 --- a/REFPROPMedium/specificEntropy_hdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEntropy_hdX - extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_hdX("+String(h)+","+String(d)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "hd",h,d,X,phase); - annotation(LateInline=true,inverse(d=density_hsX(h,s,X,phase), - h=specificEnthalpy_dsX(d,s,X,phase))); -end specificEntropy_hdX; diff --git a/REFPROPMedium/specificEntropy_pdX.mo b/REFPROPMedium/specificEntropy_pdX.mo deleted file mode 100644 index 5401d50..0000000 --- a/REFPROPMedium/specificEntropy_pdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEntropy_pdX - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_pdX("+String(p)+","+String(d)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "pd",p,d,X,phase); - annotation(LateInline=true,inverse(d = density_psX(p,s,X,phase), - p=pressure_dsX(d,s,X,phase))); -end specificEntropy_pdX; diff --git a/REFPROPMedium/specificEntropy_phX.mo b/REFPROPMedium/specificEntropy_phX.mo deleted file mode 100644 index 61652e1..0000000 --- a/REFPROPMedium/specificEntropy_phX.mo +++ /dev/null @@ -1,21 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEntropy_phX - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -/*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_phX("+String(p)+","+String(h)+",X)..."); - // p="+String(p)+",h="+String(h)+", X={"+String(X[1])+","+String(X[2])+"}"); - end if; - s:=getProp_REFPROP_check("s", "ph",p,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_psX(p,s,X,phase), - p=pressure_hsX(h,s,X,phase))); -end specificEntropy_phX; diff --git a/REFPROPMedium/specificEntropy_pqX.mo b/REFPROPMedium/specificEntropy_pqX.mo deleted file mode 100644 index 5de1d4b..0000000 --- a/REFPROPMedium/specificEntropy_pqX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEntropy_pqX "calls REFPROP-Wrapper, returns specific entropy" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -// annotation(LateInline=true,inverse(p = pressure_sqX(s,q,X,phase),q=quality_psX(p,s,X,phase)); -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_pqX("+String(p)+","+String(q)+",X)"); - end if; - s :=getProp_REFPROP_check("s", "pq",p,q,X,phase); -end specificEntropy_pqX; diff --git a/REFPROPMedium/temperature_dsX.mo b/REFPROPMedium/temperature_dsX.mo deleted file mode 100644 index 5c220fc..0000000 --- a/REFPROPMedium/temperature_dsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function temperature_dsX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_dsX("+String(d)+","+String(s)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "ds",d,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_dTX(d,T,X,phase), - d=density_TsX(T,s,X,phase))); -end temperature_dsX; diff --git a/REFPROPMedium/temperature_hdX.mo b/REFPROPMedium/temperature_hdX.mo deleted file mode 100644 index debe323..0000000 --- a/REFPROPMedium/temperature_hdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function temperature_hdX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_hdX("+String(h)+","+String(d)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "hd",h,d,X,phase); - annotation(LateInline=true,inverse(d=density_ThX(T,h,X,phase), - h=specificEnthalpy_dTX(d,T,X,phase))); -end temperature_hdX; diff --git a/REFPROPMedium/temperature_hsX.mo b/REFPROPMedium/temperature_hsX.mo deleted file mode 100644 index 4864bb4..0000000 --- a/REFPROPMedium/temperature_hsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function temperature_hsX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_hsX("+String(h)+","+String(s)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "hs",h,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_ThX(T,h,X,phase), - h=specificEnthalpy_TsX(T,s,X,phase))); -end temperature_hsX; diff --git a/REFPROPMedium/temperature_pdX.mo b/REFPROPMedium/temperature_pdX.mo deleted file mode 100644 index e03d68b..0000000 --- a/REFPROPMedium/temperature_pdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function temperature_pdX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_psX("+String(p)+","+String(d)+",X)..."); - end if; - T :=getProp_REFPROP_check("T", "pd",p,d,X,phase); - annotation(LateInline=true,inverse(d=density_pTX(p,T,X,phase), - p=pressure_dTX(d,T,X,phase))); -end temperature_pdX; diff --git a/REFPROPMedium/temperature_pqX.mo b/REFPROPMedium/temperature_pqX.mo deleted file mode 100644 index 98a382a..0000000 --- a/REFPROPMedium/temperature_pqX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function temperature_pqX -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input MassFraction q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -// annotation(LateInline=true,inverse(p = pressure_TqX(T,q,X,phase),q=quality_pTX(p,T,X,phase)); -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_pqX("+String(p)+","+String(q)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "pq",p,q,X,phase); -end temperature_pqX; diff --git a/REFPROPMediumPureSubstance/StrJoin.mo b/REFPROPMediumPureSubstance/StrJoin.mo deleted file mode 100644 index 632a94b..0000000 --- a/REFPROPMediumPureSubstance/StrJoin.mo +++ /dev/null @@ -1,11 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function StrJoin "Converts an Array of Strings into a string separated by |" - input String[:] s_in; - input String delimiter; - output String s_out; -algorithm - s_out :=s_in[1]; - for i in 2:size(s_in,1) loop - s_out :=s_out + delimiter + s_in[i]; - end for; -end StrJoin; diff --git a/REFPROPMediumPureSubstance/density_ThX.mo b/REFPROPMediumPureSubstance/density_ThX.mo deleted file mode 100644 index cbdecc1..0000000 --- a/REFPROPMediumPureSubstance/density_ThX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function density_ThX "calls REFPROP-Wrapper, returns density" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_ThX("+String(T)+","+String(h)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "Th",T,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_dTX(d,T,X,phase), - T=temperature_hdX(h,d,X,phase))); -end density_ThX; diff --git a/REFPROPMediumPureSubstance/density_TsX.mo b/REFPROPMediumPureSubstance/density_TsX.mo deleted file mode 100644 index f305235..0000000 --- a/REFPROPMediumPureSubstance/density_TsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function density_TsX "calls REFPROP-Wrapper, returns density" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_TsX("+String(T)+","+String(s)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "Ts",T,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_dTX(d,T,X,phase), - T=temperature_dsX(d,s,X,phase))); -end density_TsX; diff --git a/REFPROPMediumPureSubstance/density_hsX.mo b/REFPROPMediumPureSubstance/density_hsX.mo deleted file mode 100644 index 812b528..0000000 --- a/REFPROPMediumPureSubstance/density_hsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function density_hsX "calls REFPROP-Wrapper, returns density" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_hsX("+String(h)+","+String(s)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "hs",h,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_hdX(h,d,X,phase), - h=specificEnthalpy_dsX(d,s,X,phase))); -end density_hsX; diff --git a/REFPROPMediumPureSubstance/density_pqX.mo b/REFPROPMediumPureSubstance/density_pqX.mo deleted file mode 100644 index d493d76..0000000 --- a/REFPROPMediumPureSubstance/density_pqX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function density_pqX "calls REFPROP-Wrapper, returns specific density" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_pqX("+String(p)+","+String(q)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "pq",p,q,X,phase); -/* annotation(LateInline=true,inverse(p=pressure_dqX(d,q,X,phase), - q=quality_pdX(p,d,X,phase)));*/ -end density_pqX; diff --git a/REFPROPMediumPureSubstance/getProp_REFPROP.mo b/REFPROPMediumPureSubstance/getProp_REFPROP.mo deleted file mode 100644 index 5d9ae73..0000000 --- a/REFPROPMediumPureSubstance/getProp_REFPROP.mo +++ /dev/null @@ -1,19 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function getProp_REFPROP - "calls C function with property identifier & returns single property" - input String what2calc; - input String statevars; - input String fluidnames; - input Real[:] props; - input Real statevar1; - input Real statevar2; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - input String errormsg; -// input Integer debug=1; - output Real val; - - external "C" val = props_REFPROP(what2calc, statevars, fluidnames, props, statevar1, statevar2, X, phase, REFPROP_PATH, errormsg, debugmode); - -annotation (Include="#include ", Library="REFPROP_wrapper"); -end getProp_REFPROP; diff --git a/REFPROPMediumPureSubstance/getProp_REFPROP_check.mo b/REFPROPMediumPureSubstance/getProp_REFPROP_check.mo deleted file mode 100644 index d8e383f..0000000 --- a/REFPROPMediumPureSubstance/getProp_REFPROP_check.mo +++ /dev/null @@ -1,23 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function getProp_REFPROP_check - "wrapper for getProp_REFPROP returning 1 property value with error check" - extends partialREFPROP; - input String what2calc; - input String statevars; -// input String fluidnames; - input Real statevar1; - input Real statevar2; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Real val; -algorithm - assert(size(X,1)>0,"The mass fraction vector must have at least 1 element."); - -// Modelica.Utilities.Streams.print("Calc "+what2calc); - val :=getProp_REFPROP(what2calc,statevars,fluidnames,props,statevar1,statevar2,X,phase,errormsg) - "just passing through"; - -// Modelica.Utilities.Streams.print("ERR("+String(props[1])+"):"+errormsg); - assert(props[1]==0,"Errorcode "+String(props[1])+" in REFPROP wrapper function:\n"+errormsg +"\n"); - -end getProp_REFPROP_check; diff --git a/REFPROPMediumPureSubstance/getSatProp_REFPROP.mo b/REFPROPMediumPureSubstance/getSatProp_REFPROP.mo deleted file mode 100644 index becabb7..0000000 --- a/REFPROPMediumPureSubstance/getSatProp_REFPROP.mo +++ /dev/null @@ -1,17 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function getSatProp_REFPROP - "calls C function with property identifier & returns single property" - input String what2calc; - input String statevar; - input String fluidnames; - input Real[:] props; - input Real statevarval; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input String errormsg; - output Real val; -// input Integer debugmode=1; - - external "C" val = satprops_REFPROP(what2calc, statevar, fluidnames, props, statevarval, X, REFPROP_PATH, errormsg, debugmode); - - annotation (Include="#include ", Library="REFPROP_wrapper"); -end getSatProp_REFPROP; diff --git a/REFPROPMediumPureSubstance/getSatProp_REFPROP_check.mo b/REFPROPMediumPureSubstance/getSatProp_REFPROP_check.mo deleted file mode 100644 index 935173d..0000000 --- a/REFPROPMediumPureSubstance/getSatProp_REFPROP_check.mo +++ /dev/null @@ -1,21 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function getSatProp_REFPROP_check - "wrapper for getSatProp_REFPROP returning 1 property value with error check" - extends partialREFPROP; - input String what2calc; - input String statevar; -// input String fluidnames; - input Real statevarval; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - output Real val; -algorithm - assert(size(X,1)>0,"The mass fraction vector must have at least 1 element."); - val :=getSatProp_REFPROP(what2calc,statevar,fluidnames,props,statevarval,X,errormsg) - "just passing through"; -//Error string decoding in wrapper-c-function - assert(props[1]==0 or props[1]==141,"Errorcode "+String(props[1])+" in REFPROP wrapper function:\n"+errormsg +"\n"); - if props[1]==141 then - Modelica.Utilities.Streams.print("Saturation properties cannot be calculated, because P > p_crit!..."); - val :=-999; - end if; -end getSatProp_REFPROP_check; diff --git a/REFPROPMediumPureSubstance/package.mo b/REFPROPMediumPureSubstance/package.mo deleted file mode 100644 index e96e706..0000000 --- a/REFPROPMediumPureSubstance/package.mo +++ /dev/null @@ -1,592 +0,0 @@ -within MediaTwoPhaseMixture; -package REFPROPMediumPureSubstance "Two Phase single component two-phase medium whose property functions are supplied by REFPROP (via wrapper for refprop.dll). Extends PartialTwoPhaseMedium." -/*To create this package, REFPROPMedium has been copied and the following things have been changed: --"extends PartialMixtureTwoPhaseMedium" -> "extends Modelica.Media.Interfaces.PartialTwoPhaseMedium" --redeclare record SaturationProperties --added preset X to saturationTemperature() and saturationPressure() --added s and sat in BaseProperties --add p,T,X in ThermodynamicState --for specificEnthalpy_dTX: redeclare function -> function --remove X from ThermodynamicState and SaturationState -*/ - - -redeclare record extends SaturationProperties -// MassFraction X[nX] "Mass fractions"; -end SaturationProperties; - - -redeclare function extends saturationPressure -// extends Modelica.Icons.Function; -// input MassFraction X[:]={1} "fluid composition as mass fractions"; -algorithm - p := getSatProp_REFPROP_check("p", "T",T,reference_X); -end saturationPressure; - - -redeclare function extends saturationTemperature -// extends Modelica.Icons.Function; -// input MassFraction X[:]={1} "fluid composition as mass fractions"; -algorithm - T := getSatProp_REFPROP_check("T", "p",p,reference_X); -end saturationTemperature; -constant Boolean debugmode = false - "print messages in functions and in refpropwrapper.lib (to see the latter, start dymosim.exe in command window)"; - -constant String explicitVars = "ph" - "set of variables the model is explicit for, may be set to all combinations of p,h,T,d,s,d, REFPROP works internally with dT"; -final constant String fluidnames= StrJoin(substanceNames,"|"); - - -extends Modelica.Media.Interfaces.PartialTwoPhaseMedium( - mediumName="REFPROP Medium", - final singleState=false, - fluidConstants=rpConstants); -//"mediumName is being checked for consistency at flowports" - - constant FluidConstants[nS] rpConstants( - each chemicalFormula = "REFPROP Medium", - each structureFormula="REFPROP Medium", - each casRegistryNumber="007", - each iupacName="REFPROP Medium", - each molarMass=0.1, - each criticalTemperature = 600, - each criticalPressure = 300e5, - each criticalMolarVolume = 1, - each acentricFactor = 1, - each triplePointTemperature = 273.15, - each triplePointPressure = 1e5, - each meltingPoint = 1, - each normalBoilingPoint = 1, - each dipoleMoment = 1); - - -redeclare record extends ThermodynamicState - "a selection of variables that uniquely defines the thermodynamic state" - AbsolutePressure p "Absolute pressure of medium"; - Temperature T "Temperature of medium"; -// MassFraction X[nX] "Composition (Mass fractions in kg/kg)";/**/ - MolarMass MM "Molar Mass of the whole mixture"; - Density d(start=300) "density"; - Density d_l(start=300) "density liquid phase"; - Density d_g(start=300) "density gas phase"; - Real x "vapor quality on a mass basis [mass vapor/total mass]"; - SpecificEnergy u "Specific energy"; - SpecificEnthalpy h "Specific enthalpy"; - SpecificEntropy s "Specific entropy"; - Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; - Modelica.SIunits.SpecificHeatCapacityAtConstantVolume cv; - VelocityOfSound c; -// MolarMass MM_l "Molar Mass of liquid phase"; -// MolarMass MM_g "Molar Mass of gas phase"; -// MassFraction X_l[nX] "Composition of liquid phase (Mass fractions in kg/kg)"; -// MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; -// Real GVF "Gas Void Fraction"; -end ThermodynamicState; - - - redeclare model extends BaseProperties "Base properties of medium" - - Modelica.SIunits.SpecificEntropy s; - SaturationProperties sat "Saturation properties at the medium pressure"; - equation - u = h - p/d - "state.u - calculated anyway by REFPROP, but this way the expression can be derived symbolically"; - MM = state.MM; - R = 1 "Modelica.Constants.R/MM"; - - //ph-explicit - if explicitVars=="ph" or explicitVars=="hp" then - state = setState_phX(p,h,X,0) ",fluidnames)"; - T = temperature_phX(p,h,X) - "double calculation, but necessary if T is given"; - // T = state.T "can be used instead"; - - s = specificEntropy_phX(p,h,X) - "double calculation, but necessary if s is given"; - // s = state.s "can be used instead"; - - d = density_phX(p,h,X) "double calculation, but necessary if d is given"; - //d = state.d "can be used instead"; - elseif explicitVars=="pT" or explicitVars=="Tp" then - //pT-explicit - state = setState_pTX(p,T,X,0) ",fluidnames)"; - h = specificEnthalpy_pTX(p,T,X) - "double calculation, but necessary if s is given"; - //h = state.h "can be used instead"; - - s = specificEntropy_pTX(p,T,X) - "state.s double calculation, but necessary if s is given"; - // s = state.s "can be used instead"; - - d = density_pTX(p,T,X) - "state.d double calculation, but necessary if d is given"; - //d = state.d "can be used instead"; - elseif explicitVars=="dT" or explicitVars=="Td" then - //Td-explicit - state = setState_dTX(d,T,X,0) ",fluidnames)"; - h = specificEnthalpy_dTX(d,T,X) - "double calculation, but necessary if s is given"; - //h = state.h "can be used instead"; - - s = specificEntropy_dTX(d,T,X) - "state.s double calculation, but necessary if s is given"; - // s = state.s "can be used instead"; - p = pressure_dTX(d,T,X) - "state.d double calculation, but necessary if d is given"; - // p = state.p "can be used instead"; - elseif explicitVars=="ps" or explicitVars=="ps" then - state = setState_psX(p,s,X,0) ",fluidnames)"; - T = temperature_psX(p,s,X); - h = specificEnthalpy_psX(p,s,X); - d = density_psX(p,s,X); - elseif explicitVars=="pd" or explicitVars=="pd" then - state = setState_pdX(p,d,X,0) ",fluidnames)"; - T = temperature_pdX(p,d,X); - h = specificEnthalpy_pdX(p,d,X); - s = specificEntropy_pdX(p,d,X); - elseif explicitVars=="hT" or explicitVars=="Th" then - state = setState_ThX(T,h,X,0) ",fluidnames)"; - p = pressure_ThX(T,h,X); - s = specificEntropy_ThX(T,h,X); - d = density_ThX(T,h,X); - elseif explicitVars=="sT" or explicitVars=="Ts" then - state = setState_TsX(T,s,X,0) ",fluidnames)"; - p = pressure_TsX(T,s,X); - h = specificEnthalpy_TsX(T,s,X); - d = density_TsX(T,s,X); - elseif explicitVars=="hd" or explicitVars=="hd" then - state = setState_hdX(h,d,X,0) ",fluidnames)"; - p = pressure_hdX(h,d,X); - s = specificEntropy_hdX(h,d,X); - T = temperature_hdX(h,d,X); - elseif explicitVars=="hs" or explicitVars=="sh" then - state = setState_hsX(h,s,X,0) ",fluidnames)"; - p = pressure_hsX(h,s,X); - T = temperature_hsX(h,s,X); - d = density_hsX(h,s,X); - elseif explicitVars=="sd" or explicitVars=="ds" then - state = setState_dsX(d,s,X,0) ",fluidnames)"; - p = pressure_dsX(d,s,X); - h = specificEnthalpy_dsX(d,s,X); - T = temperature_dsX(d,s,X); - end if; - - sat.psat = p; - sat.Tsat = saturationTemperature(p); - // sat.X = X; - annotation (Documentation(info=" - - The baseproperties model is explicit for one set of 2 variables, which can be chosen to be ph, pT, ps, pd, Th, dT, Ts, hd, hs, ds (set explicitVars when calling this package or in package).
- That means, that if only one of these variables is explicitly given, the other one is calculated by inverting its property function.
- Then alle state variables are calculated using the corresponding setstate_XX function.
- In order to avoid numerical inversion by the solver, 3 state variables are set explicitly using their respective property function, which has its inverses defined.
- Example: So for p and h as explicit variables a state given by p and T is calculated by first calculating h with specificEnthalpy_pTX (inverse function of temperature_phX), - then calculating the other variables using setState_phX. s and d, however, are then calculated, although they are already known in the state variable.
- Knowing this, the baseproperty model can be adapted to your calculation needs to decrease computation time: -

    -
  • Choose the explicitVars to the combination occurring most often in your model. (The combination dT might be favorable, because it is used by REFPROP's internal algorithm.)
  • -
  • if you are sure, that it won't be needed, in BaseProperties replace explicit calculation of T/s/d/h with definition as state (commented line)
  • -
- ")); - end BaseProperties; - - - redeclare function extends specificEntropy - "Return specific entropy - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" - algorithm - s := state.s; - end specificEntropy; - - - redeclare replaceable function extends density - "returns density from state - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" - algorithm - d := state.d; - end density; - - -redeclare function extends dewEnthalpy "dew curve specific enthalpy" - extends Modelica.Icons.Function; -algorithm - hv := getProp_REFPROP_check("h", "pq", sat.psat,1,reference_X,1); -end dewEnthalpy; - - - redeclare function extends dewEntropy "dew curve specific entropy of water" - extends Modelica.Icons.Function; - algorithm - sv := getProp_REFPROP_check("s", "pq", sat.psat,1,reference_X,1); - end dewEntropy; - - - redeclare function extends dewDensity "dew curve specific density of water" - extends Modelica.Icons.Function; - algorithm - dv := getProp_REFPROP_check("d", "pq", sat.psat,1,reference_X,1); - end dewDensity; - - - redeclare function extends bubbleEnthalpy - "boiling curve specific enthalpy of water" - extends Modelica.Icons.Function; - algorithm - hl := getProp_REFPROP_check("h", "pq", sat.psat,0,reference_X,1); - end bubbleEnthalpy; - - - redeclare function extends bubbleEntropy - "boiling curve specific entropy of water" - extends Modelica.Icons.Function; - algorithm - sl := getProp_REFPROP_check("s", "pq", sat.psat,0,reference_X,1); - end bubbleEntropy; - - - redeclare function extends bubbleDensity - "boiling curve specific density of water" - extends Modelica.Icons.Function; - algorithm - dl := getProp_REFPROP_check("d", "pq", sat.psat,0,reference_X,1); - end bubbleDensity; - - -redeclare replaceable partial function extends molarMass - "Return the molar mass of the medium" - extends Modelica.Icons.Function; -algorithm - MM:=state.MM; -end molarMass; - - -redeclare replaceable partial function extends setState_phX - "Calculates medium properties from p,h,X" - // input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_phX("+String(p)+","+String(h)+",X)..."); - end if; - state := setState("ph",p,h,X,phase) ",fluidnames)"; -end setState_phX; - - - redeclare function density_phX "calls REFPROP-Wrapper, returns density" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X - "composition defined by mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_phX("+String(p)+","+String(h)+",X)"); - end if; - // p="+String(p)+",h="+String(h)+", X={"+String(X[1])+","+String(X[2])+"}"); - d :=getProp_REFPROP_check("d", "ph",p,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_pdX(p,d,X,phase), - p=pressure_hdX(h,d,X,phase))); - end density_phX; - - - redeclare function temperature_phX - "calls REFPROP-Wrapper, returns temperature" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_phX("+String(p)+","+String(h)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "ph",p,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_pTX(p,T,X,phase), - p=pressure_ThX(T,h,X,phase))); - end temperature_phX; - - -redeclare replaceable partial function extends setState_pTX -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_pTX("+String(p)+","+String(T)+",X)..."); - end if; - state := setState("pT",p,T,X,phase) ",fluidnames)"; -end setState_pTX; - - - redeclare function density_pTX "calls REFPROP-Wrapper, returns density" - extends Modelica.Icons.Function; - // input String fluidnames; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_pTX("+String(p)+","+String(T)+",X)..."); - end if; - d :=getProp_REFPROP_check("d", "pT",p,T,X,phase); - annotation(LateInline=true,inverse(T=temperature_pdX(p,d,X,phase), - p=pressure_dTX(d,T,X,phase))); - end density_pTX; - - - redeclare function specificEnthalpy_pTX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - // input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; - /*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_pTX("+String(p)+","+String(T)+",X)..."); - end if; - // p="+String(p)+",T="+String(T)+", X={"+String(X[1])+","+String(X[2])+"}"); - h :=getProp_REFPROP_check("h", "pT",p,T,X,phase); - annotation(LateInline=true,inverse(T=temperature_phX(p,h,X,phase), - p=pressure_ThX(T,h,X,phase))); - end specificEnthalpy_pTX; - - - redeclare function specificEntropy_pTX - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_pTX("+String(p)+","+String(T)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "pT",p,T,X,phase); - annotation(LateInline=true,inverse(T=temperature_psX(p,s,X,phase), - p=pressure_TsX(T,s,X,phase))); - end specificEntropy_pTX; - - -redeclare replaceable partial function extends setState_psX - "Calculates medium properties from p,s,X" -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_psX("+String(p)+","+String(s)+",X)..."); - end if; - state := setState("ps",p,s,X,phase) ",fluidnames)"; -end setState_psX; - - - redeclare function temperature_psX - "calls REFPROP-Wrapper, returns temperature" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_psX("+String(p)+","+String(s)+",X)..."); - end if; - T :=getProp_REFPROP_check("T", "ps",p,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_pTX(p,T,X,phase), - p=pressure_TsX(T,s,X,phase))); - end temperature_psX; - - - redeclare function specificEnthalpy_psX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - // input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; - /*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_psX("+String(p)+","+String(s)+",X)..."); - end if; - h :=getProp_REFPROP_check("h", "ps",p,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_phX(p,h,X,phase), - p=pressure_hsX(h,s,X,phase))); - end specificEnthalpy_psX; - - - redeclare function density_psX "calls REFPROP-Wrapper, returns density" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_psX("+String(p)+","+String(s)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "ps",p,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_pdX(p,d,X,phase), - p=pressure_dsX(d,s,X,phase))); - end density_psX; - - -redeclare replaceable partial function extends setState_dTX -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_dTX("+String(d)+","+String(T)+",X)..."); - end if; - state := setState("dT",d,T,X,phase) ",fluidnames)"; -end setState_dTX; - - -redeclare function extends dynamicViscosity -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running dynamicViscosity"); - end if; - eta := getProp_REFPROP_check("v", "Td",state.T,state.d,state.X,state.phase); -end dynamicViscosity; - - -redeclare function extends thermalConductivity -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running thermalConductivity"); - end if; - lambda := getProp_REFPROP_check("l", "Td",state.T,state.d,state.X,state.phase); -end thermalConductivity; - - - redeclare function extends specificHeatCapacityCp - - algorithm - cp:=state.cp; - end specificHeatCapacityCp; - - - redeclare function extends specificHeatCapacityCv - - algorithm - cv:=state.cv; - end specificHeatCapacityCv; - - -redeclare function pressure "Return pressure from state record" - input ThermodynamicState state "Thermodynamic state record"; - output Modelica.SIunits.Pressure p "Vapour quality"; -algorithm - p := state.p; -end pressure; - - -redeclare function specificEnthalpy - "Return specific enthalpy from state record" - input ThermodynamicState state "Thermodynamic state record"; - output Modelica.SIunits.SpecificEnthalpy h "Vapour quality"; -algorithm - h := state.h; -end specificEnthalpy; - - -redeclare function vapourQuality "Return vapour quality" - input ThermodynamicState state "Thermodynamic state record"; - output MassFraction x "Vapour quality"; -algorithm - x := state.x; -end vapourQuality; - - - annotation (Documentation(info=" -

-REFPROPMediumPureSubstance is a package that delivers REFPROP data to a model based on and compatible to the Modelica.Media library. -It can be used to calculate two-phase states of all fluids whose data is delivered with REFPROP. It has been developed and tested only in Dymola up to 2012 FD01. -

-

-All files in this library, including the C source files are released under the Modelica License 2. -

-

Installation

-The installation basically consists in copying 2 files and changing one line in this package: -
    -
  • We need access to the REFPROP.DLL and to the Fluid-Data directory in the REFPROP directory. - So you need to set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of this parent package). - Make sure you mask the backslashes. It should look something like -
    constant String REFPROP_PATH = \"C:\\\\Program Files\\\\REFPROP\\\\\";
  • -
  • We need REFPROP_WRAPPER.LIB in %DYMOLADIR%\\BIN\\LIB\ and REFPROP_WRAPPER.H in %DYMOLADIR%\\SOURCE\\ (%DYMOLADIR% is DYMOLA's program directory)
  • -
-This package needs the package PartialMixtureMediumTwoPhase which should be included in the parent package. - -

-

Usage

-Being based on Modelica.Media, it is used like the two-phase water model:
-Create an Instance of REFPROPMediumPureSubstance and pass the components.defines the medium components (medium names are the names of the .fld files in the %REFPROP%\\fluids directory): -
-  package Medium = REFPROPMediumPureSubstance (final substanceNames={\"nitrogen\"});
-
-Create an Instance of REFPROPMediumPureSubstance.Baseproperties: -
-  Medium.BaseProperties props;
-
-You can then use the Baseproperties model to define the thermodynamic state and calculate the corresponding properties. -
-  props.p = 1e5;
-  props.T = 300;
-  d = props.d;
-  h = props.h;
-
-

Any combination of the pressure, temperature, specific enthalpy, specific entropy and density (p,T,h,s,d) can be used to define a -thermodynamic state. Explicit functions for all combinations exist in REFPROP and likewise in the REFPROPMedium package. -The calculation of all variables of a thermodynamic state, however, is by default done by setState_phX, so p and h have to be -calculated from the given combination of two variables first. Actually, by doing this, REFPROP already calculates all variables -of the thermodynamic state, but they cannot be used directly. This is a limitation of DYMOLA, as it is not able to invert a function -returning an array. -You can change the set of variables the property model is explicit for by setting the string variable explicitVars e.g. to \"pT\" or \"dT\": -

-package Medium = REFPROPMedium(final substanceNames={\"water\"}, final explicitVars = \"pT\");
-
-

-

All calculated values are returned in SI-Units and are mass based. -

- - -

Details

- All property functions contain a definition of their inverses. So, in many cases no numerical inversion by the solver is needed because - explicit REFPROP functions are used (meaning, numerical inversion happens in REFPROP instead).
- Example: When explicitVars are set to \"ph\" and p and T are given, the specificEnthalpy is calculated first using the inverse function of - Temperature_phX --> specificEnthalpy_pTX. With p and h known all other variables are calculated by setstate_phX. -

- -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -", - revisions=" - -")); -end REFPROPMediumPureSubstance; diff --git a/REFPROPMediumPureSubstance/package.order b/REFPROPMediumPureSubstance/package.order deleted file mode 100644 index 4a5597f..0000000 --- a/REFPROPMediumPureSubstance/package.order +++ /dev/null @@ -1,78 +0,0 @@ -SaturationProperties -saturationPressure -saturationTemperature -debugmode -explicitVars -fluidnames -rpConstants -ThermodynamicState -BaseProperties -StrJoin -partialREFPROP -getSatProp_REFPROP_check -getSatProp_REFPROP -getProp_REFPROP_check -getProp_REFPROP -setState -specificEntropy -density -dewEnthalpy -dewEntropy -dewDensity -bubbleEnthalpy -bubbleEntropy -bubbleDensity -molarMass -setState_phX -density_phX -temperature_phX -specificEntropy_phX -setState_pTX -density_pTX -specificEnthalpy_pTX -specificEntropy_pTX -setState_psX -temperature_psX -specificEnthalpy_psX -density_psX -setState_pdX -temperature_pdX -specificEnthalpy_pdX -specificEntropy_pdX -setState_ThX -pressure_ThX -density_ThX -specificEntropy_ThX -setState_dTX -pressure_dTX -specificEnthalpy_dTX -specificEntropy_dTX -setState_TsX -pressure_TsX -specificEnthalpy_TsX -density_TsX -setState_hdX -pressure_hdX -temperature_hdX -specificEntropy_hdX -setState_hsX -pressure_hsX -temperature_hsX -density_hsX -setState_dsX -pressure_dsX -temperature_dsX -specificEnthalpy_dsX -setState_pqX -density_pqX -pressure_TqX -specificEnthalpy_pqX -specificEntropy_pqX -temperature_pqX -dynamicViscosity -thermalConductivity -specificHeatCapacityCp -specificHeatCapacityCv -pressure -specificEnthalpy -vapourQuality diff --git a/REFPROPMediumPureSubstance/partialREFPROP.mo b/REFPROPMediumPureSubstance/partialREFPROP.mo deleted file mode 100644 index 1211a40..0000000 --- a/REFPROPMediumPureSubstance/partialREFPROP.mo +++ /dev/null @@ -1,9 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -partial function partialREFPROP "Declaration of array props" -//used by getSatProp_REFPROP_check() and getProp_REFPROP_check() - extends Modelica.Icons.Function; -protected - Real[16+2*nX] props; - String errormsg=StrJoin(fill("xxxx",64),"") - "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; -end partialREFPROP; diff --git a/REFPROPMediumPureSubstance/pressure_ThX.mo b/REFPROPMediumPureSubstance/pressure_ThX.mo deleted file mode 100644 index d976431..0000000 --- a/REFPROPMediumPureSubstance/pressure_ThX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_ThX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_ThX("+String(T)+","+String(h)+",X)..."); - end if; - p :=getProp_REFPROP_check("p", "Th",T,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_pTX(p,T,X,phase), - T=temperature_phX(p,h,X,phase))); -end pressure_ThX; diff --git a/REFPROPMediumPureSubstance/pressure_TqX.mo b/REFPROPMediumPureSubstance/pressure_TqX.mo deleted file mode 100644 index 1dbbf7c..0000000 --- a/REFPROPMediumPureSubstance/pressure_TqX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_TqX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; - //T=quality_pTX(p,T,X,phase) -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_TqX("+String(T)+","+String(q)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "Tq",T,q,X,phase); - annotation(LateInline=true,inverse(T=temperature_pqX(p,q,X,phase))); -end pressure_TqX; diff --git a/REFPROPMediumPureSubstance/pressure_TsX.mo b/REFPROPMediumPureSubstance/pressure_TsX.mo deleted file mode 100644 index ce0e7ef..0000000 --- a/REFPROPMediumPureSubstance/pressure_TsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_TsX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_TsX("+String(T)+","+String(s)+",X)..."); - end if; - p :=getProp_REFPROP_check("p", "Ts",T,s,X,phase); - annotation(LateInline=true,inverse(s = specificEntropy_pTX(p,T,X,phase), - T=temperature_psX(p,s,X,phase))); -end pressure_TsX; diff --git a/REFPROPMediumPureSubstance/pressure_dTX.mo b/REFPROPMediumPureSubstance/pressure_dTX.mo deleted file mode 100644 index b5c5b99..0000000 --- a/REFPROPMediumPureSubstance/pressure_dTX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_dTX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_dTX("+String(d)+","+String(T)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "dT",d,T,X,phase); - annotation(LateInline=true,inverse(d = density_pTX(p,T,X,phase), - T=temperature_pdX(p,d,X,phase))); -end pressure_dTX; diff --git a/REFPROPMediumPureSubstance/pressure_dsX.mo b/REFPROPMediumPureSubstance/pressure_dsX.mo deleted file mode 100644 index 22e45c9..0000000 --- a/REFPROPMediumPureSubstance/pressure_dsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_dsX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_dsX("+String(d)+","+String(s)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "ds",d,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_pdX(p,d,X,phase), - d=density_psX(p,s,X,phase))); -end pressure_dsX; diff --git a/REFPROPMediumPureSubstance/pressure_hdX.mo b/REFPROPMediumPureSubstance/pressure_hdX.mo deleted file mode 100644 index 3d3cb16..0000000 --- a/REFPROPMediumPureSubstance/pressure_hdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_hdX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_hdX("+String(h)+","+String(d)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "hd",h,d,X,phase); - annotation(LateInline=true,inverse(d=density_phX(p,h,X,phase), - h=specificEnthalpy_pdX(p,d,X,phase))); -end pressure_hdX; diff --git a/REFPROPMediumPureSubstance/pressure_hsX.mo b/REFPROPMediumPureSubstance/pressure_hsX.mo deleted file mode 100644 index 2df7c7d..0000000 --- a/REFPROPMediumPureSubstance/pressure_hsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_hsX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_hsX("+String(h)+","+String(s)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "hs",h,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_phX(p,h,X,phase), - h=specificEnthalpy_psX(p,s,X,phase))); -end pressure_hsX; diff --git a/REFPROPMediumPureSubstance/setState.mo b/REFPROPMediumPureSubstance/setState.mo deleted file mode 100644 index a28d557..0000000 --- a/REFPROPMediumPureSubstance/setState.mo +++ /dev/null @@ -1,45 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState "Calculates medium properties" - extends partialREFPROP; - input String statevars; - input Real statevar1; - input Real statevar2; - input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -// Real[:] props=getProps_REFPROP_check(statevars, fluidnames,statevar1, statevar2, X, phase); -/*protected - Real[16+2*nX] props; - String errormsg=StrJoin(fill("xxxx",64),"") - "Allocating memory, string will be written by C function";*/ - -algorithm - assert(size(X,1)>0,"The mass fraction vector must have at least 1 element."); - getProp_REFPROP("",statevars,fluidnames,props,statevar1,statevar2,X,phase,errormsg); - assert(props[1]==0,"Error in REFPROP wrapper function: "+errormsg +"\n"); -/* If q = 990 Then Modelica.Utilities.Streams.print(msg+String(z)) end if; - - If q = 998 Then Quality = Trim2("Superheated vapor with T>Tc") - If q = 999 Then Quality = Trim2("Supercritical state (T>Tc, p>pc)") - If q = -998 Then Quality = Trim2("Subcooled liquid with p>pc")*/ - state := ThermodynamicState( p= props[2], - T= props[3], - MM= props[4], - d=props[5], - d_l=props[6], - d_g=props[7], - x=min(max(props[8],0),1), - u=props[9], - h=props[10], - s=props[11], - cv=props[12], - cp=props[13], - c=props[14], - phase=if props[8]>0 and props[8]<1 then 2 else 1); -/* - X= X, - X_l=props[17:16+nX], - X_g=props[17+nX:16+2*nX], -*/ -end setState; diff --git a/REFPROPMediumPureSubstance/setState_ThX.mo b/REFPROPMediumPureSubstance/setState_ThX.mo deleted file mode 100644 index d166644..0000000 --- a/REFPROPMediumPureSubstance/setState_ThX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_ThX "Calculates medium properties from T,h,X" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - input SpecificEnthalpy h "Enthalpy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_ThX("+String(T)+","+String(h)+",X)..."); - end if; - state := setState("Th",T,h,X,phase) ",fluidnames)"; -end setState_ThX; diff --git a/REFPROPMediumPureSubstance/setState_TsX.mo b/REFPROPMediumPureSubstance/setState_TsX.mo deleted file mode 100644 index a4da8af..0000000 --- a/REFPROPMediumPureSubstance/setState_TsX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_TsX "Calculates medium properties from T,s,X" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - input SpecificEntropy s "Entropy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_TsX("+String(T)+","+String(s)+",X)..."); - end if; - state := setState("Ts",T,s,X,phase) ",fluidnames)"; -end setState_TsX; diff --git a/REFPROPMediumPureSubstance/setState_dsX.mo b/REFPROPMediumPureSubstance/setState_dsX.mo deleted file mode 100644 index 057f7ed..0000000 --- a/REFPROPMediumPureSubstance/setState_dsX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_dsX "Calculates medium properties from d,s,X" - extends Modelica.Icons.Function; - input Density d "Temperature"; - input SpecificEntropy s "Entropy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_dsX("+String(d)+","+String(s)+",X)..."); - end if; - state := setState("ds",d,s,X,phase) ",fluidnames)"; -end setState_dsX; diff --git a/REFPROPMediumPureSubstance/setState_hdX.mo b/REFPROPMediumPureSubstance/setState_hdX.mo deleted file mode 100644 index dbb2425..0000000 --- a/REFPROPMediumPureSubstance/setState_hdX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_hdX "Calculates medium properties from h,d,X" - extends Modelica.Icons.Function; - input SpecificEnthalpy h "Enthalpy"; - input Density d "Temperature"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_hdX("+String(h)+","+String(d)+",X)..."); - end if; - state := setState("hd",h,d,X,phase) ",fluidnames)"; -end setState_hdX; diff --git a/REFPROPMediumPureSubstance/setState_hsX.mo b/REFPROPMediumPureSubstance/setState_hsX.mo deleted file mode 100644 index 23ea017..0000000 --- a/REFPROPMediumPureSubstance/setState_hsX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_hsX "Calculates medium properties from h,s,X" - extends Modelica.Icons.Function; - input SpecificEnthalpy h "Enthalpy"; - input SpecificEntropy s "Entropy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running ("+String(h)+","+String(s)+",X)..."); - end if; - state := setState("hs",h,s,X,phase) ",fluidnames)"; -end setState_hsX; diff --git a/REFPROPMediumPureSubstance/setState_pdX.mo b/REFPROPMediumPureSubstance/setState_pdX.mo deleted file mode 100644 index ce95e6a..0000000 --- a/REFPROPMediumPureSubstance/setState_pdX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_pdX "Calculates medium properties from p,d,X" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Density d "Density"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_pdX("+String(p)+","+String(d)+",X)..."); - end if; - state := setState("pd",p,d,X,phase) ",fluidnames)"; -end setState_pdX; diff --git a/REFPROPMediumPureSubstance/setState_pqX.mo b/REFPROPMediumPureSubstance/setState_pqX.mo deleted file mode 100644 index 10556ac..0000000 --- a/REFPROPMediumPureSubstance/setState_pqX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_pqX "Calculates medium properties from p,q,X" - extends Modelica.Icons.Function; - input Modelica.SIunits.AbsolutePressure p "Pressure"; - input Modelica.SIunits.MassFraction q "quality (vapor mass fraction)"; - input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_pqX("+String(p)+","+String(q)+",X)..."); - end if; - state := setState("pq",p,q,X,phase) ",fluidnames)"; -end setState_pqX; diff --git a/REFPROPMediumPureSubstance/specificEnthalpy_TsX.mo b/REFPROPMediumPureSubstance/specificEnthalpy_TsX.mo deleted file mode 100644 index 786c847..0000000 --- a/REFPROPMediumPureSubstance/specificEnthalpy_TsX.mo +++ /dev/null @@ -1,19 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEnthalpy_TsX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_TsX("+String(T)+","+String(s)+",X)"); - end if; - h :=getProp_REFPROP_check("h", "Ts",T,s,X,phase); - annotation(LateInline=true,inverse(s = specificEntropy_ThX(T,h,X,phase), - T=temperature_hsX(h,s,X,phase))); -end specificEnthalpy_TsX; diff --git a/REFPROPMediumPureSubstance/specificEnthalpy_dTX.mo b/REFPROPMediumPureSubstance/specificEnthalpy_dTX.mo deleted file mode 100644 index de59101..0000000 --- a/REFPROPMediumPureSubstance/specificEnthalpy_dTX.mo +++ /dev/null @@ -1,19 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEnthalpy_dTX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_dTX("+String(d)+","+String(T)+",X)"); - end if; - h :=getProp_REFPROP_check("h", "dT",d,T,X,phase); - annotation(LateInline=true,inverse(d=density_ThX(T,h,X,phase), - T=temperature_hdX(h,d,X,phase))); -end specificEnthalpy_dTX; diff --git a/REFPROPMediumPureSubstance/specificEnthalpy_dsX.mo b/REFPROPMediumPureSubstance/specificEnthalpy_dsX.mo deleted file mode 100644 index 80c85d5..0000000 --- a/REFPROPMediumPureSubstance/specificEnthalpy_dsX.mo +++ /dev/null @@ -1,22 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEnthalpy_dsX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -/*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_dsX("+String(d)+","+String(s)+",X)"); - end if; - h :=getProp_REFPROP_check("h", "ds",d,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_hdX(h,d,X,phase), - d=density_hsX(h,s,X,phase))); -end specificEnthalpy_dsX; diff --git a/REFPROPMediumPureSubstance/specificEnthalpy_pdX.mo b/REFPROPMediumPureSubstance/specificEnthalpy_pdX.mo deleted file mode 100644 index 5c9c9ef..0000000 --- a/REFPROPMediumPureSubstance/specificEnthalpy_pdX.mo +++ /dev/null @@ -1,18 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEnthalpy_pdX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_pdX("+String(p)+","+String(d)+",X)..."); - end if; - h :=getProp_REFPROP_check("h", "pd",p,d,X,phase); - annotation(LateInline=true,inverse(d = density_phX(p,h,X,phase), - p=pressure_hdX(h,d,X,phase))); -end specificEnthalpy_pdX; diff --git a/REFPROPMediumPureSubstance/specificEnthalpy_pqX.mo b/REFPROPMediumPureSubstance/specificEnthalpy_pqX.mo deleted file mode 100644 index 858f068..0000000 --- a/REFPROPMediumPureSubstance/specificEnthalpy_pqX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEnthalpy_pqX - "calls REFPROP-Wrapper, returns specific enthalpy" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -// annotation(LateInline=true,inverse(p = pressure_hqX(h,q,X,phase),quality_phX(p,h,X,phase))); -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_pqX("+String(p)+","+String(q)+",X)"); - end if; - h :=getProp_REFPROP_check("h", "pq",p,q,X,phase); -end specificEnthalpy_pqX; diff --git a/REFPROPMediumPureSubstance/specificEntropy_ThX.mo b/REFPROPMediumPureSubstance/specificEntropy_ThX.mo deleted file mode 100644 index eff9438..0000000 --- a/REFPROPMediumPureSubstance/specificEntropy_ThX.mo +++ /dev/null @@ -1,20 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEntropy_ThX - extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -/*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_ThX("+String(T)+","+String(h)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "Th",T,h,X,phase); - annotation(LateInline=true,inverse(h = specificEnthalpy_TsX(T,s,X,phase), - T=temperature_hsX(h,s,X,phase))); -end specificEntropy_ThX; diff --git a/REFPROPMediumPureSubstance/specificEntropy_dTX.mo b/REFPROPMediumPureSubstance/specificEntropy_dTX.mo deleted file mode 100644 index b676dc0..0000000 --- a/REFPROPMediumPureSubstance/specificEntropy_dTX.mo +++ /dev/null @@ -1,17 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEntropy_dTX - extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_dTX("+String(d)+","+String(T)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "dT",d,T,X,phase); - annotation(LateInline=true,inverse(d = density_TsX(T,s,X,phase), - T=temperature_dsX(d,s,X,phase))); -end specificEntropy_dTX; diff --git a/REFPROPMediumPureSubstance/specificEntropy_hdX.mo b/REFPROPMediumPureSubstance/specificEntropy_hdX.mo deleted file mode 100644 index 4bc5bbe..0000000 --- a/REFPROPMediumPureSubstance/specificEntropy_hdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEntropy_hdX - extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_hdX("+String(h)+","+String(d)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "hd",h,d,X,phase); - annotation(LateInline=true,inverse(d=density_hsX(h,s,X,phase), - h=specificEnthalpy_dsX(d,s,X,phase))); -end specificEntropy_hdX; diff --git a/REFPROPMediumPureSubstance/specificEntropy_pdX.mo b/REFPROPMediumPureSubstance/specificEntropy_pdX.mo deleted file mode 100644 index edf6224..0000000 --- a/REFPROPMediumPureSubstance/specificEntropy_pdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEntropy_pdX - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_pdX("+String(p)+","+String(d)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "pd",p,d,X,phase); - annotation(LateInline=true,inverse(d = density_psX(p,s,X,phase), - p=pressure_dsX(d,s,X,phase))); -end specificEntropy_pdX; diff --git a/REFPROPMediumPureSubstance/specificEntropy_phX.mo b/REFPROPMediumPureSubstance/specificEntropy_phX.mo deleted file mode 100644 index 7fb508f..0000000 --- a/REFPROPMediumPureSubstance/specificEntropy_phX.mo +++ /dev/null @@ -1,21 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEntropy_phX - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -/*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_phX("+String(p)+","+String(h)+",X)..."); - // p="+String(p)+",h="+String(h)+", X={"+String(X[1])+","+String(X[2])+"}"); - end if; - s:=getProp_REFPROP_check("s", "ph",p,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_psX(p,s,X,phase), - p=pressure_hsX(h,s,X,phase))); -end specificEntropy_phX; diff --git a/REFPROPMediumPureSubstance/specificEntropy_pqX.mo b/REFPROPMediumPureSubstance/specificEntropy_pqX.mo deleted file mode 100644 index e8c5bf2..0000000 --- a/REFPROPMediumPureSubstance/specificEntropy_pqX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEntropy_pqX "calls REFPROP-Wrapper, returns specific entropy" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -// annotation(LateInline=true,inverse(p = pressure_sqX(s,q,X,phase),q=quality_psX(p,s,X,phase)); -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_pqX("+String(p)+","+String(q)+",X)"); - end if; - s :=getProp_REFPROP_check("s", "pq",p,q,X,phase); -end specificEntropy_pqX; diff --git a/REFPROPMediumPureSubstance/temperature_dsX.mo b/REFPROPMediumPureSubstance/temperature_dsX.mo deleted file mode 100644 index d3e7893..0000000 --- a/REFPROPMediumPureSubstance/temperature_dsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function temperature_dsX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_dsX("+String(d)+","+String(s)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "ds",d,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_dTX(d,T,X,phase), - d=density_TsX(T,s,X,phase))); -end temperature_dsX; diff --git a/REFPROPMediumPureSubstance/temperature_hdX.mo b/REFPROPMediumPureSubstance/temperature_hdX.mo deleted file mode 100644 index e58dfc9..0000000 --- a/REFPROPMediumPureSubstance/temperature_hdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function temperature_hdX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_hdX("+String(h)+","+String(d)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "hd",h,d,X,phase); - annotation(LateInline=true,inverse(d=density_ThX(T,h,X,phase), - h=specificEnthalpy_dTX(d,T,X,phase))); -end temperature_hdX; diff --git a/REFPROPMediumPureSubstance/temperature_hsX.mo b/REFPROPMediumPureSubstance/temperature_hsX.mo deleted file mode 100644 index 9c447e9..0000000 --- a/REFPROPMediumPureSubstance/temperature_hsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function temperature_hsX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_hsX("+String(h)+","+String(s)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "hs",h,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_ThX(T,h,X,phase), - h=specificEnthalpy_TsX(T,s,X,phase))); -end temperature_hsX; diff --git a/REFPROPMediumPureSubstance/temperature_pdX.mo b/REFPROPMediumPureSubstance/temperature_pdX.mo deleted file mode 100644 index 11d5b91..0000000 --- a/REFPROPMediumPureSubstance/temperature_pdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function temperature_pdX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_psX("+String(p)+","+String(d)+",X)..."); - end if; - T :=getProp_REFPROP_check("T", "pd",p,d,X,phase); - annotation(LateInline=true,inverse(d=density_pTX(p,T,X,phase), - p=pressure_dTX(d,T,X,phase))); -end temperature_pdX; diff --git a/REFPROPMediumPureSubstance/temperature_pqX.mo b/REFPROPMediumPureSubstance/temperature_pqX.mo deleted file mode 100644 index 8f5549a..0000000 --- a/REFPROPMediumPureSubstance/temperature_pqX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function temperature_pqX -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input MassFraction q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -// annotation(LateInline=true,inverse(p = pressure_TqX(T,q,X,phase),q=quality_pTX(p,T,X,phase)); -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_pqX("+String(p)+","+String(q)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "pq",p,q,X,phase); -end temperature_pqX; diff --git a/Testers/AmmoniaWater.mo b/Testers/AmmoniaWater.mo new file mode 100644 index 0000000..43090ce --- /dev/null +++ b/Testers/AmmoniaWater.mo @@ -0,0 +1,1313 @@ +within REFPROP2Modelica.Testers; +package AmmoniaWater + + model NH3_Water_setSatModel + + package Medium = REFPROP2Modelica.Media.NH3_Water; + + Medium.ThermodynamicState dewstate; + Medium.ThermodynamicState bubstate; + + Medium.SaturationProperties satL; + Medium.SaturationProperties satL2; + Medium.SaturationProperties satV; + + Medium.AbsolutePressure p; + Medium.MassFraction X[2]; + + Real A[3]; + Real B[2]; + + Real sigma; + equation + (A[1],A[2],A[3],B) = Medium.criticalProperties(X); + + p=100e5; + X={0.5,0.5}; + + satL = Medium.setSat_pX(p,X,kph=1,calcTransport=false); + satL2 = Medium.setSat_TX(satL.Tsat,X,kph=1,calcTransport=false); + bubstate = Medium.setBubbleState(satL); + + satV = Medium.setSat_pX(p,X,kph=2,calcTransport=false); + dewstate = Medium.setDewState(satV); + + sigma = Medium.surfaceTension(satL); + + end NH3_Water_setSatModel; + + model NH3_Water_setStateModel + + package Medium = REFPROP2Modelica.Media.NH3_Water; + + Medium.ThermodynamicState state; + // Medium.SaturationProperties sat; + + Medium.AbsolutePressure p; + Medium.SpecificEnthalpy h; + Medium.MassFraction X[2]; + Medium.Density d; + + Medium.MassFraction Xdef[Medium.nX]=Medium.X_default; + + Real q; + + Real dddh_pX; + Real dddp_hX; + Real dddh_pX_num; + Real dddp_hX_num; + + //Real dddX_ph_num; + + equation + p=100e5; + h=3e5 + time*25e5; + X={0.5,0.5}; + + state = Medium.setState_phX(p,h,X,calcTransport=false,partialDersInputChoice=3); + q = Medium.vapourQuality(state); + d = Medium.density(state); + + dddh_pX = Medium.density_derh_p(state); + dddh_pX_num = Medium.density(Medium.setState_phX(p,h+1,X))-d; + + dddp_hX = Medium.density_derp_h(state); + dddp_hX_num = Medium.density(Medium.setState_phX(p+1,h,X))-d; + + // dddX_ph_num = (Medium.density(Medium.setState_phX(p,h,cat(1,{X[1]+0.0001},{X[2]-0.0001})))-d)/0.0001; + + end NH3_Water_setStateModel; + + model NH3_Water_setState_plus_setSat + + package Medium = REFPROP2Modelica.Media.NH3_Water; + + Medium.ThermodynamicState state; + Medium.SaturationProperties sat; + + Medium.AbsolutePressure p; + Medium.SpecificEnthalpy h; + Medium.MassFraction X[2]; + + Medium.MassFraction Xdef[Medium.nX]=Medium.X_default; + + //Real dddX_ph_num; + + Medium.ThermodynamicState dewstate; + Medium.ThermodynamicState bubstate; + + equation + p=150e5; + h=3e5 + time*25e5; + X={0.5,0.5}; + + state = Medium.setState_phX(p,h,X,calcTransport=false,partialDersInputChoice=3); + + sat = state.sat; + + bubstate = Medium.setBubbleState(sat); + dewstate = Medium.setDewState(sat); + + // sat = if state.q<=0 then Medium.setSat_pX(p,X,kph=1) elseif state.q>=1 then Medium.setSat_pX(p,X,kph=2) else state.sat; + + end NH3_Water_setState_plus_setSat; + + model NH3_Water_setStateModel_test_partial_inputs + + package Medium = REFPROP2Modelica.Media.NH3_Water; + //package Medium2 = REFPROP2Modelica.Media.NH3_Water; + + // Medium.PartialDersInputChoice partialDersInputChoice = Medium.PartialDersInputChoice.none; + // Medium2.PartialDersInputChoice partialDersInputChoice2 = Medium.PartialDersInputChoice.pTX_numeric; + + Medium.ThermodynamicState state; + Medium.ThermodynamicState state2; + + // input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + + Medium.AbsolutePressure p; + Medium.SpecificEnthalpy h; + Medium.MassFraction X[2]; + + parameter Medium.PartialDersInputChoice partialDersInputChoice0 = Medium.PartialDersInputChoice.none; + parameter Medium.PartialDersInputChoice partialDersInputChoice1 = Medium.PartialDersInputChoice.phX_numeric; + parameter Medium.PartialDersInputChoice partialDersInputChoice2 = Medium.PartialDersInputChoice.phX_pseudoanalytic; + parameter Medium.PartialDersInputChoice partialDersInputChoice3 = Medium.PartialDersInputChoice.pTX_numeric; + + equation + p=50e5; + h=3e5+time*100e3; + X={0.5,0.5}; + + state = Medium.setState_phX(p,h,X); + state2 = Medium.setState_phX(p,h,X,partialDersInputChoice=3); + + end NH3_Water_setStateModel_test_partial_inputs; + + package NH3Water_MUXvsPHXvsPTX + + model Volume_MUX "NH3 Water" + + replaceable package Medium = REFPROP2Modelica.Media.NH3_Water constrainedby + REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium annotation (choicesAllMatching=true); + Medium.ThermodynamicState state; + + parameter Modelica.SIunits.Volume V=1; + + parameter Real hstart=3500e3; + parameter Real pstart=50e5; + parameter Real X1start=0.5; + + Medium.Density d(start = Medium.density(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); + Medium.SpecificInternalEnergy u(start = hstart-pstart/Medium.density(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); + // Real X1(start=X1start); + + Medium.AbsolutePressure p; + Medium.SpecificEnthalpy h; + Medium.MassFraction X[Medium.nX](start={X1start,1-X1start}); + Medium.Temperature T(start=400); + + Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium=Medium) + annotation (Placement(transformation(extent={{50,-10},{70,10}}))); + + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Thermal port" + annotation (Placement(transformation(extent={{-20,50},{20,70}}, rotation=0), + iconTransformation(extent={{-20,50},{20,70}}))); + + equation + // Mass conservation + V * der(d) = port.m_flow; + // species conservation + V * (X[1]*der(d) + d*der(X[1])) = port.m_flow*actualStream(port.Xi_outflow[1]); + X[2] = 1-X[1]; + // energy cons + V * (d*der(u) + u*der(d)) = port.m_flow*actualStream(port.h_outflow) + heatPort.Q_flow; + + // Thermodynamic properties + state = Medium.setState_dTX(d,T,X); + // sat = Medium.setSat_pX(p,X[:]); + // u = Medium.specificInternalEnergy(state); + u = h - p/d; + //T = Medium.temperature(state); + h = Medium.specificEnthalpy(state); + // d = Medium.density(state); + p = Medium.pressure(state); + + // port connections + h = port.h_outflow; + X[1] = port.Xi_outflow[1]; + // X[2] = port.Xi_outflow[2]; + p = port.p; + T = heatPort.T; + + annotation (Diagram(graphics), Icon(coordinateSystem(preserveAspectRatio=false, + extent={{-100,-100},{100,100}}), + graphics={Ellipse( + extent={{-60,60},{60,-60}}, + lineColor={0,0,255}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid)})); + end Volume_MUX; + + model Volume_phX "ideal gas mixture" + + replaceable package Medium = REFPROP2Modelica.Media.NH3_Water constrainedby + REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium annotation (choicesAllMatching=true); + Medium.ThermodynamicState state; + + parameter Modelica.SIunits.Volume V=1; + + parameter Real hstart=3500e3; + parameter Real pstart=50e5; + parameter Real X1start=0.5; + + Medium.Density d; + Medium.SpecificInternalEnergy u; + // Real X1(start=X1start); + + Medium.AbsolutePressure p(start=pstart); + Medium.SpecificEnthalpy h(start=hstart); + Medium.MassFraction X[Medium.nX](start={X1start,1-X1start}); + Medium.Temperature T; + + Real dddt; + // Real dhdt; + // Real dddX[Medium.nX]; + // Real dddX_num; + // Real dddX_num_check; + + Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium=Medium) + annotation (Placement(transformation(extent={{50,-10},{70,10}}))); + + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Thermal port" + annotation (Placement(transformation(extent={{-20,50},{20,70}}, rotation=0), + iconTransformation(extent={{-20,50},{20,70}}))); + + equation + // derivative transformations + dddt = Medium.density_derh_p(state)*der(h) + Medium.density_derp_h(state)*der(p) + state.dddX_ph*der(X[1]); + // dddX = Medium.density_derX(state); + // dhdt = Medium.h_TX_der(T=T,X=X,dT=der(T),dX={der(X[1]),-der(X[1])}) "h is function of T and X only... and not p"; + + // Mass conservation + V * dddt = port.m_flow; + // species conservation + V * (X[1]*dddt + d*der(X[1])) = port.m_flow*actualStream(port.Xi_outflow[1]); + X[2] = 1-X[1]; + // energy cons + V * (d*der(h) + h*dddt - der(p)) = port.m_flow*actualStream(port.h_outflow) + heatPort.Q_flow; + + // der(u)=0; + // der(d)=0; + // der(X1)=0; + + // // Thermodynamic properties + // state = Medium.setState_phX(p,h,X); + // sat = Medium.setSat_pX(p,X[:]); + // u = Medium.specificInternalEnergy(state); + // T = Medium.temperature(state); + // h = Medium.specificEnthalpy(state); + // d = Medium.density(state); + // p = Medium.pressure(state); + + // Thermodynamic properties + state = Medium.setState_phX(p,h,X,partialDersInputChoice=3); + // sat = Medium.setSat_pX(p,X[:]); + // u = Medium.specificInternalEnergy(state); + u = h - p/d; + T = Medium.temperature(state); + // h = Medium.specificEnthalpy(state); + d = Medium.density(state); + // p = Medium.pressure(state); + + // port connections + h = port.h_outflow; + X[1] = port.Xi_outflow[1]; + // X[2] = port.Xi_outflow[2]; + p = port.p; + T = heatPort.T; + + // additional sum test.. This shows that dddX[1] - dddX[2] is equal to dddX_num with both mass fractions varied... + + // dddX_num = (Medium.density(state_dX)-d)/0.0001; + // dddX_num_check = dddX[1] - dddX[2]; + + annotation (Diagram(graphics), Icon(coordinateSystem(preserveAspectRatio=false, + extent={{-100,-100},{100,100}}), + graphics={Ellipse( + extent={{-60,60},{60,-60}}, + lineColor={0,0,255}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid)})); + end Volume_phX; + + model Volume_pTX "ideal gas mixture" + + replaceable package Medium = REFPROP2Modelica.Media.NH3_Water constrainedby + REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium annotation (choicesAllMatching=true); + Medium.ThermodynamicState state; + + parameter Modelica.SIunits.Volume V=1; + + parameter Real hstart=3500e3; + parameter Real pstart=50e5; + parameter Real X1start=0.5; + + Medium.Density d(start=Medium.density(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); + Medium.SpecificInternalEnergy u; + // Real X1(start=X1start); + + Medium.AbsolutePressure p(start=pstart); + Medium.SpecificEnthalpy h(start=hstart); + Medium.MassFraction X[Medium.nX](start={X1start,1-X1start}); + Medium.Temperature T(start=Medium.temperature(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); + + Real dddt; + Real dhdt; + + Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium=Medium) + annotation (Placement(transformation(extent={{50,-10},{70,10}}))); + + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Thermal port" + annotation (Placement(transformation(extent={{-20,50},{20,70}}, rotation=0), + iconTransformation(extent={{-20,50},{20,70}}))); + + equation + // derivative transformations + dddt = state.dddT_pX*der(T) + state.dddp_TX*der(p) + state.dddX_pT*der(X[1]); + dhdt = state.dhdT_pX*der(T) + state.dhdp_TX*der(p) + state.dhdX_pT*der(X[1]); + + // Mass conservation + V * dddt = port.m_flow; + // species conservation + V * (X[1]*dddt + d*der(X[1])) = port.m_flow*actualStream(port.Xi_outflow[1]); + X[2] = 1-X[1]; + // energy cons + V * (d*dhdt + h*dddt - der(p)) = port.m_flow*actualStream(port.h_outflow) + heatPort.Q_flow; + + // der(u)=0; + // der(d)=0; + // der(X1)=0; + + // // Thermodynamic properties + // state = Medium.setState_phX(p,h,X); + // sat = Medium.setSat_pX(p,X[:]); + // u = Medium.specificInternalEnergy(state); + // T = Medium.temperature(state); + // h = Medium.specificEnthalpy(state); + // d = Medium.density(state); + // p = Medium.pressure(state); + + // Thermodynamic properties + state = Medium.setState_pTX(p,T,X,partialDersInputChoice=4); + // sat = Medium.setSat_pX(p,X[:]); + // u = Medium.specificInternalEnergy(state); + u = h - p/d; + // T = Medium.temperature(state); + h = Medium.specificEnthalpy(state); + d = Medium.density(state); + // p = Medium.pressure(state); + + // port connections + h = port.h_outflow; + X[1] = port.Xi_outflow[1]; + // X[2] = port.Xi_outflow[2]; + p = port.p; + T = heatPort.T; + + // additional sum test.. This shows that dddX[1] - dddX[2] is equal to dddX_num with both mass fractions varied... + + // dddX_num = (Medium.density(state_dX)-d)/0.0001; + // dddX_num_check = dddX[1] - dddX[2]; + + annotation (Diagram(graphics), Icon(coordinateSystem(preserveAspectRatio=false, + extent={{-100,-100},{100,100}}), + graphics={Ellipse( + extent={{-60,60},{60,-60}}, + lineColor={0,0,255}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid)})); + end Volume_pTX; + + model system_MUX_sp + + Volume_MUX volume(V=0.01, hstart=3000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{-32,-10},{-12,10}}))); + Modelica.Fluid.Sources.MassFlowSource_h boundary( + nPorts=1, + use_h_in=false, + m_flow=0, + use_m_flow_in=true, + X={0.8,0.2}, + h=3000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-46,30},{-26,50}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-80,36},{-68,48}}))); + equation + connect(boundary.ports[1], volume.port) annotation (Line( + points={{58,34},{66,34},{66,0},{-16,0}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-67.4,42},{-56,42},{-56,40},{-46,40}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(sine.y, boundary.m_flow_in) annotation (Line( + points={{24.6,36},{30,36},{30,42},{38,42}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(fixedHeatFlow.port, volume.heatPort) annotation (Line( + points={{-26,40},{-24,40},{-24,6},{-22,6}}, + color={191,0,0}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics)); + end system_MUX_sp; + + model system_MUX_tp + + Volume_MUX volume(V=0.01, hstart=1500e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{-32,-10},{-12,10}}))); + Modelica.Fluid.Sources.MassFlowSource_h boundary( + nPorts=1, + use_h_in=false, + m_flow=0, + use_m_flow_in=true, + X={0.8,0.2}, + h=2000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-46,30},{-26,50}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-80,36},{-68,48}}))); + equation + connect(boundary.ports[1], volume.port) annotation (Line( + points={{58,34},{66,34},{66,0},{-16,0}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-67.4,42},{-56,42},{-56,40},{-46,40}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(sine.y, boundary.m_flow_in) annotation (Line( + points={{24.6,36},{30,36},{30,42},{38,42}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(fixedHeatFlow.port, volume.heatPort) annotation (Line( + points={{-26,40},{-24,40},{-24,6},{-22,6}}, + color={191,0,0}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics)); + end system_MUX_tp; + + model system_phX_sp + + Modelica.Fluid.Sources.MassFlowSource_h boundary( + use_h_in=false, + nPorts=1, + m_flow=0, + use_m_flow_in=true, + X={0.8,0.2}, + h=3000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Volume_phX volume( + V=0.01, + hstart=3000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{-36,-8},{-16,12}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); + equation + connect(volume.port, boundary.ports[1]) annotation (Line( + points={{-20,2},{32,2},{32,0},{78,0},{78,34},{58,34}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( + points={{-26,8},{-18,8},{-18,38},{-20,38}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(sine.y, boundary.m_flow_in) annotation (Line( + points={{24.6,36},{30,36},{30,42},{38,42}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ + {-100,-100},{100,100}}))); + end system_phX_sp; + + model system_phX_tp + + Modelica.Fluid.Sources.MassFlowSource_h boundary( + use_h_in=false, + nPorts=1, + m_flow=0, + use_m_flow_in=true, + X={0.8,0.2}, + h=2000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Volume_phX volume( + V=0.01, + hstart=1500e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{-36,-8},{-16,12}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); + equation + connect(volume.port, boundary.ports[1]) annotation (Line( + points={{-20,2},{32,2},{32,0},{78,0},{78,34},{58,34}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( + points={{-26,8},{-18,8},{-18,38},{-20,38}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(sine.y, boundary.m_flow_in) annotation (Line( + points={{24.6,36},{30,36},{30,42},{38,42}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ + {-100,-100},{100,100}}))); + end system_phX_tp; + + model system_pTX_sp + + Modelica.Fluid.Sources.MassFlowSource_h boundary( + use_h_in=false, + nPorts=1, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water, + m_flow=0, + X={0.8,0.2}, + use_m_flow_in=true, + h=3000e3) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2, + startTime=0) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Volume_pTX volume(V=0.01, hstart=3000e3) + annotation (Placement(transformation(extent={{-36,-8},{-16,12}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); + equation + connect(volume.port, boundary.ports[1]) annotation (Line( + points={{-20,2},{32,2},{32,0},{78,0},{78,34},{58,34}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( + points={{-26,8},{-18,8},{-18,38},{-20,38}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(boundary.m_flow_in, sine.y) annotation (Line( + points={{38,42},{34,42},{34,38},{24.6,38},{24.6,36}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ + {-100,-100},{100,100}}))); + end system_pTX_sp; + + model system_pTX_tp + + Modelica.Fluid.Sources.MassFlowSource_h boundary( + use_h_in=false, + nPorts=1, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water, + m_flow=0, + X={0.8,0.2}, + use_m_flow_in=true, + h=2000e3) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2, + startTime=0) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Volume_pTX volume(V=0.01, hstart=1500e3) + annotation (Placement(transformation(extent={{-38,-10},{-16,12}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); + equation + connect(volume.port, boundary.ports[1]) annotation (Line( + points={{-20.4,1},{32,1},{32,0},{78,0},{78,34},{58,34}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( + points={{-27,7.6},{-18,7.6},{-18,38},{-20,38}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(boundary.m_flow_in, sine.y) annotation (Line( + points={{38,42},{34,42},{34,38},{24.6,38},{24.6,36}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ + {-100,-100},{100,100}}))); + end system_pTX_tp; + + end NH3Water_MUXvsPHXvsPTX; + +package TransportPropsTest + model MassFractionSweep_visc_vap + + parameter Modelica.SIunits.Pressure p=100e5; + parameter Modelica.SIunits.Temperature T=325 + 273.15; + Modelica.SIunits.MassFraction X[2]; + + package MediumWilke = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPWilke); + MediumWilke.ThermodynamicState state=MediumWilke.setState_pTX( + p, + T, + X, + calcTransport=false); + + package MediumReich = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPReichenberg); + + package MediumChung = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPChung); + + package MediumChungErrorWeight = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPChungPureErrorWeight); + + //Real eta_reich,eta_chung,eta_chungErrorWeight; + Real eta_wilke; + Real eta_reich; + Real eta_chung; + Real eta_chungErrorWeight; + + equation + X = {time,1 - time}; + + eta_wilke = MediumWilke.dynamicViscosity(state); + eta_reich = MediumReich.dynamicViscosity(state); + eta_chung = MediumChung.dynamicViscosity(state); + eta_chungErrorWeight = MediumChungErrorWeight.dynamicViscosity(state); + + annotation (experiment(Interval=0.01)); + end MassFractionSweep_visc_vap; + + model EnthalpySweep_visc_vap + package Medium = REFPROP2Modelica.Media.NH3_Water; + parameter Medium.AbsolutePressure p=150e5; + // parameter Medium.Temperature Tstart=50+273.15; + parameter Medium.Temperature Tend=500+273.15; + parameter Medium.MassFraction X[2]={0.5,0.5}; + parameter Real hstart = Medium.specificEnthalpy(Medium.setState_pqX(p,1,X)); + parameter Real hend = Medium.specificEnthalpy(Medium.setState_pTX(p,Tend,X)); + Medium.ThermodynamicState state = Medium.setState_phX(p,h,X); + + Real h; + Real eta_chung,eta_chungWeight,eta_wilke,eta_reichenberg; + + package MediumWilke = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPWilke); + + package MediumReich = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPReichenberg); + + package MediumChung = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPChung); + + package MediumChungErrorWeight = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPChungPureErrorWeight); + equation + h=hstart + (hend-hstart)*time; + + eta_chung = Medium.dynamicViscosity_VAPChung(state); + eta_chungWeight = Medium.dynamicViscosity_VAPChungPureErrorWeight(state); + eta_wilke = Medium.dynamicViscosity_VAPWilke(state); + eta_reichenberg = Medium.dynamicViscosity_VAPReichenberg(state); + + annotation (experiment(Interval=0.01)); + end EnthalpySweep_visc_vap; + + model MassFractionSweep_visc_liq + + parameter Modelica.SIunits.Pressure p=50e5; + parameter Modelica.SIunits.Temperature T=50 + 273.15; + Modelica.SIunits.MassFraction X[2]; + + package Medium = REFPROP2Modelica.Media.NH3_Water; + Medium.ThermodynamicState state=Medium.setState_pTX( + p, + T, + X, + calcTransport=false); + + Real eta_conde,eta_elsayed,eta_HDK,eta_TejaRice,eta_TejaRiceStecco,eta_TejaRiceSassensTcrit; + + package MediumConde = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQconde); + + package MediumElSayed = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQelsayed); + + package MediumHdbKaltetechnik = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQHDK); + + package MediumSteccoDesideri = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQTejeRiceSteccoWay); + + package MediumTejaRice = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQTejeRice); + + package MediumTejaRiceSassen = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQTejeRiceSassensTcrit); + + equation + X = {time,1 - time}; + + eta_conde = MediumConde.dynamicViscosity(state); + eta_elsayed = MediumElSayed.dynamicViscosity(state); + eta_HDK = MediumHdbKaltetechnik.dynamicViscosity(state); + eta_TejaRiceStecco = MediumSteccoDesideri.dynamicViscosity(state); + eta_TejaRice = MediumTejaRice.dynamicViscosity(state); + eta_TejaRiceSassensTcrit = MediumTejaRiceSassen.dynamicViscosity(state); + + annotation (experiment(Interval=0.01)); + end MassFractionSweep_visc_liq; + + model EnthalpySweep_visc_liq + + package Medium = REFPROP2Modelica.Media.NH3_Water; + Medium.ThermodynamicState state = Medium.setState_phX(p,h,X); + + parameter Medium.AbsolutePressure p=100e5; + parameter Medium.Temperature Tstart=50+273.15; + parameter Medium.MassFraction X[2]={0.5,0.5}; + Real h; + parameter Real hstart = Medium.specificEnthalpy(Medium.setState_pTX(p,Tstart,X)); + parameter Real hend = Medium.specificEnthalpy(Medium.setState_pqX(p,0,X)); + Real eta_conde,eta_elsayed,eta_HDK,eta_TejaRiceStecco; + + package MediumConde = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQconde); + + package MediumElSayed = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQelsayed); + + package MediumHdbKaltetechnik = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQHDK); + + package MediumSteccoDesideri = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQTejeRiceSteccoWay); + + equation + h=hstart + (hend-hstart)*time; + + eta_conde = MediumConde.dynamicViscosity(state); + eta_elsayed = MediumElSayed.dynamicViscosity(state); + eta_HDK = MediumHdbKaltetechnik.dynamicViscosity(state); + eta_TejaRiceStecco = MediumSteccoDesideri.dynamicViscosity(state); + + annotation (experiment(Interval=0.01)); + end EnthalpySweep_visc_liq; + + model MassFractionSweep_cond_vap + + parameter Modelica.SIunits.Pressure p=100e5; + parameter Modelica.SIunits.Temperature T=325 + 273.15; + Modelica.SIunits.MassFraction X[2]; + + package MediumAverage = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPLinearMolePoling); + MediumAverage.ThermodynamicState state=MediumAverage.setState_pTX( + p, + T, + X, + calcTransport=false); + + package MediumMasonSaxena = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPWilke); + package MediumChung = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPChung); + package MediumChungErrorWeight = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPChungPureErrorWeight); + + Real lambda_wilke,lambda_polingLin,lambda_chung,lambda_chungErrorWeight; + + equation + X = {time,1 - time}; + + lambda_wilke = MediumAverage.thermalConductivity(state); + lambda_polingLin = MediumMasonSaxena.thermalConductivity(state); + lambda_chung = MediumChung.thermalConductivity(state); + lambda_chungErrorWeight = MediumChungErrorWeight.thermalConductivity(state); + + annotation (experiment(Interval=0.01)); + end MassFractionSweep_cond_vap; + + model EnthalpySweep_cond_vap + + package Medium = REFPROP2Modelica.Media.NH3_Water; + parameter Medium.AbsolutePressure p=150e5; + // parameter Medium.Temperature Tstart=50+273.15; + parameter Medium.Temperature Tend=500 + 273.15; + parameter Medium.MassFraction X[2]={0.5,0.5}; + parameter Real hstart=Medium.specificEnthalpy(Medium.setState_pqX( + p, + 1, + X)); + parameter Real hend=Medium.specificEnthalpy(Medium.setState_pTX( + p, + Tend, + X)); + Medium.ThermodynamicState state=Medium.setState_phX( + p, + h, + X); + + Real h; + Real lambda_wilke; + Real lambda_chung; + Real lambda_chungErrorWeight; + Real lambda_polingLin; + + package MediumAverage = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPLinearMolePoling); + package MediumMasonSaxena = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPWilke); + package MediumChung = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPChung); + package MediumChungErrorWeight = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPChungPureErrorWeight); + + equation + h = hstart + (hend - hstart)*time; + + lambda_wilke = MediumAverage.thermalConductivity(state); + lambda_polingLin = MediumMasonSaxena.thermalConductivity(state); + lambda_chung = MediumChung.thermalConductivity(state); + lambda_chungErrorWeight = MediumChungErrorWeight.thermalConductivity( + state); + + annotation (experiment(Interval=0.01)); + end EnthalpySweep_cond_vap; + + model MassFractionSweep_cond_liq + + parameter Modelica.SIunits.Pressure p=50e5; + parameter Modelica.SIunits.Temperature T=50 + 273.15; + Modelica.SIunits.MassFraction X[2]; + + package Medium = REFPROP2Modelica.Media.NH3_Water; + Medium.ThermodynamicState state = Medium.setState_pTX(p,T,X,calcTransport=false); + + package MediumConde = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQConde); + package MediumElSayed = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQLinearMoleElsayed); + package MediumFilippov = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQFilipov); + package MediumJamieson = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQJamie); + + Real lambda_elsayed,lambda_conde,lambda_filipov,lambda_jamieson; + + equation + X={time,1-time}; + + lambda_conde = MediumConde.thermalConductivity(state); + lambda_elsayed = MediumElSayed.thermalConductivity(state); + lambda_filipov = MediumFilippov.thermalConductivity(state); + lambda_jamieson = MediumJamieson.thermalConductivity(state); + + annotation (experiment(Interval=0.01)); + end MassFractionSweep_cond_liq; + + model EnthalpySweep_cond_liq + + package Medium = REFPROP2Modelica.Media.NH3_Water; + Medium.ThermodynamicState state = Medium.setState_phX(p,h,X); + + parameter Medium.AbsolutePressure p=100e5; + parameter Medium.Temperature Tstart=50+273.15; + parameter Medium.MassFraction X[2]={0.5,0.5}; + Real h; + parameter Real hstart = Medium.specificEnthalpy(Medium.setState_pTX(p,Tstart,X)); + parameter Real hend = Medium.specificEnthalpy(Medium.setState_pqX(p,0,X)); + + Real lambda_elsayed,lambda_conde,lambda_filipov,lambda_jamieson; + + package MediumConde = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQConde); + package MediumElSayed = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQLinearMoleElsayed); + package MediumFilippov = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQFilipov); + package MediumJamieson = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQJamie); + + equation + h=hstart + (hend-hstart)*time; + // h=hstart + (2e6-hstart)*time; + + lambda_conde = MediumConde.thermalConductivity(state); + lambda_elsayed = MediumElSayed.thermalConductivity(state); + lambda_filipov = MediumFilippov.thermalConductivity(state); + lambda_jamieson = MediumJamieson.thermalConductivity(state); + + annotation (experiment(Interval=0.01)); + end EnthalpySweep_cond_liq; + + model MassFractionSweepSurfaceTension + + package Medium = REFPROP2Modelica.Media.NH3_Water; + Medium.SaturationProperties sat; + Real T; + Medium.MassFraction X[2]; + Real sigma; + + equation + X={time,1-time}; + sat = Medium.setSat_TX(T,X,calcTransport=true); + T=350+273.15; + + sigma = Medium.surfaceTension(sat); + + end MassFractionSweepSurfaceTension; + +package TestCore + model liquid_viscosity_sweep + + package Medium = REFPROP2Modelica.Media.NH3_Water; + parameter Integer n=101; + Medium.ThermodynamicState state50[n] annotation(hideResult=true); + Medium.ThermodynamicState state90[n] annotation(hideResult=true); + Medium.ThermodynamicState state130[n] annotation(hideResult=true); + Medium.AbsolutePressure p; + + Real x1[n] = linspace(0,1,n); + + Real eta_conde50[n]; + Real eta_elsayed50[n]; + Real eta_HDK50[n]; + Real eta_TejaRice50[n]; + Real eta_TejaRiceStecco50[n]; + + Real eta_conde90[n]; + Real eta_elsayed90[n]; + Real eta_HDK90[n]; + Real eta_TejaRice90[n]; + Real eta_TejaRiceStecco90[n]; + + Real eta_conde130[n]; + Real eta_elsayed130[n]; + Real eta_HDK130[n]; + Real eta_TejaRice130[n]; + Real eta_TejaRiceStecco130[n]; + + equation + p=50e5; + + for i in 1:n loop + state50[i] = Medium.setState_pTX(p,50+273.15,{x1[i],1-x1[i]}); + eta_conde50[i] = Media.NH3_Water.dynamicViscosity_LIQconde( state50[i]); + eta_elsayed50[i] = Media.NH3_Water.dynamicViscosity_LIQelsayed( state50[i]); + eta_HDK50[i] = Media.NH3_Water.dynamicViscosity_LIQHDK( state50[i]); + eta_TejaRice50[i] = Media.NH3_Water.dynamicViscosity_LIQTejeRice(state50[i]); + eta_TejaRiceStecco50[i] = Media.NH3_Water.dynamicViscosity_LIQTejeRiceSteccoWay(state50[i]); + + state90[i] = Medium.setState_pTX(p,90+273.15,{x1[i],1-x1[i]}); + eta_conde90[i] = Media.NH3_Water.dynamicViscosity_LIQconde( state90[i]); + eta_elsayed90[i] = Media.NH3_Water.dynamicViscosity_LIQelsayed( state90[i]); + eta_HDK90[i] = Media.NH3_Water.dynamicViscosity_LIQHDK( state90[i]); + eta_TejaRice90[i] = Media.NH3_Water.dynamicViscosity_LIQTejeRice(state90[i]); + eta_TejaRiceStecco90[i] = Media.NH3_Water.dynamicViscosity_LIQTejeRiceSteccoWay(state90[i]); + + state130[i] = Medium.setState_pTX(p,130+273.15,{x1[i],1-x1[i]}); + eta_conde130[i] = Media.NH3_Water.dynamicViscosity_LIQconde(state130[i]); + eta_elsayed130[i] = Media.NH3_Water.dynamicViscosity_LIQelsayed(state130[i]); + eta_HDK130[i] = Media.NH3_Water.dynamicViscosity_LIQHDK(state130[i]); + eta_TejaRice130[i] = Media.NH3_Water.dynamicViscosity_LIQTejeRice(state130[i]); + eta_TejaRiceStecco130[i] = Media.NH3_Water.dynamicViscosity_LIQTejeRiceSteccoWay(state130[i]); + + end for; + + end liquid_viscosity_sweep; + + model vapor_viscosity_sweep + + package Medium = REFPROP2Modelica.Media.NH3_Water; + parameter Integer n=101; + Medium.ThermodynamicState state_325_050[n] annotation(hideResult=true); + Medium.ThermodynamicState state_325_100[n] annotation(hideResult=true); + Medium.ThermodynamicState state_525_100[n] annotation(hideResult=true); + Medium.ThermodynamicState state_425_100[n] annotation(hideResult=true); + // Medium.AbsolutePressure p; + + Real x1[n] = linspace(0,1,n); + + Real eta_reich_325_050[n]; + Real eta_reich_325_100[n]; + Real eta_reich_525_100[n]; + Real eta_reich_425_100[n]; + + Real eta_wilke_325_050[n]; + Real eta_wilke_325_100[n]; + Real eta_wilke_525_100[n]; + Real eta_wilke_425_100[n]; + + Real eta_chung_325_050[n]; + Real eta_chung_325_100[n]; + Real eta_chung_525_100[n]; + Real eta_chung_425_100[n]; + + Real eta_chungWeight_325_050[n]; + Real eta_chungWeight_325_100[n]; + Real eta_chungWeight_525_100[n]; + Real eta_chungWeight_425_100[n]; + equation + for i in 1:n loop + + // state_315_100[i] = Medium.setState_pTX(100e5,315+273.15,{x1[i],1-x1[i]}); + // eta_reich_315_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_315_100[i]); + // eta_wilke_315_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_315_100[i]); + // + // state_330_125[i] = Medium.setState_pTX(125e5,330+273.15,{x1[i],1-x1[i]}); + // eta_reich_330_125[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_330_125[i]); + // eta_wilke_330_125[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_330_125[i]); + // + // state_345_150[i] = Medium.setState_pTX(150e5,345+273.15,{x1[i],1-x1[i]}); + // eta_reich_345_150[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_345_150[i]); + // eta_wilke_345_150[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_345_150[i]); + + // state_325_050[i] = Medium.setState_pTX(050e5,325+273.15,{x1[i],1-x1[i]}); + // eta_reich_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_325_050[i]); + // eta_wilke_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_325_050[i]); + // eta_chung_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_325_050[i]); + // + // state_325_100[i] = Medium.setState_pTX(100e5,325+273.15,{x1[i],1-x1[i]}); + // eta_reich_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_325_100[i]); + // eta_wilke_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_325_100[i]); + // eta_chung_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_325_100[i]); + // + // state_375_100[i] = Medium.setState_pTX(100e5,375+273.15,{x1[i],1-x1[i]}); + // eta_reich_375_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_375_100[i]); + // eta_wilke_375_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_375_100[i]); + // eta_chung_375_100[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_375_100[i]); + // + // state_425_100[i] = Medium.setState_pTX(100e5,425+273.15,{x1[i],1-x1[i]}); + // eta_reich_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_425_100[i]); + // eta_wilke_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_425_100[i]); + // eta_chung_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_425_100[i]); + + state_325_050[i] = Medium.setState_pTX(050e5,325+273.15,{x1[i],1-x1[i]}); + eta_reich_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_325_050[i]); + eta_wilke_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_325_050[i]); + eta_chung_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_325_050[i]); + eta_chungWeight_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPChungPureErrorWeight( state_325_050[i]); + + state_325_100[i] = Medium.setState_pTX(100e5,325+273.15,{x1[i],1-x1[i]}); + eta_reich_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_325_100[i]); + eta_wilke_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_325_100[i]); + eta_chung_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_325_100[i]); + eta_chungWeight_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPChungPureErrorWeight( state_325_100[i]); + + state_425_100[i] = Medium.setState_pTX(100e5,425+273.15,{x1[i],1-x1[i]}); + eta_reich_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_425_100[i]); + eta_wilke_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_425_100[i]); + eta_chung_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_425_100[i]); + eta_chungWeight_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPChungPureErrorWeight( state_425_100[i]); + + state_525_100[i] = Medium.setState_pTX(100e5,525+273.15,{x1[i],1-x1[i]}); + eta_reich_525_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_525_100[i]); + eta_wilke_525_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_525_100[i]); + eta_chung_525_100[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_525_100[i]); + eta_chungWeight_525_100[i] = Media.NH3_Water.dynamicViscosity_VAPChungPureErrorWeight( state_525_100[i]); + + end for; + + end vapor_viscosity_sweep; + + model liquid_conductivity_sweep + + package Medium = REFPROP2Modelica.Media.NH3_Water; + parameter Integer n=101; + + Medium.ThermodynamicState state50_100[n] annotation(hideResult=true); + Medium.ThermodynamicState state90_100[n] annotation(hideResult=true); + Medium.ThermodynamicState state130_100[n] annotation(hideResult=true); + + Real x1[n] = linspace(0,1,n); + + Real lambda_elsayedLin50_100[n]; + Real lambda_filipov50_100[n]; + Real lambda_jamieson50_100[n]; + Real lambda_conde50_100[n]; + + Real lambda_elsayedLin90_100[n]; + Real lambda_filipov90_100[n]; + Real lambda_jamieson90_100[n]; + Real lambda_conde90_100[n]; + + Real lambda_elsayedLin130_100[n]; + Real lambda_filipov130_100[n]; + Real lambda_jamieson130_100[n]; + Real lambda_conde130_100[n]; + + equation + for i in 1:n loop + state50_100[i] = Medium.setState_pTX(100e5,50+273.15,{x1[i],1-x1[i]}); + lambda_elsayedLin50_100[i] = Media.NH3_Water.thermalConductivity_LIQLinearMoleElsayed( state50_100[i]); + lambda_filipov50_100[i] = Media.NH3_Water.thermalConductivity_LIQFilipov( state50_100[i]); + lambda_jamieson50_100[i] = Media.NH3_Water.thermalConductivity_LIQJamie( state50_100[i]); + lambda_conde50_100[i] = Media.NH3_Water.thermalConductivity_LIQConde( state50_100[i]); + + state90_100[i] = Medium.setState_pTX(100e5,90+273.15,{x1[i],1-x1[i]}); + lambda_elsayedLin90_100[i] = Media.NH3_Water.thermalConductivity_LIQLinearMoleElsayed( state90_100[i]); + lambda_filipov90_100[i] = Media.NH3_Water.thermalConductivity_LIQFilipov( state90_100[i]); + lambda_jamieson90_100[i] = Media.NH3_Water.thermalConductivity_LIQJamie( state90_100[i]); + lambda_conde90_100[i] = Media.NH3_Water.thermalConductivity_LIQConde( state90_100[i]); + + state130_100[i] = Medium.setState_pTX(100e5,130+273.15,{x1[i],1-x1[i]}); + lambda_elsayedLin130_100[i] = Media.NH3_Water.thermalConductivity_LIQLinearMoleElsayed( state130_100[i]); + lambda_filipov130_100[i] = Media.NH3_Water.thermalConductivity_LIQFilipov( state130_100[i]); + lambda_jamieson130_100[i] = Media.NH3_Water.thermalConductivity_LIQJamie( state130_100[i]); + lambda_conde130_100[i] = Media.NH3_Water.thermalConductivity_LIQConde( state130_100[i]); + + end for; + + end liquid_conductivity_sweep; + + model vapor_conductivity_sweep + + package Medium = REFPROP2Modelica.Media.NH3_Water; + parameter Integer n=101; + Medium.ThermodynamicState state_325_050[n] annotation(hideResult=true); + Medium.ThermodynamicState state_325_100[n] annotation(hideResult=true); + Medium.ThermodynamicState state_425_100[n] annotation(hideResult=true); + Medium.ThermodynamicState state_525_100[n] annotation(hideResult=true); + // Medium.AbsolutePressure p; + + Real x1[n] = linspace(0,1,n); + + Real lambda_polingLin_325_050[n]; + Real lambda_polingLin_325_100[n]; + Real lambda_polingLin_425_100[n]; + Real lambda_polingLin_525_100[n]; + + Real lambda_wilke_325_050[n]; + Real lambda_wilke_325_100[n]; + Real lambda_wilke_425_100[n]; + Real lambda_wilke_525_100[n]; + + Real lambda_chung_325_050[n]; + Real lambda_chung_325_100[n]; + Real lambda_chung_425_100[n]; + Real lambda_chung_525_100[n]; + + Real lambda_chungErrorWeight_325_050[n]; + Real lambda_chungErrorWeight_325_100[n]; + Real lambda_chungErrorWeight_425_100[n]; + Real lambda_chungErrorWeight_525_100[n]; + + equation + for i in 1:n loop + + state_325_050[i] = Medium.setState_pTX(050e5,325+273.15,{x1[i],1-x1[i]}); + lambda_polingLin_325_050[i] = Media.NH3_Water.thermalConductivity_VAPLinearMolePoling( state_325_050[i]); + lambda_wilke_325_050[i] = Media.NH3_Water.thermalConductivity_VAPWilke( state_325_050[i]); + lambda_chung_325_050[i] = Media.NH3_Water.thermalConductivity_VAPChung(state_325_050[i]); + lambda_chungErrorWeight_325_050[i] = Media.NH3_Water.thermalConductivity_VAPChungPureErrorWeight(state_325_050[i]); + + state_325_100[i] = Medium.setState_pTX(100e5,325+273.15,{x1[i],1-x1[i]}); + lambda_polingLin_325_100[i] = Media.NH3_Water.thermalConductivity_VAPLinearMolePoling( state_325_100[i]); + lambda_wilke_325_100[i] = Media.NH3_Water.thermalConductivity_VAPWilke( state_325_100[i]); + lambda_chung_325_100[i] = Media.NH3_Water.thermalConductivity_VAPChung(state_325_100[i]); + lambda_chungErrorWeight_325_100[i] = Media.NH3_Water.thermalConductivity_VAPChungPureErrorWeight(state_325_100[i]); + + state_425_100[i] = Medium.setState_pTX(100e5,475+273.15,{x1[i],1-x1[i]}); + lambda_polingLin_425_100[i] = Media.NH3_Water.thermalConductivity_VAPLinearMolePoling( state_425_100[i]); + lambda_wilke_425_100[i] = Media.NH3_Water.thermalConductivity_VAPWilke( state_425_100[i]); + lambda_chung_425_100[i] = Media.NH3_Water.thermalConductivity_VAPChung(state_425_100[i]); + lambda_chungErrorWeight_425_100[i] = Media.NH3_Water.thermalConductivity_VAPChungPureErrorWeight(state_425_100[i]); + + state_525_100[i] = Medium.setState_pTX(100e5,525+273.15,{x1[i],1-x1[i]}); + lambda_polingLin_525_100[i] = Media.NH3_Water.thermalConductivity_VAPLinearMolePoling( state_525_100[i]); + lambda_wilke_525_100[i] = Media.NH3_Water.thermalConductivity_VAPWilke( state_525_100[i]); + lambda_chung_525_100[i] = Media.NH3_Water.thermalConductivity_VAPChung(state_525_100[i]); + lambda_chungErrorWeight_525_100[i] = Media.NH3_Water.thermalConductivity_VAPChungPureErrorWeight(state_525_100[i]); + + end for; + + end vapor_conductivity_sweep; +end TestCore; +end TransportPropsTest; +end AmmoniaWater; diff --git a/Testers/PentaneTester.mo b/Testers/PentaneTester.mo new file mode 100644 index 0000000..cc8cce6 --- /dev/null +++ b/Testers/PentaneTester.mo @@ -0,0 +1,57 @@ +within REFPROP2Modelica.Testers; +model PentaneTester "Evaporation of pentane at 1 bar" + package Medium = REFPROP2Modelica.Media.Pentane (debugmode=true); + Medium.BaseProperties props(h(start=300e3), d(start=1)); + Real drhodtime_num; + Real drhodtime_ana; + Real factor1; + Real factor2; + Real check1; + Real check2; + Real deltap; + Real deltah; + Real ddddp_num; + Real ddddp_RP; + Real ddddp_ana; + Real ddddh_num; + Real ddddh_RP; + Real ddddh_ana; +equation + deltap = 5; + deltah = 5; + props.p = 10e5;//1e5+3*time*4e5*(sin(20*time)+1)*0.5; + props.h = -3e5 + time*7e5; + + // get derivatives for checking + factor1 = der(props.p); + factor2 = der(props.h); + + drhodtime_num = ddddp_num*factor1 + ddddh_num*factor2; + ddddp_num = (Medium.density_phX( + props.p + 0.5*deltap, + props.h, + props.X) - Medium.density_phX( + props.p - 0.5*deltap, + props.h, + props.X))/deltap; + ddddh_num = (Medium.density_phX( + props.p, + props.h + 0.5*deltah, + props.X) - Medium.density_phX( + props.p, + props.h - 0.5*deltah, + props.X))/deltah; + + drhodtime_ana = ddddp_ana*factor1 + ddddh_ana*factor2; + -1 = ddddp_ana*1/(props.state.dhdp_rho)*props.state.dhdrho_p; + ddddh_ana*props.state.dhdrho_p = 1; + + check1 = abs(ddddp_num - props.state.drhodp_h)/abs(ddddp_num)*100 + "difference of derivatives in percent"; + check2 = abs(ddddh_num - props.state.drhodh_p)/abs(ddddh_num)*100 + "difference of derivatives in percent"; + + ddddh_RP = props.state.drhodh_p "drho/dh at constant pressure"; + ddddp_RP = props.state.drhodp_h "drho/dp at constant enthalpy"; + +end PentaneTester; diff --git a/Examples/PropsMixture.mo b/Testers/PropsMixture.mo similarity index 83% rename from Examples/PropsMixture.mo rename to Testers/PropsMixture.mo index 8345f7f..f120c58 100644 --- a/Examples/PropsMixture.mo +++ b/Testers/PropsMixture.mo @@ -1,61 +1,54 @@ -within MediaTwoPhaseMixture.Examples; -model PropsMixture -//package Medium = REFPROPMedium(final substanceNames={"isobutan"}); -//package Medium = REFPROPMedium(final substanceNames={"R12"}); -package Medium = REFPROPMedium(final substanceNames={"isobutan","propane"}); -// ",final explicitVars = "pd""; -//package Medium = MediaTwoPhaseMixture.REFPROPMedium(final substanceNames={"CO2","water"}); - - Medium.BaseProperties props; - - Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); - -/* Modelica.SIunits.SpecificEnthalpy h=Medium.specificEnthalpy_pTX(1e5,293,{.5,.5}); - Modelica.SIunits.Density d; - Modelica.SIunits.SpecificEntropy s; - Modelica.SIunits.Temperature Tsat; - Modelica.SIunits.Pressure psat; - */ -Modelica.SIunits.Pressure p=Medium.pressure(props.state); -// Modelica.SIunits.MolarMass MM; -/*Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); - -Modelica.SIunits.DynamicViscosity eta_l = Medium.dynamicViscosity_liq(props.state); -Modelica.SIunits.DynamicViscosity eta_g = Medium.dynamicViscosity_gas(props.state); -*/ - Real q = Medium.vapourQuality(props.state); - Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); - Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); -equation - - props.p = 1e5; - props.h = 0+time*8e5; - // props.s = 5.88105; -// props.T = 400; -// props.state.x = 0.5; -// props.Xi = {.5}; -// props.X = {.1,.9}; - props.Xi = {.5}; - - // d = props.d; - //h = props.h; - //h = Medium.dewEnthalpy(props.sat); - - //d = Medium.density(props.state); - //s = specificEntropy(props.state); - //s = props.state.s; -// MM = Medium.molarMass(props.state); - -/* - Tsat = Medium.saturationTemperature(props.p,props.X); -// Tsat = Medium.temperature_pqX(props.p,0.5,props.X); - psat = Medium.saturationPressure(props.T,props.X); -// psat = Medium.pressure_TqX(props.T,0.5,props.X); -// h = Medium.dewEnthalpy(props.sat); -// s = Medium.dewEntropy(props.sat); - s = Medium.bubbleEntropy(props.sat); -// d = Medium.dewDensity(props.sat); - d = Medium.bubbleDensity(props.sat); -*/ - -end PropsMixture; +within REFPROP2Modelica.Testers; +model PropsMixture +//package Medium = REFPROPMedium(final substanceNames={"isobutan"}); +//package Medium = REFPROPMedium(final substanceNames={"R12"}); +package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( + final substanceNames={"isobutan","propane"}); +// ",final explicitVars = "pd""; +//package Medium = REFPROP2Modelica.REFPROPMedium(final substanceNames={"CO2","water"}); + Medium.BaseProperties props; + Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); +/* Modelica.SIunits.SpecificEnthalpy h=Medium.specificEnthalpy_pTX(1e5,293,{.5,.5}); + Modelica.SIunits.Density d; + Modelica.SIunits.SpecificEntropy s; + Modelica.SIunits.Temperature Tsat; + Modelica.SIunits.Pressure psat; + */ +Modelica.SIunits.Pressure p(min=10,max=10e6)=Medium.pressure(props.state); +// Modelica.SIunits.MolarMass MM; +/*Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); + +Modelica.SIunits.DynamicViscosity eta_l = Medium.dynamicViscosity_liq(props.state); +Modelica.SIunits.DynamicViscosity eta_g = Medium.dynamicViscosity_gas(props.state); +*/ + Real q = Medium.vapourQuality(props.state); + Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); + Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); +equation + props.p = 1e5; + props.h = 0+time*8e5; + // props.s = 5.88105; +// props.T = 400; +// props.state.x = 0.5; +// props.Xi = {.5}; +// props.X = {.1,.9}; + props.Xi = {0.5}; + // d = props.d; + //h = props.h; + //h = Medium.dewEnthalpy(props.sat); + //d = Medium.density(props.state); + //s = specificEntropy(props.state); + //s = props.state.s; +// MM = Medium.molarMass(props.state); +/* + Tsat = Medium.saturationTemperature(props.p,props.X); +// Tsat = Medium.temperature_pqX(props.p,0.5,props.X); + psat = Medium.saturationPressure(props.T,props.X); +// psat = Medium.pressure_TqX(props.T,0.5,props.X); +// h = Medium.dewEnthalpy(props.sat); +// s = Medium.dewEntropy(props.sat); + s = Medium.bubbleEntropy(props.sat); +// d = Medium.dewDensity(props.sat); + d = Medium.bubbleDensity(props.sat); +*/ +end PropsMixture; diff --git a/Testers/PropsMixtureTwo.mo b/Testers/PropsMixtureTwo.mo new file mode 100644 index 0000000..77bdb33 --- /dev/null +++ b/Testers/PropsMixtureTwo.mo @@ -0,0 +1,27 @@ +within REFPROP2Modelica.Testers; +model PropsMixtureTwo +package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( + final substanceNames={"isobutan","propane"}); + Medium.BaseProperties props; + Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); +Modelica.SIunits.Pressure p(min=10,max=10e6)=Medium.pressure(props.state); + Real q = Medium.vapourQuality(props.state); + Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); + Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); + + Medium.SaturationProperties sat = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.setSat( + props.p,props.X); + Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); + Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); + Medium.Density dl = Medium.bubbleDensity(sat); + Medium.Density dv = Medium.dewDensity(sat); + + Medium.ThermodynamicState state_l=Medium.setState_pqX(props.p,0,props.X); + Medium.ThermodynamicState state_v=Medium.setState_pqX(props.p,1,props.X); + +equation + props.p = 1e5; + props.h = 0+time*8e5; + props.Xi = {0.5}; + +end PropsMixtureTwo; diff --git a/Examples/PropsPureSubstance.mo b/Testers/PropsPureSubstance.mo similarity index 86% rename from Examples/PropsPureSubstance.mo rename to Testers/PropsPureSubstance.mo index 1637ec0..e23b4a8 100644 --- a/Examples/PropsPureSubstance.mo +++ b/Testers/PropsPureSubstance.mo @@ -1,55 +1,49 @@ -within MediaTwoPhaseMixture.Examples; -model PropsPureSubstance -//package Medium = Modelica.Media.Water.WaterIF97_ph; -//package Medium = MediaTwoPhaseMixture.Water_MixtureTwoPhase_pT; -//package Medium = REFPROPMedium(final substanceNames={"water"}, final explicitVars = "pT"); -//package Medium = REFPROPMedium(final substanceNames={"ammonia"}); -//package Medium = REFPROPMedium(final substanceNames={"co2"}); -package Medium = MediaTwoPhaseMixture.REFPROPMediumPureSubstance (final substanceNames={"butane"}); - -//package Medium = REFPROPMediumPureSubstance(final substanceNames={"water"}); -//package Medium = REFPROPMediumPureSubstance(final substanceNames={"ammonia"}, final explicitVars = "ph"); - - Medium.BaseProperties props; -// Modelica.SIunits.Density d=Medium.density_phX(props.p,props.h); -// d = Medium.bubbleDensity(props.sat); -// d = Medium.density_pTX(1e5,300); -// Modelica.SIunits.SpecificEnthalpy h; -// Modelica.SIunits.SpecificEntropy s; -// Modelica.SIunits.Temperature T=props.T; - Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); -// Modelica.SIunits.MolarMass MM; - Real q= Medium.vapourQuality(props.state); -// Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; -// Modelica.SIunits.ThermalConductivity lambda= Medium.thermalConductivity(props.state); -// Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); - Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); - Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300); -equation - props.p = 1e5 "sine_p.y"; - props.h = 0+time*722774; - -// props.s = 5.88105; -// props.T = 350; -// props.Xi = fill(0,0); - - //d = props.d; - //h = props.h; - //h = Medium.dewEnthalpy(props.sat); - - //d = Medium.density(props.state); - //s = specificEntropy(props.state); - //s = props.state.s; -// MM = Medium.molarMass(props.state); -// Tsat = Medium.saturationTemperature(props.p,props.X); -// Tsat = Medium.temperature_pqX(props.p,0.5,props.X); -// psat = Medium.saturationPressure(props.T,props.X); -// psat = Medium.pressure_TqX(props.T,0.5,props.X); -// h = Medium.dewEnthalpy(props.sat); -// s = Medium.dewEntropy(props.sat); -// s = Medium.bubbleEntropy(props.sat); -// d = Medium.dewDensity(props.sat); - - annotation (experiment(StopTime=10, NumberOfIntervals=1000), - __Dymola_experimentSetupOutput); -end PropsPureSubstance; +within REFPROP2Modelica.Testers; +model PropsPureSubstance +//package Medium = Modelica.Media.Water.WaterIF97_ph; +//package Medium = REFPROP2Modelica.Water_MixtureTwoPhase_pT; +//package Medium = REFPROPMedium(final substanceNames={"water"}, final explicitVars = "pT"); +//package Medium = REFPROPMedium(final substanceNames={"ammonia"}); +//package Medium = REFPROPMedium(final substanceNames={"co2"}); +package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames={"butane"},debugmode=true); +//package Medium = REFPROPMediumPureSubstance(final substanceNames={"water"}); +//package Medium = REFPROPMediumPureSubstance(final substanceNames={"ammonia"}, final explicitVars = "ph"); + Medium.BaseProperties props; +// Modelica.SIunits.Density d=Medium.density_phX(props.p,props.h); +// d = Medium.bubbleDensity(props.sat); +// d = Medium.density_pTX(1e5,300); +// Modelica.SIunits.SpecificEnthalpy h; +// Modelica.SIunits.SpecificEntropy s; +// Modelica.SIunits.Temperature T=props.T; + Modelica.SIunits.Pressure psat=Medium.saturationPressure(300,{1}); +// Modelica.SIunits.MolarMass MM; + Real q= Medium.vapourQuality(props.state); +// Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; +// Modelica.SIunits.ThermalConductivity lambda= Medium.thermalConductivity(props.state); +// Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); + Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); + Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300,{1}); +equation + props.p = 1e5 "sine_p.y"; + props.h = 0+time*722774; +// props.s = 5.88105; +// props.T = 350; +// props.Xi = fill(0,0); + //d = props.d; + //h = props.h; + //h = Medium.dewEnthalpy(props.sat); + //d = Medium.density(props.state); + //s = specificEntropy(props.state); + //s = props.state.s; +// MM = Medium.molarMass(props.state); +// Tsat = Medium.saturationTemperature(props.p,props.X); +// Tsat = Medium.temperature_pqX(props.p,0.5,props.X); +// psat = Medium.saturationPressure(props.T,props.X); +// psat = Medium.pressure_TqX(props.T,0.5,props.X); +// h = Medium.dewEnthalpy(props.sat); +// s = Medium.dewEntropy(props.sat); +// s = Medium.bubbleEntropy(props.sat); +// d = Medium.dewDensity(props.sat); + annotation (experiment(StopTime=10, NumberOfIntervals=1000), + __Dymola_experimentSetupOutput); +end PropsPureSubstance; diff --git a/Testers/R410mixTester.mo b/Testers/R410mixTester.mo new file mode 100644 index 0000000..c28c7c3 --- /dev/null +++ b/Testers/R410mixTester.mo @@ -0,0 +1,15 @@ +within REFPROP2Modelica.Testers; +model R410mixTester "Density of saturated R410 vapour" +package Medium = REFPROP2Modelica.Media.R410mix(debugmode=true); + Medium.BaseProperties props; + Medium.Density d; + Medium.SpecificEnthalpy h(start=300e3); + Medium.AbsolutePressure p = Medium.pressure(props.state); + Medium.SpecificHeatCapacity cv = Medium.specificHeatCapacityCv(props.state); +equation + props.p = 101325; + h = Medium.dewEnthalpy(props.sat); + props.h = h+0.2*h*0.5*(sin(5*time)+1); + props.d = d; + props.Xi = {0.697615}; +end R410mixTester; diff --git a/Water_MixtureTwoPhase_pT/package.mo b/Testers/Water_MixtureTwoPhase_pT.mo similarity index 88% rename from Water_MixtureTwoPhase_pT/package.mo rename to Testers/Water_MixtureTwoPhase_pT.mo index 5aa7ebd..deb20fd 100644 --- a/Water_MixtureTwoPhase_pT/package.mo +++ b/Testers/Water_MixtureTwoPhase_pT.mo @@ -1,319 +1,286 @@ -within MediaTwoPhaseMixture; -package Water_MixtureTwoPhase_pT "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" - - - extends PartialMixtureTwoPhaseMedium( - final mediumName="TwoPhaseMixtureWater", - final substanceNames={"water"}, - final reducedX = true, - final singleState=false, - reference_X=cat(1,fill(0,nX-1),{1}), - fluidConstants = BrineConstants); -// final extraPropertiesNames={"gas enthalpy","liquid enthalpy"}, - - constant Modelica.SIunits.MolarMass M_H2O = 0.018015 "[kg/mol] TODO"; - - - redeclare model extends BaseProperties "Base properties of medium" - - Real GVF=q*d/d_g "gas void fraction"; - Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_T(T); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_T(T); - /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_p(p); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_p(p);*/ - /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_p(p); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhov_p(p);*/ - Modelica.SIunits.SpecificEnthalpy h_l = bubbleEnthalpy(sat); - Modelica.SIunits.SpecificEnthalpy h_g = dewEnthalpy(sat); - Real q = min(max((h - h_l)/(h_g - h_l+ 1e-18), 0), 1) - "(min=0,max=1) gas phase mass fraction"; - // Integer phase_out "calculated phase"; - //END no gas case - equation - u = h - p/d; - MM = M_H2O; - R = Modelica.Constants.R/MM; - - //End GVF - - //DENSITY - // q = vapourQuality(state); - d = Modelica.Media.Water.WaterIF97_base.density_ph(p,h); - // d = d_l/(1-q*(1-d_l/d_g)); - //End DENSITY - - //ENTHALPY - h = specificEnthalpy_pTX(p,T,X); - /* - if (p_H2O>p) then - h_H2O_g = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T,1); - else - h_H2O_g = Modelica.Media.Water.WaterIF97_base.dewEnthalpy(Modelica.Media.Water.WaterIF97_base.setSat_p(p)); - end if; - h_gas_dissolved = 0; - Delta_h_solution = solutionEnthalpy(T) - "TODO: gilt nur bei gesättigter Lösung"; -*/ - //assert(abs(((1-q)*h_l + q*h_g-h)/h) < 1e-3,"Enthalpie stimmt nicht! h_calc="+String((1-q)*h_l + q*h_g)+"<>h="+String(h)); - //End ENTHALPY - - s=0 "TODO"; - - state = ThermodynamicState( - p=p, - T=T, - X=X, - X_l=X, - h=h, - GVF=GVF, - q=q, - s=0, - d_g=d_g, - d_l=d_l, - d=d, - phase=0) "phase_out"; - - sat.psat = p "TODO"; - sat.Tsat = T "saturationTemperature(p) TODO"; - sat.X = X; - - annotation (Documentation(info=""), - Documentation(revisions=" - -")); - end BaseProperties; - - - redeclare function specificEnthalpy_pTX - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - /* input MassFraction q "(min=0,max=1)"; - input Real y "molar fraction of gas in gas phase";*/ - // input Real[3] TP; - output Modelica.SIunits.SpecificEnthalpy h=Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T); - algorithm - // Modelica.Utilities.Streams.print("specificEnthalpy_pTXqy("+String(p)+","+String(T)+",X,"+String(q)+","+String(y)+")"); - annotation(LateInline=true,inverse(T = temperature_phX(p=p,h=h,X=X,phase=phase))); - end specificEnthalpy_pTX; - - - redeclare function temperature_phX - "numerically inverts specificEnthalpy_liquid_pTX" - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:] "mass fraction m_XCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temp_K T=Modelica.Media.Water.WaterIF97_base.temperature_ph(p,h); - algorithm - // Modelica.Utilities.Streams.print("temperature_phX"); - - annotation(LateInline=true,inverse(h = specificEnthalpy_pTX(p=p,T=T,phase=phase,X=X))); - end temperature_phX; - - -redeclare record extends ThermodynamicState - "a selection of variables that uniquely defines the thermodynamic state" -/* AbsolutePressure p "Absolute pressure of medium"; - Temperature T(unit="K") "Temperature of medium"; - MassFraction X[nX] "Mass fraction of NaCl in kg/kg";*/ - SpecificEnthalpy h "Specific enthalpy"; - SpecificEntropy s "Specific entropy"; - Density d(start=300) "density"; - Real GVF "Gas Void Fraction"; - Density d_l(start=300) "density liquid phase"; - Density d_g(start=300) "density gas phase"; - Real q "vapor quality on a mass basis [mass vapor/total mass]"; - - annotation (Documentation(info=" - -")); -end ThermodynamicState; - - - redeclare function extends dewEnthalpy "dew curve specific enthalpy of water" - algorithm - hv := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(sat.psat); - end dewEnthalpy; - - - redeclare function extends bubbleEnthalpy - "boiling curve specific enthalpy of water" - algorithm - hl := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat); - end bubbleEnthalpy; - - - redeclare function extends saturationTemperature - algorithm - //T := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p); - T := Modelica.Media.Water.WaterIF97_base.saturationTemperature(p); - end saturationTemperature; - - - redeclare function extends dynamicViscosity - algorithm - eta := Modelica.Media.Water.WaterIF97_base.dynamicViscosity(state); - end dynamicViscosity; - - -redeclare function extends specificEntropy "specific entropy of water" -algorithm - s := Modelica.Media.Water.IF97_Utilities.s_ph(state.p, state.h, state.phase); -end specificEntropy; - - -redeclare function specificEnthalpy_ps - "Computes specific enthalpy as a function of pressure and temperature" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; -algorithm - h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); -end specificEnthalpy_ps; - - -redeclare function extends setState_psX - "Return thermodynamic state of water as function of p and s" -algorithm - state := ThermodynamicState( - d=density_ps(p,s), - T=temperature_ps(p,s), - phase=0, - h=specificEnthalpy_ps(p,s), - p=p, - X=X, - s=s, - q=-1, - GVF=-1, - d_l=-1, - d_g=-1); -end setState_psX; - - - redeclare function extends temperature "return temperature of ideal gas" - algorithm - T := state.T; - end temperature; - - - redeclare function extends density "return density of ideal gas" - algorithm - d := state.d; - end density; - - -redeclare function extends setState_pTX - "Return thermodynamic state of water as function of p and T" -algorithm - state := ThermodynamicState( - d=density_pT(p,T), - T=T, - phase=0, - h=specificEnthalpy_pTX(p,s), - p=p, - X=X, - s=specificEntropy_pT(p.T), - q=-1, - GVF=-1, - d_l=-1, - d_g=-1); -end setState_pTX; - - -redeclare function specificEntropy_pTX - "Computes specific enthalpy as a function of pressure and temperature" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy T "Specific entropy"; - input MassFraction X[:] "mass fraction m_XCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy s "specific enthalpy"; -algorithm - h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); -end specificEntropy_pTX; - - - redeclare function extends thermalConductivity - "Thermal conductivity of water" - algorithm - lambda := Modelica.Media.Water.IF97_Utilities.thermalConductivity( - state.d, - state.T, - state.p, - state.phase); - end thermalConductivity; - - - redeclare function extends specificHeatCapacityCp - "specific heat capacity at constant pressure of water" - - algorithm - if Modelica.Media.Water.WaterIF97_base.dT_explicit then - cp := Modelica.Media.Water.IF97_Utilities.cp_dT( - state.d, - state.T, - state.phase); - elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then - cp := Modelica.Media.Water.IF97_Utilities.cp_pT(state.p, state.T); - else - cp := Modelica.Media.Water.IF97_Utilities.cp_ph( - state.p, - state.h, - state.phase); - end if; - annotation (Documentation(info=" -

In the two phase region this function returns the interpolated heat capacity between the - liquid and vapour state heat capacities.

- ")); - end specificHeatCapacityCp; - - - redeclare function extends saturationPressure - algorithm - p := Modelica.Media.Water.WaterIF97_base.saturationPressure(T); - end saturationPressure; - - - redeclare function extends specificHeatCapacityCv - "specific heat capacity at constant pressure of water" - - algorithm - if Modelica.Media.Water.WaterIF97_base.dT_explicit then - cv := Modelica.Media.Water.IF97_Utilities.cv_dT( - state.d, - state.T, - state.phase); - elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then - cv := Modelica.Media.Water.IF97_Utilities.cv_pT(state.p, state.T); - else - cv := Modelica.Media.Water.IF97_Utilities.cv_ph( - state.p, - state.h, - state.phase); - end if; - annotation (Documentation(info=" -

In the two phase region this function returns the interpolated heat capacity between the - liquid and vapour state heat capacities.

- ")); - end specificHeatCapacityCv; - - annotation (Documentation(info=" -

Water_MixtureTwoPhase_pT

- This is a an example use of PartialMixtureTwoPhaseMedium. - It is a (incomplete) water model using the template PartialMixtureTwoPhaseMedium. It uses the property functions from Modelica.Media.Water.
- -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -")); -end Water_MixtureTwoPhase_pT; +within REFPROP2Modelica.Testers; +package Water_MixtureTwoPhase_pT + "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" + extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMedium( + final mediumName="TwoPhaseMixtureWater", + final substanceNames={"water"}, + final reducedX = true, + final singleState=false, + reference_X=cat(1,fill(0,nX-1),{1}), + fluidConstants = BrineConstants); +// final extraPropertiesNames={"gas enthalpy","liquid enthalpy"}, + constant Modelica.SIunits.MolarMass M_H2O = 0.018015 "[kg/mol] TODO"; + + redeclare model extends BaseProperties "Base properties of medium" + Real GVF=q*d/d_g "gas void fraction"; + Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_T(T); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_T(T); + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_p(p);*/ + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhov_p(p);*/ + Modelica.SIunits.SpecificEnthalpy h_l = bubbleEnthalpy(sat); + Modelica.SIunits.SpecificEnthalpy h_g = dewEnthalpy(sat); + Real q = min(max((h - h_l)/(h_g - h_l+ 1e-18), 0), 1) + "(min=0,max=1) gas phase mass fraction"; + // Integer phase_out "calculated phase"; + //END no gas case + equation + u = h - p/d; + MM = M_H2O; + R = Modelica.Constants.R/MM; + //End GVF + //DENSITY + // q = vapourQuality(state); + d = Modelica.Media.Water.WaterIF97_base.density_ph(p,h); + // d = d_l/(1-q*(1-d_l/d_g)); + //End DENSITY + //ENTHALPY + h = specificEnthalpy_pTX(p,T,X); + /* + if (p_H2O>p) then + h_H2O_g = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T,1); + else + h_H2O_g = Modelica.Media.Water.WaterIF97_base.dewEnthalpy(Modelica.Media.Water.WaterIF97_base.setSat_p(p)); + end if; + h_gas_dissolved = 0; + Delta_h_solution = solutionEnthalpy(T) + "TODO: gilt nur bei gesättigter Lösung"; +*/ + //assert(abs(((1-q)*h_l + q*h_g-h)/h) < 1e-3,"Enthalpie stimmt nicht! h_calc="+String((1-q)*h_l + q*h_g)+"<>h="+String(h)); + //End ENTHALPY + s=0 "TODO"; + state = ThermodynamicState( + p=p, + T=T, + X=X, + X_l=X, + h=h, + GVF=GVF, + q=q, + s=0, + d_g=d_g, + d_l=d_l, + d=d, + phase=0) "phase_out"; + sat.psat = p "TODO"; + sat.Tsat = T "saturationTemperature(p) TODO"; + sat.X = X; + annotation (Documentation(info=""), + Documentation(revisions=" + +")); + end BaseProperties; + + redeclare function specificEnthalpy_pTX + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temp_K T; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + /* input MassFraction q "(min=0,max=1)"; + input Real y "molar fraction of gas in gas phase";*/ + // input Real[3] TP; + output Modelica.SIunits.SpecificEnthalpy h=Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T); + algorithm + // Modelica.Utilities.Streams.print("specificEnthalpy_pTXqy("+String(p)+","+String(T)+",X,"+String(q)+","+String(y)+")"); + annotation(LateInline=true,inverse(T = temperature_phX(p=p,h=h,X=X,phase=phase))); + end specificEnthalpy_pTX; + + redeclare function temperature_phX + "numerically inverts specificEnthalpy_liquid_pTX" + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temp_K T=Modelica.Media.Water.WaterIF97_base.temperature_ph(p,h); + algorithm + // Modelica.Utilities.Streams.print("temperature_phX"); + annotation(LateInline=true,inverse(h = specificEnthalpy_pTX(p=p,T=T,phase=phase,X=X))); + end temperature_phX; + +redeclare record extends ThermodynamicState + "a selection of variables that uniquely defines the thermodynamic state" +/* AbsolutePressure p "Absolute pressure of medium"; + Temperature T(unit="K") "Temperature of medium"; + MassFraction X[nX] "Mass fraction of NaCl in kg/kg";*/ + SpecificEnthalpy h "Specific enthalpy"; + SpecificEntropy s "Specific entropy"; + Density d(start=300) "density"; + Real GVF "Gas Void Fraction"; + Density d_l(start=300) "density liquid phase"; + Density d_g(start=300) "density gas phase"; + Real q "vapor quality on a mass basis [mass vapor/total mass]"; + annotation (Documentation(info=" + +")); +end ThermodynamicState; + + redeclare function extends dewEnthalpy "dew curve specific enthalpy of water" + algorithm + hv := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(sat.psat); + end dewEnthalpy; + + redeclare function extends bubbleEnthalpy + "boiling curve specific enthalpy of water" + algorithm + hl := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat); + end bubbleEnthalpy; + + redeclare function extends saturationTemperature + algorithm + //T := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p); + T := Modelica.Media.Water.WaterIF97_base.saturationTemperature(p); + end saturationTemperature; + + redeclare function extends dynamicViscosity + algorithm + eta := Modelica.Media.Water.WaterIF97_base.dynamicViscosity(state); + end dynamicViscosity; + +redeclare function extends specificEntropy "specific entropy of water" +algorithm + s := Modelica.Media.Water.IF97_Utilities.s_ph(state.p, state.h, state.phase); +end specificEntropy; + +redeclare function specificEnthalpy_ps + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; +algorithm + h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEnthalpy_ps; + +redeclare function extends setState_psX + "Return thermodynamic state of water as function of p and s" +algorithm + state := ThermodynamicState( + d=density_ps(p,s), + T=temperature_ps(p,s), + phase=0, + h=specificEnthalpy_ps(p,s), + p=p, + X=X, + s=s, + q=-1, + GVF=-1, + d_l=-1, + d_g=-1); +end setState_psX; + + redeclare function extends temperature "return temperature of ideal gas" + algorithm + T := state.T; + end temperature; + + redeclare function extends density "return density of ideal gas" + algorithm + d := state.d; + end density; + +redeclare function extends setState_pTX + "Return thermodynamic state of water as function of p and T" +algorithm + state := ThermodynamicState( + d=density_pT(p,T), + T=T, + phase=0, + h=specificEnthalpy_pTX(p,s), + p=p, + X=X, + s=specificEntropy_pT(p.T), + q=-1, + GVF=-1, + d_l=-1, + d_g=-1); +end setState_pTX; + +redeclare function specificEntropy_pTX + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy T "Specific entropy"; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy s "specific enthalpy"; +algorithm + h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEntropy_pTX; + + redeclare function extends thermalConductivity + "Thermal conductivity of water" + algorithm + lambda := Modelica.Media.Water.IF97_Utilities.thermalConductivity( + state.d, + state.T, + state.p, + state.phase); + end thermalConductivity; + + redeclare function extends specificHeatCapacityCp + "specific heat capacity at constant pressure of water" + algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cp := Modelica.Media.Water.IF97_Utilities.cp_dT( + state.d, + state.T, + state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cp := Modelica.Media.Water.IF97_Utilities.cp_pT(state.p, state.T); + else + cp := Modelica.Media.Water.IF97_Utilities.cp_ph( + state.p, + state.h, + state.phase); + end if; + annotation (Documentation(info=" +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); + end specificHeatCapacityCp; + + redeclare function extends saturationPressure + algorithm + p := Modelica.Media.Water.WaterIF97_base.saturationPressure(T); + end saturationPressure; + + redeclare function extends specificHeatCapacityCv + "specific heat capacity at constant pressure of water" + algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cv := Modelica.Media.Water.IF97_Utilities.cv_dT( + state.d, + state.T, + state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cv := Modelica.Media.Water.IF97_Utilities.cv_pT(state.p, state.T); + else + cv := Modelica.Media.Water.IF97_Utilities.cv_ph( + state.p, + state.h, + state.phase); + end if; + annotation (Documentation(info=" +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); + end specificHeatCapacityCv; + + annotation (Documentation(info=" +

Water_MixtureTwoPhase_pT

+ This is a an example use of PartialMixtureTwoPhaseMedium. + It is a (incomplete) water model using the template PartialMixtureTwoPhaseMedium. It uses the property functions from Modelica.Media.Water.
+ +

Created by

+Henning Francke
+Helmholtz Centre Potsdam
+GFZ German Research Centre for Geosciences
+Telegrafenberg, D-14473 Potsdam
+Germany +

+francke@gfz-potsdam.de + +")); +end Water_MixtureTwoPhase_pT; diff --git a/Testers/Water_MixtureTwoPhase_pT/BaseProperties.mo b/Testers/Water_MixtureTwoPhase_pT/BaseProperties.mo new file mode 100644 index 0000000..2b1ef47 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/BaseProperties.mo @@ -0,0 +1,50 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +model extends BaseProperties "Base properties of medium" + Real GVF = q * d / d_g "gas void fraction"; + Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_T(T); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_T(T); + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_p(p);*/ + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhov_p(p);*/ + Modelica.SIunits.SpecificEnthalpy h_l = bubbleEnthalpy(sat); + Modelica.SIunits.SpecificEnthalpy h_g = dewEnthalpy(sat); + Real q = min(max((h - h_l) / (h_g - h_l + 1e-18), 0), 1) + "(min=0,max=1) gas phase mass fraction"; + // Integer phase_out "calculated phase"; + //END no gas case +equation + u = h - p / d; + MM = M_H2O; + R = Modelica.Constants.R / MM; + //End GVF + //DENSITY + // q = vapourQuality(state); + d = Modelica.Media.Water.WaterIF97_base.density_ph(p, h); + // d = d_l/(1-q*(1-d_l/d_g)); + //End DENSITY + //ENTHALPY + h = specificEnthalpy_pTX(p, T, X); + /* + if (p_H2O>p) then + h_H2O_g = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T,1); + else + h_H2O_g = Modelica.Media.Water.WaterIF97_base.dewEnthalpy(Modelica.Media.Water.WaterIF97_base.setSat_p(p)); + end if; + h_gas_dissolved = 0; + Delta_h_solution = solutionEnthalpy(T) + "TODO: gilt nur bei ges�ttigter L�sung"; +*/ + //assert(abs(((1-q)*h_l + q*h_g-h)/h) < 1e-3,"Enthalpie stimmt nicht! h_calc="+String((1-q)*h_l + q*h_g)+"<>h="+String(h)); + //End ENTHALPY + s = 0 "TODO"; + state = ThermodynamicState(p= p, T= T, X= X, X_l= X, h= h, GVF= GVF, q= q, s= 0, d_g= d_g, d_l= d_l, d= d, phase= 0) + "phase_out"; + sat.psat = p "TODO"; + sat.Tsat = T "saturationTemperature(p) TODO"; + sat.X = X; + annotation(Documentation(info = ""), Documentation(revisions = " + +")); +end BaseProperties; + diff --git a/Testers/Water_MixtureTwoPhase_pT/ThermodynamicState.mo b/Testers/Water_MixtureTwoPhase_pT/ThermodynamicState.mo new file mode 100644 index 0000000..18e4c5e --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/ThermodynamicState.mo @@ -0,0 +1,18 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +record extends ThermodynamicState + "a selection of variables that uniquely defines the thermodynamic state" + /* AbsolutePressure p "Absolute pressure of medium"; + Temperature T(unit="K") "Temperature of medium"; + MassFraction X[nX] "Mass fraction of NaCl in kg/kg";*/ + SpecificEnthalpy h "Specific enthalpy"; + SpecificEntropy s "Specific entropy"; + Density d(start = 300) "density"; + Real GVF "Gas Void Fraction"; + Density d_l(start = 300) "density liquid phase"; + Density d_g(start = 300) "density gas phase"; + Real q "vapor quality on a mass basis [mass vapor/total mass]"; + annotation(Documentation(info = " + +")); +end ThermodynamicState; + diff --git a/Testers/Water_MixtureTwoPhase_pT/bubbleEnthalpy.mo b/Testers/Water_MixtureTwoPhase_pT/bubbleEnthalpy.mo new file mode 100644 index 0000000..c42d2b8 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/bubbleEnthalpy.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends bubbleEnthalpy "boiling curve specific enthalpy of water" +algorithm + hl:=Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat); +end bubbleEnthalpy; + diff --git a/Testers/Water_MixtureTwoPhase_pT/density.mo b/Testers/Water_MixtureTwoPhase_pT/density.mo new file mode 100644 index 0000000..7dee4e0 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/density.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends density "return density of ideal gas" +algorithm + d:=state.d; +end density; + diff --git a/Testers/Water_MixtureTwoPhase_pT/dynamicViscosity.mo b/Testers/Water_MixtureTwoPhase_pT/dynamicViscosity.mo new file mode 100644 index 0000000..5e67604 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/dynamicViscosity.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends dynamicViscosity +algorithm + eta:=Modelica.Media.Water.WaterIF97_base.dynamicViscosity(state); +end dynamicViscosity; + diff --git a/Water_MixtureTwoPhase_pT/package.order b/Testers/Water_MixtureTwoPhase_pT/package.order similarity index 94% rename from Water_MixtureTwoPhase_pT/package.order rename to Testers/Water_MixtureTwoPhase_pT/package.order index 9510fbd..72b850c 100644 --- a/Water_MixtureTwoPhase_pT/package.order +++ b/Testers/Water_MixtureTwoPhase_pT/package.order @@ -1,20 +1,20 @@ -M_H2O -BaseProperties -specificEnthalpy_pTX -temperature_phX -ThermodynamicState -dewEnthalpy -bubbleEnthalpy -saturationTemperature -dynamicViscosity -specificEntropy -specificEnthalpy_ps -setState_psX -temperature -density -setState_pTX -specificEntropy_pTX -thermalConductivity -specificHeatCapacityCp -saturationPressure -specificHeatCapacityCv +M_H2O +BaseProperties +bubbleEnthalpy +density +dewEnthalpy +dynamicViscosity +saturationPressure +saturationTemperature +setState_psX +setState_pTX +specificEnthalpy_ps +specificEnthalpy_pTX +specificEntropy +specificEntropy_pTX +specificHeatCapacityCp +specificHeatCapacityCv +temperature +temperature_phX +thermalConductivity +ThermodynamicState diff --git a/Testers/Water_MixtureTwoPhase_pT/saturationPressure.mo b/Testers/Water_MixtureTwoPhase_pT/saturationPressure.mo new file mode 100644 index 0000000..6848b0f --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/saturationPressure.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends saturationPressure +algorithm + p:=Modelica.Media.Water.WaterIF97_base.saturationPressure(T); +end saturationPressure; + diff --git a/Testers/Water_MixtureTwoPhase_pT/saturationTemperature.mo b/Testers/Water_MixtureTwoPhase_pT/saturationTemperature.mo new file mode 100644 index 0000000..0be8c96 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/saturationTemperature.mo @@ -0,0 +1,7 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends saturationTemperature +algorithm + //T := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p); + T:=Modelica.Media.Water.WaterIF97_base.saturationTemperature(p); +end saturationTemperature; + diff --git a/Testers/Water_MixtureTwoPhase_pT/setState_pTX.mo b/Testers/Water_MixtureTwoPhase_pT/setState_pTX.mo new file mode 100644 index 0000000..0c42d26 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/setState_pTX.mo @@ -0,0 +1,7 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends setState_pTX + "Return thermodynamic state of water as function of p and T" +algorithm + state:=ThermodynamicState(d= density_pT(p, T), T= T, phase= 0, h= specificEnthalpy_pTX(p, s), p= p, X= X, s= specificEntropy_pT(p.T), q= -1, GVF= -1, d_l= -1, d_g= -1); +end setState_pTX; + diff --git a/Testers/Water_MixtureTwoPhase_pT/setState_psX.mo b/Testers/Water_MixtureTwoPhase_pT/setState_psX.mo new file mode 100644 index 0000000..72c1ea4 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/setState_psX.mo @@ -0,0 +1,7 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends setState_psX + "Return thermodynamic state of water as function of p and s" +algorithm + state:=ThermodynamicState(d= density_ps(p, s), T= temperature_ps(p, s), phase= 0, h= specificEnthalpy_ps(p, s), p= p, X= X, s= s, q= -1, GVF= -1, d_l= -1, d_g= -1); +end setState_psX; + diff --git a/Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_pTX.mo b/Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_pTX.mo new file mode 100644 index 0000000..57e4e47 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_pTX.mo @@ -0,0 +1,15 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function specificEnthalpy_pTX + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temp_K T; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known"; + /* input MassFraction q "(min=0,max=1)"; + input Real y "molar fraction of gas in gas phase";*/ + // input Real[3] TP; + output Modelica.SIunits.SpecificEnthalpy h = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p, T); +algorithm + // Modelica.Utilities.Streams.print("specificEnthalpy_pTXqy("+String(p)+","+String(T)+",X,"+String(q)+","+String(y)+")"); + annotation(LateInline = true, inverse(T = temperature_phX(p= p, h= h, X= X, phase= phase))); +end specificEnthalpy_pTX; + diff --git a/Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_ps.mo b/Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_ps.mo new file mode 100644 index 0000000..79f8a21 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_ps.mo @@ -0,0 +1,12 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function specificEnthalpy_ps + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; +algorithm + h:=Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEnthalpy_ps; + diff --git a/Testers/Water_MixtureTwoPhase_pT/specificEntropy.mo b/Testers/Water_MixtureTwoPhase_pT/specificEntropy.mo new file mode 100644 index 0000000..46807ba --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/specificEntropy.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends specificEntropy "specific entropy of water" +algorithm + s:=Modelica.Media.Water.IF97_Utilities.s_ph(state.p, state.h, state.phase); +end specificEntropy; + diff --git a/Testers/Water_MixtureTwoPhase_pT/specificEntropy_pTX.mo b/Testers/Water_MixtureTwoPhase_pT/specificEntropy_pTX.mo new file mode 100644 index 0000000..97f54f6 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/specificEntropy_pTX.mo @@ -0,0 +1,13 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function specificEntropy_pTX + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy T "Specific entropy"; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy s "specific enthalpy"; +algorithm + h:=Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEntropy_pTX; + diff --git a/Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCp.mo b/Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCp.mo new file mode 100644 index 0000000..b9ed244 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCp.mo @@ -0,0 +1,17 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends specificHeatCapacityCp + "specific heat capacity at constant pressure of water" +algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cp:=Modelica.Media.Water.IF97_Utilities.cp_dT(state.d, state.T, state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cp:=Modelica.Media.Water.IF97_Utilities.cp_pT(state.p, state.T); + else + cp:=Modelica.Media.Water.IF97_Utilities.cp_ph(state.p, state.h, state.phase); + end if; + annotation(Documentation(info = " +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); +end specificHeatCapacityCp; + diff --git a/Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCv.mo b/Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCv.mo new file mode 100644 index 0000000..2bf961e --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCv.mo @@ -0,0 +1,17 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends specificHeatCapacityCv + "specific heat capacity at constant pressure of water" +algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cv:=Modelica.Media.Water.IF97_Utilities.cv_dT(state.d, state.T, state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cv:=Modelica.Media.Water.IF97_Utilities.cv_pT(state.p, state.T); + else + cv:=Modelica.Media.Water.IF97_Utilities.cv_ph(state.p, state.h, state.phase); + end if; + annotation(Documentation(info = " +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); +end specificHeatCapacityCv; + diff --git a/Testers/Water_MixtureTwoPhase_pT/temperature.mo b/Testers/Water_MixtureTwoPhase_pT/temperature.mo new file mode 100644 index 0000000..365dcf7 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/temperature.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends temperature "return temperature of ideal gas" +algorithm + T:=state.T; +end temperature; + diff --git a/Testers/Water_MixtureTwoPhase_pT/temperature_phX.mo b/Testers/Water_MixtureTwoPhase_pT/temperature_phX.mo new file mode 100644 index 0000000..beef10d --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/temperature_phX.mo @@ -0,0 +1,12 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function temperature_phX "numerically inverts specificEnthalpy_liquid_pTX" + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temp_K T = Modelica.Media.Water.WaterIF97_base.temperature_ph(p, h); +algorithm + // Modelica.Utilities.Streams.print("temperature_phX"); + annotation(LateInline = true, inverse(h = specificEnthalpy_pTX(p= p, T= T, phase= phase, X= X))); +end temperature_phX; + diff --git a/Testers/Water_MixtureTwoPhase_pT/thermalConductivity.mo b/Testers/Water_MixtureTwoPhase_pT/thermalConductivity.mo new file mode 100644 index 0000000..3264a22 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/thermalConductivity.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends thermalConductivity "Thermal conductivity of water" +algorithm + lambda:=Modelica.Media.Water.IF97_Utilities.thermalConductivity(state.d, state.T, state.p, state.phase); +end thermalConductivity; + diff --git a/Testers/package.mo b/Testers/package.mo new file mode 100644 index 0000000..878288f --- /dev/null +++ b/Testers/package.mo @@ -0,0 +1,9 @@ +within REFPROP2Modelica; +package Testers + + + + + + +end Testers; diff --git a/Testers/package.order b/Testers/package.order new file mode 100644 index 0000000..4f27931 --- /dev/null +++ b/Testers/package.order @@ -0,0 +1,7 @@ +PentaneTester +PropsMixture +PropsMixtureTwo +PropsPureSubstance +R410mixTester +Water_MixtureTwoPhase_pT +AmmoniaWater diff --git a/_REFPROP-Wrapper/Version 0.5/REFPROP_dll.H b/_REFPROP-Wrapper/Version 0.5/REFPROP_dll.H deleted file mode 100644 index 080a91c..0000000 --- a/_REFPROP-Wrapper/Version 0.5/REFPROP_dll.H +++ /dev/null @@ -1,199 +0,0 @@ -// Definitions of the Refprop types -typedef void (__stdcall *fp_ABFL1dllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_ABFL2dllTYPE)(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_ACTVYdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_AGdllTYPE)(double &,double &,double *,double &,double &); -typedef void (__stdcall *fp_CCRITdllTYPE)(double &,double &,double &,double *,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_CP0dllTYPE)(double &,double *,double &); -typedef void (__stdcall *fp_CRITPdllTYPE)(double *,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_CSATKdllTYPE)(long &,double &,long &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_CV2PKdllTYPE)(long &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_CVCPKdllTYPE)(long &,double &,double &,double &,double &); -typedef void (__stdcall *fp_CVCPdllTYPE)(double &,double &,double *,double &,double &); -typedef void (__stdcall *fp_DBDTdllTYPE)(double &,double *,double &); -typedef void (__stdcall *fp_DBFL1dllTYPE)(double &,double &,double *,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_DBFL2dllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_DDDPdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_DDDTdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_DEFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_DHD1dllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &); -typedef void (__stdcall *fp_DHFL1dllTYPE)(double &,double &,double *,double &,long &,char*,long );//added by Henning Francke -typedef void (__stdcall *fp_DHFL2dllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long );//added by Henning Francke -typedef void (__stdcall *fp_DHFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_DIELECdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_DOTFILLdllTYPE)(long &,double *,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_DPDD2dllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_DPDDKdllTYPE)(long &,double &,double &,double &); -typedef void (__stdcall *fp_DPDDdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_DPDTKdllTYPE)(long &,double &,double &,double &); -typedef void (__stdcall *fp_DPDTdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_DPTSATKdllTYPE)(long &,double &,long &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_DSFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_DSFL1dllTYPE)(double &,double &,double *,double &,long &,char*,long );//added by Henning Francke -typedef void (__stdcall *fp_DSFL2dllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long );//added by Henning Francke -typedef void (__stdcall *fp_ENTHALdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_ENTROdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_ESFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_FGCTYdllTYPE)(double &,double &,double *,double *); -typedef void (__stdcall *fp_FPVdllTYPE)(double &,double &,double &,double *,double &); -typedef void (__stdcall *fp_GERG04dllTYPE)(long &,long &,long &,char*,long ); -typedef void (__stdcall *fp_GETFIJdllTYPE)(char*,double *,char*,char*,long ,long ,long ); -typedef void (__stdcall *fp_GETKTVdllTYPE)(long &,long &,char*,double *,char*,char*,char*,char*,long ,long ,long ,long ,long ); -typedef void (__stdcall *fp_GIBBSdllTYPE)(double &,double &,double *,double &,double &); -typedef void (__stdcall *fp_HSFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_INFOdllTYPE)(long &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); -typedef void (__stdcall *fp_LIMITKdllTYPE)(char*,long &,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ,long ); -typedef void (__stdcall *fp_LIMITSdllTYPE)(char*,double *,double &,double &,double &,double &,long ); -typedef void (__stdcall *fp_LIMITXdllTYPE)(char*,double &,double &,double &,double *,double &,double &,double &,double &,long &,char*,long ,long ); -typedef void (__stdcall *fp_MELTPdllTYPE)(double &,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_MELTTdllTYPE)(double &,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_MLTH2OdllTYPE)(double &,double &,double &); -typedef void (__stdcall *fp_NAMEdllTYPE)(long &,char*,char*,char*,long ,long ,long ); -typedef void (__stdcall *fp_PDFL1dllTYPE)(double &,double &,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_PDFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PEFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PHFL1dllTYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PHFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PQFLSHdllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PREOSdllTYPE)(long &); -typedef void (__stdcall *fp_PRESSdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_PSFL1dllTYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PSFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PUREFLDdllTYPE)(long &); -typedef void (__stdcall *fp_QMASSdllTYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_QMOLEdllTYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_SATDdllTYPE)(double &,double *,long &,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); -typedef void (__stdcall *fp_SATEdllTYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_SATHdllTYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_SATPdllTYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); -typedef void (__stdcall *fp_SATSdllTYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_SATTdllTYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); -typedef void (__stdcall *fp_SETAGAdllTYPE)(long &,char*,long ); -typedef void (__stdcall *fp_SETKTVdllTYPE)(long &,long &,char*,double *,char*,long &,char*,long ,long ,long ); -typedef void (__stdcall *fp_SETMIXdllTYPE)(char*,char*,char*,long &,char*,double *,long &,char*,long ,long ,long ,long ,long ); -typedef void (__stdcall *fp_SETMODdllTYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); -typedef void (__stdcall *fp_SETREFdllTYPE)(char*,long &,double *,double &,double &,double &,double &,long &,char*,long ,long ); -typedef void (__stdcall *fp_SETUPdllTYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); -typedef void (__stdcall *fp_SPECGRdllTYPE)(double &,double &,double &,double &); -typedef void (__stdcall *fp_SUBLPdllTYPE)(double &,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_SUBLTdllTYPE)(double &,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_SURFTdllTYPE)(double &,double &,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_SURTENdllTYPE)(double &,double &,double &,double *,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_TDFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_TEFLSHdllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_THERM0dllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &); -typedef void (__stdcall *fp_THERM2dllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); -typedef void (__stdcall *fp_THERM3dllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); -typedef void (__stdcall *fp_THERMdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &); -typedef void (__stdcall *fp_THFLSHdllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_TPFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_TPFL2dllTYPE)(double &,double &,double *,double &,double &,double *,double *,double &,long &,char*,long );//added by Henning Francke -typedef void (__stdcall *fp_TPRHOdllTYPE)(double &,double &,double *,long &,long &,double &,long &,char*,long ); -typedef void (__stdcall *fp_TQFLSHdllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_TRNPRPdllTYPE)(double &,double &,double *,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_TSFLSHdllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_VIRBdllTYPE)(double &,double *,double &); -typedef void (__stdcall *fp_VIRCdllTYPE)(double &,double *,double &); -typedef void (__stdcall *fp_WMOLdllTYPE)(double *,double &); -typedef void (__stdcall *fp_XMASSdllTYPE)(double *,double *,double &); -typedef void (__stdcall *fp_XMOLEdllTYPE)(double *,double *,double &); - -//Define explicit function pointers -fp_ABFL1dllTYPE ABFL1dll; -fp_ABFL2dllTYPE ABFL2dll; -fp_ACTVYdllTYPE ACTVYdll; -fp_AGdllTYPE AGdll; -fp_CCRITdllTYPE CCRITdll; -fp_CP0dllTYPE CP0dll; -fp_CRITPdllTYPE CRITPdll; -fp_CSATKdllTYPE CSATKdll; -fp_CV2PKdllTYPE CV2PKdll; -fp_CVCPKdllTYPE CVCPKdll; -fp_CVCPdllTYPE CVCPdll; -fp_DBDTdllTYPE DBDTdll; -fp_DBFL1dllTYPE DBFL1dll; -fp_DBFL2dllTYPE DBFL2dll; -fp_DDDPdllTYPE DDDPdll; -fp_DDDTdllTYPE DDDTdll; -fp_DEFLSHdllTYPE DEFLSHdll; -fp_DHD1dllTYPE DHD1dll; -fp_DHFLSHdllTYPE DHFLSHdll; -fp_DHFL1dllTYPE DHFL1dll; //added by Henning Francke -fp_DHFL2dllTYPE DHFL2dll; //added by Henning Francke -fp_DIELECdllTYPE DIELECdll; -fp_DOTFILLdllTYPE DOTFILLdll; -fp_DPDD2dllTYPE DPDD2dll; -fp_DPDDKdllTYPE DPDDKdll; -fp_DPDDdllTYPE DPDDdll; -fp_DPDTKdllTYPE DPDTKdll; -fp_DPDTdllTYPE DPDTdll; -fp_DPTSATKdllTYPE DPTSATKdll; -fp_DSFLSHdllTYPE DSFLSHdll; -fp_DSFL1dllTYPE DSFL1dll; //added by Henning Francke -fp_DSFL2dllTYPE DSFL2dll; //added by Henning Francke -fp_ENTHALdllTYPE ENTHALdll; -fp_ENTROdllTYPE ENTROdll; -fp_ESFLSHdllTYPE ESFLSHdll; -fp_FGCTYdllTYPE FGCTYdll; -fp_FPVdllTYPE FPVdll; -fp_GERG04dllTYPE GERG04dll; -fp_GETFIJdllTYPE GETFIJdll; -fp_GETKTVdllTYPE GETKTVdll; -fp_GIBBSdllTYPE GIBBSdll; -fp_HSFLSHdllTYPE HSFLSHdll; -fp_INFOdllTYPE INFOdll; -fp_LIMITKdllTYPE LIMITKdll; -fp_LIMITSdllTYPE LIMITSdll; -fp_LIMITXdllTYPE LIMITXdll; -fp_MELTPdllTYPE MELTPdll; -fp_MELTTdllTYPE MELTTdll; -fp_MLTH2OdllTYPE MLTH2Odll; -fp_NAMEdllTYPE NAMEdll; -fp_PDFL1dllTYPE PDFL1dll; -fp_PDFLSHdllTYPE PDFLSHdll; -fp_PEFLSHdllTYPE PEFLSHdll; -fp_PHFL1dllTYPE PHFL1dll; -fp_PHFLSHdllTYPE PHFLSHdll; -fp_PQFLSHdllTYPE PQFLSHdll; -fp_PREOSdllTYPE PREOSdll; -fp_PRESSdllTYPE PRESSdll; -fp_PSFL1dllTYPE PSFL1dll; -fp_PSFLSHdllTYPE PSFLSHdll; -fp_PUREFLDdllTYPE PUREFLDdll; -fp_QMASSdllTYPE QMASSdll; -fp_QMOLEdllTYPE QMOLEdll; -fp_SATDdllTYPE SATDdll; -fp_SATEdllTYPE SATEdll; -fp_SATHdllTYPE SATHdll; -fp_SATPdllTYPE SATPdll; -fp_SATSdllTYPE SATSdll; -fp_SATTdllTYPE SATTdll; -fp_SETAGAdllTYPE SETAGAdll; -fp_SETKTVdllTYPE SETKTVdll; -fp_SETMIXdllTYPE SETMIXdll; -fp_SETMODdllTYPE SETMODdll; -fp_SETREFdllTYPE SETREFdll; -fp_SETUPdllTYPE SETUPdll; -fp_SPECGRdllTYPE SPECGRdll; -fp_SUBLPdllTYPE SUBLPdll; -fp_SUBLTdllTYPE SUBLTdll; -fp_SURFTdllTYPE SURFTdll; -fp_SURTENdllTYPE SURTENdll; -fp_TDFLSHdllTYPE TDFLSHdll; -fp_TEFLSHdllTYPE TEFLSHdll; -fp_THERM0dllTYPE THERM0dll; -fp_THERM2dllTYPE THERM2dll; -fp_THERM3dllTYPE THERM3dll; -fp_THERMdllTYPE THERMdll; -fp_THFLSHdllTYPE THFLSHdll; -fp_TPFLSHdllTYPE TPFLSHdll; -fp_TPFL2dllTYPE TPFL2dll;//added by Henning Francke -fp_TPRHOdllTYPE TPRHOdll; -fp_TQFLSHdllTYPE TQFLSHdll; -fp_TRNPRPdllTYPE TRNPRPdll; -fp_TSFLSHdllTYPE TSFLSHdll; -fp_VIRBdllTYPE VIRBdll; -fp_VIRCdllTYPE VIRCdll; -fp_WMOLdllTYPE WMOLdll; -fp_XMASSdllTYPE XMASSdll; -fp_XMOLEdllTYPE XMOLEdll; diff --git a/_REFPROP-Wrapper/Version 0.5/REFPROP_wrapper.cpp b/_REFPROP-Wrapper/Version 0.5/REFPROP_wrapper.cpp deleted file mode 100644 index 22897e8..0000000 --- a/_REFPROP-Wrapper/Version 0.5/REFPROP_wrapper.cpp +++ /dev/null @@ -1,797 +0,0 @@ -/* - wrapper code for a static library containing functions from the dynamic library refprop.dll - to be used from Modelica - - This file is released under the Modelica License 2. - - Coded in 2010 by - Henning Francke - francke@gfz-potsdam.de - - Helmholtz Centre Potsdam - GFZ German Research Centre for Geosciences - Telegrafenberg, D-14473 Potsdam - - needs - REFPROP_dll.H - header for REFPROP.DLL slightly modified from %REFPROPDIR%\Examples\CPP.ZIP - refprop_wrapper.h - header for static REFPROP_wrapper.lib, also needed by Dymola - - compile with Visual C++ Compiler: - cl /c REFPROP_wrapper.cpp - lib REFPROP_wrapper.obj - copy REFPROP_wrapper.lib "%DYMOLADIR%\bin\lib\" - copy refprop_wrapper.h "%DYMOLADIR%\Source\" -*/ -//#define DEBUGMODE 1 - -#include -#include -#include "REFPROP_wrapper.h" -#include "REFPROP_dll.h" - - -// Some constants... -const long filepathlength=1024; -const long errormessagelength=255+filepathlength; -const long lengthofreference=3; -const long refpropcharlength=255; -const long ncmax=20; // Note: ncmax is the max number of components - -char *str_replace(char *str, char *search, char *replace, long *count) { - int i,n_ret; - int newlen = strlen(replace); - int oldlen = strlen(search); - char *ret; - *count = 0; - - //count occurrences of searchstring - for (i = 0; oldlen && str[i]; ++i) - if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr - ++*count, i+=oldlen - 1; - } - ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); - if (!ret){ - printf("Could not allocate memory"); - return ""; - } - - if (!*count){ - strncpy(ret,str,n_ret); - //if (DEBUGMODE) printf("RET: %i %s\n",oldlen,str); - }else{ - i = 0; - while (*str) - if (strstr(str, search) == str) - strncpy(&ret[i], replace,n_ret-i-1), - i += newlen, - str += oldlen; - else - ret[i++] = *str++; - ret[i] = '\0'; - } - return ret; -} - -int init_REFPROP(char* fluidnames, char* REFPROP_PATH, long* nX, char* herr, HINSTANCE* RefpropdllInstance, char* errormsg, int DEBUGMODE){ -// Sets up the interface to the REFPROP.DLL -// is called by props_REFPROP and satprops_REFPROP - char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; - long ierr=0; - - if (strlen(REFPROP_PATH)>filepathlength){ - sprintf(errormsg,"REFPROP_PATH too long (%i > %i)\n",strlen(REFPROP_PATH),filepathlength); - return 0; - } - - strcpy(FLD_PATH, REFPROP_PATH); - strcpy(DLL_PATH, REFPROP_PATH); - if (REFPROP_PATH[strlen(REFPROP_PATH)-1]=='\\'){ //if last char is backslash - strcat(DLL_PATH, "refprop.dll"); - strcat(FLD_PATH, "fluids\\"); - }else{//add missing backslash - strcat(DLL_PATH,"\\refprop.dll"); - strcat(FLD_PATH, "\\fluids\\"); - } - - *RefpropdllInstance = LoadLibrary(DLL_PATH); - if (!*RefpropdllInstance){ - sprintf(errormsg,"ERROR in opening REFPROP.DLL at \"%s\"",DLL_PATH); - return 100; - } - - - char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; - //char hf[refpropcharlength*ncmax]; - char *hf; - - - //parse fluid composition string and insert absolute paths - char replace[filepathlength+6]; - strcpy(replace,".fld|"); - //if (DEBUGMODE) printf("REPLACE: %s\n",replace); - strncat(replace, FLD_PATH,filepathlength-strlen(replace)); - - int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; - hf = (char*) calloc(hf_len, sizeof(char)); - - strncpy(hf,FLD_PATH,hf_len); - strncat(hf,str_replace(fluidnames, "|", replace, nX),hf_len-strlen(hf)); //str_replace returns the number of delimiters -> nX, but components are one more ... - if (++*nX>ncmax){ //...that's why nX is incremented - sprintf(errormsg,"Too many components (More than %i)\n",ncmax); - return 0; - } - strncat(hf,".fld",hf_len-strlen(hf)); - if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); - - strncpy(hfmix,FLD_PATH,filepathlength+1);//add absolute path - strncat(hfmix,"hmx.bnc",filepathlength+1+7-strlen(hfmix)); - strcpy(hrf,"DEF"); - - - //...Call SETUP to initialize the program - SETUPdll = (fp_SETUPdllTYPE) GetProcAddress(*RefpropdllInstance,"SETUPdll"); - //printf("hf:%s\n hrf: %s\n hfmix: %s\n",hf,hrf,hfmix); - - - if (DEBUGMODE) printf("Running SETUPdll...\n"); - SETUPdll(*nX, hf, hfmix, hrf, ierr, herr, - hf_len,filepathlength+1+7, - lengthofreference,errormessagelength); - if (DEBUGMODE) printf("SETUPdll run complete (Error no: %i)\n",ierr); - - -// if (DEBUGMODE) printf("Error code processing...\n"); - switch(ierr){ - case 101: - //strcpy(errormsg,"error in opening file"); -// if (DEBUGMODE) printf("Error 101\n"); - sprintf(errormsg,"error in opening file %s",hf); - break; - case 102: -// if (DEBUGMODE) printf("Error 102\n"); - strcpy(errormsg,"error in file or premature end of file"); - break; - case -103: -// if (DEBUGMODE) printf("Error -103\n"); - strcpy(errormsg,"unknown model encountered in file"); - break; - case 104: -// if (DEBUGMODE) printf("Error 104\n"); - strcpy(errormsg,"error in setup of model"); - break; - case 105: -// if (DEBUGMODE) printf("Error 105\n"); - strcpy(errormsg,"specified model not found"); - break; - case 111: -// if (DEBUGMODE) printf("Error 111\n"); - strcpy(errormsg,"error in opening mixture file"); - break; - case 112: -// if (DEBUGMODE) printf("Error 112\n"); - strcpy(errormsg,"mixture file of wrong type"); - break; - case 114: -// if (DEBUGMODE) printf("Error 114\n"); - strcpy(errormsg,"nc<>nc from setmod"); - break; - case 0: - break; - default: -// if (DEBUGMODE) printf("Unknown error\n"); - strcpy(errormsg,"Unknown error"); - //strcpy(errormsg,"Setup was successful!"); - strncpy(errormsg,herr,errormessagelength); - break; - } - free(hf); - return ierr; -} - - -double props_REFPROP(char* what, char* statevars_in, char* fluidnames, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ -/*Calculates thermodynamic properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) -INPUT: - what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function - statevars: string of any combination of two variables out of p,T,h,s,d - fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory - statevar1,statevar2: values of the two variables specified in statevars - x: array containing the mass fractions of the components of the mixture - REFPROP_PATH: string defining the path of the refprop.dll -OUTPUT - return value: value of variable specified by the input variable what - props: Array containing all calculated values (props[0] containing error number) - errormsg: string containing error message -*/ - char statevars[3]; - double p, T, d, val, dl,dv,q,e,h,s,cv,cp,w,wm,wmliq,wmvap,eta,tcx; - long nX,ierr=0; //zero means no error - char herr[errormessagelength+1]; - HINSTANCE RefpropdllInstance;// Then have windows load the library. - - if (DEBUGMODE) printf("\nStarting function props_REFPROP to calc %c...\n", what[0]); - - //initialize interface to REFPROP.dll - - if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, &RefpropdllInstance, errormsg, DEBUGMODE)){ - printf("Error no. %g initializing REFPROP: \"%s\"\n", props[0], errormsg); - return 0; - } - - //CALCULATE MOLAR MASS - WMOLdll = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); - WMOLdll(x,wm); -// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); - wm /= 1000; //g/mol -> kg/mol - - //identify and assign passed state variables - statevars[0] = tolower(statevars_in[0]); - statevars[1] = tolower(statevars_in[1]); - statevars[2] = '\0'; - if (statevars[0]!='\0'){ - if (statevars[0]==statevars[1]){ - props[0] = 3; - sprintf(errormsg,"State variable 1 is the same as state variable 2 (%c)",statevars[0]); - return 0; - } - for (int ii=0;ii<2;ii++){ - val = (ii==0?statevar1:statevar2); - switch(statevars[ii]){ - case 'p': - p = val/1000; //Pa->kPa - break; - case 't': - T = val; - break; - case 's': - s = val*wm; //J/(kg·K) -> kJ/(mol·K) - break; - case 'h': - h = val*wm; //J/kg --> kJ/mol - break; - case 'd': - d = val/wm/1000; //kg/m³ -> mol/dm³ - break; - case 'q': //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - q = val; - break; - default: - props[0] = 2; - sprintf(errormsg,"Unknown state variable %i: %c",ii+1 ,statevars[ii]);/**/ - return 0; - } - } - } - -/* -//...If phase j is known, call TPRHOdll: - long j=2; //phase definition(j=1: Liquid, j=2: Vapor) - long tmp_int=0; - TPRHOdll = (fp_TPRHOdllTYPE) GetProcAddress(RefpropdllInstance,"TPRHOdll"); - TPRHOdll(t,p,x,j,tmp_int,d,ierr,herr,errormessagelength); -*/ -//...If phase is not known, call TPFLSH - double xliq[ncmax],xvap[ncmax],f[ncmax]; - long kq=2;/* additional input--only for TQFLSH and PQFLSH - kq--flag specifying units for input quality - kq = 1 quality on MOLAR basis [moles vapor/total moles] - kq = 2 quality on MASS basis [mass vapor/total mass]*/ -// sprintf(errormsg,"Huhu! %s %d", statevars, ierr); - if (ierr==0){ - if (strcmp(statevars,"pt")==0 || strcmp(statevars,"tp")==0){ -// strcat(errormsg,"Bin in TP!"); - if (phase==2){ //fluid state is known to be two phase - TPFL2dll = (fp_TPFL2dllTYPE) GetProcAddress(RefpropdllInstance,"TPFL2dll"); - TPFL2dll(T,p,x,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - }else{ - TPFLSHdll = (fp_TPFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TPFLSHdll"); - TPFLSHdll(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"ph")==0 || strcmp(statevars,"hp")==0){ -/* if (phase==1){ //fluid state is known to be single phase - PHFL1dll = (fp_PHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PHFL1dll"); - PHFL1dll(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); - if (liqvap==1) dl=d; else dv=d; - }else{*/ - PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); - PHFLSHdll(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"pd")==0 || strcmp(statevars,"dp")==0){ - if (phase==1){ //fluid state is known to be single phase - PDFL1dll = (fp_PDFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PDFL1dll"); - PDFL1dll(p,d,x,T,ierr,herr,errormessagelength); - }else{ - PDFLSHdll = (fp_PDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PDFLSHdll"); - PDFLSHdll(p,d,x,T,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"ps")==0 || strcmp(statevars,"sp")==0){ -/* if (phase==1){ //fluid state is known to be single phase - PSFL1dll = (fp_PSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PSFL1dll"); - PSFL1dll(p,s,x,kph,T,d,ierr,herr,errormessagelength); - if (liqvap==1) dl=d; else dv=d; - }else{*/ - PSFLSHdll = (fp_PSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PSFLSHdll"); - PSFLSHdll(p,s,x,T,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"pq")==0 || strcmp(statevars,"qp")==0){ - PQFLSHdll = (fp_PQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PQFLSHdll"); - PQFLSHdll(p,q,x,kq,T,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); -// strcat(errormsg,"Bin in PQ!"); - }else if (strcmp(statevars,"th")==0 || strcmp(statevars,"ht")==0){ -/* if (phase==1){ //fluid state is known to be single phase - THFL1dll = (fp_THFL1dllTYPE) GetProcAddress(RefpropdllInstance,"THFL1dll"); - THFL1dll(T,h,x,Dmin,Dmax,d,ierr,herr,errormessagelength); - }else{*/ - THFLSHdll = (fp_THFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"THFLSHdll"); - long kr = 2; -/* kr--phase flag: 1 = input state is liquid - 2 = input state is vapor in equilibrium with liq - 3 = input state is liquid in equilibrium with solid - 4 = input state is vapor in equilibrium with solid */ - THFLSHdll (T,h,x,kr,p,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"td")==0 || strcmp(statevars,"dt")==0){ - TDFLSHdll = (fp_TDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); - TDFLSHdll(T,d,x,p,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"ts")==0 || strcmp(statevars,"st")==0){ - TSFLSHdll = (fp_TSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TSFLSHdll"); - long kr = 2; - TSFLSHdll (T,s,x,kr,p,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"tq")==0 || strcmp(statevars,"qt")==0){ - TQFLSHdll = (fp_TQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TQFLSHdll"); - TQFLSHdll(T,q,x,kq,p,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"hd")==0 || strcmp(statevars,"dh")==0){ - switch(phase){ //fluid state is known to be single phase - case 1: - DHFL1dll = (fp_DHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL1dll"); - DHFL1dll(d,h,x,T,ierr,herr,errormessagelength); - break; - case 2: - DHFL2dll = (fp_DHFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL2dll"); - DHFL2dll(d,h,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - break; - default: - DHFLSHdll = (fp_DHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DHFLSHdll"); - DHFLSHdll(d,h,x,T,p,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"hs")==0 || strcmp(statevars,"sh")==0){ - HSFLSHdll = (fp_HSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"HSFLSHdll"); - HSFLSHdll(h,s,x,T,p,d,dl,dv,xliq,xvap,q,e,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"ds")==0 || strcmp(statevars,"sd")==0){ - switch(phase){ //fluid state is known to be single phase - case 1: - DSFL1dll = (fp_DSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL1dll"); - DSFL1dll(d,s,x,T,ierr,herr,errormessagelength); - break; - case 2: - DSFL2dll = (fp_DSFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL2dll"); - DSFL2dll(d,s,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - break; - default: - DSFLSHdll = (fp_DSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DSFLSHdll"); - DSFLSHdll(d,s,x,T,p,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); - } - }else - sprintf(errormsg,"Unknown combination of state variables! %s", statevars); - } - - switch(tolower(what[0])){ //CHOOSE RETURN VARIABLE - case 'v': //dynamic viscosity uPa.s - case 'l': //thermal conductivity W/m.K - TRNPRPdll = (fp_TRNPRPdllTYPE) GetProcAddress(RefpropdllInstance,"TRNPRPdll"); - TRNPRPdll (T,d,x,eta,tcx,ierr,herr,errormessagelength); - } - - - switch(ierr){ - case 1: - sprintf(errormsg,"T=%f < Tmin",T); - break; - case 4: - sprintf(errormsg,"P=%f < 0",p); - break; - case 5: - sprintf(errormsg,"T=%f and p=%f out of range",T,p); - break; - case 8: - strcpy(errormsg,"x out of range (component and/or sum < 0 or > 1)"); - break; - case 9: - sprintf(errormsg,"x or T=%f out of range",T); - break; - case 12: - sprintf(errormsg,"x out of range and P=%f < 0",p); - break; - case 13: - sprintf(errormsg,"x, T=%f and p=%f out of range",T,p); - break; - case 16: - strcpy(errormsg,"TPFLSH error: p>melting pressure"); - break; - case -31: - sprintf(errormsg,"Temperature T=%f out of range for conductivity",T); - break; - case -32: - sprintf(errormsg,"density d=%f out of range for conductivity",d); - break; - case -33: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",T,d); - break; - case -41: - sprintf(errormsg,"Temperature T=%f out of range for viscosity",T); - break; - case -42: - sprintf(errormsg,"density d=%f out of range for viscosity",d); - break; - case -43: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",T,d); - break; - case -51: - sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",T); - break; - case -52: - sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",d); - break; - case -53: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",T,d); - break; - case 39: - sprintf(errormsg,"model not found for thermal conductivity"); - break; - case 49: - sprintf(errormsg,"model not found for viscosity"); - break; - case 50: - sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); - break; - case 51: - sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",T); - break; - case -58: - case -59: - sprintf(errormsg,"ECS model did not converge"); - break; - case 211: - sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); - case 239: - sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",h); - break; - case 248: - sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",d,s); - break; - case 249: - sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",h); - break; - case 271: - sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",T); - break; - case 291: - sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",T); - break; - default: - strncpy(errormsg,herr,errormessagelength); - } - - - //CONVERT TO SI-UNITS - if (ierr==0){ - WMOLdll(xliq,wmliq); - wmliq /= 1000; //g/mol -> kg/mol - WMOLdll(xvap,wmvap); - wmvap /= 1000; //g/mol -> kg/mol - //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); - d *= wm*1000; //mol/dm³ -> kg/m³ - dl *= wmliq*1000; //mol/dm³ -> kg/m³ - dv *= wmvap*1000; //mol/dm³ -> kg/m³ - e /= e/wm; //kJ/mol -> J/kg - h /= wm; //kJ/mol -> J/kg - s /= wm; //kJ/(mol·K) -> J/(kg·K) - cv /= wm; - cp /= wm; - p *= 1000; //kPa->Pa - if (nX>1 && abs(q)<990) q *= wmvap/wm; //molar bass -> mass basis - eta/=1e6; //uPa.s -> Pa.s - } - - //ASSIGN VALUES TO RETURN ARRAY - props[0] = ierr;//error code - props[1] = p;//pressure in Pa - props[2] = T; //Temperature in K - props[3] = wm; //molecular weight - props[4] = d; //density - props[5] = dl; //density of liquid phase - props[6] = dv; //density of liquid phase - props[7] = q; //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - props[8] = e; //inner energy - props[9] = h; //specific enthalpy - props[10] = s;//specific entropy - props[11] = cv; - props[12] = cp; - props[13] = w; //speed of sound - props[14] = wmliq; - props[15] = wmvap; - for (int ii=0;ii kg/mol - - - //identify and assign passed state variables - statevar[0] = tolower(statevar[0]); - if (statevar[0]!='\0'){ - switch(statevar[0]){ - case 'p': - p = statevarval/1000; //Pa->kPa - break; - case 't': - T = statevarval; - break; - case 'd': - d = statevarval/wm/1000; //kg/m³ -> mol/dm³ - break; -/* case 's': - s = statevarval*wm; //J/(kg·K) -> kJ/(mol·K) - break; - case 'h': - h = statevarval*wm; //J/kg --> kJ/mol - break; -*/ default: - props[0] = 2; - sprintf(errormsg,"Unknown state variable: %c", statevarval); - return 0; - } - } - double xliq[ncmax],xvap[ncmax],f[ncmax]; - - long j=2,kr; -/* j--phase flag: 1 = input x is liquid composition (bubble point) - 2 = input x is vapor composition (dew point) - 3 = input x is liquid composition (freezing point) - 4 = input x is vapor composition (sublimation point) -*/ - if (ierr==0) - if (~strcmp(statevar,"t")){ - SATTdll = (fp_SATTdllTYPE) GetProcAddress(RefpropdllInstance,"SATTdll"); - SATTdll(T,x,j,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - }else if (~strcmp(statevar,"p")){ - SATPdll = (fp_SATPdllTYPE) GetProcAddress(RefpropdllInstance,"SATPdll"); - SATPdll(p,x,j,T,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - switch(ierr){ - case 2: - strcpy(errormsg,"P < Ptp"); - break; - case 4: - strcpy(errormsg,"P < 0"); - break; - } - //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); - }else if (~strcmp(statevar,"d")){ - SATDdll = (fp_SATDdllTYPE) GetProcAddress(RefpropdllInstance,"SATDdll"); - SATDdll(d,x,j,kr,T,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - switch(ierr){ - case 2: - strcpy(errormsg,"D > Dmax"); - break; - } - } - - switch(ierr){ - case 0: - strcpy(errormsg,"Saturation routine successful"); - break; - case 1: - sprintf(errormsg,"T=%f < Tmin",T); - break; - case 8: - strcpy(errormsg,"x out of range"); - break; - case 9: - strcpy(errormsg,"T and x out of range"); - break; - case 10: - strcpy(errormsg,"D and x out of range"); - break; - case 12: - strcpy(errormsg,"P and x out of range"); - break; - case 120: - strcpy(errormsg,"CRITP did not converge"); - break; - case 121: - strcpy(errormsg,"T > Tcrit"); - break; - case 122: - strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); - break; - case 123: - strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); - break; - case 124: - strcpy(errormsg,"pure fluid iteration did not converge"); - break; - case -125: - strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); - break; - case -126: - strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); - break; - case -127: - strcpy(errormsg,"composition iteration did not converge"); - break; - case 128: - strcpy(errormsg,"mixture iteration did not converge"); - break; - case 140: - strcpy(errormsg,"CRITP did not converge"); - break; - case 141: - strcpy(errormsg,"P > Pcrit"); - break; - case 142: - strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); - break; - case 143: - strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); - break; - case 144: - strcpy(errormsg,"pure fluid iteration did not converge"); - break; - case -144: - strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); - break; - case -145: - strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); - break; - case -146: - strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); - break; - case -147: - strcpy(errormsg,"composition iteration did not converge"); - break; - case 148: - strcpy(errormsg,"mixture iteration did not converge"); - break; - case 160: - strcpy(errormsg,"CRITP did not converge"); - break; - case 161: - strcpy(errormsg,"SATD did not converge"); - break; - default: - strncpy(errormsg,herr,errormessagelength); - } - - /*SATHdll = (fp_SATHdllTYPE) GetProcAddress(RefpropdllInstance,"SATHdll"); - SATEdll = (fp_SATEdllTYPE) GetProcAddress(RefpropdllInstance,"SATEdll"); - SATSdll = (fp_SATSdllTYPE) GetProcAddress(RefpropdllInstance,"SATSdll");*/ - - - //CONVERT TO SI-UNITS - if (ierr==0){ - WMOLdll(xliq,wmliq); - wmliq /= 1000; //g/mol -> kg/mol - WMOLdll(xvap,wmvap); - wmvap /= 1000; //g/mol -> kg/mol - //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); - d *= wm*1000; //mol/dm³ -> kg/m³ - dl *= wmliq*1000; //mol/dm³ -> kg/m³ - dv *= wmvap*1000; //mol/dm³ -> kg/m³ -/* e /= e/wm; //kJ/mol -> J/kg - h /= wm; //kJ/mol -> J/kg - s /= wm; //kJ/(mol·K) -> J/(kg·K) -*/ p *= 1000; //kPa->Pa - } - - - //ASSIGN VALUES TO RETURN ARRAY - props[0] = ierr;//error code - props[1] = p;//pressure in kPa->Pa - props[2] = T; //Temperature in K - props[3] = wm; //molecular weight - props[4] = d; //density - props[5] = dl; //density of liquid phase - props[6] = dv; //density of liquid phase - props[7] = 0; - props[8] = 0; //inner energy - props[9] = 0; //specific enthalpy - props[10] = 0;//specific entropy - props[11] = 0; - props[12] = 0; - props[13] = 0; //speed of sound - props[14] = wmliq; - props[15] = wmvap; - for (int ii=0;ii -#include -//#include "refprop_density_fixgas.h" -#include "refprop_wrapper.h" - -//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); -//double density(char* fluidname_in, double p, double t); -//double density(double p, double t); -//char *str_replace(char *str, char *search, char *replace, long *count); - -void main(int argc, char* argv[]){ - double p,t,d; - char fluidname[255]; - char errormsg[255+1024]; - double* x; - double *props; - double sumx; - int i; - int nX = argc-5; - - if (argc<5){ - printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); - return; - } - - x = (double*) calloc(nX,sizeof(double)); - props=(double*) calloc(16+2*nX,sizeof(double)); - - - sumx = 0; - for (i=0;i +#include +#include +#include +#include +#include +#include +#include "../src/refprop_library.h" +#include "../src/refprop_wrapper.h" +#include "cpp_wrapped.h" + +int main(int argc, char* argv[]){ + char errormsg[255]; + double* x; + double *props; + double *ders; + double *trns; + int DEBUG = 1; + int transport = 0; + int partialDersInputChoice= 3; + + int kph=1; // concentration is liquid + + double *satprops; + double *critprops; + double *transprops; + + int nX=2; // Number of components + +# if defined(__ISWINDOWS__) + char thepathChar[255] = "c:\\Program Files (x86)\\Refprop"; + char theSepChar[2] = "\\"; +# elif defined(__ISLINUX__) + char thepathChar[255] = "/opt/refprop"; + char theSepChar[2] = "/"; +# endif + + + + // Allocate space for objects + x = (double*) calloc(nX,sizeof(double)); + props = (double*) calloc(20+2*nX,sizeof(double)); + ders = (double*) calloc(12,sizeof(double)); + trns = (double*) calloc(4,sizeof(double)); + + satprops = (double*) calloc(10+2*nX,sizeof(double)); + + critprops = (double*) calloc(3+nX,sizeof(double)); + transprops = (double*) calloc(2,sizeof(double)); + + char fluidname[255] = "ammoniaL|water"; + x[0] = 0.5; + x[1] = 1.0 - x[0]; + + double p = 50.e5; + double h = 3.0e5; + double dh = 1500e3;//2.5e6; + + int N = 2; // steps in enthalpy + int M = 1; // repetitions + + double res = 0.0; + double h_in = 0.0; + + // Format the output properly + char buffer [100]; + int limit = 105; + + std::ostringstream out; + out << std::endl; + + // Get the time, calculate and get the time again + time_t tstart, tend; + tstart = time(0); + for (int i = 0; i < M; i++) { + for (int count = 0; count < N; count++) { + h_in = h + dh * count / (N - 1); + + res = props_REFPROP((char*)"u", (char*)"ph", fluidname, ders, trns, props, p, h_in, x, 0, thepathChar, errormsg, DEBUG, transport, partialDersInputChoice); + + if (N*M +# define _CRT_SECURE_NO_WARNINGS +#elif __APPLE__ +# define __ISAPPLE__ +#elif __linux +# define __ISLINUX__ +#endif + +#if defined(__ISWINDOWS__) +# define CALLCONV __stdcall +# define SETUPdll SETUPdll +# define WMOLdll WMOLdll +# define XMOLEdll XMOLEdll +# define PHFLSHdll PHFLSHdll +# define TDFLSHdll TDFLSHdll +#elif defined(__ISLINUX__) +# define CALLCONV +# define SETUPdll setupdll_ +# define WMOLdll wmoldll_ +# define XMOLEdll xmoledll_ +# define PHFLSHdll phflshdll_ +# define TDFLSHdll tdflshdll_ +#endif + +typedef void (CALLCONV *SETUPdll_POINTER)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); +typedef void (CALLCONV *WMOLdll_POINTER)(double *,double &); +typedef void (CALLCONV *XMOLEdll_POINTER)(double *,double *,double &); +typedef void (CALLCONV *PHFLSHdll_POINTER)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); +typedef void (CALLCONV *TDFLSHdll_POINTER)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); +//SETUPdll_POINTER SETUPdll; +//WMOLdll_POINTER WMOLdll; +//PHFLSHdll_POINTER PHFLSHdll; + +extern SETUPdll_POINTER SETUPdll; +extern WMOLdll_POINTER WMOLdll; +extern XMOLEdll_POINTER XMOLEdll; +extern PHFLSHdll_POINTER PHFLSHdll; +extern TDFLSHdll_POINTER TDFLSHdll; + +#endif diff --git a/_wrapper/cpptest/cpp_wrapped2.cpp b/_wrapper/cpptest/cpp_wrapped2.cpp new file mode 100644 index 0000000..36f2d04 --- /dev/null +++ b/_wrapper/cpptest/cpp_wrapped2.cpp @@ -0,0 +1,494 @@ +#include +#include +#include +#include +#include +#include +#include +#include "cpp_wrapped2.h" +//#include "../src/refprop_library.h" +#include + + +int main(int argc, char* argv[]){ + + // Allocate space for objects + int nX=2; // Number of components + double* x; + x = (double*) calloc(nX,sizeof(double)); + x[0] = 0.25; + x[1] = 1.0 - x[0]; + + double href[ncmax]; + href[0] = 8295.6883966232; + href[1] = 14873.1879732343; + + + char thepathChar[255] = "c:\\Program Files (x86)\\Refprop"; + char theSepChar[2] = "\\"; + char hf[refpropcharlength*ncmax], hrf[lengthofreference+1], + herr[errormessagelength+1],hfmix[refpropcharlength+1]; + long i=0, ierr=0; + + HINSTANCE RefpropdllInstance; + RefpropdllInstance = LoadLibrary("C:\\Program Files (x86)\\REFPROP\\REFPROP.dll"); + + TDFLSHdll = (TDFLSHdll_POINTER) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); + PHFLSHdll = (PHFLSHdll_POINTER) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); + SETUPdll = (SETUPdll_POINTER) GetProcAddress(RefpropdllInstance,"SETUPdll"); + WMOLdll = (WMOLdll_POINTER) GetProcAddress(RefpropdllInstance,"WMOLdll"); + XMOLEdll = (XMOLEdll_POINTER) GetProcAddress(RefpropdllInstance,"XMOLEdll"); + + RMIX2dll = (RMIX2dll_POINTER) GetProcAddress(RefpropdllInstance,"RMIX2dll"); + RDXHMXdll = (RDXHMXdll_POINTER) GetProcAddress(RefpropdllInstance,"RDXHMXdll"); + PHIXdll = (PHIXdll_POINTER) GetProcAddress(RefpropdllInstance,"PHIXdll"); + PHI0dll = (PHI0dll_POINTER) GetProcAddress(RefpropdllInstance,"PHI0dll"); + + + PRESSdll = (PRESSdll_POINTER) GetProcAddress(RefpropdllInstance,"PRESSdll"); + ENTHALdll = (ENTHALdll_POINTER) GetProcAddress(RefpropdllInstance,"ENTHALdll"); + CRITPdll = (CRITPdll_POINTER) GetProcAddress(RefpropdllInstance,"CRITPdll"); + XMASSdll = (XMASSdll_POINTER) GetProcAddress(RefpropdllInstance,"XMASSdll"); + + + + // new fluid + strcpy(hf,thepathChar); + strcat(hf,theSepChar); + strcat(hf,"fluids"); + strcat(hf,theSepChar); + strcat(hf,"methane.fld|"); + strcat(hf,thepathChar); + strcat(hf,theSepChar); + strcat(hf,"fluids"); + strcat(hf,theSepChar); + strcat(hf,"ethane.fld"); + + strcpy(hfmix,thepathChar); + strcat(hfmix,theSepChar); + strcat(hfmix,"fluids"); + strcat(hfmix,theSepChar); + strcat(hfmix,"HMX.BNC"); + + strcpy(hrf,"DEF"); + strcpy(herr,"Ok"); + + i = nX; + + //...Call SETUP to initialize the program + SETUPdll(i, hf, hfmix, hrf, ierr, herr,refpropcharlength*ncmax,refpropcharlength,lengthofreference,errormessagelength); + printf("ierr = %ld\n",ierr); + + double wm,xkg[ncmax]; +// WMOLdll(x,wm); + XMASSdll(x,xkg,wm); + printf("mass fraction [0] = %2.10f\n",xkg[0]); + printf("mass fraction [1] = %2.10f\n",xkg[1]); + printf("molecular weight = %2.10f\n\n",wm); +// here derivatives start + + int n = 2; // derivative wrt component n + double xn[ncmax],xp[ncmax]; + double delx = 0.00001; + double delx2 = 2 * delx; + + for (i = 0; i < nX; i++) { + xn[i] = x[i]; + xp[i] = x[i]; + } + xn[n-1] = xn[n-1] - delx; + xp[n-1] = xp[n-1] + delx; + double t = 250; + double d = 15; + + long im1=-1; + long i0=0; + long ip1=1; + double R, t0, d0, phi01, phi10, phig10, tau, delta; + double pn,pp,dpdxi1,hn,hp,dhdxi1,hrn,hrp,dhrdxi1; + double dpdxi2; + double dhdxi2; + + double hrefdiff; + + // test pressure equation.. + PRESSdll(t,d,x,pn); + printf("PRESSdll, p = %f\n",pn); + + RMIX2dll(x, R); + RDXHMXdll(&im1,&i0,&i0,x,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, x,phi01); + pn = d * R * t * (1 + phi01); + printf("Definition, p = %f\n",pn); + + // test enthalpy equation.. + ENTHALdll(t,d,x,hn); + printf("ENTHALdll, h = %f\n",hn); + + RMIX2dll(x, R); + RDXHMXdll(&im1,&i0,&i0,x,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, x,phi01); + PHIXdll(&ip1,&i0, tau, delta, x,phi10); + PHI0dll(&ip1, &i0, t, d, x, phig10); + hrefdiff = hn; + hn = R * t * (1 + phig10 + phi10 + phi01); + hrefdiff = hrefdiff - hn; + printf("Definition, h = %f\n",hn); + printf("hrefdiff = %5.10f\n",hrefdiff); + + // new test with new computed enthalpy reference from above at another temperature.. + t=t+50; + ENTHALdll(t,d,x,hn); + printf("ENTHALdll, h = %f\n",hn); + RMIX2dll(x, R); + RDXHMXdll(&im1,&i0,&i0,x,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, x,phi01); + PHIXdll(&ip1,&i0, tau, delta, x,phi10); + PHI0dll(&ip1, &i0, t, d, x, phig10); + hn = R * t * (1 + phig10 + phi10 + phi01) + x[0]*href[0] + x[1]*href[1]; + printf("Definition, h = %f\n",hn); + + t=250; // set back tempereture + d=15; + + + + printf("\n definitions work, proceed with numerical derivatives\n\n"); + +// PERFORM DERIVATIVES... + + + // negative increment + RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xn,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, xn, phi01); + PHIXdll(&ip1,&i0, tau, delta, xn, phi10); + PHI0dll(&ip1, &i0, t, d, xn, phig10); + pn = d * R * t * (1 + phi01); + hrn = R * t * (1 + phi10 + phi01); + hn = R * t * (1 + phig10 + phi10 + phi01) + xn[0]*href[0] + xn[1]*href[1]; + + // positive increment + RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xp,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, xp, phi01); + PHIXdll(&ip1,&i0, tau, delta, xp, phi10); + PHI0dll(&ip1, &i0, t, d, xp, phig10); + pp = d * R * t * (1 + phi01); + hrp = R * t * (1 + phi10 + phi01); + hp = R * t * (1 + phig10 + phi10 + phi01) + xp[0]*href[0] + xp[1]*href[1]; + + // derivatives.. + dpdxi2 = (pp - pn) / delx2; +// dhrdxi2 = (hrp - hrn) / delx2; + dhdxi2 = (hp - hn) / delx2; + printf("dpdx2 = %f\n",dpdxi2); +// printf("dhrdxi = %f\n",dhrdxi2); + printf("dhdx2 = %f\n",dhdxi2); + + + + n = 1; // derivative wrt component n + for (i = 0; i < nX; i++) { + xn[i] = x[i]; + xp[i] = x[i]; + } + xn[n-1] = xn[n-1] - delx; + xp[n-1] = xp[n-1] + delx; + + // negative increment + RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xn,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, xn, phi01); + PHIXdll(&ip1,&i0, tau, delta, xn, phi10); + PHI0dll(&ip1, &i0, t, d, xn, phig10); + pn = d * R * t * (1 + phi01); + hrn = R * t * (1 + phi10 + phi01); + hn = R * t * (1 + phig10 + phi10 + phi01) + xn[0]*href[0] + xn[1]*href[1];; + + // positive increment + RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xp,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, xp, phi01); + PHIXdll(&ip1,&i0, tau, delta, xp, phi10); + PHI0dll(&ip1, &i0, t, d, xp, phig10); + pp = d * R * t * (1 + phi01); + hrp = R * t * (1 + phi10 + phi01); + hp = R * t * (1 + phig10 + phi10 + phi01) + xp[0]*href[0] + xp[1]*href[1];; + + // derivatives.. + dpdxi1 = (pp - pn) / delx2; +// dhrdxi1 = (hrp - hrn) / delx2; + dhdxi1= (hp - hn) / delx2; + printf("dpdx1 = %f\n",dpdxi1); + //printf("dhrdxi = %f\n",dhrdxi1); + printf("dhdx1 = %f\n",dhdxi1); + + printf("dpdx1-dpdx2 = %f\n",dpdxi1-dpdxi2); + printf("dhdx1-dhdx2 = %f\n",dhdxi1-dhdxi2); + + + // ' calculate d(p)/d(xi) and d(h)/d(xi) at constant T and V and + // ' The following do not work because R in d*R*T is changed as a function of x + double xnn[ncmax],xpp[ncmax]; + double dpdxi12,dhdxi12; + + xpp[0] = x[0]+delx; + xpp[1] = x[1]-delx; + xnn[0] = x[0]-delx; + xnn[1] = x[1]+delx; + + PRESSdll(t,d,xnn,pn); + PRESSdll(t,d,xpp,pp); + ENTHALdll(t,d,xnn,hn); + ENTHALdll(t,d,xpp,hp); + dpdxi12 = (pp - pn) / delx2; + printf("dpdx1-dpdx2 using PRESSdll = %f\n",dpdxi12); + dhdxi12 = (hp - hn) / delx2; + printf("dhdx1-dhdx2 using ENTHALdll = %f\n",dhdxi12); + + +// +// +// + + printf("\n"); + printf(" lets try mass basis, i.e. compute xmol from xkg +/- increments\n"); + printf(" NOTE that when we want to keep density on mass basis constant, then the molar density mol/L must be corrected when computing +/- increments\n"); + printf(" This is because when concentration (mass or mole) changes, so does molecular weight \n"); + printf(" (i.e. either moler density or mass density must change when keeping the other constant)\n"); + printf("\n"); + // ' calculate d(p)/d(xi) and d(h)/d(xi) at constant T and V and + // ' The following do not work because R in d*R*T is changed as a function of x + double xkgn[ncmax],xkgp[ncmax],wmn,wmp; + + XMASSdll(x,xkg,wm); + XMASSdll(x,xkgn,wm); + XMASSdll(x,xkgp,wm); + + xkgp[0] = xkg[0]+delx; + xkgp[1] = xkg[1]-delx; + xkgn[0] = xkg[0]-delx; + xkgn[1] = xkg[1]+delx; + XMOLEdll(xkgn,xnn,wmn); + XMOLEdll(xkgp,xpp,wmp); + + // diff dxdz numerically + double dxdz_num = (xkgp[0]-xkgn[0])/(xpp[0]-xnn[0]); + printf("dxdz_num = %f\n",dxdz_num); + + printf("dpdx_num = %f\n",(dpdxi1-dpdxi2)/dxdz_num); + + + + + +/* + printf("wmn = %f\n",wmn); + printf("wmp = %f\n",wmp); + + printf("xkgp[0] = %f\n",xkgp[0]); + printf("xkgp[1] = %f\n",xkgp[1]); + printf("xkgn[0] = %f\n",xkgn[0]); + printf("xkgn[1] = %f\n",xkgn[1]); + + printf("xpp[0] = %f\n",xpp[0]); + printf("xpp[1] = %f\n",xpp[1]); + printf("xnn[0] = %f\n",xnn[0]); + printf("xnn[1] = %f\n",xnn[1]); +*/ + + //double dpdxi12; + double dn=d;//*wm/wmn; // mass density should be kept constant even through we change concentration.. + PRESSdll(t,dn,xnn,pn); + double dp=d;//*wm/wmp; // mass density should be kept constant even through we change concentration.. + PRESSdll(t,dp,xpp,pp); + + dpdxi12 = (pp - pn) / (delx2); +// printf("pn = %f\n", pn); +// printf("pp = %f\n", pp); + printf("dpdx1 - dpdx2 using PRESSdll = %f\n",dpdxi12); + +// try do the conversion your self... + double wm1; + xkgp[0] = 1; + xkgp[1] = 0; + WMOLdll(xkgp,wm1); + printf("wm1 = %f\n",wm1); + double wm2; + xkgp[0] = 0; + xkgp[1] = 1; + WMOLdll(xkgp,wm2); + printf("wm2 = %f\n",wm2); + printf("wm = %f\n",wm); + +// printf("ratio %f\n",dpdxi12/(dpdxi1-dpdxi2)); + + /* + printf("x[0] = %f\n",x[0]); + printf("x[1] = %f\n",x[1]); + printf("xkg[0] = %f\n",xkg[0]); + printf("xkg[1] = %f\n",xkg[1]); + printf("dpdxi1 = %f\n",dpdxi1); + printf("dpdxi2 = %f\n",dpdxi2); + + */ + + double dxdz1,dxdz2,dzdx1,dzdx2; + dxdz1=wm1*x[1]*wm2/(wm*wm); // this one from maple + dzdx1=wm1*wm2*xkg[1]/((xkg[0]*wm2+xkg[1]*wm1)*(xkg[0]*wm2+xkg[1]*wm1)); + printf("dxdz1 = %f\n",dxdz1); + printf("1/dzdx1 = %f\n",1/dzdx1); + dxdz2=wm1*x[0]*wm2/(wm*wm); // this one from maple + dzdx2=wm1*wm2*xkg[0]/((xkg[0]*wm2+xkg[1]*wm1)*(xkg[0]*wm2+xkg[1]*wm1)); + printf("dxdz2 = %f\n",dxdz2); + printf("1/dzdx2 = %f\n",1/dzdx2); + printf("dpdx = %f\n",dpdxi1/dzdx1-dpdxi2/dzdx2); + printf("dpdx = %f\n",dpdxi1/dxdz1-dpdxi2/dxdz2); + printf("dpdxhmm = %f\n",(dpdxi1-dpdxi2)/(dxdz1-dxdz2)/2); + + dxdz1 = wm1/wm - x[0]*wm1*(wm1-wm2)/(wm*wm); + dxdz2 = wm2/wm - x[1]*wm2*(wm2-wm1)/(wm*wm); + printf("dxdz1 = %f\n",dxdz1); + printf("dxdz2 = %f\n",dxdz2); + + printf("dpdx = %f\n",dpdxi1*dxdz1-dpdxi2*dxdz2); + printf("dpdx = %f\n",dpdxi1/dxdz1-dpdxi2/dxdz2); +// + printf("\n"); +// +// printf("dpdx = %f\n",dpdxi1*wm1/wm-dpdxi2*wm2/wm); +// printf("dpdx = %f\n",dpdxi1*wm/wm1-dpdxi2*wm/wm2); + + + + +// printf("\n"); +// printf(" I expect that dpdxi1 and dpdxi2 have some small error when transforming to mass basis, due to that molecular weight is changed when performing these numerical derivatives"); + + + double p; + double h; + PRESSdll(t,d,x,p); + ENTHALdll(t,d,x,h); + + + + + + +///////////////////////////////////////////////////////// +/* + printf("\n try something else \n\n"); + + + n=2; + for (i = 0; i < nX; i++) { + xkgn[i] = xkg[i]; + xkgp[i] = xkg[i]; + } + xkgn[n-1] = xkgn[n-1] - delx; + xkgp[n-1] = xkgp[n-1] + delx; + + + xnn[0] = xkgn[0] *wm/wm1; + xnn[1] = xkgn[1] *wm/wm2; + xpp[0] = xkgp[0] *wm/wm1; + xpp[1] = xkgp[1] *wm/wm2; + + + printf("xkgp[0] = %f\n",xkgp[0]); + printf("xkgp[1] = %f\n",xkgp[1]); + printf("xkgn[0] = %f\n",xkgn[0]); + printf("xkgn[1] = %f\n",xkgn[1]); + + printf("xpp[0] = %f\n",xpp[0]); + printf("xpp[1] = %f\n",xpp[1]); + printf("xnn[0] = %f\n",xnn[0]); + printf("xnn[1] = %f\n",xnn[1]); + + // XMOLEdll(xkgn,xnn,wmn); + // XMOLEdll(xkgp,xpp,wmp); + + RMIX2dll(x, R); + double Rkg=R/wm; + double dkg=d*wm; + + + RDXHMXdll(&im1,&i0,&i0,xnn,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =dkg/wmn / d0; + PHIXdll(&i0,&ip1, tau, delta, xnn, phi01); + pn = dkg * Rkg * t * (1 + phi01); + + // positive increment + //RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xpp,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =dkg/wmp / d0; + PHIXdll(&i0,&ip1, tau, delta, xpp, phi01); + pp = dkg * Rkg * t * (1 + phi01); + + // derivatives.. + dpdxi2 = (pp - pn) / delx2; + printf("dpdx2 = %f\n",dpdxi2); + + n=1; + for (i = 0; i < nX; i++) { + xkgn[i] = xkg[i]; + xkgp[i] = xkg[i]; + } + xkgn[n-1] = xkgn[n-1] - delx; + xkgp[n-1] = xkgp[n-1] + delx; + // double t = 250; + // XMOLEdll(xkgn,xnn,wmn); + // XMOLEdll(xkgp,xpp,wmp); + xnn[0] = xkgn[0] *wm/wm1; + xnn[1] = xkgn[1] *wm/wm2; + xpp[0] = xkgp[0] *wm/wm1; + xpp[1] = xkgp[1] *wm/wm2; + + // negative increment + //RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xnn,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta = dkg/wmn / d0; + PHIXdll(&i0,&ip1, tau, delta, xnn, phi01); + pn = dkg * Rkg * t * (1 + phi01); + + // positive increment + // RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xp,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =dkg/wmp / d0; + PHIXdll(&i0,&ip1, tau, delta, xp, phi01); + pp = dkg * Rkg * t * (1 + phi01); + + // derivatives.. + dpdxi1 = (pp - pn) / delx2; + + printf("dpdx1 = %f\n",dpdxi1); + + printf("dpdx1-dpdx2 = %f\n",dpdxi1-dpdxi2); + +*/ + + + + + return 0; +} diff --git a/_wrapper/cpptest/cpp_wrapped2.h b/_wrapper/cpptest/cpp_wrapped2.h new file mode 100644 index 0000000..84e0737 --- /dev/null +++ b/_wrapper/cpptest/cpp_wrapped2.h @@ -0,0 +1,81 @@ + +#ifndef CPP_WRAPPED_H +#define CPP_WRAPPED_H + +//#include "../src/refprop_library.h" + +// Some constants for REFPROP... defined by macros for ease of use +#define refpropcharlength 255 +#define refpropcharlong 10000 +#define filepathlength 255 +#define lengthofreference 3 +#define errormessagelength 255 +#define ncmax 20 // Note: ncmax is the max number of components +#define numparams 72 +#define maxcoefs 50 + +/* Define some new functions to access low-level refprop routines. + * + * The new functions should be used to compare the speed of the wrapper to the speed + * of the Fortran code and the Matlab implementation. + */ + +#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) +# define __ISWINDOWS__ +# include +# define _CRT_SECURE_NO_WARNINGS +#elif __APPLE__ +# define __ISAPPLE__ +#elif __linux +# define __ISLINUX__ +#endif + +# define CALLCONV __stdcall +# define SETUPdll SETUPdll +# define WMOLdll WMOLdll +# define XMOLEdll XMOLEdll +# define PHFLSHdll PHFLSHdll +# define TDFLSHdll TDFLSHdll + +# define RMIX2dll RMIX2dll +# define RDXHMXdll RDXHMXdll +# define PHIXdll PHIXdll +# define PHI0dll PHI0dll +# define PRESSdll PRESSdll +# define ENTHALdll ENTHALdll +# define CRITPdll CRITPdll +# define MASSdll MASSdll + + +typedef void (CALLCONV *SETUPdll_POINTER)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); +typedef void (CALLCONV *WMOLdll_POINTER)(double *,double &); +typedef void (CALLCONV *XMOLEdll_POINTER)(double *,double *,double &); +typedef void (CALLCONV *PHFLSHdll_POINTER)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); +typedef void (CALLCONV *TDFLSHdll_POINTER)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + +typedef void (CALLCONV *RMIX2dll_POINTER)(double *,double &); +typedef void (CALLCONV *RDXHMXdll_POINTER)(long *,long *,long *,double *,double &,double &,long &,char*,long ); +typedef void (CALLCONV *PHIXdll_POINTER)(long *,long *,double &,double &,double *,double &); +typedef void (CALLCONV *PHI0dll_POINTER)(long *,long *,double &,double &,double *,double &); + +typedef void (CALLCONV *PRESSdll_POINTER)(double &,double &,double *,double &); +typedef void (CALLCONV *ENTHALdll_POINTER)(double &,double &,double *,double &); +typedef void (CALLCONV *CRITPdll_POINTER)(double *,double &,double &,double &,long &,char*,long ); +typedef void (CALLCONV *XMASSdll_POINTER)(double *,double *,double &); + +SETUPdll_POINTER SETUPdll; +WMOLdll_POINTER WMOLdll; +XMOLEdll_POINTER XMOLEdll; +PHFLSHdll_POINTER PHFLSHdll; +TDFLSHdll_POINTER TDFLSHdll; + +RMIX2dll_POINTER RMIX2dll; +RDXHMXdll_POINTER RDXHMXdll; +PHIXdll_POINTER PHIXdll; +PHI0dll_POINTER PHI0dll; +PRESSdll_POINTER PRESSdll; +ENTHALdll_POINTER ENTHALdll; +CRITPdll_POINTER CRITPdll; +XMASSdll_POINTER XMASSdll; + +#endif diff --git a/_wrapper/cpptest/refprop_c.c b/_wrapper/cpptest/refprop_c.c new file mode 100644 index 0000000..8bd009c --- /dev/null +++ b/_wrapper/cpptest/refprop_c.c @@ -0,0 +1,339 @@ +// EX_C2.c written by: +// Ian Bell +// Herrick Labs +// Purdue University +// ibell@purdue.edu +// August 31, 2010 + +// heavily based on example file EX_C1.cpp by + +// Chris Muzny +// N.I.S.T. +// Chemical Science and Technology Laboratory +// Physical and Chemical Properties of Fluids Division +// (303) 497-5549 +// chris.muzny@nist.gov + +//This program demonstrates explicitly linking the subroutines available in +// refprop.dll. In order to link this code refprop1.h +// must be available in the current directory. When executing refprop.dll must be in the dll +// search path (current directory and $PATH). + +#if defined(__ISWINDOWS__) +#include +#elif defined(__ISLINUX__) +#include +#endif + +#include +#include +#include +#include +#include "refprop_c.h" + + +// Some constants... +#define refpropcharlength 255 +#define filepathlength 255 +#define lengthofreference 3 +#define errormessagelength 255 +#define ncmax 20 // Note: ncmax is the max number of components +#define numparams 72 +#define maxcoefs 50 + +int main(int argc, char* argv[]) +{ + int count; + clock_t myt; + + double dh; + int N=500; + double* T_save; + double* h_in; + + char *FLD_PATH; + + double x[ncmax],xliq[ncmax],xvap[ncmax],f[ncmax],xmol[ncmax]; + + long i,ierr=0; + char hf[refpropcharlength*ncmax], hrf[lengthofreference+1], + herr[errormessagelength+1],hfmix[refpropcharlength+1]; + + double wm,ttp,tnbp,tc,pc,dc,zc,acf,dip,rgas; + long info_index=1; + double t=100.0; + double p,dl,dv; + long j=1; + double d=0.0,q=0.0,e=0.0,h=0.0,s=0.0,cv=0.0,cp=0.0,w=0.0,b=0.0,c=0.0, + dpdrho,d2pdd2,dpdt,dhdt_d,dhdt_p,dhdp_t,dhdp_d, + sigma,dhdd_t,dhdd_p,eta,tcx,pp,tt,hjt,h1,dd; + long tmp_int=0; + long kr=1; + + //xkg = (double*) calloc(ncmax,sizeof(double)); + + //double xkg[ncmax]; + //double wmix; + double hmol,pkpa; + + +#if defined(__ISWINDOWS__) + RefpropdllInstance = LoadLibrary("C:\\Program Files (x86)\\REFPROP\\refprop.dll"); + PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); + SETUPdll = (fp_SETUPdllTYPE) GetProcAddress(RefpropdllInstance,"SETUPdll"); + XMOLEdll = (fp_XMOLEdllTYPE) GetProcAddress(RefpropdllInstance,"XMOLEdll"); +#elif defined(__ISLINUX__) + RefpropdllInstance = dlopen("librefprop.so", RTLD_LAZY); + PHFLSHdll = (fp_PHFLSHdllTYPE) dlsym(RefpropdllInstance, "PHFLSHdll"); + SETUPdll = (fp_SETUPdllTYPE) dlsym(RefpropdllInstance, "SETUPdll"); + XMOLEdll = (fp_XMOLEdllTYPE) dlsym(RefpropdllInstance, "XMOLEdll"); +#endif + + + +// Now use the functions. + +// Refprop variables that need to be defined +// +// nc = Number of components in the mixture +// x[NumberOfComponentsInMixtures] = Mole fraction of each component +// ierr = An integer flag defining an error +// hf[] = a character array defining the fluids in a mixture +// hrf[] = a character array denoting the reference state +// herr[] = a character array for storing a string - Error message +// hfmix[] a character array defining the path to the mixture file + + + //Exlicitely set the fluid file PATH +# if defined(__ISWINDOWS__) + FLD_PATH = "C:\\Program Files (x86)\\REFPROP\\fluids"; + char theSepChar[2] = "\\"; +# elif defined(__ISLINUX__) + FLD_PATH = "/opt/refprop/fluids"; + char theSepChar[2] = "/"; +# endif +// strcpy(hf,FLD_PATH); +// strcpy(hfmix,FLD_PATH); + + //...initialize the program and set the pure fluid component name + //i=1; + //strcpy(hf,"nitrogen.fld"); + //strcpy(hfmix,"hmx.bnc"); + //strcpy(hrf,"DEF"); + //strcpy(herr,"Ok"); + +//...For a mixture, use the following setup instead of the lines above. + // Use "|" as the file name delimiter for mixtures + i=2; + strcpy(hf,FLD_PATH); + strcat(hf,theSepChar); + strcat(hf,"ammoniaL.fld|"); + strcat(hf,FLD_PATH); + strcat(hf,theSepChar); + strcat(hf,"water.fld"); + + strcpy(hfmix,FLD_PATH); + strcat(hfmix,theSepChar); + strcat(hfmix,"HMX.BNC"); + + strcpy(hrf,"DEF"); + strcpy(herr,"Ok"); + + x[0]=.5; //Air composition + x[1]=.5; + //x[2]=.2096; + + //...Call SETUP to initialize the program + SETUPdll(&i, hf, hfmix, hrf, &ierr, herr, + refpropcharlength*ncmax,refpropcharlength, + lengthofreference,errormessagelength); + //long ,char*,char*,char*,long ,char*,long ,long ,long ,long + if (ierr != 0) printf("%s\n",herr); + + p=50e5; + h=3e5; + + //wmix=1; + //xkg=1; + //XMOLEdll (x,&xkg,&wmix); + + XMOLEdll (x,xmol,&wm); + //WMOLdll(x,&wm); + //printf("WM, %10.4f\n",wm); + + hmol = h*wm/1000; + pkpa = p/1000; + + printf("hmol, pkpa %10.4f, %10.4f\n",hmol,pkpa); + + PHFLSHdll (&pkpa,&hmol,xmol,&tt,&dd,&dl,&dv,xliq,xvap,&q,&e,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, Pkpa, hmol from PHFLSH %10.4f,%10.4f,%10.4f,%10.4f\n",tt,dd,pkpa,hmol); + + + dh=25e5; + T_save = (double*) calloc(N,sizeof(double)); + h_in = (double*) calloc(N,sizeof(double)); + + // Get the time, calculate and get the time again + time_t tstart, tend; + tstart = time(0); + + for (count = 0; count < N; count++) + { + h_in[count] = (h+dh*count/(N-1))*wm/1000; + + PHFLSHdll (&pkpa,&h_in[count],xmol,&tt,&dd,&dl,&dv,xliq,xvap,&q,&e,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + + T_save[count] = tt; + + //printf("T=%f [K]\n",T_save[count]); + } + tend = time(0); + + int deltat = difftime(tend, tstart)*1e3; + printf("Time per call: %8.4f milliseconds\n", deltat/(N*1.0)); + +/* + + INFOdll(&info_index,&wm,&ttp,&tnbp,&tc,&pc,&dc,&zc,&acf,&dip,&rgas); + printf("WM,ACF,DIP,TTP,TNBP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",wm,acf,dip,ttp,tnbp); + printf("TC,PC,DC,RGAS %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",tc,pc,dc,rgas); +//...Calculate molecular weight of a mixture +// wm=WMOLdll(x) + +//...Get saturation properties given t,x; for i=1: x is liquid phase +//..... for i=2: x is vapor phase + + + i=1; + SATTdll(&t,x,&i,&p,&dl,&dv,xliq,xvap,&ierr,herr,errormessagelength); + printf("P,Dl,Dv,xl[0],xv[0] %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",p,dl,dv,xliq[0],xvap[0]); + i=2; + SATTdll(&t,x,&i,&p,&dl,&dv,xliq,xvap,&ierr,herr,errormessagelength); + printf("P,Dl,Dv,xl[0],xv[0] %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",p,dl,dv,xliq[0],xvap[0]); + +//...Calculate saturation properties at a given p. i is same as SATT + i=2; + SATPdll(&p,x,&i,&t,&dl,&dv,xliq,xvap,&ierr,herr,errormessagelength); + printf("T,Dl,Dv,xl(1),xv(1) %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",t,dl,dv,xliq[0],xvap[0]); + +//...Other saturation routines are given in SAT_SUB.FOR + + t=300.0; + p=20000.0; + +//...Calculate d from t,p,x +//...If phase is known: (j=1: Liquid, j=2: Vapor) + + TPRHOdll(&t,&p,x,&j,&tmp_int,&d,&ierr,herr,errormessagelength); + printf("T,P,D %10.4f,%10.4f,%10.4f\n",t,p,d); + +//...If phase is not known, call TPFLSH +//...Calls to TPFLSH are much slower than TPRHO since SATT must be called first. +//.....(If two phase, quality is returned as q) + + TPFLSHdll(&t,&p,x,&d,&dl,&dv,xliq,xvap,&q,&e,&h,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T,P,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",t,p,d,h,cp); + +//...Calculate pressure (p), internal energy (e), enthalpy (h), entropy (s), +//.....isochoric (cv) and isobaric (cp) heat capacities, speed of sound (w), +//.....and Joule-Thomson coefficient (hjt) from t,d,x +//.....(subroutines THERM2 and THERM3 contain more properties, see PROP_SUB.FOR) + THERMdll(&t,&d,x,&p,&e,&h,&s,&cv,&cp,&w,&hjt); + +//...Calculate pressure + PRESSdll(&t,&d,x,&p); + +//...Calculate fugacity + FGCTYdll(&t,&d,x,f); + +//...Calculate second and third virial coefficients + VIRBdll (&t,x,&b); + VIRCdll (&t,x,&c); + printf("F,B,C %10.4f,%10.4f,%10.4f\n",f[0],b,c); +// +//...Calculate the derivatives: dP/dD, d^2P/dD^2, dP/dT (D indicates density) +//...(dD/dP, dD/dT, and dB/dT are also available, see PROP_SUB.FOR) + DPDDdll (&t,&d,x,&dpdrho); + DPDD2dll (&t,&d,x,&d2pdd2); + DPDTdll (&t,&d,x,&dpdt); + printf("dP/dD,d2P/dD2,dP/dT %10.4f,%10.4f,%10.4f\n",dpdrho,d2pdd2,dpdt); + + +//...Calculate derivatives of enthalpy with respect to T, P, and D + DHD1dll(&t,&d,x,&dhdt_d,&dhdt_p,&dhdd_t,&dhdd_p,&dhdp_t,&dhdp_d); + printf("Enthalpy derivatives %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n", + dhdt_d,dhdt_p,dhdd_t,dhdd_p/1000.0,dhdp_t); +//...Calculate surface tension + SURFTdll (&t,&dl,x,&sigma,&ierr,herr,errormessagelength); + printf("T,SURF. TN. %10.4f,%10.4f\n",t,sigma); + +//...Calculate viscosity (eta) and thermal conductivity (tcx) + TRNPRPdll (&t,&d,x,&eta,&tcx,&ierr,herr,errormessagelength); + printf("VIS.,TH.CND. %10.4f,%10.4f\n",eta,tcx*1000.0); + +//...General property calculation with inputs of t,d,x + TDFLSHdll (&t,&d,x,&pp,&dl,&dv,xliq,xvap,&q,&e,&h1,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, P from TDFLSH %10.4f,%10.4f,%10.4f\n",t,d,pp/1000.0); + +//...General property calculation with inputs of p,d,x + PDFLSHdll (&p,&d,x,&tt,&dl,&dv,xliq,xvap,&q,&e,&h1,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, P from PDFLSH %10.4f,%10.4f,%10.4f\n",tt,d,p/1000.0); + +//...General property calculation with inputs of p,h,x + PHFLSHdll (&p,&h,x,&tt,&dd,&dl,&dv,xliq,xvap,&q,&e,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, P from PHFLSH %10.4f,%10.4f,%10.4f\n",tt,dd,p/1000.0); + +//...General property calculation with inputs of p,s,x + PSFLSHdll (&p,&s,x,&tt,&dd,&dl,&dv,xliq,xvap,&q,&e,&h1,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, P from PSFLSH %10.4f,%10.4f,%10.4f\n",tt,dd,p/1000.0); + +//...General property calculation with inputs of d,h,x + DHFLSHdll (&d,&h,x,&tt,&pp,&dl,&dv,xliq,xvap,&q,&e,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, P from DHFLSH %10.4f,%10.4f,%10.4f\n",tt,d,pp/1000.0); + +//...General property calculation with inputs of t,h,x +// kr--flag specifying desired root for multi-valued inputs: +// 1=return lower density root +// 2=return higher density root + + THFLSHdll (&t,&h,x, + &kr,&pp,&dd,&dl,&dv,xliq,xvap,&q,&e,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, P from THFLSH %10.4f,%10.4f,%10.4f\n",t,dd,pp/1000.0); + +//...Other general property calculation routines are given in FLSH_SUB.FOR +//...and FLASH2.FOR + +//...Calculate melting pressure + t=100.0; + MELTTdll (&t,x,&p,&ierr,herr,errormessagelength); + printf("Melting pressure(MPa) %10.4f,%10.4f\n",p/1000.0,t); + +//...Calculate melting temperature + MELTPdll (&p,x,&tt,&ierr,herr,errormessagelength); + printf("Melting temperature(K)%10.4f,%10.4f\n",tt,p/1000.0); + +//...Calculate sublimation pressure + t=200.0; + SUBLTdll (&t,x,&p,&ierr,herr,errormessagelength); + printf("Sublimation pr.(kPa) %10.4f,%10.4f\n",p,t); + +//...Calculate sublimation temperature + SUBLPdll (&p,x,&tt,&ierr,herr,errormessagelength); + printf("Sublimation temp.(K) %10.4f,%10.4f\n",tt,p); + +//...Get limits of the equations and check if t,d,p is a valid point +//...Equation of state +// call LIMITK ('EOS',1,t,d,p,tmin,tmax,Dmax,pmax,ierr,herr) +//...Viscosity equation +// call LIMITK ('ETA',1,t,d,p,tmin,tmax,Dmax,pmax,ierr,herr) +//...Thermal conductivity equation +// call LIMITK ('TCX',1,t,d,p,tmin,tmax,Dmax,pmax,ierr,herr) + +//...Other routines are given in UTILITY.FOR + +*/ + + return 0; +} +//--------------------------------------------------------------------------- diff --git a/_wrapper/cpptest/refprop_c.h b/_wrapper/cpptest/refprop_c.h new file mode 100644 index 0000000..ec0f266 --- /dev/null +++ b/_wrapper/cpptest/refprop_c.h @@ -0,0 +1,35 @@ + +#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) +# define __ISWINDOWS__ +# include +# define _CRT_SECURE_NO_WARNINGS +#elif __APPLE__ +# define __ISAPPLE__ +#elif __linux +# define __ISLINUX__ +#endif + +#if defined(__ISWINDOWS__) +#include +#elif defined(__ISLINUX__) +#include +#endif + +#if defined(__ISWINDOWS__) +HINSTANCE RefpropdllInstance; +// For C calling conventions, replaced all "double &" with "double *", and "long &" with "long *" +typedef void (__stdcall *fp_PHFLSHdllTYPE)(double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,long *,char*,long ); +typedef void (__stdcall *fp_SETUPdllTYPE)(long *,char*,char*,char*,long *,char*,long ,long ,long ,long ); +typedef void (__stdcall *fp_XMOLEdllTYPE)(double *,double *,double *); +#elif defined(__ISLINUX__) +void *RefpropdllInstance; +// For C calling conventions, replaced all "double &" with "double *", and "long &" with "long *" +typedef void ( *fp_PHFLSHdllTYPE)(double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,long *,char*,long ); +typedef void ( *fp_SETUPdllTYPE)(long *,char*,char*,char*,long *,char*,long ,long ,long ,long ); +typedef void ( *fp_XMOLEdllTYPE)(double *,double *,double *); +#endif + +//Define explicit function pointers +fp_PHFLSHdllTYPE PHFLSHdll; +fp_SETUPdllTYPE SETUPdll; +fp_XMOLEdllTYPE XMOLEdll; diff --git a/_wrapper/cpptest/refpropwrappertest.cpp b/_wrapper/cpptest/refpropwrappertest.cpp new file mode 100644 index 0000000..18c5cba --- /dev/null +++ b/_wrapper/cpptest/refpropwrappertest.cpp @@ -0,0 +1,160 @@ +#include +#include +#include +#include "refprop_wrapper.h" + +//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); +//double density(char* fluidname_in, double p, double t); +//double density(double p, double t); +//char *str_replace(char *str, char *search, char *replace, long *count); + +int main(int argc, char* argv[]){ + double p,t,d; + char fluidname[255]; + char errormsg[255]; + double* x; + double *props; + double *ders; + double *trns; + double sumx; + int i; + int nX = argc-5; + int DEBUG = 1; + + if (argc<5){ +// printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); + printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); + return 1; + } + + x = (double*) calloc(nX,sizeof(double)); + props=(double*) calloc(16+2*nX,sizeof(double)); + ders=(double*) calloc(21,sizeof(double)); + trns=(double*) calloc(3,sizeof(double)); + + + sumx = 0; + for (i=0;i +#include +#include +#include +#include "../src/refprop_library.h" +#include "../src/refprop_wrapper.h" +#include +#include + + + +//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); +//double density(char* fluidname_in, double p, double t); +//double density(double p, double t); +//char *str_replace(char *str, char *search, char *replace, long *count); + +int main(int argc, char* argv[]){ + double p,t,d; + char fluidname[255]; + char errormsg[255]; + double* x; + double *props; + double *ders; + double *trns; + double sumx; + int i; +// int nX = argc-5; + int DEBUG = 0; + int transport = 0; + int partialDersInputChoice= 3; + + +/* + int count; + printf ("This program was called with \"%s\".\n",argv[0]); + if (argc > 1) + { + for (count = 1; count < argc; count++) + { + printf("argv[%d] = %s\n", count, argv[count]); + } + } + else + { + printf("The command had no other arguments.\n"); + } +printf("argc is %li \n",argc); +*/ + + +/* + if (argc<5){ + printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); +// printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); + return 1; + } +*/ +// usage +// refpropwrappertest "pT" "isobutan|propane" 1e5 293 "c:\\Program Files (x86)\\REFPROP" .1 + +int nX=2; + + x = (double*) calloc(nX,sizeof(double)); + props=(double*) calloc(16+2*nX,sizeof(double)); + ders=(double*) calloc(21,sizeof(double)); + trns=(double*) calloc(3,sizeof(double)); + +x[0] = 0.5; +x[1] = 1.0-x[0]; +//x[2] = 1-x[1]; + + + + + +/* + sumx = 0; + for (i=0;i +# define _CRT_SECURE_NO_WARNINGS +#elif __APPLE__ +# define __ISAPPLE__ +#elif __linux +# define __ISLINUX__ +#endif + +// Do some manual changes to the function names +// if needed, uses CoolProp platform detection. +#if defined(__ISWINDOWS__) +// Define compiler specific calling conventions +// for the shared library. +# define CALLCONV __stdcall +// Do not redefine function names for the shared library, +// in this case it is the REFPROP.dll and no special +// names are needed. Macros still need a value for the +// name function used below. +# define RPVersion RPVersion +# define SATSPLNdll SATSPLNdll +# define SETPATHdll SETPATHdll +# define ABFL1dll ABFL1dll +# define ABFL2dll ABFL2dll +# define ACTVYdll ACTVYdll +# define AGdll AGdll +# define CCRITdll CCRITdll +# define CP0dll CP0dll +# define CRITPdll CRITPdll +# define CSATKdll CSATKdll +# define CV2PKdll CV2PKdll +# define CVCPKdll CVCPKdll +# define CVCPdll CVCPdll +# define DBDTdll DBDTdll +# define DBFL1dll DBFL1dll +# define DBFL2dll DBFL2dll +# define DDDPdll DDDPdll +# define DDDTdll DDDTdll +# define DEFLSHdll DEFLSHdll +# define DHD1dll DHD1dll +# define DHFL1dll DHFL1dll +# define DHFL2dll DHFL2dll +# define DHFLSHdll DHFLSHdll +# define DIELECdll DIELECdll +# define DOTFILLdll DOTFILLdll +# define DPDD2dll DPDD2dll +# define DPDDKdll DPDDKdll +# define DPDDdll DPDDdll +# define DPDTKdll DPDTKdll +# define DPDTdll DPDTdll +# define DPTSATKdll DPTSATKdll +# define DSFLSHdll DSFLSHdll +# define DSFL1dll DSFL1dll +# define DSFL2dll DSFL2dll +# define ENTHALdll ENTHALdll +# define ENTROdll ENTROdll +# define ESFLSHdll ESFLSHdll +# define FGCTYdll FGCTYdll +# define FPVdll FPVdll +# define GERG04dll GERG04dll +# define GETFIJdll GETFIJdll +# define GETKTVdll GETKTVdll +# define GIBBSdll GIBBSdll +# define HSFLSHdll HSFLSHdll +# define INFOdll INFOdll +# define LIMITKdll LIMITKdll +# define LIMITSdll LIMITSdll +# define LIMITXdll LIMITXdll +# define MELTPdll MELTPdll +# define MELTTdll MELTTdll +# define MLTH2Odll MLTH2Odll +# define NAMEdll NAMEdll +# define PDFL1dll PDFL1dll +# define PDFLSHdll PDFLSHdll +# define PEFLSHdll PEFLSHdll +# define PHFL1dll PHFL1dll +# define PHFLSHdll PHFLSHdll +# define PQFLSHdll PQFLSHdll +# define PREOSdll PREOSdll +# define PRESSdll PRESSdll +# define PSFL1dll PSFL1dll +# define PSFLSHdll PSFLSHdll +# define PUREFLDdll PUREFLDdll +# define QMASSdll QMASSdll +# define QMOLEdll QMOLEdll +# define RESIDUALdll RESIDUALdll +# define SATDdll SATDdll +# define SATEdll SATEdll +# define SATHdll SATHdll +# define SATPdll SATPdll +# define SATSdll SATSdll +# define SATTdll SATTdll +# define SETAGAdll SETAGAdll +# define SETKTVdll SETKTVdll +# define SETMIXdll SETMIXdll +# define SETMODdll SETMODdll +# define SETREFdll SETREFdll +# define SETUPdll SETUPdll +//# define SPECGRdll SPECGRdll // not found in library +# define SUBLPdll SUBLPdll +# define SUBLTdll SUBLTdll +# define SURFTdll SURFTdll +# define SURTENdll SURTENdll +# define TDFLSHdll TDFLSHdll +# define TEFLSHdll TEFLSHdll +# define THERM0dll THERM0dll +# define THERM2dll THERM2dll +# define THERM3dll THERM3dll +# define THERMdll THERMdll +# define THFLSHdll THFLSHdll +# define TPFLSHdll TPFLSHdll +# define TPFL2dll TPFL2dll +# define TPRHOdll TPRHOdll +# define TQFLSHdll TQFLSHdll +# define TRNPRPdll TRNPRPdll +# define TSFLSHdll TSFLSHdll +# define VIRBdll VIRBdll +# define VIRCdll VIRCdll +# define WMOLdll WMOLdll +# define XMASSdll XMASSdll +# define XMOLEdll XMOLEdll + +# define RMIX2dll RMIX2dll +# define RDXHMXdll RDXHMXdll +# define PHIXdll PHIXdll +# define PHI0dll PHI0dll +# define DQFL2dll DQFL2dll + + +#elif defined(__ISLINUX__) // defined(__ISWINDOWS__) +// Define compiler specific calling conventions +// for the shared library. +# define CALLCONV +// Define function names for the shared library, +// in this case it is the librefprop.so and the +// names might change on some systems during +// the compilation of the Fortran files. +// Possible other branches for this code could be: +// # if !defined(_AIX) +// # if !defined(__hpux) +// # if defined( _CRAY +// However, I cannot test that and therefore do not include it. +# define RPVersion rpversion_ +# define SATSPLNdll satsplndll_ +# define SETPATHdll setpathdll_ +# define ABFL1dll abfl1dll_ +# define ABFL2dll abfl2dll_ +# define ACTVYdll actvydll_ +# define AGdll agdll_ +# define CCRITdll ccritdll_ +# define CP0dll cp0dll_ +# define CRITPdll critpdll_ +# define CSATKdll csatkdll_ +# define CV2PKdll cv2pkdll_ +# define CVCPKdll cvcpkdll_ +# define CVCPdll cvcpdll_ +# define DBDTdll dbdtdll_ +# define DBFL1dll dbfl1dll_ +# define DBFL2dll dbfl2dll_ +# define DDDPdll dddpdll_ +# define DDDTdll dddtdll_ +# define DEFLSHdll deflshdll_ +# define DHD1dll dhd1dll_ +# define DHFL1dll dhfl1dll_ +# define DHFL2dll dhfl2dll_ +# define DHFLSHdll dhflshdll_ +# define DIELECdll dielecdll_ +# define DOTFILLdll dotfilldll_ +# define DPDD2dll dpdd2dll_ +# define DPDDKdll dpddkdll_ +# define DPDDdll dpdddll_ +# define DPDTKdll dpdtkdll_ +# define DPDTdll dpdtdll_ +# define DPTSATKdll dptsatkdll_ +# define DSFLSHdll dsflshdll_ +# define DSFL1dll dsfl1dll_ +# define DSFL2dll dsfl2dll_ +# define ENTHALdll enthaldll_ +# define ENTROdll entrodll_ +# define ESFLSHdll esflshdll_ +# define FGCTYdll fgctydll_ +# define FPVdll fpvdll_ +# define GERG04dll gerg04dll_ +# define GETFIJdll getfijdll_ +# define GETKTVdll getktvdll_ +# define GIBBSdll gibbsdll_ +# define HSFLSHdll hsflshdll_ +# define INFOdll infodll_ +# define LIMITKdll limitkdll_ +# define LIMITSdll limitsdll_ +# define LIMITXdll limitxdll_ +# define MELTPdll meltpdll_ +# define MELTTdll melttdll_ +# define MLTH2Odll mlth2odll_ +# define NAMEdll namedll_ +# define PDFL1dll pdfl1dll_ +# define PDFLSHdll pdflshdll_ +# define PEFLSHdll peflshdll_ +# define PHFL1dll phfl1dll_ +# define PHFLSHdll phflshdll_ +# define PQFLSHdll pqflshdll_ +# define PREOSdll preosdll_ +# define PRESSdll pressdll_ +# define PSFL1dll psfl1dll_ +# define PSFLSHdll psflshdll_ +# define PUREFLDdll pureflddll_ +# define QMASSdll qmassdll_ +# define QMOLEdll qmoledll_ +# define RESIDUALdll residualdll_ +# define SATDdll satddll_ +# define SATEdll satedll_ +# define SATHdll sathdll_ +# define SATPdll satpdll_ +# define SATSdll satsdll_ +# define SATTdll sattdll_ +# define SETAGAdll setagadll_ +# define SETKTVdll setktvdll_ +# define SETMIXdll setmixdll_ +# define SETMODdll setmoddll_ +# define SETREFdll setrefdll_ +# define SETUPdll setupdll_ +//# define SPECGRdll specgrdll_ // not found in library +# define SUBLPdll sublpdll_ +# define SUBLTdll subltdll_ +# define SURFTdll surftdll_ +# define SURTENdll surtendll_ +# define TDFLSHdll tdflshdll_ +# define TEFLSHdll teflshdll_ +# define THERM0dll therm0dll_ +# define THERM2dll therm2dll_ +# define THERM3dll therm3dll_ +# define THERMdll thermdll_ +# define THFLSHdll thflshdll_ +# define TPFLSHdll tpflshdll_ +# define TPFL2dll tpfl2dll_ +# define TPRHOdll tprhodll_ +# define TQFLSHdll tqflshdll_ +# define TRNPRPdll trnprpdll_ +# define TSFLSHdll tsflshdll_ +# define VIRBdll virbdll_ +# define VIRCdll vircdll_ +# define WMOLdll wmoldll_ +# define XMASSdll xmassdll_ +# define XMOLEdll xmoledll_ + +# define RMIX2dll rmix2dll_ +# define RDXHMXdll rdxhmxdll_ +# define PHIXdll phixdll_ +# define PHI0dll phi0dll_ +# define DQFL2dll dqfl2dll_ + +#else // #elif defined(__ISLINUX__) +// Set some dummy names for the compiler +# define CALLCONV +# define RPVersion NOTAVAILABLE +# define SATSPLNdll satsplndll +# define SETPATHdll setpathdll +# define ABFL1dll abfl1dll +# define ABFL2dll abfl2dll +# define ACTVYdll actvydll +# define AGdll agdll +# define CCRITdll ccritdll +# define CP0dll cp0dll +# define CRITPdll critpdll +# define CSATKdll csatkdll +# define CV2PKdll cv2pkdll +# define CVCPKdll cvcpkdll +# define CVCPdll cvcpdll +# define DBDTdll dbdtdll +# define DBFL1dll dbfl1dll +# define DBFL2dll dbfl2dll +# define DDDPdll dddpdll +# define DDDTdll dddtdll +# define DEFLSHdll deflshdll +# define DHD1dll dhd1dll +# define DHFL1dll dhfl1dll +# define DHFL2dll dhfl2dll +# define DHFLSHdll dhflshdll +# define DIELECdll dielecdll +# define DOTFILLdll dotfilldll +# define DPDD2dll dpdd2dll +# define DPDDKdll dpddkdll +# define DPDDdll dpdddll +# define DPDTKdll dpdtkdll +# define DPDTdll dpdtdll +# define DPTSATKdll dptsatkdll +# define DSFLSHdll dsflshdll +# define DSFL1dll dsfl1dll +# define DSFL2dll dsfl2dll +# define ENTHALdll enthaldll +# define ENTROdll entrodll +# define ESFLSHdll esflshdll +# define FGCTYdll fgctydll +# define FPVdll fpvdll +# define GERG04dll gerg04dll +# define GETFIJdll getfijdll +# define GETKTVdll getktvdll +# define GIBBSdll gibbsdll +# define HSFLSHdll hsflshdll +# define INFOdll infodll +# define LIMITKdll limitkdll +# define LIMITSdll limitsdll +# define LIMITXdll limitxdll +# define MELTPdll meltpdll +# define MELTTdll melttdll +# define MLTH2Odll mlth2odll +# define NAMEdll namedll +# define PDFL1dll pdfl1dll +# define PDFLSHdll pdflshdll +# define PEFLSHdll peflshdll +# define PHFL1dll phfl1dll +# define PHFLSHdll phflshdll +# define PQFLSHdll pqflshdll +# define PREOSdll preosdll +# define PRESSdll pressdll +# define PSFL1dll psfl1dll +# define PSFLSHdll psflshdll +# define PUREFLDdll pureflddll +# define QMASSdll qmassdll +# define QMOLEdll qmoledll +# define RESIDUALdll residualdll +# define SATDdll satddll +# define SATEdll satedll +# define SATHdll sathdll +# define SATPdll satpdll +# define SATSdll satsdll +# define SATTdll sattdll +# define SETAGAdll setagadll +# define SETKTVdll setktvdll +# define SETMIXdll setmixdll +# define SETMODdll setmoddll +# define SETREFdll setrefdll +# define SETUPdll setupdll +//# define SPECGRdll specgrdll // not found in library +# define SUBLPdll sublpdll +# define SUBLTdll subltdll +# define SURFTdll surftdll +# define SURTENdll surtendll +# define TDFLSHdll tdflshdll +# define TEFLSHdll teflshdll +# define THERM0dll therm0dll +# define THERM2dll therm2dll +# define THERM3dll therm3dll +# define THERMdll thermdll +# define THFLSHdll thflshdll +# define TPFLSHdll tpflshdll +# define TPFL2dll tpfl2dll +# define TPRHOdll tprhodll +# define TQFLSHdll tqflshdll +# define TRNPRPdll trnprpdll +# define TSFLSHdll tsflshdll +# define VIRBdll virbdll +# define VIRCdll vircdll +# define WMOLdll wmoldll +# define XMASSdll xmassdll +# define XMOLEdll xmoledll + +# define RMIX2dll rmix2dll +# define RDXHMXdll rdxhmxdll +# define PHIXdll phixdll +# define PHI0dll phi0dll +# define DQFL2dll dqfl2dll + +#endif // else branch +// +// +// Only continue if function names have been defined. +// We might want to include some more tests here... +#if defined(RPVersion) +// define new macros for function names +// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value +#include +#include +#define STR_VALUE(arg) #arg +#define FUNCTION_NAME(name) STR_VALUE(name) +// +// Prepare the strings to be used by the functions that +// handle the library later on. +#define RPVersion_NAME FUNCTION_NAME(RPVersion) +#define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) +#define SATSPLNdll_NAME FUNCTION_NAME(SATSPLNdll) +#define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) +#define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) +#define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) +#define AGdll_NAME FUNCTION_NAME(AGdll) +#define CCRITdll_NAME FUNCTION_NAME(CCRITdll) +#define CP0dll_NAME FUNCTION_NAME(CP0dll) +#define CRITPdll_NAME FUNCTION_NAME(CRITPdll) +#define CSATKdll_NAME FUNCTION_NAME(CSATKdll) +#define CV2PKdll_NAME FUNCTION_NAME(CV2PKdll) +#define CVCPKdll_NAME FUNCTION_NAME(CVCPKdll) +#define CVCPdll_NAME FUNCTION_NAME(CVCPdll) +#define DBDTdll_NAME FUNCTION_NAME(DBDTdll) +#define DBFL1dll_NAME FUNCTION_NAME(DBFL1dll) +#define DBFL2dll_NAME FUNCTION_NAME(DBFL2dll) +#define DDDPdll_NAME FUNCTION_NAME(DDDPdll) +#define DDDTdll_NAME FUNCTION_NAME(DDDTdll) +#define DEFLSHdll_NAME FUNCTION_NAME(DEFLSHdll) +#define DHD1dll_NAME FUNCTION_NAME(DHD1dll) +#define DHFL1dll_NAME FUNCTION_NAME(DHFL1dll) +#define DHFL2dll_NAME FUNCTION_NAME(DHFL2dll) +#define DHFLSHdll_NAME FUNCTION_NAME(DHFLSHdll) +#define DIELECdll_NAME FUNCTION_NAME(DIELECdll) +#define DOTFILLdll_NAME FUNCTION_NAME(DOTFILLdll) +#define DPDD2dll_NAME FUNCTION_NAME(DPDD2dll) +#define DPDDKdll_NAME FUNCTION_NAME(DPDDKdll) +#define DPDDdll_NAME FUNCTION_NAME(DPDDdll) +#define DPDTKdll_NAME FUNCTION_NAME(DPDTKdll) +#define DPDTdll_NAME FUNCTION_NAME(DPDTdll) +#define DPTSATKdll_NAME FUNCTION_NAME(DPTSATKdll) +#define DSFLSHdll_NAME FUNCTION_NAME(DSFLSHdll) +#define DSFL1dll_NAME FUNCTION_NAME(DSFL1dll) +#define DSFL2dll_NAME FUNCTION_NAME(DSFL2dll) +#define ENTHALdll_NAME FUNCTION_NAME(ENTHALdll) +#define ENTROdll_NAME FUNCTION_NAME(ENTROdll) +#define ESFLSHdll_NAME FUNCTION_NAME(ESFLSHdll) +#define FGCTYdll_NAME FUNCTION_NAME(FGCTYdll) +#define FPVdll_NAME FUNCTION_NAME(FPVdll) +#define GERG04dll_NAME FUNCTION_NAME(GERG04dll) +#define GETFIJdll_NAME FUNCTION_NAME(GETFIJdll) +#define GETKTVdll_NAME FUNCTION_NAME(GETKTVdll) +#define GIBBSdll_NAME FUNCTION_NAME(GIBBSdll) +#define HSFLSHdll_NAME FUNCTION_NAME(HSFLSHdll) +#define INFOdll_NAME FUNCTION_NAME(INFOdll) +#define LIMITKdll_NAME FUNCTION_NAME(LIMITKdll) +#define LIMITSdll_NAME FUNCTION_NAME(LIMITSdll) +#define LIMITXdll_NAME FUNCTION_NAME(LIMITXdll) +#define MELTPdll_NAME FUNCTION_NAME(MELTPdll) +#define MELTTdll_NAME FUNCTION_NAME(MELTTdll) +#define MLTH2Odll_NAME FUNCTION_NAME(MLTH2Odll) +#define NAMEdll_NAME FUNCTION_NAME(NAMEdll) +#define PDFL1dll_NAME FUNCTION_NAME(PDFL1dll) +#define PDFLSHdll_NAME FUNCTION_NAME(PDFLSHdll) +#define PEFLSHdll_NAME FUNCTION_NAME(PEFLSHdll) +#define PHFL1dll_NAME FUNCTION_NAME(PHFL1dll) +#define PHFLSHdll_NAME FUNCTION_NAME(PHFLSHdll) +#define PQFLSHdll_NAME FUNCTION_NAME(PQFLSHdll) +#define PREOSdll_NAME FUNCTION_NAME(PREOSdll) +#define PRESSdll_NAME FUNCTION_NAME(PRESSdll) +#define PSFL1dll_NAME FUNCTION_NAME(PSFL1dll) +#define PSFLSHdll_NAME FUNCTION_NAME(PSFLSHdll) +#define PUREFLDdll_NAME FUNCTION_NAME(PUREFLDdll) +#define QMASSdll_NAME FUNCTION_NAME(QMASSdll) +#define QMOLEdll_NAME FUNCTION_NAME(QMOLEdll) +#define RESIDUALdll_NAME FUNCTION_NAME(RESIDUALdll) +#define SATDdll_NAME FUNCTION_NAME(SATDdll) +#define SATEdll_NAME FUNCTION_NAME(SATEdll) +#define SATHdll_NAME FUNCTION_NAME(SATHdll) +#define SATPdll_NAME FUNCTION_NAME(SATPdll) +#define SATSdll_NAME FUNCTION_NAME(SATSdll) +#define SATTdll_NAME FUNCTION_NAME(SATTdll) +#define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) +#define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) +#define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) +#define SETMODdll_NAME FUNCTION_NAME(SETMODdll) +#define SETREFdll_NAME FUNCTION_NAME(SETREFdll) +#define SETUPdll_NAME FUNCTION_NAME(SETUPdll) +//#define SPECGRdll_NAME FUNCTION_NAME(SPECGRdll) // not found in library +#define SUBLPdll_NAME FUNCTION_NAME(SUBLPdll) +#define SUBLTdll_NAME FUNCTION_NAME(SUBLTdll) +#define SURFTdll_NAME FUNCTION_NAME(SURFTdll) +#define SURTENdll_NAME FUNCTION_NAME(SURTENdll) +#define TDFLSHdll_NAME FUNCTION_NAME(TDFLSHdll) +#define TEFLSHdll_NAME FUNCTION_NAME(TEFLSHdll) +#define THERM0dll_NAME FUNCTION_NAME(THERM0dll) +#define THERM2dll_NAME FUNCTION_NAME(THERM2dll) +#define THERM3dll_NAME FUNCTION_NAME(THERM3dll) +#define THERMdll_NAME FUNCTION_NAME(THERMdll) +#define THFLSHdll_NAME FUNCTION_NAME(THFLSHdll) +#define TPFLSHdll_NAME FUNCTION_NAME(TPFLSHdll) +#define TPFL2dll_NAME FUNCTION_NAME(TPFL2dll) +#define TPRHOdll_NAME FUNCTION_NAME(TPRHOdll) +#define TQFLSHdll_NAME FUNCTION_NAME(TQFLSHdll) +#define TRNPRPdll_NAME FUNCTION_NAME(TRNPRPdll) +#define TSFLSHdll_NAME FUNCTION_NAME(TSFLSHdll) +#define VIRBdll_NAME FUNCTION_NAME(VIRBdll) +#define VIRCdll_NAME FUNCTION_NAME(VIRCdll) +#define WMOLdll_NAME FUNCTION_NAME(WMOLdll) +#define XMASSdll_NAME FUNCTION_NAME(XMASSdll) +#define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) + +#define RMIX2dll_NAME FUNCTION_NAME(RMIX2dll) +#define RDXHMXdll_NAME FUNCTION_NAME(RDXHMXdll) +#define PHIXdll_NAME FUNCTION_NAME(PHIXdll) +#define PHI0dll_NAME FUNCTION_NAME(PHI0dll) +#define DQFL2dll_NAME FUNCTION_NAME(DQFL2dll) + +// +// I'll try to follow this example from: +// http://www.gershnik.com/tips/cpp.asp +// function type: typedef void [compiler stuff] func_t(int, float); +// function declaration: func_t func; +// pointer type: typedef func_t * func_ptr; +#if defined(__cplusplus) +extern "C" { +#endif + typedef void (CALLCONV RPVersion_TYPE)( char* ); + typedef void (CALLCONV SETPATHdll_TYPE)( const char* ); + typedef void (CALLCONV SATSPLNdll_TYPE)(double *,long &,char*,long ); + + // + typedef void (CALLCONV ABFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV ABFL2dll_TYPE)(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV ACTVYdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV AGdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV CCRITdll_TYPE)(double &,double &,double &,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CP0dll_TYPE)(double &,double *,double &); + typedef void (CALLCONV CRITPdll_TYPE)(double *,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CV2PKdll_TYPE)(long &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CVCPKdll_TYPE)(long &,double &,double &,double &,double &); + typedef void (CALLCONV CVCPdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV DBDTdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV DBFL1dll_TYPE)(double &,double &,double *,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DBFL2dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV DDDPdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DDDTdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DHD1dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV DHFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV DHFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV DHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DIELECdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DOTFILLdll_TYPE)(long &,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV DPDD2dll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPDDKdll_TYPE)(long &,double &,double &,double &); + typedef void (CALLCONV DPDDdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPDTKdll_TYPE)(long &,double &,double &,double &); + typedef void (CALLCONV DPDTdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPTSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DSFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV DSFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV ENTHALdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV ENTROdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV ESFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV FGCTYdll_TYPE)(double &,double &,double *,double *); + typedef void (CALLCONV FPVdll_TYPE)(double &,double &,double &,double *,double &); + typedef void (CALLCONV GERG04dll_TYPE)(long &,long &,long &,char*,long ); + typedef void (CALLCONV GETFIJdll_TYPE)(char*,double *,char*,char*,long ,long ,long ); + typedef void (CALLCONV GETKTVdll_TYPE)(long &,long &,char*,double *,char*,char*,char*,char*,long ,long ,long ,long ,long ); + typedef void (CALLCONV GIBBSdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV HSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV INFOdll_TYPE)(long &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV LIMITKdll_TYPE)(char*,long &,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV LIMITSdll_TYPE)(char*,double *,double &,double &,double &,double &,long ); + typedef void (CALLCONV LIMITXdll_TYPE)(char*,double &,double &,double &,double *,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV MELTPdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV MELTTdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV MLTH2Odll_TYPE)(double &,double &,double &); + typedef void (CALLCONV NAMEdll_TYPE)(long &,char*,char*,char*,long ,long ,long ); + typedef void (CALLCONV PDFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV PDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PHFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PREOSdll_TYPE)(long &); + typedef void (CALLCONV PRESSdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV PSFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PUREFLDdll_TYPE)(long &); + typedef void (CALLCONV QMASSdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV QMOLEdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV RESIDUALdll_TYPE)(double &,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *); + typedef void (CALLCONV SATDdll_TYPE)(double &,double *,long &,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SATEdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATHdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATPdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SATSdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATTdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SETAGAdll_TYPE)(long &,char*,long ); + typedef void (CALLCONV SETKTVdll_TYPE)(long &,long &,char*,double *,char*,long &,char*,long ,long ,long ); + typedef void (CALLCONV SETMIXdll_TYPE)(char*,char*,char*,long &,char*,double *,long &,char*,long ,long ,long ,long ,long ); + typedef void (CALLCONV SETMODdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); + typedef void (CALLCONV SETREFdll_TYPE)(char*,long &,double *,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV SETUPdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); + typedef void (CALLCONV SPECGRdll_TYPE)(double &,double &,double &,double &); + typedef void (CALLCONV SUBLPdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SUBLTdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SURFTdll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SURTENdll_TYPE)(double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV TDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TEFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV THERM0dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERM2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERM3dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERMdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TPFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TPFL2dll_TYPE)(double &,double &,double *,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV TPRHOdll_TYPE)(double &,double &,double *,long &,long &,double &,long &,char*,long ); + typedef void (CALLCONV TQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TRNPRPdll_TYPE)(double &,double &,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV TSFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV VIRBdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV VIRCdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV WMOLdll_TYPE)(double *,double &); + typedef void (CALLCONV XMASSdll_TYPE)(double *,double *,double &); + typedef void (CALLCONV XMOLEdll_TYPE)(double *,double *,double &); + + typedef void (CALLCONV RMIX2dll_TYPE)(double *,double &); + typedef void (CALLCONV RDXHMXdll_TYPE)(long *,long *,long *,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV PHIXdll_TYPE)(long *,long *,double &,double &,double *,double &); + typedef void (CALLCONV PHI0dll_TYPE)(long *,long *,double &,double &,double *,double &); + typedef void (CALLCONV DQFL2dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); + + // +// Disabled because we prefer pointers here! +// // Declare the functions for direct access, +// RPVersion_TYPE RPVersion; +// SETPATHdll_TYPE SETPATHdll; +// ABFL1dll_TYPE ABFL1dll; +// ABFL2dll_TYPE ABFL2dll; +// ACTVYdll_TYPE ACTVYdll; +// AGdll_TYPE AGdll; +// CCRITdll_TYPE CCRITdll; +// CP0dll_TYPE CP0dll; +// CRITPdll_TYPE CRITPdll; +// CSATKdll_TYPE CSATKdll; +// CV2PKdll_TYPE CV2PKdll; +// CVCPKdll_TYPE CVCPKdll; +// CVCPdll_TYPE CVCPdll; +// DBDTdll_TYPE DBDTdll; +// DBFL1dll_TYPE DBFL1dll; +// DBFL2dll_TYPE DBFL2dll; +// DDDPdll_TYPE DDDPdll; +// DDDTdll_TYPE DDDTdll; +// DEFLSHdll_TYPE DEFLSHdll; +// DHD1dll_TYPE DHD1dll; +// DHFLSHdll_TYPE DHFLSHdll; +// DHFL1dll_TYPE DHFL1dll; +// DHFL2dll_TYPE DHFL2dll; +// DIELECdll_TYPE DIELECdll; +// DOTFILLdll_TYPE DOTFILLdll; +// DPDD2dll_TYPE DPDD2dll; +// DPDDKdll_TYPE DPDDKdll; +// DPDDdll_TYPE DPDDdll; +// DPDTKdll_TYPE DPDTKdll; +// DPDTdll_TYPE DPDTdll; +// DPTSATKdll_TYPE DPTSATKdll; +// DSFLSHdll_TYPE DSFLSHdll; +// DSFL1dll_TYPE DSFL1dll; +// DSFL2dll_TYPE DSFL2dll; +// ENTHALdll_TYPE ENTHALdll; +// ENTROdll_TYPE ENTROdll; +// ESFLSHdll_TYPE ESFLSHdll; +// FGCTYdll_TYPE FGCTYdll; +// FPVdll_TYPE FPVdll; +// GERG04dll_TYPE GERG04dll; +// GETFIJdll_TYPE GETFIJdll; +// GETKTVdll_TYPE GETKTVdll; +// GIBBSdll_TYPE GIBBSdll; +// HSFLSHdll_TYPE HSFLSHdll; +// INFOdll_TYPE INFOdll; +// LIMITKdll_TYPE LIMITKdll; +// LIMITSdll_TYPE LIMITSdll; +// LIMITXdll_TYPE LIMITXdll; +// MELTPdll_TYPE MELTPdll; +// MELTTdll_TYPE MELTTdll; +// MLTH2Odll_TYPE MLTH2Odll; +// NAMEdll_TYPE NAMEdll; +// PDFL1dll_TYPE PDFL1dll; +// PDFLSHdll_TYPE PDFLSHdll; +// PEFLSHdll_TYPE PEFLSHdll; +// PHFL1dll_TYPE PHFL1dll; +// PHFLSHdll_TYPE PHFLSHdll; +// PQFLSHdll_TYPE PQFLSHdll; +// PREOSdll_TYPE PREOSdll; +// PRESSdll_TYPE PRESSdll; +// PSFL1dll_TYPE PSFL1dll; +// PSFLSHdll_TYPE PSFLSHdll; +// PUREFLDdll_TYPE PUREFLDdll; +// QMASSdll_TYPE QMASSdll; +// QMOLEdll_TYPE QMOLEdll; +// SATDdll_TYPE SATDdll; +// SATEdll_TYPE SATEdll; +// SATHdll_TYPE SATHdll; +// SATPdll_TYPE SATPdll; +// SATSdll_TYPE SATSdll; +// SATTdll_TYPE SATTdll; +// SETAGAdll_TYPE SETAGAdll; +// SETKTVdll_TYPE SETKTVdll; +// SETMIXdll_TYPE SETMIXdll; +// SETMODdll_TYPE SETMODdll; +// SETREFdll_TYPE SETREFdll; +// SETUPdll_TYPE SETUPdll; +//// SPECGRdll_TYPE SPECGRdll; // not found in library +// SUBLPdll_TYPE SUBLPdll; +// SUBLTdll_TYPE SUBLTdll; +// SURFTdll_TYPE SURFTdll; +// SURTENdll_TYPE SURTENdll; +// TDFLSHdll_TYPE TDFLSHdll; +// TEFLSHdll_TYPE TEFLSHdll; +// THERM0dll_TYPE THERM0dll; +// THERM2dll_TYPE THERM2dll; +// THERM3dll_TYPE THERM3dll; +// THERMdll_TYPE THERMdll; +// THFLSHdll_TYPE THFLSHdll; +// TPFLSHdll_TYPE TPFLSHdll; +// TPFL2dll_TYPE TPFL2dll; +// TPRHOdll_TYPE TPRHOdll; +// TQFLSHdll_TYPE TQFLSHdll; +// TRNPRPdll_TYPE TRNPRPdll; +// TSFLSHdll_TYPE TSFLSHdll; +// VIRBdll_TYPE VIRBdll; +// VIRCdll_TYPE VIRCdll; +// WMOLdll_TYPE WMOLdll; +// XMASSdll_TYPE XMASSdll; +// XMOLEdll_TYPE XMOLEdll; + // + // Define explicit function pointers + + + + + + typedef RPVersion_TYPE * RPVersion_POINTER; + typedef SETPATHdll_TYPE * SETPATHdll_POINTER; + typedef SATSPLNdll_TYPE * SATSPLNdll_POINTER; + typedef ABFL1dll_TYPE * ABFL1dll_POINTER; + typedef ABFL2dll_TYPE * ABFL2dll_POINTER; + typedef ACTVYdll_TYPE * ACTVYdll_POINTER; + typedef AGdll_TYPE * AGdll_POINTER; + typedef CCRITdll_TYPE * CCRITdll_POINTER; + typedef CP0dll_TYPE * CP0dll_POINTER; + typedef CRITPdll_TYPE * CRITPdll_POINTER; + typedef CSATKdll_TYPE * CSATKdll_POINTER; + typedef CV2PKdll_TYPE * CV2PKdll_POINTER; + typedef CVCPKdll_TYPE * CVCPKdll_POINTER; + typedef CVCPdll_TYPE * CVCPdll_POINTER; + typedef DBDTdll_TYPE * DBDTdll_POINTER; + typedef DBFL1dll_TYPE * DBFL1dll_POINTER; + typedef DBFL2dll_TYPE * DBFL2dll_POINTER; + typedef DDDPdll_TYPE * DDDPdll_POINTER; + typedef DDDTdll_TYPE * DDDTdll_POINTER; + typedef DEFLSHdll_TYPE * DEFLSHdll_POINTER; + typedef DHD1dll_TYPE * DHD1dll_POINTER; + typedef DHFLSHdll_TYPE * DHFLSHdll_POINTER; + typedef DHFL1dll_TYPE * DHFL1dll_POINTER; + typedef DHFL2dll_TYPE * DHFL2dll_POINTER; + typedef DIELECdll_TYPE * DIELECdll_POINTER; + typedef DOTFILLdll_TYPE * DOTFILLdll_POINTER; + typedef DPDD2dll_TYPE * DPDD2dll_POINTER; + typedef DPDDKdll_TYPE * DPDDKdll_POINTER; + typedef DPDDdll_TYPE * DPDDdll_POINTER; + typedef DPDTKdll_TYPE * DPDTKdll_POINTER; + typedef DPDTdll_TYPE * DPDTdll_POINTER; + typedef DPTSATKdll_TYPE * DPTSATKdll_POINTER; + typedef DSFLSHdll_TYPE * DSFLSHdll_POINTER; + typedef DSFL1dll_TYPE * DSFL1dll_POINTER; + typedef DSFL2dll_TYPE * DSFL2dll_POINTER; + typedef ENTHALdll_TYPE * ENTHALdll_POINTER; + typedef ENTROdll_TYPE * ENTROdll_POINTER; + typedef ESFLSHdll_TYPE * ESFLSHdll_POINTER; + typedef FGCTYdll_TYPE * FGCTYdll_POINTER; + typedef FPVdll_TYPE * FPVdll_POINTER; + typedef GERG04dll_TYPE * GERG04dll_POINTER; + typedef GETFIJdll_TYPE * GETFIJdll_POINTER; + typedef GETKTVdll_TYPE * GETKTVdll_POINTER; + typedef GIBBSdll_TYPE * GIBBSdll_POINTER; + typedef HSFLSHdll_TYPE * HSFLSHdll_POINTER; + typedef INFOdll_TYPE * INFOdll_POINTER; + typedef LIMITKdll_TYPE * LIMITKdll_POINTER; + typedef LIMITSdll_TYPE * LIMITSdll_POINTER; + typedef LIMITXdll_TYPE * LIMITXdll_POINTER; + typedef MELTPdll_TYPE * MELTPdll_POINTER; + typedef MELTTdll_TYPE * MELTTdll_POINTER; + typedef MLTH2Odll_TYPE * MLTH2Odll_POINTER; + typedef NAMEdll_TYPE * NAMEdll_POINTER; + typedef PDFL1dll_TYPE * PDFL1dll_POINTER; + typedef PDFLSHdll_TYPE * PDFLSHdll_POINTER; + typedef PEFLSHdll_TYPE * PEFLSHdll_POINTER; + typedef PHFL1dll_TYPE * PHFL1dll_POINTER; + typedef PHFLSHdll_TYPE * PHFLSHdll_POINTER; + typedef PQFLSHdll_TYPE * PQFLSHdll_POINTER; + typedef PREOSdll_TYPE * PREOSdll_POINTER; + typedef PRESSdll_TYPE * PRESSdll_POINTER; + typedef PSFL1dll_TYPE * PSFL1dll_POINTER; + typedef PSFLSHdll_TYPE * PSFLSHdll_POINTER; + typedef PUREFLDdll_TYPE * PUREFLDdll_POINTER; + typedef QMASSdll_TYPE * QMASSdll_POINTER; + typedef QMOLEdll_TYPE * QMOLEdll_POINTER; + typedef RESIDUALdll_TYPE * RESIDUALdll_POINTER; + typedef SATDdll_TYPE * SATDdll_POINTER; + typedef SATEdll_TYPE * SATEdll_POINTER; + typedef SATHdll_TYPE * SATHdll_POINTER; + typedef SATPdll_TYPE * SATPdll_POINTER; + typedef SATSdll_TYPE * SATSdll_POINTER; + typedef SATTdll_TYPE * SATTdll_POINTER; + typedef SETAGAdll_TYPE * SETAGAdll_POINTER; + typedef SETKTVdll_TYPE * SETKTVdll_POINTER; + typedef SETMIXdll_TYPE * SETMIXdll_POINTER; + typedef SETMODdll_TYPE * SETMODdll_POINTER; + typedef SETREFdll_TYPE * SETREFdll_POINTER; + typedef SETUPdll_TYPE * SETUPdll_POINTER; +// typedef SPECGRdll_TYPE * SPECGRdll_POINTER; // not found in library + typedef SUBLPdll_TYPE * SUBLPdll_POINTER; + typedef SUBLTdll_TYPE * SUBLTdll_POINTER; + typedef SURFTdll_TYPE * SURFTdll_POINTER; + typedef SURTENdll_TYPE * SURTENdll_POINTER; + typedef TDFLSHdll_TYPE * TDFLSHdll_POINTER; + typedef TEFLSHdll_TYPE * TEFLSHdll_POINTER; + typedef THERM0dll_TYPE * THERM0dll_POINTER; + typedef THERM2dll_TYPE * THERM2dll_POINTER; + typedef THERM3dll_TYPE * THERM3dll_POINTER; + typedef THERMdll_TYPE * THERMdll_POINTER; + typedef THFLSHdll_TYPE * THFLSHdll_POINTER; + typedef TPFLSHdll_TYPE * TPFLSHdll_POINTER; + typedef TPFL2dll_TYPE * TPFL2dll_POINTER; + typedef TPRHOdll_TYPE * TPRHOdll_POINTER; + typedef TQFLSHdll_TYPE * TQFLSHdll_POINTER; + typedef TRNPRPdll_TYPE * TRNPRPdll_POINTER; + typedef TSFLSHdll_TYPE * TSFLSHdll_POINTER; + typedef VIRBdll_TYPE * VIRBdll_POINTER; + typedef VIRCdll_TYPE * VIRCdll_POINTER; + typedef WMOLdll_TYPE * WMOLdll_POINTER; + typedef XMASSdll_TYPE * XMASSdll_POINTER; + typedef XMOLEdll_TYPE * XMOLEdll_POINTER; + + typedef RMIX2dll_TYPE * RMIX2dll_POINTER; + typedef RDXHMXdll_TYPE * RDXHMXdll_POINTER; + typedef PHIXdll_TYPE * PHIXdll_POINTER; + typedef PHI0dll_TYPE * PHI0dll_POINTER; + typedef DQFL2dll_TYPE * DQFL2dll_POINTER; + + + + +#if defined(__cplusplus) +} // extern "C" +#endif // __cplusplus +#endif // defined(RPversion) +#endif // REFPROP_LIB_H diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp new file mode 100644 index 0000000..381622c --- /dev/null +++ b/_wrapper/src/refprop_wrapper.cpp @@ -0,0 +1,3122 @@ +/* + This is a wrapper file for the Refprop library. It does not include + any functionality besides providing the connection to Refprop. + + The current version was developed by Jorrit Wronski (jowr@mek.dtu.dk) + based on Henning Francke's (francke@gfz-potsdam.de) wrapper. A little + inspiration also came from Ian Bell's (ian.h.bell@gmail.com) wrapper + used in CoolProp - http://coolprop.sourceforge.net/ + + Compatible to the Modelica interface developed by Henning Francke + (francke@gfz-potsdam.de) and his first wrapper class that you can + find in the folder with version 0.5 for Windows systems. +*/ +/* + * Here are the included files + */ +#include "refprop_library.h" +#include "refprop_wrapper.h" + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__ISWINDOWS__) +#include +#define pathSep STR_VALUE(\\) +#define libName STR_VALUE(refprop.dll) +#define _CRT_SECURE_NO_WARNINGS +#elif defined(__ISLINUX__) +#include +#define pathSep STR_VALUE(/) +#define libName STR_VALUE(librefprop.so) +#elif defined(__ISAPPLE__) +#include +#define pathSep STR_VALUE(/) +#define libName STR_VALUE(librefprop.dylib) +#endif + + +// Some constants for REFPROP... defined by macros for ease of use +#define refpropcharlength 255 +#define refpropcharlong 10000 +#define filepathlength 255 +#define lengthofreference 3 +#define errormessagelength 255 +#define ncmax 20 // Note: ncmax is the max number of components +#define numparams 72 +#define maxcoefs 50 + +/* + * Define pointer to library as well as the + * strings we need to determine whether a + * call to SETUPdll is needed. + */ +#if defined(__ISWINDOWS__) +HINSTANCE RefpropdllInstance= NULL; +#elif defined(__ISLINUX__) +void *RefpropdllInstance = NULL; +#elif defined(__ISAPPLE__) +void *RefpropdllInstance = NULL; +#else +void *RefpropdllInstance = NULL; +#endif +std::string loadedFluids; + + + +/* + * Here we define the fluid's properties. These values get updated after each + * call to Refprop and are used for caching values. I decided to use the + * Refprop units for internal data storage Be careful when converting + * properties using the molecular weight. It is stored in g/mol. + */ + long kq = 2; // all qualities are calculated on a mass basis +static const double noValue = 0; + +//static const std::string FLUIDS_PATH = "fluids"; +//static const std::string LIN_LIBRARY = "librefprop.so"; +//static const std::string WIN_LIBRARY = "refprop.dll"; +//Poco::Path FLD_PATH(true); + + +// static const double noFactor = 1e+0; +// static const double presFactor = 1e+3; +// static const double viscFactor = 1e+6; +// static const double molwFactor = 1e-3; +// double energyFactor = noValue; // J/mol / g/mol * 1000g/kg = J/kg +// double densityFactor[3] = {noValue}; // mol/l * g/mol = g/l = kg/m3 for all phases +// double fractionFactor[ncmax] = {noValue}; // xkgi = xmi * mwi * mw (array) +// double qualityFactor = noValue; // qmass = qmole * mw_vap / mw + +bool debug; // set the debug flag +bool calcTrans; +//bool calcTwoPhaseNumDers; +//bool calcTwoPhasePsuedoAnalDers; +//bool dynstatesTPX; +int PartialDersInputChoice; + +//long lerr; // Error return mechanism +double dhelp = noValue; + + + + +// Properties for setSat functions +double dxmolsat[ncmax], dwmsat, dpsat, dtsat,ddlsat,ddvsat, + dxmollsat[ncmax],dxmolvsat[ncmax],dhlsat,dslsat, + dwlsat,dhvsat,dsvsat,dwvsat,ddsat; + +/* + * Most of the fluid properties are stored here. There are arrays for + * composition information as well as single values for the other + * properties. + * The flush function gets called when the state changes and the + * previously calculated are not valid anymore. + */ +double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, + ddv, dxmoll[ncmax], dxmolv[ncmax], dCv, dCp, dw, dwliq, dwvap, + dhjt, dZ[ncmax], dA, dG, dxkappa, dbeta, + dhl,dhv,dsl,dsv,dsigma,dts; + +double *dxkg; +double dxkg_old[ncmax]; +double dx1kg_old; +double dx1molsat_old; + +// viscosity and thermal conductivity +double deta, dtcx; + +// partial derivatives +double ddddp_h, ddddh_p, ddddX_ph, + ddddp_T, ddddT_p, ddddX_pT, + ddhdp_T, ddhdT_p, ddhdX_pT; + +int flushProperties(){ + dt=noValue; + dp=noValue; + de=noValue; + dh=noValue; + ds=noValue; + dqmol=noValue; + dd=noValue; + dxmol[0]=noValue; + ddl=noValue; + ddv=noValue; + dhl=noValue; + dhv=noValue; + dsl=noValue; + dsv=noValue; + + dxmoll[0]=noValue; + dxmolv[0]=noValue; + dCv=noValue; + dCp=noValue; + dw=noValue; + dwliq=noValue; + dwvap=noValue; + + dhjt=noValue; + dZ[0]=noValue; + dA=noValue; + dG=noValue; + dxkappa=noValue; + dbeta=noValue; + deta=noValue; + dtcx=noValue; + dsigma=noValue; + + ddddX_ph=noValue; + ddddp_h=noValue; + ddddh_p=noValue; + + ddddp_T=noValue; + ddddT_p=noValue; + ddddX_pT=noValue; + ddhdp_T=noValue; + ddhdT_p=noValue; + ddhdX_pT=noValue; + + if (debug) printf ("Finished flushing normal fluid properties.\n"); + return 0; +} + + +/* + * Properties that are constants for pure fluids. Hence, the flushing + * function gets called when a new fluid is loaded. In case of a mixture, + * a change of composition also triggers a flushing since this also + * changes those that also exist for mixtures. + * A change of composition or fluid always leads to a flushing of the + * other properties. + */ +long lnc; // number of components +double dwm, dttp, dtnbp, dtc, dpc, ddc, dZc, dacf, ddip, drgas; +int flushConstants() { + //lnc = -1; + dwm = noValue; + dttp = noValue; + dtnbp = noValue; + dtc = noValue; + dpc = noValue; + ddc = noValue; + dZc = noValue; + dacf = noValue; + ddip = noValue; + drgas = noValue; + if (debug) printf ("Finished flushing fluid/mixture \"constants\".\n"); + return flushProperties(); +} + +char hfmix[] = "HMX.BNC"; +char hrf[] = "DEF"; + + + + + +/* + * Define functions as pointers and initialise them to NULL + * Declare the functions for direct access + */ +RPVersion_POINTER RPVersion; +SETPATHdll_POINTER SETPATHdll; +SATSPLNdll_POINTER SATSPLNdll; +ABFL1dll_POINTER ABFL1dll; +ABFL2dll_POINTER ABFL2dll; +ACTVYdll_POINTER ACTVYdll; +AGdll_POINTER AGdll; +CCRITdll_POINTER CCRITdll; +CP0dll_POINTER CP0dll; +CRITPdll_POINTER CRITPdll; +CSATKdll_POINTER CSATKdll; +CV2PKdll_POINTER CV2PKdll; +CVCPKdll_POINTER CVCPKdll; +CVCPdll_POINTER CVCPdll; +DBDTdll_POINTER DBDTdll; +DBFL1dll_POINTER DBFL1dll; +DBFL2dll_POINTER DBFL2dll; +DDDPdll_POINTER DDDPdll; +DDDTdll_POINTER DDDTdll; +DEFLSHdll_POINTER DEFLSHdll; +DHD1dll_POINTER DHD1dll; +DHFLSHdll_POINTER DHFLSHdll; +DHFL1dll_POINTER DHFL1dll; +DHFL2dll_POINTER DHFL2dll; +DIELECdll_POINTER DIELECdll; +DOTFILLdll_POINTER DOTFILLdll; +DPDD2dll_POINTER DPDD2dll; +DPDDKdll_POINTER DPDDKdll; +DPDDdll_POINTER DPDDdll; +DPDTKdll_POINTER DPDTKdll; +DPDTdll_POINTER DPDTdll; +DPTSATKdll_POINTER DPTSATKdll; +DSFLSHdll_POINTER DSFLSHdll; +DSFL1dll_POINTER DSFL1dll; +DSFL2dll_POINTER DSFL2dll; +ENTHALdll_POINTER ENTHALdll; +ENTROdll_POINTER ENTROdll; +ESFLSHdll_POINTER ESFLSHdll; +FGCTYdll_POINTER FGCTYdll; +FPVdll_POINTER FPVdll; +GERG04dll_POINTER GERG04dll; +GETFIJdll_POINTER GETFIJdll; +GETKTVdll_POINTER GETKTVdll; +GIBBSdll_POINTER GIBBSdll; +HSFLSHdll_POINTER HSFLSHdll; +INFOdll_POINTER INFOdll; +LIMITKdll_POINTER LIMITKdll; +LIMITSdll_POINTER LIMITSdll; +LIMITXdll_POINTER LIMITXdll; +MELTPdll_POINTER MELTPdll; +MELTTdll_POINTER MELTTdll; +MLTH2Odll_POINTER MLTH2Odll; +NAMEdll_POINTER NAMEdll; +PDFL1dll_POINTER PDFL1dll; +PDFLSHdll_POINTER PDFLSHdll; +PEFLSHdll_POINTER PEFLSHdll; +PHFL1dll_POINTER PHFL1dll; +PHFLSHdll_POINTER PHFLSHdll; +PQFLSHdll_POINTER PQFLSHdll; +PREOSdll_POINTER PREOSdll; +PRESSdll_POINTER PRESSdll; +PSFL1dll_POINTER PSFL1dll; +PSFLSHdll_POINTER PSFLSHdll; +PUREFLDdll_POINTER PUREFLDdll; +QMASSdll_POINTER QMASSdll; +QMOLEdll_POINTER QMOLEdll; +RESIDUALdll_POINTER RESIDUALdll; +SATDdll_POINTER SATDdll; +SATEdll_POINTER SATEdll; +SATHdll_POINTER SATHdll; +SATPdll_POINTER SATPdll; +SATSdll_POINTER SATSdll; +SATTdll_POINTER SATTdll; +SETAGAdll_POINTER SETAGAdll; +SETKTVdll_POINTER SETKTVdll; +SETMIXdll_POINTER SETMIXdll; +SETMODdll_POINTER SETMODdll; +SETREFdll_POINTER SETREFdll; +SETUPdll_POINTER SETUPdll; +// SPECGRdll_POINTER SPECGRdll; // not found in library +SUBLPdll_POINTER SUBLPdll; +SUBLTdll_POINTER SUBLTdll; +SURFTdll_POINTER SURFTdll; +SURTENdll_POINTER SURTENdll; +TDFLSHdll_POINTER TDFLSHdll; +TEFLSHdll_POINTER TEFLSHdll; +THERM0dll_POINTER THERM0dll; +THERM2dll_POINTER THERM2dll; +THERM3dll_POINTER THERM3dll; +THERMdll_POINTER THERMdll; +THFLSHdll_POINTER THFLSHdll; +TPFLSHdll_POINTER TPFLSHdll; +TPFL2dll_POINTER TPFL2dll; +TPRHOdll_POINTER TPRHOdll; +TQFLSHdll_POINTER TQFLSHdll; +TRNPRPdll_POINTER TRNPRPdll; +TSFLSHdll_POINTER TSFLSHdll; +VIRBdll_POINTER VIRBdll; +VIRCdll_POINTER VIRCdll; +WMOLdll_POINTER WMOLdll; +XMASSdll_POINTER XMASSdll; +XMOLEdll_POINTER XMOLEdll; + +RMIX2dll_POINTER RMIX2dll; +RDXHMXdll_POINTER RDXHMXdll; +PHIXdll_POINTER PHIXdll; +PHI0dll_POINTER PHI0dll; +DQFL2dll_POINTER DQFL2dll; + +/* + * Helper function to split strings the + * Python way. Taken from CoolProp. + */ +std::vector strsplit(std::string s, char del) { + int iL = 0, iR = 0, N; + N = s.size(); + std::vector v; + // Find the first instance of the delimiter + iR = s.find_first_of(del); + // Delimiter not found, return the same string again + if (iR < 0) { + v.push_back(s); + return v; + } + while (iR != N-1) { + v.push_back(s.substr(iL,iR-iL)); + iL = iR; + iR = s.find_first_of(del,iR+1); + // Move the iL to the right to avoid the delimiter + iL += 1; + if (iR == (int)std::string::npos) { + v.push_back(s.substr(iL,N-iL)); + break; + } + } + return v; +} + +// http://stackoverflow.com/questions/11635/case-insensitive-string-comparison-in-c +bool strCompare(const std::string& str1, const std::string& str2) { + if (str1.size() != str2.size()) { + return false; + } + for (std::string::const_iterator c1 = str1.begin(), c2 = str2.begin(); c1 != str1.end(); ++c1, ++c2) { + if (tolower(*c1) != tolower(*c2)) { + return false; + } + } + return true; +} + + +void useSATSPLN(long lerr, char* errormsg) { + // need to check the composition if old . + if (lnc>1) { + if (dxkg[1]>0 && dxkg[1]<1) { + if (dx1kg_old!=dxkg[1]) { + SATSPLNdll(dxmol,lerr,errormsg,errormessagelength); + if (debug) { + printf("\n\n USING SATSPLN, because we have new composition\n\n"); + printf("dx1kg_old = %f\n", dx1kg_old); + printf("dxkg[1] = %f \n", dxkg[1]); + } + } + dx1kg_old=dxkg[1]; + } + } +} + + + +/* + * Just a helper function control the output of + * an array. Used to debug the handling of the + * composition arrays. + */ +std::string printX(double arr[], long nc) { + std::string ret = std::string("("); + int stop = nc-1; + char buffer [10]; + + for(int i = 0; i <= (stop); i++) { + sprintf(buffer, "%1.4f", arr[i]); // four decimals + ret.append(buffer); + } + ret.append(")"); + return ret; +} + +/* + * Resolves Refprop error numbers and returns meaningful error message + * INPUT: + * in1: character specifying input + * lerr: error as a long value + * OUTPUT + * errormsg: string containing error message + * std::string: the same as errormsg + */ +std::string resolve_error(std::string in1, long lerr, char* errormsg) { + switch(lerr){ + case 0: + strcpy(errormsg,"Calculation successful"); + break; + case 1: + sprintf(errormsg,"T=%f < Tmin",dt); + break; + case 2: + if (!in1.compare("p")){ + sprintf(errormsg,"P=%f < Ptp",dp); + } else if (!in1.compare("d")){ + sprintf(errormsg,"D=%f > Dmax",dd); + } else { + strcpy(errormsg,"unknown error"); + } + break; + case 4: + if (!in1.compare("p")){ + sprintf(errormsg,"P=%f < 0",dp); + } else { + strcpy(errormsg,"unknown error"); + } + break; + case 5: + sprintf(errormsg,"T=%f and p=%f out of range",dt,dp); + break; + case 8: + sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(dxmol,lnc).c_str()); + break; + case 9: + sprintf(errormsg,"x=%s or T=%f out of range",printX(dxmol,lnc).c_str(),dt); + break; + case 10: + strcpy(errormsg,"D and x out of range"); + break; + case 12: + sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(dxmol,lnc).c_str(),dp); + break; + case 13: + sprintf(errormsg,"x=%s, T=%f and p=%f out of range",printX(dxmol,lnc).c_str(),dt,dp); + break; + case 16: + strcpy(errormsg,"TPFLSH error: p>melting pressure"); + break; + case -31: + sprintf(errormsg,"Temperature T=%f out of range for conductivity",dt); + break; + case -32: + sprintf(errormsg,"density d=%f out of range for conductivity",dd); + break; + case -33: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",dt,dd); + break; + case -41: + sprintf(errormsg,"Temperature T=%f out of range for viscosity",dt); + break; + case -42: + sprintf(errormsg,"density d=%f out of range for viscosity",dd); + break; + case -43: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",dt,dd); + break; + case -51: + sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",dt); + break; + case -52: + sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",dd); + break; + case -53: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",dt,dd); + break; + case 39: + sprintf(errormsg,"model not found for thermal conductivity"); + break; + case 49: + sprintf(errormsg,"model not found for viscosity"); + break; + case 50: + sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); + break; + case 51: + sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",dt); + break; + case -58: + strcpy(errormsg,"unknown error"); + break; + case -59: + sprintf(errormsg,"ECS model did not converge"); + break; + case 101: + sprintf(errormsg,"error in opening fluid file"); + break; + case 102: + strcpy(errormsg,"error in file or premature end of file"); + break; + case -103: + strcpy(errormsg,"unknown model encountered in file"); + break; + case 104: + strcpy(errormsg,"error in setup of model"); + break; + case 105: + strcpy(errormsg,"specified model not found"); + break; + case 111: + strcpy(errormsg,"error in opening mixture file"); + break; + case 112: + strcpy(errormsg,"mixture file of wrong type"); + break; + case 114: + strcpy(errormsg,"nc<>nc from setmod"); + break; + case 120: + strcpy(errormsg,"CRITP did not converge"); + break; + case 121: + strcpy(errormsg,"T > Tcrit"); + break; + case 122: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 123: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 124: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -125: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -126: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -127: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 128: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 140: + strcpy(errormsg,"CRITP did not converge"); + break; + case 141: + strcpy(errormsg,"P > Pcrit"); + break; + case 142: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 143: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 144: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -144: + strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); + break; + case -145: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -146: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -147: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 148: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 160: + strcpy(errormsg,"CRITP did not converge"); + break; + case 161: + strcpy(errormsg,"SATD did not converge"); + break; + case 211: + sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); + break; + case 239: + sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + case 248: + sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",dd,ds); + break; + case 249: + sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + case 271: + sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",dt); + break; + case 291: + sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",dt); + break; + default: + strcpy(errormsg,"unknown error"); + break; + } + + if (debug) { + printf("Error code: %ld \n",lerr); + printf("Yields message: %s \n", errormsg); + } + return std::string(errormsg); +} + +/* + * Load the library and handle all the + * platform specific stuff. + */ +double loadLibrary(std::string sPath) { + if (RefpropdllInstance == NULL) { // Refprop is not loaded +#if defined(__ISWINDOWS__) +#if defined(UNICODE) + sPath.append((LPCWSTR)pathSep); + sPath.append((LPCWSTR)libName); + RefpropdllInstance = LoadLibraryW(sPath.c_str()); +#else + sPath.append((LPCSTR)pathSep); + sPath.append((LPCSTR)libName); + RefpropdllInstance = LoadLibrary(sPath.c_str()); +#endif +#elif defined(__ISLINUX__) + RefpropdllInstance = dlopen(libName, RTLD_LAZY); +#elif defined(__ISAPPLE__) + RefpropdllInstance = dlopen (libName, RTLD_LAZY); +#else + throw NotImplementedError("We should not reach this point."); + RefpropdllInstance = NULL; +#endif + + if (RefpropdllInstance == NULL) { // Still NULL after loading +#if defined(__ISWINDOWS__) + printf("Library problem: "); +#elif defined(__ISLINUX__) + fputs(dlerror(), stderr); +#elif defined(__ISAPPLE__) + fputs(dlerror(), stderr); +#else + throw NotImplementedError("You should not be here."); +#endif + printf("Could not load %s\n\n", libName); + return FAIL; + } + + if (debug) printf ("Library was loaded successfully.\n"); + return OK; + } else { // Refprop was already loaded + if (debug) printf ("Library was already loaded, doing nothing.\n"); + return OK; + } + return FAIL; +} + +/* + * Multiplatform pointer handling + * Not very neat, but works. + */ +void *getFunctionPointer(char * name) { +#if defined(__ISWINDOWS__) + return (void *) GetProcAddress(RefpropdllInstance,name); +#elif defined(__ISLINUX__) + return dlsym(RefpropdllInstance, name); +#else + throw NotImplementedError("This function should not be called."); + return NULL; +#endif +} + +/* + * Moved pointer handling to a function, helps to maintain + * an overview and structures OS dependent parts + */ +double setFunctionPointers() { +// if (RefpropdllInstance != NULL) { +// printf("You only need to define the pointers once, "); +// printf("please revise your code.\n"); +// return FAIL; +// } else { // set the pointers +// if (loadLibrary() != OK) { +// printf("Refprop library %s cannot be loaded, make sure you ",libName); +// printf("installed it properly.\n"); +// return FAIL; +// } + + if (RefpropdllInstance == NULL) { + printf("Refprop library %s is not loaded, make sure you ",libName); + printf("referenced and installed it properly.\n"); + return FAIL; + } else { // set the pointers + // set the pointers, platform independent + RPVersion = (RPVersion_POINTER) getFunctionPointer((char *) RPVersion_NAME); + + SATSPLNdll = (SATSPLNdll_POINTER) getFunctionPointer((char *) SATSPLNdll_NAME); + + ABFL1dll = (ABFL1dll_POINTER) getFunctionPointer((char *) ABFL1dll_NAME); + ABFL2dll = (ABFL2dll_POINTER) getFunctionPointer((char *) ABFL2dll_NAME); + ACTVYdll = (ACTVYdll_POINTER) getFunctionPointer((char *) ACTVYdll_NAME); + AGdll = (AGdll_POINTER) getFunctionPointer((char *) AGdll_NAME); + CCRITdll = (CCRITdll_POINTER) getFunctionPointer((char *) CCRITdll_NAME); + CP0dll = (CP0dll_POINTER) getFunctionPointer((char *) CP0dll_NAME); + CRITPdll = (CRITPdll_POINTER) getFunctionPointer((char *) CRITPdll_NAME); + CSATKdll = (CSATKdll_POINTER) getFunctionPointer((char *) CSATKdll_NAME); + CV2PKdll = (CV2PKdll_POINTER) getFunctionPointer((char *) CV2PKdll_NAME); + CVCPKdll = (CVCPKdll_POINTER) getFunctionPointer((char *) CVCPKdll_NAME); + CVCPdll = (CVCPdll_POINTER) getFunctionPointer((char *) CVCPdll_NAME); + DBDTdll = (DBDTdll_POINTER) getFunctionPointer((char *) DBDTdll_NAME); + DBFL1dll = (DBFL1dll_POINTER) getFunctionPointer((char *) DBFL1dll_NAME); + DBFL2dll = (DBFL2dll_POINTER) getFunctionPointer((char *) DBFL2dll_NAME); + DDDPdll = (DDDPdll_POINTER) getFunctionPointer((char *) DDDPdll_NAME); + DDDTdll = (DDDTdll_POINTER) getFunctionPointer((char *) DDDTdll_NAME); + DEFLSHdll = (DEFLSHdll_POINTER) getFunctionPointer((char *) DEFLSHdll_NAME); + DHD1dll = (DHD1dll_POINTER) getFunctionPointer((char *) DHD1dll_NAME); + DHFLSHdll = (DHFLSHdll_POINTER) getFunctionPointer((char *) DHFLSHdll_NAME); + DIELECdll = (DIELECdll_POINTER) getFunctionPointer((char *) DIELECdll_NAME); + DOTFILLdll = (DOTFILLdll_POINTER) getFunctionPointer((char *) DOTFILLdll_NAME); + DPDD2dll = (DPDD2dll_POINTER) getFunctionPointer((char *) DPDD2dll_NAME); + DPDDKdll = (DPDDKdll_POINTER) getFunctionPointer((char *) DPDDKdll_NAME); + DPDDdll = (DPDDdll_POINTER) getFunctionPointer((char *) DPDDdll_NAME); + DPDTKdll = (DPDTKdll_POINTER) getFunctionPointer((char *) DPDTKdll_NAME); + DPDTdll = (DPDTdll_POINTER) getFunctionPointer((char *) DPDTdll_NAME); + DPTSATKdll = (DPTSATKdll_POINTER) getFunctionPointer((char *) DPTSATKdll_NAME); + DSFLSHdll = (DSFLSHdll_POINTER) getFunctionPointer((char *) DSFLSHdll_NAME); + ENTHALdll = (ENTHALdll_POINTER) getFunctionPointer((char *) ENTHALdll_NAME); + ENTROdll = (ENTROdll_POINTER) getFunctionPointer((char *) ENTROdll_NAME); + ESFLSHdll = (ESFLSHdll_POINTER) getFunctionPointer((char *) ESFLSHdll_NAME); + FGCTYdll = (FGCTYdll_POINTER) getFunctionPointer((char *) FGCTYdll_NAME); + FPVdll = (FPVdll_POINTER) getFunctionPointer((char *) FPVdll_NAME); + GERG04dll = (GERG04dll_POINTER) getFunctionPointer((char *) GERG04dll_NAME); + GETFIJdll = (GETFIJdll_POINTER) getFunctionPointer((char *) GETFIJdll_NAME); + GETKTVdll = (GETKTVdll_POINTER) getFunctionPointer((char *) GETKTVdll_NAME); + GIBBSdll = (GIBBSdll_POINTER) getFunctionPointer((char *) GIBBSdll_NAME); + HSFLSHdll = (HSFLSHdll_POINTER) getFunctionPointer((char *) HSFLSHdll_NAME); + INFOdll = (INFOdll_POINTER) getFunctionPointer((char *) INFOdll_NAME); + LIMITKdll = (LIMITKdll_POINTER) getFunctionPointer((char *) LIMITKdll_NAME); + LIMITSdll = (LIMITSdll_POINTER) getFunctionPointer((char *) LIMITSdll_NAME); + LIMITXdll = (LIMITXdll_POINTER) getFunctionPointer((char *) LIMITXdll_NAME); + MELTPdll = (MELTPdll_POINTER) getFunctionPointer((char *) MELTPdll_NAME); + MELTTdll = (MELTTdll_POINTER) getFunctionPointer((char *) MELTTdll_NAME); + MLTH2Odll = (MLTH2Odll_POINTER) getFunctionPointer((char *) MLTH2Odll_NAME); + NAMEdll = (NAMEdll_POINTER) getFunctionPointer((char *) NAMEdll_NAME); + PDFL1dll = (PDFL1dll_POINTER) getFunctionPointer((char *) PDFL1dll_NAME); + PDFLSHdll = (PDFLSHdll_POINTER) getFunctionPointer((char *) PDFLSHdll_NAME); + PEFLSHdll = (PEFLSHdll_POINTER) getFunctionPointer((char *) PEFLSHdll_NAME); + PHFL1dll = (PHFL1dll_POINTER) getFunctionPointer((char *) PHFL1dll_NAME); + PHFLSHdll = (PHFLSHdll_POINTER) getFunctionPointer((char *) PHFLSHdll_NAME); + PQFLSHdll = (PQFLSHdll_POINTER) getFunctionPointer((char *) PQFLSHdll_NAME); + PREOSdll = (PREOSdll_POINTER) getFunctionPointer((char *) PREOSdll_NAME); + PRESSdll = (PRESSdll_POINTER) getFunctionPointer((char *) PRESSdll_NAME); + PSFL1dll = (PSFL1dll_POINTER) getFunctionPointer((char *) PSFL1dll_NAME); + PSFLSHdll = (PSFLSHdll_POINTER) getFunctionPointer((char *) PSFLSHdll_NAME); + PUREFLDdll = (PUREFLDdll_POINTER) getFunctionPointer((char *) PUREFLDdll_NAME); + RESIDUALdll = (RESIDUALdll_POINTER) getFunctionPointer((char *) RESIDUALdll_NAME); + QMASSdll = (QMASSdll_POINTER) getFunctionPointer((char *) QMASSdll_NAME); + QMOLEdll = (QMOLEdll_POINTER) getFunctionPointer((char *) QMOLEdll_NAME); + SATDdll = (SATDdll_POINTER) getFunctionPointer((char *) SATDdll_NAME); + SATEdll = (SATEdll_POINTER) getFunctionPointer((char *) SATEdll_NAME); + SATHdll = (SATHdll_POINTER) getFunctionPointer((char *) SATHdll_NAME); + SATPdll = (SATPdll_POINTER) getFunctionPointer((char *) SATPdll_NAME); + SATSdll = (SATSdll_POINTER) getFunctionPointer((char *) SATSdll_NAME); + SATTdll = (SATTdll_POINTER) getFunctionPointer((char *) SATTdll_NAME); + SETAGAdll = (SETAGAdll_POINTER) getFunctionPointer((char *) SETAGAdll_NAME); + SETKTVdll = (SETKTVdll_POINTER) getFunctionPointer((char *) SETKTVdll_NAME); + SETMIXdll = (SETMIXdll_POINTER) getFunctionPointer((char *) SETMIXdll_NAME); + SETMODdll = (SETMODdll_POINTER) getFunctionPointer((char *) SETMODdll_NAME); + SETREFdll = (SETREFdll_POINTER) getFunctionPointer((char *) SETREFdll_NAME); + SETUPdll = (SETUPdll_POINTER) getFunctionPointer((char *) SETUPdll_NAME); +// SPECGRdll = (SPECGRdll_POINTER) getFunctionPointer((char *)SPECGRdll_NAME); // not in library + SUBLPdll = (SUBLPdll_POINTER) getFunctionPointer((char *) SUBLPdll_NAME); + SUBLTdll = (SUBLTdll_POINTER) getFunctionPointer((char *) SUBLTdll_NAME); + SURFTdll = (SURFTdll_POINTER) getFunctionPointer((char *) SURFTdll_NAME); + SURTENdll = (SURTENdll_POINTER) getFunctionPointer((char *) SURTENdll_NAME); + TDFLSHdll = (TDFLSHdll_POINTER) getFunctionPointer((char *) TDFLSHdll_NAME); + TEFLSHdll = (TEFLSHdll_POINTER) getFunctionPointer((char *) TEFLSHdll_NAME); + THERM0dll = (THERM0dll_POINTER) getFunctionPointer((char *) THERM0dll_NAME); + THERM2dll = (THERM2dll_POINTER) getFunctionPointer((char *) THERM2dll_NAME); + THERM3dll = (THERM3dll_POINTER) getFunctionPointer((char *) THERM3dll_NAME); + THERMdll = (THERMdll_POINTER) getFunctionPointer((char *) THERMdll_NAME); + THFLSHdll = (THFLSHdll_POINTER) getFunctionPointer((char *) THFLSHdll_NAME); + TPFLSHdll = (TPFLSHdll_POINTER) getFunctionPointer((char *) TPFLSHdll_NAME); + TPRHOdll = (TPRHOdll_POINTER) getFunctionPointer((char *) TPRHOdll_NAME); + TQFLSHdll = (TQFLSHdll_POINTER) getFunctionPointer((char *) TQFLSHdll_NAME); + TRNPRPdll = (TRNPRPdll_POINTER) getFunctionPointer((char *) TRNPRPdll_NAME); + TSFLSHdll = (TSFLSHdll_POINTER) getFunctionPointer((char *) TSFLSHdll_NAME); + VIRBdll = (VIRBdll_POINTER) getFunctionPointer((char *) VIRBdll_NAME); + VIRCdll = (VIRCdll_POINTER) getFunctionPointer((char *) VIRCdll_NAME); + WMOLdll = (WMOLdll_POINTER) getFunctionPointer((char *) WMOLdll_NAME); + XMASSdll = (XMASSdll_POINTER) getFunctionPointer((char *) XMASSdll_NAME); + XMOLEdll = (XMOLEdll_POINTER) getFunctionPointer((char *) XMOLEdll_NAME); + + RMIX2dll = (RMIX2dll_POINTER) getFunctionPointer((char *) RMIX2dll_NAME); + RDXHMXdll = (RDXHMXdll_POINTER) getFunctionPointer((char *) RDXHMXdll_NAME); + PHIXdll = (PHIXdll_POINTER) getFunctionPointer((char *) PHIXdll_NAME); + PHI0dll = (PHI0dll_POINTER) getFunctionPointer((char *) PHI0dll_NAME); + DQFL2dll = (DQFL2dll_POINTER) getFunctionPointer((char *) DQFL2dll_NAME); + + + if (debug) printf ("Function pointers set to macro values.\n"); + return OK; + } + return FAIL; +} + +/* + * Make sure the library is loaded + * properly and set pointers. + */ +double initRefprop(std::string sPath) { + + //std::string rPath = std::string(sPath); + + if (RefpropdllInstance == NULL) { + if (debug) printf ("Library not loaded, trying to do so.\n"); + if (loadLibrary(sPath) != OK) { + printf("Refprop library %s cannot be loaded, make sure you ",libName); + printf("installed it properly.\n"); + return FAIL; + } + if (setFunctionPointers() != OK) { + printf("There was an error setting the REFPROP function pointers, "); + printf("check types and names in header file.\n"); + return FAIL; + } + // Set the desired equation of state, consult the Refprop + // documentation for more details. + // 0 : use default values + // 2 : force Peng-Robinson + long eosSwitch = 0; + PREOSdll(eosSwitch); + return OK; + } else { + if (debug) printf ("Library loaded, not doing anything.\n"); + return OK; + } + return FAIL; +} + +/* + * Construct the fluid string with the full path + * from the simple names, needed for Linux version. + * Call setupdll if necessary to define the fluid + * or mixture for subsequent calls to flash routines. + */ +double setFluids(std::string sPath, std::string sFluids, char* error){ + // sPath: "/opt/refprop" or "C:\Program Files\Refprop" + // sFluids: "pentane|butane" or "air" + + //std::string rPath = std::string(sPath); + + if (initRefprop(sPath) != OK){ + std::cerr << "ERROR: library not loaded.\n"; + std::terminate(); + } + + long ierr=999; + char hf[refpropcharlength*ncmax]; + + std::string RefString; + std::string fdPath = std::string(sPath); + fdPath.append((char *)pathSep); + fdPath.append("fluids"); + fdPath.append((char *)pathSep); + + if (loadedFluids.compare(sFluids)) { // The fluid is not already loaded + std::vector components_split = strsplit(sFluids,'|');// Split into components + RefString.clear(); // Flush out fluid string + + // Build new fluid string + for (unsigned int j=0;jncmax){ + sprintf(error,"Too many components (More than %i)\n",ncmax); + return FAIL; + } + + // Prepare strings and call SETUP to initialise the program + strcpy(hf,RefString.c_str()); + char* hfm = (char*) calloc(refpropcharlength+8, sizeof(char)); + strcpy(hfm,fdPath.c_str()); + strcat(hfm,hfmix); + + //...Call SETUPdll to set the fluids + if (debug) { + printf ("Running SETUP...\n"); + printf ("No. of components: %li \n", lnc); + printf ("Fluid files: %s \n", RefString.c_str()); + printf ("Mixture file: %s \n", hfmix); + } + + SETUPdll(lnc, hf, hfm, hrf, ierr, error, + refpropcharlength*ncmax,refpropcharlength, + lengthofreference,errormessagelength); + free (hfm); + + if (ierr != 0) { + printf("REFPROP setup gives this error during SETUP:\n %s\n",error); + printf("Further information:\n %s\n",resolve_error("",ierr,error).c_str()); + return FAIL; + } else { //Copy the name of the loaded fluid + loadedFluids = std::string(sFluids); + int flush = flushConstants(); + if (debug) printf("Loading a new fluid, flushing constants: %i.\n",flush); + return OK; + } + } // Fluid was already loaded + if (debug) printf("Fluid was already loaded.\n"); + return OK; +} + + +bool isInput(std::string in1, std::string in2, std::string def){ + // if the first equals the first + if ( strCompare(in1, def.substr(0,1)) ) { + if ( strCompare(in2, def.substr(1,1)) ) return true; + } else if ( strCompare(in2, def.substr(0,1)) ) { + if ( strCompare(in1, def.substr(1,1)) ) return true; + } + return false; +} + +double getT_refprop(double t) { + // t--temperature [K] + return t*1.; +} + +double getP_refprop(double p) { + // p--pressure [kPa] + return p/1000.0; +} + +double getD_refprop(double d) { + // d--bulk molar density [mol/L] + return d/dwm; // kg/m3 = g/l / g/mol = mol/l +} + +double getE_refprop(double e) { + // e--internal energy [J/mol] + return e*dwm/1000.; // J/kg * g/mol * kg/(1000g) = J/mol +} + +double getH_refprop(double h) { + // h--enthalpy [J/mol] + return h*dwm/1000.; // J/kg * g/mol * kg/(1000g) = J/mol +} + +double getS_refprop(double s) { + // s--entropy [[J/mol-K] + return s*dwm/1000.; // J/(kg.K) * g/mol * kg/(1000g) = J/(mol.K) +} + +/* + * Convert to SI units + */ +double getT_modelica() { + // t--temperature [K] + return dt; +} + +double getP_modelica() { + // p--pressure [kPa] + return dp*1000.0; +} + +double getD_modelica() { + // d--bulk molar density [mol/L] + return dd*dwm; // mol/l * g/mol = g/l = kg/m3 +} + +double getE_modelica() { + // e--internal energy [J/mol] + return de/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} + +double getH_modelica() { + // h--enthalpy [J/mol] + return dh/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} + +double getS_modelica() { + // s--entropy [[J/mol-K] + return ds/dwm * 1000.0; // J/(mol.K) / g/mol * 1000g/kg = J/(kg.K) +} + +double getWM_modelica(){ + //molecular weight + return dwm/1000; // g/mol to kg/mol +} + +double getDL_modelica(){ + //density of liquid phase + return ddl*dwliq; // mol/l * g/mol = g/l = kg/m3 +} + +double getDV_modelica(){ + //density of gaseous phase + return ddv*dwvap; // mol/l * g/mol = g/l = kg/m3 +} +double getHL_modelica(){ + //density of liquid phase + return dhl/dwliq * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} + +double getHV_modelica(){ + //density of gaseous phase + return dhv/dwvap * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} +double getSL_modelica(){ + //density of liquid phase + return dsl/dwliq * 1000.0; // J/molK / g/mol * 1000g/kg = J/kgK +} + +double getSV_modelica(){ + //density of gaseous phase + return dsv/dwvap * 1000.0; // J/molK / g/mol * 1000g/kg = J/kgK +} + +double getQ_modelica(){ + if (lnc>1 && abs(dqmol)<990) { // maintain special values + if (dwvap==noValue) WMOLdll(dxmolv,dwvap); + return dqmol*dwvap/dwm; // TODO can you show a case where this function is called more than once? + } else { + return dqmol; + } +} + + +double getCV_modelica(){ + return dCv/dwm * 1000.0; +} + +double getCP_modelica(){ + return dCp/dwm * 1000.0; +} + +double getW_modelica(){ + //speed of sound + return dw; +} + +double getWML_modelica(){ + if (dwliq==noValue) WMOLdll(dxmoll,dwliq); + return dwliq/1000.; +} + +double getWMV_modelica(){ + if (dwvap==noValue) WMOLdll(dxmolv,dwvap); + return dwvap/1000.; +} + +//double* getXL_modelica(){ +// double dxlkg[ncmax]; +// XMASSdll(dxmoll,dxlkg,dwliq); +// return dxlkg; +//} +// +//double* getXV_modelica(){ +// double dxvkg[ncmax]; +// XMASSdll(dxmolv,dxvkg,dwvap); +// return dxvkg; +//} + +double getETA_modelica(){ + return deta/1e6; +} + +double getTCX_modelica(){ + return dtcx; +} + +double getHJT_modelica() { // isenthalpic Joule-Thompson coefficient [K/kPa]/1000Pa*kPa = K/Pa + return dhjt/1000; +} +//double* getZ_modelica() { // compressibility factor (= PV/RT) [dimensionless] +// return dZ; +//} +double getA_modelica() { // Helmholtz energy [J/mol] + return dA/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} +double getG_modelica() { // Gibbs free energy [J/mol] + return dG/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} +double getXKAPPA_modelica() { // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/kPa] /1000Pa*kPa = 1/Pa + return dxkappa / 1000. ; +} +double getBETA_modelica() { // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] + return dbeta; +} +/* +double getDPDD_modelica() { // derivative dP/drho [kPa-L/mol] * 1000Pa/kPa * mol/g = Pa.m3 / kg + return ddpdd * 1000. / dwm; +} +double getD2PDD2_modelica() { // derivative d^2P/drho^2 [kPa-L^2/mol^2] * 1000Pa/kPa * mol/g * mol/g = Pa m6 / kg2 + return dd2pdd2 * 1000. / dwm / dwm; +} +double getDPDT_modelica() { // derivative dP/dT [kPa/K] * 1000Pa/kPa = Pa/K + return ddpdt * 1000.; +} +double getDDDT_modelica() { // derivative drho/dT [mol/(L-K)] * g/mol = kg/m3 / K + return ddddt * dwm; +} +double getDDDP_modelica() { // derivative drho/dP [mol/(L-kPa)] + return ddddp*dwm/1000.; // mol/(l.kPa) * g/mol * 1kPa/1000Pa = kg/(m3.Pa) +} +double getD2PDT2_modelica() { // derivative d2P/dT2 [kPa/K^2] * 1000Pa/kPa = Pa/K2 + return dd2pdt2 * 1000.; +} +double getD2PDTD_modelica() { // derivative d2P/dTd(rho) [J/mol-K] / g/mol * 1000g/kg = J/kg.K + return dd2pdtd/dwm*1000.; +} +*/ +/* +double get_dhdt_d_modelica() { //dH/dT at constant density [J/(mol-K)] / g/mol * 1000g/kg = J/kg.K + return noValue;//ddhdt_d/dwm*1000; +} +double get_dhdt_p_modelica() { //dH/dT at constant pressure [J/(mol-K)] + return noValue;//ddhdt_p/dwm*1000; +} +double get_dhdd_t_modelica() { //dH/drho at constant temperature [(J/mol)/(mol/L)] * mol/g * 1000g/kg / g/mol = (J/kg) / (kg/m3) + return noValue;//ddhdd_t /dwm*1000. / dwm; +} +double get_dhdd_p_modelica() { //dH/drho at constant pressure [(J/mol)/(mol/L)] + return noValue;//ddhdd_p /dwm*1000. / dwm; +} +double get_dhdp_t_modelica() { //dH/dP at constant temperature [J/(mol-kPa)] /dwm*1000. / (1000Pa/kPa) = J/kg.Pa + return noValue;//ddhdp_t / dwm; +} +double get_dhdp_d_modelica() { //dH/dP at constant density [J/(mol-kPa)] + return noValue;//ddhdp_d / dwm; +} +*/ + +// Derivatives +// Derivative of density with respect to enthalpy at constant pressure +double get_dddX_ph_modelica(){ +// double dxmoltmp[ncmax],dwm1; +// dxmoltmp[0]=1; +// dxmoltmp[1]=0; +// WMOLdll(dxmoltmp,dwm1); // TODO this must be molecular weight of species 1 instead of vap... Take a look at how ddddX_pt is computed!!! + return ddddX_ph;//*dwm*dwm/dwm1; // [mol/l * mol/mol1] * g/mol * g/mol * mol1/g1 * 1e-3kg/g / 1e-3 m3/L = kg/m3 * g/gi +} +double get_dddh_p_modelica(){ + return ddddh_p*dwm*dwm/1000.; // [mol/l * mol/J] * g/mol * g/mol * 1e-3kg/g * 1e-3kg/g / 1e-3 m3/L = kg/m3 * kg/J +} +// Derivative of density with respect to pressure at constant enthalpy +double get_dddp_h_modelica(){ + return ddddp_h*dwm/1000; // [mol/l * 1/kPa) * g/mol * 1e-3kg/g / 1e-3 m3/L / 1e-3 kPa/Pa = kg/(m3.Pa) +} + + +/* + * Checks if the provided variables match the currently active + * state. Needs the current values of the state properties as + * well as the new ones. Additionally, the mole based composition + * has to be provided with the number of components. + * Changing the amount of components or the fluids itself should + * be covered by the flushing routines above. + */ +bool isState(double var1, double val1, double var2, double val2, double xmol[], long nc){ + if (debug) printf ("\nChecking state.\n"); + if (var1!=val1) return false; + if (var2!=val2) return false; + //if (lnc!=nc) return false; + // If we have a mixture, we need to check the composition. + if (nc>1) { + for ( int i = 0; i < nc; i++ ) { + if (dxmol[i]!=xmol[i]) return false; + } + } + if (debug) printf ("Going to return \"true\".\n"); + return true; +} + + +double getValue(std::string out) { + + if (debug) printf("\nChecking for %s \n",out.c_str()); + + if ( strCompare(out, "p") ) { + if (dp!=noValue) return getP_modelica(); + } else if ( strCompare(out, "t") ) { + if (dt!=noValue) return getT_modelica(); + } else if ( strCompare(out, "m") ) { + if (dwm!=noValue) return getWM_modelica(); + } else if ( strCompare(out, "d") ) { + if (dd!=noValue) return getD_modelica(); + } else if ( strCompare(out, "e") ) { + if (de!=noValue) return getE_modelica(); + } else if ( strCompare(out, "h") ) { + if (dh!=noValue) return getH_modelica(); + } else if ( strCompare(out, "s") ) { + if (ds!=noValue) return getS_modelica(); + } else if ( strCompare(out, "w") ) { + if (dw!=noValue) return getW_modelica(); + } else if ( strCompare(out, "v") ) { + if (deta!=noValue) return getETA_modelica(); + } else if ( strCompare(out, "l") ) { + if (dtcx!=noValue) return getTCX_modelica(); + } + return noValue; +} + + + +int updateDers(double *ders, long lerr){ + //ASSIGN VALUES TO RETURN ARRAY +/* ders[0] = lerr;//error code + ders[1] = getHJT_modelica(); // isenthalpic Joule-Thompson coefficient [K/Pa] + ders[2] = getA_modelica(); // Helmholtz energy [J/kg] + ders[3] = getG_modelica(); // Gibbs free energy [J/kg] + ders[4] = getXKAPPA_modelica(); // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/Pa] + ders[5] = getBETA_modelica(); // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] + ders[6] = getDPDD_modelica(); // derivative dP/drho [Pa-m3/kg] + ders[7] = getD2PDD2_modelica(); // derivative d^2P/drho^2 [Pa-m6/kg2] + ders[8] = getDPDT_modelica(); // derivative dP/dT [Pa/K] + ders[9] = getDDDT_modelica(); // derivative drho/dT [kg/(m3-K)] + ders[10] = getDDDP_modelica(); // derivative drho/dP [kg/(m3-kPa)] + ders[11] = getD2PDT2_modelica(); // derivative d2P/dT2 [Pa/K2] + ders[12] = getD2PDTD_modelica(); // derivative d2P/dTd(rho) [J/kg-K] + ders[13] = get_dhdt_d_modelica(); // dH/dT at constant density [J/(kg-K)] + ders[14] = get_dhdt_p_modelica(); // dH/dT at constant pressure [J/(kg-K)] + ders[15] = get_dhdd_t_modelica(); // dH/drho at constant temperature [(J/kg) / (kg/m3)] + ders[16] = get_dhdd_p_modelica(); // dH/drho at constant pressure [(J/kg) / (kg/m3)] + ders[17] = get_dhdp_t_modelica(); // dH/dP at constant temperature [J/(kg-Pa)] + ders[18] = get_dhdp_d_modelica(); // dH/dP at constant density [J/(kg-Pa)] + ders[19] = get_dddh_p_modelica(); // dD/dh at constant pressure [kg/m3 * kg/J] + ders[20] = get_dddp_h_modelica(); // dD/dp at constant enthalpy [kg/(m3.Pa)] +*/ + // TODO - I have reduced the variables thrown back.. Why us jtc, a, g derivatives here? + ders[0] = lerr;//error code + ders[1] = getXKAPPA_modelica(); // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/Pa] + ders[2] = getBETA_modelica(); // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] + ders[3] = get_dddX_ph_modelica(); // dD/dX at constant p,h + ders[4] = get_dddh_p_modelica(); // dD/dh at constant pressure [kg/m3 * kg/J] + ders[5] = get_dddp_h_modelica(); // dD/dp at constant enthalpy [kg/(m3.Pa)] + + ders[6] = ddddp_T*dwm/1000; // (mol/L * 1/kPa) * g/mol / 1000 g/kg * 1000L/m3 / 1000 Pa/kPa + ders[7] = ddddT_p*dwm; // (mol/L * 1/K) * g/mol / 1000 g/kg * 1000L/m3 + ders[8] = ddddX_pT;// Done in function *dwm*dwm/dw1; // [mol/l * mol/molvap] * g/mol * g/mol * moli/gi * 1e-3kg/g / 1e-3 m3/L = kg/m3 * g/gi + ders[9] = ddhdp_T/dwm; // (J/mol * 1/kPa) / g/mol * 1000 g/kg / 1000 Pa/kPa + ders[10] = ddhdT_p/dwm*1000; // (J/mol * 1/K) / g/mol * 1000 g/kg + ders[11] = ddhdX_pT;// Done in function /dwm*1000*dwm/dw1; // (J/mol * mol/molvap) / g/mol * 1000 g/kg * g/mol * molvap/gvap = J/kg * g/gvap + + return 0; +} + +int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ + debug = false; + if (DEBUGMODE) debug = true; + long lerr = 0; + + double spare3,spare4,spare5,spare6,spare7,spare8,spare9,spare10,spare2[ncmax],spare1[ncmax]; + double spare11,spare12,spare13,spare14,spare15,spare16,spare17,spare19,spare18,spare20,spare21; + + if ((dd!=noValue)&&(dt!=noValue)) { + // THERM2dll(dt, dd, dxmol, spare5, spare6, spare9, spare10, dCv, dCp, dw,dZ, dhjt, dA, dG, dxkappa, dbeta, ddpdd, dd2pdd2, ddpdt, ddddt,ddddp, dd2pdt2, dd2pdtd, spare3, spare4); + // we want to get props depending on quality below.. + + if (PartialDersInputChoice==4) { // use TPX numeric derivs + + if (dqmol < 0. || dqmol > 1.) { // single-phase region + if (debug) printf ("Using single-phase derivatives.\n"); + if (debug) printf("Calling THERM3 with T=%f and rho=%f.\n",dt,dd); + THERM3dll (dt,dd,dxmol,dxkappa,dbeta,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12); + + // analytical derivatives of density: + ddddT_p = -dbeta*dd; + ddddp_T = dxkappa*dd; + + // analytical derivatives of enthalpy: + ddhdT_p = dCp; + ddhdp_T = (1-dt*dbeta)/dd; + + + // numerical derivatives wrt. independent mass fraction, + // NOTE THAT IT IS DIFFICULT TO CHANGE FROM MOLE TO MASS BASIS, WHEN PERFORMING A NUMERICAL DERIVATIVE wrt composition. I DID NOT SUCCEED + double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew; + double dnew,hnew; + //XMASSdll(dxmol,dxkgnew,dwmnew); + dxkgnew[0] = dxkg[0]+1e-7; + dxkgnew[1] = dxkg[1]-1e-7; + XMOLEdll(dxkgnew,dxmolnew,dwmnew); + TPFLSHdll(dt,dp,dxmolnew,dnew,spare3,spare4,spare1,spare2,spare5,spare6,hnew,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + ddddX_pT = (dnew*dwmnew-dd*dwm)/1e-7; // this is on mass basis, due to the above mass change + ddhdX_pT = (hnew/dwmnew*1000-dh/dwm*1000)/1e-7; // this is on mass basis, due to the above mass change + + +// double n; +// double href[ncmax],dpdz_tv[ncmax],dhdz_tv[ncmax]; +// href[0] = 28945.714499977374; // ammoniaL +// href[1] = 45957.1914944204584; // water +// +// double delx=1e-7,delx2,R,dxmoln,dxmolp,t0,d0,tau,delta,phi01,phi10,phig10,pn,hn,pp,hp; +// long im1=-1, i0=0, ip1=1; +// int i; +// +// for (n = 0; n < lnc; n++) { +// //double n=1;// derivative wrt component n +// +// for (i = 0; i < lnc; i++) { +// dxmoln[i] = dxmol[i]; +// dxmolp[i] = dxmol[i]; +// } +// dxmoln[n-1] = dxmoln[n-1] - delx; +// dxmolp[n-1] = dxmolp[n-1] + delx; +// +// // negative increment +// RMIX2dll(dxmol, R); // R must be constant for some reason? +// RDXHMXdll(&im1,&i0,&i0,dxmoln,t0,d0,lerr,errormsg,errormessagelength); +// tau = t0 / dt; +// delta =dd / d0; +// PHIXdll(&i0,&ip1, tau, delta, dxmoln, phi01); +// PHIXdll(&ip1,&i0, tau, delta, dxmoln, phi10); +// PHI0dll(&ip1, &i0, dt, dd, dxmoln, phig10); +// pn = dd * R * dt * (1 + phi01); +// //hrn = R * t * (1 + phi10 + phi01); +// hn = R * dt * (1 + phig10 + phi10 + phi01) + dxmoln[0]*href[0] + dxmoln[1]*href[1];; +// +// // positive increment +// //RMIX2dll(dxmol, R); // R must be constant for some reason? +// RDXHMXdll(&im1,&i0,&i0,dxmolp,t0,d0,lerr,errormsg,errormessagelength); +// tau = t0 / dt; +// delta =dd / d0; +// PHIXdll(&i0,&ip1, tau, delta, dxmolp, phi01); +// PHIXdll(&ip1,&i0, tau, delta, dxmolp, phi10); +// PHI0dll(&ip1, &i0, dt, dd, dxmolp, phig10); +// pp = dd * R * dt * (1 + phi01); +// //hrp = R * t * (1 + phi10 + phi01); +// hp = R * dt * (1 + phig10 + phi10 + phi01) + dxmolp[0]*href[0] + dxmolp[1]*href[1];; +// +// // derivatives.. +// dpdz_tv[n-1] = (pp - pn) / delx2; +// //dhrdxi1 = (hrp - hrn) / delx2; +// dhdz_tv[n-1] = (hp - hn) / delx2; +// } + + + + } else { // two-phase region, get derivative of density + + // numerical derivative wrt. Temperature: + double dnew,hnew,dtnew; + dtnew=dt+1e-4; + TPFLSHdll(dtnew,dp,dxmol,dnew,spare3,spare4,spare1,spare2,spare5,spare6,hnew,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + ddddT_p = (dnew-dd)/1e-4; + ddhdT_p = (hnew-dh)/1e-4; + + // numerical derivative wrt. Pressure: + double dpnew=dp+1e-3; // this is a change in 1 Pa + TPFLSHdll(dt,dpnew,dxmol,dnew,spare3,spare4,spare1,spare2,spare5,spare6,hnew,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + ddddp_T = (dnew-dd)/1e-3; // /1; + ddhdp_T = (hnew-dh)/1e-3; // /1; + + // numerical derivative for independent mass fraction + /* NOTE THAT IT IS DIFFICULT TO CHANGE FROM MOLE TO MASS BASIS, WHEN PERFORMING A NUMERICAL DERIVATIVE wrt composition. I DID NOT SUCCEED */ + double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew; + //XMASSdll(dxmol,dxkgnew,dwmnew); + dxkgnew[0] = dxkg[0]+1e-7; + dxkgnew[1] = dxkg[1]-1e-7; + XMOLEdll(dxkgnew,dxmolnew,dwmnew); + TPFLSHdll(dt,dp,dxmolnew,dnew,spare3,spare4,spare1,spare2,spare5,spare6,hnew,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + ddddX_pT = (dnew*dwmnew-dd*dwm)/1e-7; // this is on mass basis, due to the above mass change + ddhdX_pT = (hnew/dwmnew*1000-dh/dwm*1000)/1e-7; // this is on mass basis, due to the above mass change + + } + + } else { + + if (dqmol < 0. || dqmol > 1.) { // single-phase region + if (debug) printf ("Using single-phase derivatives.\n"); + + if (debug) printf("Calling THERM3 with T=%f and rho=%f.\n",dt,dd); + THERM3dll (dt,dd,dxmol,dxkappa,dbeta,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12); + + // analytical derivatives + ddddp_h = (-dt*dbeta*dbeta + dbeta + dxkappa*dd*dCp)/dCp; + ddddh_p = -dbeta*dd/dCp; + + //using PHFLSH to get numerical derivative ddddX_ph + double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew, dnew; +// XMASSdll(dxmol,dxkg,dwmnew); + dxkgnew[0] = dxkg[0]+1e-7; + dxkgnew[1] = dxkg[1]-1e-7; + XMOLEdll(dxkgnew,dxmolnew,dwmnew); + double dhin = dh*dwmnew/dwm; // this is needed because h in mass basis is constant.. + PHFLSHdll(dp,dhin,dxmolnew,spare14,dnew,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + ddddX_ph = (dnew*dwmnew-dd*dwm)/1e-7; // mass basis + + +// // numerical derivative for ddddzi +// +// double dpdT_zv,dpdv_Tz,dhdT_vz,dhdv_Tz; +// dpdT_zv = dbeta/dxkappa; +// dpdv_Tz= -dd/dxkappa; +// dhdT_vz = dCv+dbeta/(dd*dxkappa); +// dhdv_Tz = (dt*dbeta/dxkappa - 1/dxkappa); +// +///* +// double href[ncmax],dpdz_tv[ncmax],dhdz_tv[ncmax],dvdz_ph[ncmax],ddddX_ph_tmp[ncmax]; +// //href[0] = 28945.714499977374; // ammoniaL +// //href[1] = 45957.1914944204584; // water +// +// href[0] = 8295.6883966232; //methane +// +// href[1] = 14873.1879732343; //ethane +// +// double delx=1e-7,delx2,R,dxmoln[ncmax],dxmolp[ncmax],t0,d0,tau,delta,phi01,phi10,phig10,pn,hn,pp,hp; +// long im1=-1, i0=0, ip1=1; +// delx2=delx*2; +// +// for (int n = 1; n < lnc+1; n++) { +// //double n=1;// derivative wrt component n +// +// for (int i = 0; i < lnc; i++) { +// dxmoln[i] = dxmol[i]; +// dxmolp[i] = dxmol[i]; +// } +// dxmoln[n-1] = dxmoln[n-1] - delx; +// dxmolp[n-1] = dxmolp[n-1] + delx; +// +// // negative increment +// RMIX2dll(dxmol, R); // R must be constant for some reason? +// RDXHMXdll(&im1,&i0,&i0,dxmoln,t0,d0,lerr,errormsg,errormessagelength); +// tau = t0 / dt; +// delta =dd / d0; +// PHIXdll(&i0,&ip1, tau, delta, dxmoln, phi01); +// PHIXdll(&ip1,&i0, tau, delta, dxmoln, phi10); +// PHI0dll(&ip1, &i0, dt, dd, dxmoln, phig10); +// pn = dd * R * dt * (1 + phi01); +// //hrn = R * t * (1 + phi10 + phi01); +// hn = R * dt * (1 + phig10 + phi10 + phi01) + dxmoln[0]*href[0] + dxmoln[1]*href[1];; +// +// // positive increment +// //RMIX2dll(dxmol, R); // R must be constant for some reason? +// RDXHMXdll(&im1,&i0,&i0,dxmolp,t0,d0,lerr,errormsg,errormessagelength); +// tau = t0 / dt; +// delta =dd / d0; +// PHIXdll(&i0,&ip1, tau, delta, dxmolp, phi01); +// PHIXdll(&ip1,&i0, tau, delta, dxmolp, phi10); +// PHI0dll(&ip1, &i0, dt, dd, dxmolp, phig10); +// pp = dd * R * dt * (1 + phi01); +// //hrp = R * t * (1 + phi10 + phi01); +// hp = R * dt * (1 + phig10 + phi10 + phi01) + dxmolp[0]*href[0] + dxmolp[1]*href[1];; +// +// // numerical derivatives.. +// dpdz_tv[n-1] = (pp - pn) / delx2; +// dhdz_tv[n-1] = (hp - hn) / delx2; +// +// // expression from jacobian matrix transformation +// dvdz_ph[n-1] = (dpdT_zv*dhdz_tv[n-1] - dhdT_vz*dpdz_tv[n-1]) / (dpdT_zv*dhdv_Tz - dhdT_vz*dpdv_Tz); +// ddddX_ph_tmp[n-1] = -dd*dd*dvdz_ph[n-1]; // this is still in refprop units, so X is moli/moltot.. +// +// } +// +// //printf("dhdz_tv[0] = %f\n",dhdz_tv[0]); +// //printf("dhdz_tv[1] = %f\n",dhdz_tv[1]); +// +// double dxmolnew[ncmax],dwmnew[ncmax]; +// dxmolnew[0] =1; +// dxmolnew[1] =0; +// WMOLdll(dxmolnew,dwmnew[0]); +// dxmolnew[0] =0; +// dxmolnew[1] =1; +// WMOLdll(dxmolnew,dwmnew[1]); +//// ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*dxmol[0]/dxkg[0]*dwm; +//// ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*dxmol[1]/dxkg[1]*dwm; +// //ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*1/(dwmnew[0]/dwm)*dwm; +// //ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*1/(dwmnew[1]/dwm)*dwm; +// //ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*dwm; +// //ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*dwm; +// +// double dxdz1 = dwmnew[0]/dwm - dxmol[0]*dwmnew[0]*dwmnew[0]/(dwm*dwm); +// double dxdz2 = dwmnew[1]/dwm - dxmol[1]*dwmnew[1]*dwmnew[1]/(dwm*dwm); +// +// //double ddmassddmol = dd*(dwmnew[0]*) +// +// //ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*(dwmnew[0]*dxmol[1]*dwmnew[1]/(dwm*dwm))*dwm; +// //ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*(dwmnew[0]*dxmol[0]*dwmnew[1]/(dwm*dwm))*dwm; +// +// ddddX_ph = (ddddX_ph_tmp[0] - ddddX_ph_tmp[1])/(dxdz1+dxdz2)*dwm; +// +// // this does not work... +// */ +// +// double dpdz_td,dhdz_td; +// //double dxmolnew[ncmax],dwmnew; +// double pnew,hnew; +// double dvdz_ph; +// +// // numerical derivative for independent mass fraction +// /* NOTE THAT IT IS DIFFICULT TO CHANGE FROM MOLE TO MASS BASIS, WHEN PERFORMING A NUMERICAL DERIVATIVE wrt composition. I DID NOT SUCCEED */ +// double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew; +// //XMASSdll(dxmol,dxkgnew,dwmnew); +// dxkgnew[0] = dxkg[0]+1e-5; +// dxkgnew[1] = dxkg[1]-1e-5; +// XMOLEdll(dxkgnew,dxmolnew,dwmnew); +// double din; +// din=dd*dwm/dwmnew; +// PRESSdll (dt,din,dxmolnew,pnew); +// ENTHALdll (dt,din,dxmolnew,hnew); +// +// dpdz_td = (pnew-dp)/1e-5; +// dhdz_td = (hnew/dwmnew-dh/dwm)*dwm/1e-5; +// +// // expression from jacobian matrix transformation +// dvdz_ph = -(dpdT_zv*dhdz_td - dhdT_vz*dpdz_td) / (dpdT_zv*dhdv_Tz - dhdT_vz*dpdv_Tz); // the minus in front comes from ders wrt z is a change in both concentrations +// ddddX_ph = -dd*dd*dvdz_ph; +// ddddX_ph = ddddX_ph*dwm; // this is already per X due to the above change in mass fraction and conversion.. + + + + } else { // two-phase region, get derivative of density + + // These are not computed in two-phase! + dxkappa=noValue; + dbeta=noValue; + + if (PartialDersInputChoice==3) { // Using phX Analytical twophase derivatives + if (debug) printf ("Using Analytical twophase derivatives\n"); + + // // TODO the below analytical derivs are wrong since saturated liquid and vapor concentrations change along evaporation.. + + + /* j--phase flag: 1 = input x is liquid composition (bubble point) + 2 = input x is vapor composition (dew point) + 3 = input x is liquid composition (freezing point) + 4 = input x is vapor composition (sublimation point) + */ + + //compute saturated vapor state at const p + long kph2 = 2; + double dt_v,ddv_p,dCv_v,dCp_v,dwm_v,dxkappa_v,dbeta_v,h_v,s_v; + SATPdll(dp,dxmol,kph2,dt_v,spare3,ddv_p,spare2,spare1,lerr,errormsg,errormessagelength); + ENTHALdll(dt_v,ddv_p,dxmol,h_v); + //compute saturated liquid state at const p + long kph1 = 1; + double dt_l,ddl_p,dCv_l,dCp_l,dwm_l,dxkappa_l,dbeta_l,h_l,s_l; + SATPdll(dp,dxmol,kph1,dt_l,ddl_p,spare3,spare2,spare1,lerr,errormsg,errormessagelength); + ENTHALdll(dt_l,ddl_p,dxmol,h_l); + // compute partials + double dvdh_p,dTdp_clasius, dhdpL,dhdpV,dvdpL,dvdpV,dxdp_h,dvdp_h; + // compute drhodh_p + dvdh_p = (1/ddv_p - 1/ddl_p)/(h_v-h_l); + ddddh_p = -dd*dd*dvdh_p; + // get other sat props at const T,p,x + THERM2dll(dt, ddv, dxmolv, spare3, spare4, h_v, s_v, dCv_v, dCp_v, dwm_v,spare2, spare10, spare11, spare12, dxkappa_v, dbeta_v, spare13, spare14, spare15, spare16,spare17, spare18, spare19, spare20, spare21); + THERM2dll(dt, ddl, dxmoll, spare3, spare4, h_l, s_l, dCv_l, dCp_l, dwm_l,spare2, spare10, spare11, spare12, dxkappa_l, dbeta_l, spare13, spare14, spare15, spare16,spare17, spare18, spare19, spare20, spare21); + + //ddv_v = ddv; + //ddl_l = ddl; + // compute drhodp_h + //dTdp_clasius = (1/ddv - 1/ddl)/(s_v-s_l); + dTdp_clasius = dt*(1/ddv - 1/ddl)/(h_v-h_l); + dhdpL = 1/ddl*(1-dbeta_l*dt_l)+dCp_l*dTdp_clasius; + dhdpV = 1/ddv*(1-dbeta_v*dt_v)+dCp_v*dTdp_clasius; + dvdpL = dbeta_l*1/ddl*dTdp_clasius-dxkappa_l*1/ddl; + dvdpV = dbeta_v*1/ddv*dTdp_clasius-dxkappa_v*1/ddv; + dxdp_h = (dhdpL + dqmol * (dhdpV-dhdpL))/(h_l-h_v); + dvdp_h = dvdpL+dxdp_h*(1/ddv-1/ddl)+dqmol*(dvdpV-dvdpL); + ddddp_h = -dd*dd*dvdp_h; + + // analytical derivative for ddddzi + double dhdz_tp, dvdz_tp; + double dxkgv[ncmax],dwmv,dxkgl[ncmax],dwml; + XMASSdll(dxmolv,dxkgv,dwmv); + XMASSdll(dxmoll,dxkgl,dwml); + dhdz_tp = (h_v/dwmv*1000-h_l/dwml*1000)/(dxkgv[0]-dxkgl[0]); + dvdz_tp = (1/(ddv*dwmv)-1/(ddl*dwml))/(dxkgv[0]-dxkgl[0]); + dvdh_p = dvdh_p/dwm*dwm/1000; + ddddX_ph = -dd*dwm*dd*dwm*(-dvdh_p*dhdz_tp+dvdz_tp); + + //dhdz_tp = (h_v-h_l)/(dxmolv[0]-dxmoll[0]); + //dvdz_tp = (1/ddv_v-1/ddl_l)/(dxmolv[0]-dxmoll[0]); + //ddddX_ph = -dd*dd*(-dvdh_p*dhdz_tp+dvdz_tp); + + +// // numerical derivative for ddddzi, that ensures xmol is between 0 and 1 +// double HA,HB,smooth,DX,dxmolnew[ncmax],dlow,dhigh; +// HA = 0.925*(h_v-h_l)+h_l; +// HB = 0.975*(h_v-h_l)+h_l; +// +// /* +// // using PHFLSH to get numerical derivative ddddzi +// DX=0.005; +// if (dh < HA) { +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 +// PHFLSHdll(dp,dh,dxmolnew,spare14,dlow,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); +// ddddX_ph = (dlow-dd)/DX; +// } else if (dh > HB) { +// DX=-DX; +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 +// PHFLSHdll(dp,dh,dxmolnew,spare14,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); +// ddddX_ph = (dhigh-dd)/DX; +// } else { +// smooth=(dh-HA)/(HB-HA); +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix +// PHFLSHdll(dp,dh,dxmolnew,spare14,dlow,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); +// DX = -DX; +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix +// PHFLSHdll(dp,dh,dxmolnew,spare14,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); +// ddddX_ph = (dlow-dd)/(-DX)*(1-smooth) + smooth*(dhigh-dd)/(DX); +// } +// */ +// +// // Using TPFLSH to get numerical derivative ddddzi +// double dhdT_pX, dddT_pX,hlow,hhigh,dddX_pT,dhdX_pT; +// +// dhdT_pX = (h_v - h_l)/(dt_v-dt_l); +// //dvdT_p = (1/ddv_v - 1/ddl_l)/(dt_v-dt_l); +// dddT_pX = -dd*dd*(1/ddv_v - 1/ddl_l)/(dt_v-dt_l); +// +// DX=0.0025; +// if (dh < HA) { +// //DX = DX; +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 +// TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); +// dddX_pT = (dlow-dd)/(DX); +// dhdX_pT = (hlow-dh)/(DX); +// } else if (dh > HB) { +// DX = -DX; +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix +// TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); +// dddX_pT = (dhigh-dd)/(DX); +// dhdX_pT = (hhigh-dh)/(DX); +// } else { // something smooth +// smooth=(dh-HA)/(HB-HA); +// //DX = DX; +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix +// TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); +// DX = -DX; +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix +// TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); +// dddX_pT = (dlow-dd)/(-DX)*(1-smooth) + smooth*(dhigh-dd)/(DX); +// dhdX_pT = (hlow-dh)/(-DX)*(1-smooth) + smooth*(hhigh-dh)/(DX); +// } +// ddddX_ph = -(dddT_pX*dhdX_pT-dhdT_pX*dddX_pT)/dhdT_pX; + + + } else if (PartialDersInputChoice==2) { // Using phX Numerical twophase derivatives + if (debug) printf ("Using Numerical two phase derivatives\n"); + + // in the following HA and HB are points in two-phase, where the numerical derivative changes "the sign of change", e.g dT into -dT smoothly (linearly) + + //using PHFLSH to get numerical derivative ddddp_h + double dnew,dpnew; + dpnew = dp +1e-3; // change in 1 Pa + PHFLSHdll(dpnew,dh,dxmol,spare14,dnew,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + ddddp_h = (dnew-dd)/1e-3; + + //using PHFLSH to get numerical derivative ddddh_p + double dhnew; + dhnew = dh +(1*dwm/1000); // change in 1 J/kg*K + PHFLSHdll(dp,dhnew,dxmol,spare14,dnew,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + ddddh_p = (dnew-dd)/(1*dwm/1000); + + + //using PHFLSH to get numerical derivative ddddX_ph + double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew; +// XMASSdll(dxmol,dxkg,dwmnew); + dxkgnew[0] = dxkg[0]+1e-7; + dxkgnew[1] = dxkg[1]-1e-7; + XMOLEdll(dxkgnew,dxmolnew,dwmnew); + double dhin = dh*dwmnew/dwm; // this is needed because h in mass basis is constant.. + PHFLSHdll(dp,dhin,dxmolnew,spare14,dnew,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + ddddX_ph = (dnew*dwmnew-dd*dwm)/1e-7; // mass basis + +/* + double HA,HB,dxmolnew[ncmax],Tnew,pnew,dlow,dhigh,hlow,hhigh,h_l,h_v; + //double ddq,ddl_l,ddv_v,ddx[ncmax],ddy[ncmax]; + + ENTHALdll (dt,ddl,dxmoll,h_l); + ENTHALdll (dt,ddv,dxmolv,h_v); + HA = 0.025*(h_v-h_l)+h_l; + HB = 0.075*(h_v-h_l)+h_l; + + double DT,DP,DX,smooth,dddT_pX,dhdT_pX,dddP_TX,dhdP_TX,dddX_pT,dhdX_pT; + + DT=0.5; + DP=-25; + DX=0.002; + + if (dh < HA) { + // DT + //DT=DT; + Tnew= dt+DT; + //this function does not work? + //(t,p,z,Dl,Dv,x,y,q,ierr,herr) + //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (Tnew,ddl_l,ddx,h_l); + //ENTHALdll (Tnew,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); + TPFLSHdll(Tnew,dp,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddT_pX = (dlow-dd)/(DT); + dhdT_pX = (hlow-dh)/(DT); + // DP + //DP=DP; + pnew = dp+DP; + //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); + TPFLSHdll(dt,pnew,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddP_TX = (dlow-dd)/(DP); + dhdP_TX = (hlow-dh)/(DP); + // DX + //DX = DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 + //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); + TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + double dwmnew; + WMOLdll(dxmolnew,dwmnew); + dddX_pT = (dlow/dwmnew-dd/dwm)*dwm/(DX); + dhdX_pT = (hlow/dwmnew-dh/dwm)*dwm/(DX); + } else if (dh > HB) { + // DT + DT = -DT; + Tnew= dt+DT; + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (Tnew,ddl_l,ddx,h_l); + //ENTHALdll (Tnew,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); + TPFLSHdll(Tnew,dp,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddT_pX = (dhigh-dd)/(DT); + dhdT_pX = (hhigh-dh)/(DT); + // DP + DP = -DP; + pnew=dp+DP; + //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); + TPFLSHdll(dt,pnew,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddP_TX = (dhigh-dd)/(DP); + dhdP_TX = (hhigh-dh)/(DP); + // DX + DX = -DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); + TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + double dwmnew; + WMOLdll(dxmolnew,dwmnew); + dddX_pT = (dhigh/dwmnew-dd/dwm)*dwm/(DX); + dhdX_pT = (hhigh/dwmnew-dh/dwm)*dwm/(DX); + } else { // something smooth + smooth=(dh-HA)/(HB-HA); + // DT + //DT = DT; + Tnew= dt+DT; + //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (Tnew,ddl_l,ddx,h_l); + //ENTHALdll (Tnew,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); + TPFLSHdll(Tnew,dp,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + DT=-DT; + Tnew= dt+DT; + //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (Tnew,ddl_l,ddx,h_l); + //ENTHALdll (Tnew,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); + TPFLSHdll(Tnew,dp,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddT_pX = (dlow-dd)/(-DT)*(1-smooth) + smooth*(dhigh-dd)/(DT); + dhdT_pX = (hlow-dh)/(-DT)*(1-smooth) + smooth*(hhigh-dh)/(DT); + // DP + //DP = DP; + pnew=dp+DP; + //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); + TPFLSHdll(dt,pnew,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + DP = -DP; + pnew=dp+DP; + //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); + TPFLSHdll(dt,pnew,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddP_TX = (dlow-dd)/(-DP)*(1-smooth) + smooth*(dhigh-dd)/(DP); + dhdP_TX = (hlow-dh)/(-DP)*(1-smooth) + smooth*(hhigh-dh)/(DP); + // DX + //DX = DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); + TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + DX = -DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); + TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddX_pT = (dlow-dd)/(-DX)*(1-smooth) + smooth*(dhigh-dd)/(DX); + dhdX_pT = (hlow-dh)/(-DX)*(1-smooth) + smooth*(hhigh-dh)/(DX); + } + + ddddh_p = dddT_pX/dhdT_pX; + ddddp_h = (dddP_TX*dhdT_pX-dhdP_TX*dddT_pX)/dhdT_pX; + ddddX_ph = -(dddT_pX*dhdX_pT-dhdT_pX*dddX_pT)/dhdT_pX; + ddddX_ph = ddddX_ph*dwm; +*/ + + } + + + } + + } + + } else { // We have a problem! + printf("Derivatives and transport properties calculations called at the wrong time: rho=%f and T=%f\n",dd,dt); + } + + switch(lerr){ + case 4: + sprintf(errormsg,"P=%f < 0",dp); + break; + case 8: + sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(dxmol,lnc).c_str()); + break; + case 12: + sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(dxmol,lnc).c_str(),dp); + break; + case 249: + sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + default: + break; + } + return updateDers(ders, lerr); +} + +int updateTrns(double *trns, long lerr){ + //ASSIGN VALUES TO RETURN ARRAY + trns[0] = lerr;//error code + trns[1] = getETA_modelica(); // dynamic viscosity in Pa.s + trns[2] = getTCX_modelica(); // thermal conductivity in W/m.K + trns[3] = dsigma; + return 0; +} + +int trns_REFPROP(double *trns, char* errormsg, int DEBUGMODE){ + debug = false; + if (DEBUGMODE) debug = true; + long lerr = 0; + + if ((dd!=noValue)&&(dt!=noValue)) { + // call explicit functions in d and T + // compute transport properties + if (debug) printf("Getting transport properties from T=%f and rho=%f.\n",dt,dd); + TRNPRPdll(dt,dd,dxmol,deta,dtcx,lerr,errormsg,errormessagelength); + if (debug) printf("Thermal conductivity is lambda=%f W/m.K.\n",dtcx); + if (debug) printf("Dynamic viscosity is eta=%fµPa.s.\n",deta); + + } else { // We have a problem! + printf("Derivatives and transport properties calculations called at the wrong time: rho=%f and T=%f\n",dd,dt); + } + + switch(lerr){ + case -31: + printf(errormsg,"Temperature T=%f out of range for conductivity",dt); + break; + case -32: + printf(errormsg,"density d=%f out of range for conductivity",dd); + break; + case -33: + printf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",dt,dd); + break; + case -41: + printf(errormsg,"Temperature T=%f out of range for viscosity",dt); + break; + case -42: + printf(errormsg,"density d=%f out of range for viscosity",dd); + break; + case -43: + printf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",dt,dd); + break; + case -51: + printf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",dt); + break; + case -52: + printf(errormsg,"density d=%f out of range for conductivity and viscosity",dd); + break; + case -53: + printf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",dt,dd); + break; + case 39: + printf(errormsg,"model not found for thermal conductivity"); + break; + case 49: + printf(errormsg,"model not found for viscosity"); + break; + case 50: + printf(errormsg,"ammonia/water mixture (no properties calculated)"); + break; + case 51: + printf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",dt); + break; + case -58: + printf(errormsg,"ECS model did not converge"); + break; + case -59: + printf(errormsg,"ECS model did not converge"); + break; + default: + break; + } + return updateTrns(trns, lerr); +} + + +int updateProps(double *props, long lerr){ + + double dxlkg[ncmax], dxvkg[ncmax]; + XMASSdll(dxmoll,dxlkg,dwliq); + XMASSdll(dxmolv,dxvkg,dwvap); + + //ASSIGN VALUES TO RETURN ARRAY + props[0] = lerr;//error code + props[1] = getP_modelica(); //pressure in Pa + props[2] = getT_modelica(); //Temperature in K + props[3] = getWM_modelica(); //molecular weight + props[4] = getD_modelica(); //density + props[5] = getDL_modelica(); //density of liquid phase + props[6] = getDV_modelica(); //density of liquid phase + props[7] = getQ_modelica(); //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) + props[8] = getE_modelica(); //inner energy + props[9] = getH_modelica(); //specific enthalpy + props[10] = getS_modelica(); //specific entropy + props[11] = getCV_modelica(); + props[12] = getCP_modelica(); + props[13] = getW_modelica(); //speed of sound + props[14] = getWML_modelica(); + props[15] = getWMV_modelica(); + props[16] = getHL_modelica(); //h of liquid phase + props[17] = getHV_modelica(); //h of vapor phase + props[18] = getSL_modelica(); //s of liquid phase + props[19] = getSV_modelica(); //s of vapor phase + props[20] = dts; //saturation temperature + + + for (int dim=0; dim1) flushConstants(); + else flushProperties(); + if (debug) printf("Loading a new state, flushed state. \n"); + + +/* + * //TODO Is this really nescesary? I think the possibility of dymola calling with same state twice is almost none (it will call for other states to compute, in between).. + + bool knownState = isState(var1,val1,var2,val2,dxmoltmp,lnc); // dummies to force recalculation + double result = getValue(out); + bool valueExists = (result!=noValue); + + if (!knownState) { + if (lnc>1) flushConstants(); + else flushProperties(); + if (debug) printf("Loading a new state, flushed state. \n"); + } else { // We have calculated it before. + if (valueExists) { + if (debug) printf("Working with old state, returning value for %s: %f.\n",out.c_str(),result); + updateProps(props, lerr); // TODO Why only props? Are ders,trns, and props not already known? + return result; + } + } +*/ + + /* + * If we get to this point, the requested value was not part of an earlier + * calculation and we have to proceed to determine it via the Refprop library. + */ + // ( strCompare(Poco::Environment::osName(), "linux") ) + + // Set variables to input values + if ( strCompare(in1, in2) ) { + sprintf(errormsg,"State variable 1 is the same as state variable 2 (%s)\n",in1.c_str()); + return FAIL; + } + + + memcpy(dxmol, dxmoltmp, sizeof(dxmoltmp)) ; + //dxmol = dxmoltmp; + dwm = dwmtmp; + + + + + + + double dqkg; + for (int ii=1;ii<3;ii++){ + + if (ii==1) { + tmpVar = in1; + tmpValue = statevar1; + } else if (ii==2) { + tmpVar = in2; + tmpValue = statevar2; + } + + // loop through possible inputs + if ( strCompare(tmpVar, "p") ) { + dp = getP_refprop(tmpValue); + } else if ( strCompare(tmpVar, "T") ) { + dt = getT_refprop(tmpValue); + } else if ( strCompare(tmpVar, "s") ) { + ds = getS_refprop(tmpValue); + } else if ( strCompare(tmpVar, "h") ) { + dh = getH_refprop(tmpValue); + } else if ( strCompare(tmpVar, "d") ) { + dd = getD_refprop(tmpValue); + } else if ( strCompare(tmpVar, "q") ) { + dqkg = tmpValue; + } else { + lerr = 2; + sprintf(errormsg,"Unknown state variable %i: %s",ii ,tmpVar.c_str()); + return lerr; + } + + if (debug) printf("Checked input variable: %s\n",tmpVar.c_str()); + } + + if (lerr==0){ + if (isInput(in1,in2,std::string("tp"))){ +// if (phase==2){ //fluid state is known to be two phase +// TPFL2dll(dt,dp,dxmol,ddl,ddv,dxmoll,dxmolv,dqmol,lerr,errormsg,errormessagelength); +// }else{ + if (debug) printf("Calling TPFLSH with %f and %f.\n",dt,dp); + TPFLSHdll(dt,dp,dxmol,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + //if (debug) printf("Getting dd: %f\n",dd); + if (lerr!=0) { // compute phase envelope if error occurs, and try again + useSATSPLN(lerr, errormsg); + TPFLSHdll(dt,dp,dxmol,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + } +// } + }else if (isInput(in1,in2,std::string("ph"))){ +// if (phase==1){ //fluid state is known to be single phase +// PHFL1(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); +//// if (liqvap==1) dl=d; else dv=d; +// }else{ + if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,dh); + PHFLSHdll(dp,dh,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (lerr!=0) { // compute phase envelope if error occurs, and try again + useSATSPLN(lerr, errormsg); + PHFLSHdll(dp,dh,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + } +// } + }else if (isInput(in1,in2,std::string("pd"))){ + if (phase==1){ //fluid state is known to be single phase + PDFL1dll(dp,dd,dxmol,dt,lerr,errormsg,errormessagelength); + if (lerr!=0) { // compute phase envelope if error occurs, and try again + useSATSPLN(lerr, errormsg); + PDFL1dll(dp,dd,dxmol,dt,lerr,errormsg,errormessagelength); + } + }else{ + if (debug) printf("Calling PDFLSH with %f and %f.\n",dp,dd); + PDFLSHdll(dp,dd,dxmol,dt,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (lerr!=0) { // compute phase envelope if error occurs, and try again + useSATSPLN(lerr, errormsg); + PDFLSHdll(dp,dd,dxmol,dt,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + } + } + }else if (isInput(in1,in2,std::string("sp"))){ +/* if (phase==1){ //fluid state is known to be single phase + PSFL1(p,s,dxmol,kph,T,d,lerr,errormsg,errormessagelength); + if (liqvap==1) dl=d; else dv=d; + }else{*/ + if (debug) printf("Calling PSFLSH with %f and %f.\n",dp,ds); + PSFLSHdll(dp,ds,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (lerr!=0) { // compute phase envelope if error occurs, and try again + useSATSPLN(lerr, errormsg); + PSFLSHdll(dp,ds,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,dCv,dCp,dw,lerr,errormsg,errormessagelength); + } +// } + }else if (isInput(in1,in2,std::string("pq"))){ + if (debug) printf("Calling PQFLSH with %f and %f.\n",dp,dqkg); + PQFLSHdll(dp,dqkg,dxmol,kq,dt,dd,ddl,ddv,dxmoll,dxmolv,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (lerr!=0 || ddl<=ddv) { // compute phase envelope if error occurs, and try again + useSATSPLN(lerr, errormsg); + PQFLSHdll(dp,dqkg,dxmol,kq,dt,dd,ddl,ddv,dxmoll,dxmolv,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + } + WMOLdll(dxmolv,dwvap); + dqmol = dqkg*dwm/dwvap; +// strcat(errormsg,"Bin in PQ!"); + }else if (isInput(in1,in2,std::string("dq"))){ + if (debug) printf("Calling DQFL2 with %f and %f.\n",dd,dqkg); + DQFL2dll(dd,dqkg,dxmol,kq,dt,dp,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + if (lerr!=0 || ddl<=ddv) { // compute phase envelope if error occurs, and try again + useSATSPLN(lerr, errormsg); + DQFL2dll(dd,dqkg,dxmol,kq,dt,dp,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + } + // (d, q, z, kq, t, p, Dl, Dv, x, y ,ierr,herr) +// strcat(errormsg,"Bin in PQ!"); + }else if (isInput(in1,in2,std::string("th"))){ +/* if (phase==1){ //fluid state is known to be single phase + THFL1(T,h,dxmol,Dmin,Dmax,d,lerr,errormsg,errormessagelength); + }else{*/ + long kr = 2; +/* kr--phase flag: 1 = input state is liquid + 2 = input state is vapor in equilibrium with liq + 3 = input state is liquid in equilibrium with solid + 4 = input state is vapor in equilibrium with solid */ + if (debug) printf("Calling THFLSH with %f and %f.\n",dt,dh); + THFLSHdll(dt,dh,dxmol,kr,dp,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (lerr!=0) { // compute phase envelope if error occurs, and try again + useSATSPLN(lerr, errormsg); + THFLSHdll(dt,dh,dxmol,kr,dp,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + } +// } + }else if (isInput(in1,in2,std::string("td"))){ + /* + if (phase==1){ //fluid state is known to be single phase + if (debug) printf("Calling THERM with %f and %f.\n",dt,dd); + THERMdll(dt,dd,dxmol,dp,de,dh,ds,dCv,dCp,dw,dhjt); + long kphsatp=1; + double dtl; + SATPdll(dp,dxmol,kphsatp,dtl,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + kphsatp=2; + double dtv; + SATPdll(dp,dxmol,kphsatp,dtv,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + if (dt/dtl < dt/dtv) { // liquid + dqmol=0; + } else { + dqmol=1; + } + for (int ii=0;ii 1):%s",printX(dxmol,lnc).c_str()); + break; + case 9: + sprintf(errormsg,"x=%s or T=%f out of range",printX(dxmol,lnc).c_str(),dt); + break; + case 12: + sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(dxmol,lnc).c_str(),dp); + break; + case 13: + sprintf(errormsg,"x=%s, T=%f and p=%f out of range",printX(dxmol,lnc).c_str(),dt,dp); + break; + case 16: + strcpy(errormsg,"TPFLSH error: p>melting pressure"); + break; + case -31: + sprintf(errormsg,"Temperature T=%f out of range for conductivity",dt); + break; + case -32: + sprintf(errormsg,"density d=%f out of range for conductivity",dd); + break; + case -33: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",dt,dd); + break; + case -41: + sprintf(errormsg,"Temperature T=%f out of range for viscosity",dt); + break; + case -42: + sprintf(errormsg,"density d=%f out of range for viscosity",dd); + break; + case -43: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",dt,dd); + break; + case -51: + sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",dt); + break; + case -52: + sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",dd); + break; + case -53: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",dt,dd); + break; + case 39: + sprintf(errormsg,"model not found for thermal conductivity"); + break; + case 49: + sprintf(errormsg,"model not found for viscosity"); + break; + case 50: + sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); + break; + case 51: + sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",dt); + break; + case -58: + case -59: + sprintf(errormsg,"ECS model did not converge"); + break; + case 211: + sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); + break; + case 239: + sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + case 248: + sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",dd,ds); + break; + case 249: + sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + case 271: + sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",dt); + break; + case 291: + sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",dt); + break; + default: + //strncpy(errormsg,errormsg,errormessagelength); + break; + } + + + // my fancy way of ensuring things are computed right at the liquid and vapor saturation + double dqmolLIM; + if (dqmol<=0) { + dqmolLIM=0; + } else if (dqmol>=1) { + dqmolLIM=1; + } else { + dqmolLIM=dqmol; + } + + + //printf("dqmol %f\n",dqmol); + //printf("dp %f\n",dp); + //printf("dxmol %f,%f\n",dxmol[0],dxmol[1]); + double pcrit,tcrit,dcrit; + CRITPdll(dxmol,tcrit,pcrit,dcrit,lerr,errormsg,errormessagelength); + //printf("tc %f\n",tcrit); + //printf("pc %f\n",pcrit); + //printf("dc %f\n",dcrit); + + if (dp >= pcrit-0.01) { // critical T or p or both + ENTHALdll(tcrit,dcrit,dxmol,dhl); + ENTROdll(tcrit,dcrit,dxmol,dsl); + dhv=dhl; + dsv=dsl; + dts=tcrit; + ddl=dcrit; + ddv=dcrit; + } else { + if (dqmolLIM == 0.) { // liquid region + long kphsatp=1; + SATPdll(dp,dxmol,kphsatp,dts,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + if (lerr!=0 || ddl<=ddv) { // compute phase envelope if error occurs, and try again + useSATSPLN(lerr, errormsg); + SATPdll(dp,dxmol,kphsatp,dts,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + } + ENTHALdll(dts,ddl,dxmoll,dhl); + ENTROdll(dts,ddl,dxmoll,dsl); + ENTHALdll(dts,ddv,dxmolv,dhv); + ENTROdll(dts,ddv,dxmolv,dsv); + } else if (dqmolLIM == 1.) { // vapor region + long kphsatp=2; + SATPdll(dp,dxmol,kphsatp,dts,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + if (lerr!=0 || ddl<=ddv) { // compute phase envelope if error occurs, and try again + useSATSPLN(lerr, errormsg); + SATPdll(dp,dxmol,kphsatp,dts,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + } + ENTHALdll(dts,ddl,dxmoll,dhl); + ENTROdll(dts,ddl,dxmoll,dsl); + ENTHALdll(dts,ddv,dxmolv,dhv); + ENTROdll(dts,ddv,dxmolv,dsv); + } else { // two-phase region + ENTHALdll(dt,ddl,dxmoll,dhl); + ENTROdll(dt,ddl,dxmoll,dsl); + ENTROdll(dt,ddv,dxmolv,dsv); + ENTHALdll(dt,ddv,dxmolv,dhv); + dts=dt; + } + } + + + // some linear interpoltion to avoid strange cp on liquid/vapor lines + if (dqmol>=0 && dqmol<=1) { // two-phase + double dcp_l,dcp_v,spare; + CVCPdll(dt,ddl,dxmoll,spare,dcp_l); + CVCPdll(dt,ddv,dxmolv,spare,dcp_v); + dCp = dcp_l + (dcp_v-dcp_l)*dqmol; + if (calcTrans) { + SURTENdll (dt,ddl,ddv,dxmoll,dxmolv,dsigma,lerr,errormsg,errormessagelength); + } else { + dsigma =0; + } + } else { // single-phase + dsigma = 0; + } + + + + + updateProps(props, lerr); + + if (PartialDersInputChoice!=1) { + int outVal = ders_REFPROP(ders,errormsg,debug); + if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); + } else { // compute beta and kappa anyway in single-phase region + if (dqmol < 0. || dqmol > 1.) { + if (debug) printf("Calling THERM3 with T=%f and rho=%f.\n",dt,dd); + double spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12; + THERM3dll (dt,dd,dxmol,dxkappa,dbeta,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12); + } else { + dxkappa=noValue; //TODO why is this not flushed? + dbeta=noValue; + } + updateDers(ders, lerr); + } + +// updateProps(props, lerr); + + if (calcTrans) { + int outVal = trns_REFPROP(trns,errormsg,debug); + if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); + } + + if ( strCompare(out, "p") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getP_modelica()); + return getP_modelica(); + } else if ( strCompare(out, "t") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getT_modelica()); + return getT_modelica(); + } else if ( strCompare(out, "m") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getWML_modelica()); + return getWM_modelica(); + } else if ( strCompare(out, "d") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getD_modelica()); + return getD_modelica(); + } else if ( strCompare(out, "q") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getQ_modelica()); + return getQ_modelica(); + } else if ( strCompare(out, "e") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getE_modelica()); + return getE_modelica(); + } else if ( strCompare(out, "h") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getH_modelica()); + return getH_modelica(); + } else if ( strCompare(out, "s") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getS_modelica()); + return getS_modelica(); + } else if ( strCompare(out, "w") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getW_modelica()); + return getW_modelica(); + } else if ( strCompare(out, "v") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getETA_modelica()); + return getETA_modelica(); + } else if ( strCompare(out, "l") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getTCX_modelica()); + return getTCX_modelica(); + } else { + return -1.0; + } + +} + + +//--------------------------------------------------------------------------- + + +double satprops_REFPROP(char* what, char* statevar_in, char* fluidnames, double *satprops, double statevarval, double* x, int kph, char* REFPROP_PATH, char* errormsg, int DEBUGMODE, int calcTransport){ +/*Calculates thermodynamic saturation properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) +INPUT: + what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function + statevar: string of 1 variable out of p,T,h,s,d + fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory + statevarval: values of the variable specified in statevar + x: array containing the mass fractions of the components of the mixture + REFPROP_PATH: string defining the path of the refprop.dll +OUTPUT + return value: value of variable specified by the input variable what + props: Array containing all calculated values + errormsg: string containing error message +*/ + + + long lerr = 0; + + long dkph = kph; + + +// DEBUGMODE = 1; + if (DEBUGMODE) debug = true; + if (calcTransport) calcTrans = true; else calcTrans = false; + + std::string out = std::string(what).substr(0,1); + std::string in1 = std::string(statevar_in).substr(0,1); + std::string fluids = std::string(fluidnames); + std::string rPath = std::string(REFPROP_PATH); + + + /* + * Call method to initialise the library and check for new fluids. + * Afterwards, the fluids have been processed and the constants might + * have been flushed. + */ + if (debug) printf("\nStarting function satprops_REFPROP to calculate %s.\n", out.c_str()); + + if (setFluids(rPath,fluids,errormsg) != OK) { + printf("Error initialising REFPROP: \"%s\"\n", errormsg); + return -FAIL; + } + + + /* + * Here should be the state checking to avoid unnecessary calculations. when + * working with mixtures, the constants also have to be flushed if the + * composition changes. + */ + bool knownState = false; // dummies to force recalculation + bool valueExists = false; + +// TODO This is out-commented for props_refprop function +// TODO - why do we want to flush properties for the setState functions here when setsat is called? + if (!knownState) { + if (lnc>1) flushConstants(); + else flushProperties(); + if (debug) printf("Loading a new state, flushed state. \n"); + } else { // We have calculated it before. + if (valueExists) { + if (debug) printf("Working with old state, returning value for %i: %f.\n",what[0],-1.0); + return -1.0; + } + } + + + /* + * If we get to this point, the requested value was not part of an earlier + * calculation and we have to proceed to determine it via the Refprop library. + */ + + // Convert mass-based composition to mole fractions and set molecular weight. +// double* dxkg; + dxkg = x; + XMOLEdll(dxkg,dxmolsat,dwmsat); + // dwm = dwm / 1000; // from g/mol to kg/mol //keep refprop units.. + + // loop through possible inputs + if ( strCompare(in1, "p") ) { + dpsat = getP_refprop(statevarval); + } else if ( strCompare(in1, "t") ) { + dtsat = getT_refprop(statevarval); + } else if ( strCompare(in1, "d") ) { + ddsat = getD_refprop(statevarval); + } else { + lerr = 2; + sprintf(errormsg,"Unknown state variable: %s\n", in1.c_str()); + return lerr; + } + if (debug) printf("\nstatevar %s checked\n",in1.c_str()); + + + /* + c kph--phase flag: 1 = input x is liquid composition (bubble point) + c 2 = input x is vapor composition (dew point) + c 3 = input x is liquid composition (freezing point) + c 4 = input x is vapor composition (sublimation point) + */ + + double pcrit,tcrit,dcrit; + CRITPdll(dxmolsat,tcrit,pcrit,dcrit,lerr,errormsg,errormessagelength); + + + if (lerr==0) { + if ( strCompare(in1, "t") ) { + if (dtsat >= tcrit-1) { // critical + ENTHALdll(tcrit,dcrit,dxmolsat,dhlsat); + ENTROdll(tcrit,dcrit,dxmolsat,dslsat); + dhvsat=dhlsat; + dsvsat=dslsat; + dtsat=tcrit; + ddlsat=dcrit; + ddvsat=dcrit; + for (int ii=0;ii1) { + if (dxmolsat[1]>0 && dxmolsat[1]<1) { + if (dx1molsat_old!=dxmolsat[1]) { + SATSPLNdll(dxmolsat,lerr,errormsg,errormessagelength); + if (debug) { + printf("\n\n USING SATSPLN, because we have new composition\n\n"); + printf("dx1molsat_old = %f\n", dx1molsat_old); + printf("dxmolsat[1] = %f \n", dxmolsat[1]); + } + } + dx1molsat_old=dxmolsat[1]; + } + } + SATTdll(dtsat,dxmolsat,dkph,dpsat,ddlsat,ddvsat,dxmollsat,dxmolvsat,lerr,errormsg,errormessagelength); + } + ENTHALdll(dtsat,ddlsat,dxmollsat,dhlsat); + ENTHALdll(dtsat,ddvsat,dxmolvsat,dhvsat); + ENTROdll(dtsat,ddlsat,dxmollsat,dslsat); + ENTROdll(dtsat,ddvsat,dxmolvsat,dsvsat); + } + } else if ( strCompare(in1, "p") ) { + + if (dpsat >= pcrit-0.01) { // critical + ENTHALdll(tcrit,dcrit,dxmolsat,dhlsat); + ENTROdll(tcrit,dcrit,dxmolsat,dslsat); + dhvsat=dhlsat; + dsvsat=dslsat; + dtsat=tcrit; + ddlsat=dcrit; + ddvsat=dcrit; + for (int ii=0;ii1) { + if (dxmolsat[1]>0 && dxmolsat[1]<1) { + if (dx1molsat_old!=dxmolsat[1]) { + SATSPLNdll(dxmolsat,lerr,errormsg,errormessagelength); + if (debug) { + printf("\n\n USING SATSPLN, because we have new composition\n\n"); + printf("dx1molsat_old = %f\n", dx1molsat_old); + printf("dxmolsat[1] = %f \n", dxmolsat[1]); + } + } + dx1molsat_old=dxmolsat[1]; + } + } + SATPdll(dpsat,dxmolsat,dkph,dtsat,ddlsat,ddvsat,dxmollsat,dxmolvsat,lerr,errormsg,errormessagelength); + } + ENTHALdll(dtsat,ddlsat,dxmollsat,dhlsat); + ENTHALdll(dtsat,ddvsat,dxmolvsat,dhvsat); + ENTROdll(dtsat,ddlsat,dxmollsat,dslsat); + ENTROdll(dtsat,ddvsat,dxmolvsat,dsvsat); + switch(lerr){ + case 2: + strcpy(errormsg,"P < Ptp"); + break; + case 4: + strcpy(errormsg,"P < 0"); + break; + } + } + //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); + } else if ( strCompare(in1, "d") ) { + + long dkphsatD=2; + SATDdll(ddsat,dxmolsat,dkphsatD,dkph,dtsat,dpsat,ddlsat,ddvsat,dxmollsat,dxmolvsat,lerr,errormsg,errormessagelength); + if (lerr!=0 || ddlsat<=ddvsat) { // compute phase envelope if error occurs, and try again + + if (lnc>1) { + if (dxmolsat[1]>0 && dxmolsat[1]<1) { + if (dx1molsat_old!=dxmolsat[1]) { + SATSPLNdll(dxmolsat,lerr,errormsg,errormessagelength); + if (debug) { + printf("\n\n USING SATSPLN, because we have new composition\n\n"); + printf("dx1molsat_old = %f\n", dx1molsat_old); + printf("dxmolsat[1] = %f \n", dxmolsat[1]); + } + } + dx1molsat_old=dxmolsat[1]; + } + } + + SATDdll(ddsat,dxmolsat,dkphsatD,dkph,dtsat,dpsat,ddlsat,ddvsat,dxmollsat,dxmolvsat,lerr,errormsg,errormessagelength); + } + ENTHALdll(dtsat,ddlsat,dxmollsat,dhlsat); + ENTHALdll(dtsat,ddvsat,dxmolvsat,dhvsat); + ENTROdll(dtsat,ddlsat,dxmollsat,dslsat); + ENTROdll(dtsat,ddvsat,dxmolvsat,dsvsat); + + switch(lerr){ + case 2: + strcpy(errormsg,"D > Dmax"); + break; + } + + } + + } + + switch(lerr){ + case 0: + strcpy(errormsg,"Saturation routine successful"); + break; + case 1: + sprintf(errormsg,"T=%f < Tmin",dt); + break; + case 8: + sprintf(errormsg,"x out of range, %s",printX(dxmol,lnc).c_str()); + break; + case 9: + sprintf(errormsg,"T=%f and x=%s out of range",dt,printX(dxmol,lnc).c_str()); + break; + case 10: + strcpy(errormsg,"D and x out of range"); + break; + case 12: + strcpy(errormsg,"P and x out of range"); + break; + case 120: + strcpy(errormsg,"CRITP did not converge"); + break; + case 121: + strcpy(errormsg,"T > Tcrit"); + break; + case 122: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 123: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 124: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -125: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -126: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -127: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 128: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 140: + strcpy(errormsg,"CRITP did not converge"); + break; + case 141: + strcpy(errormsg,"P > Pcrit"); + break; + case 142: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 143: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 144: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -144: + strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); + break; + case -145: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -146: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -147: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 148: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 160: + strcpy(errormsg,"CRITP did not converge"); + break; + case 161: + strcpy(errormsg,"SATD did not converge"); + break; + default: + //strncpy(errormsg,herr,errormessagelength); + break; + } + + + + + double dsigma; + + if (calcTrans) { + SURTENdll (dtsat,ddlsat,ddvsat,dxmollsat,dxmolvsat,dsigma,lerr,errormsg,errormessagelength); + } else { + dsigma =0; + } + + + double dxlkg[ncmax], dxvkg[ncmax]; + XMASSdll(dxmollsat,dxlkg,dwlsat); + XMASSdll(dxmolvsat,dxvkg,dwvsat); + + //ASSIGN VALUES TO RETURN ARRAY + satprops[0] = lerr;//error code + satprops[1] = dtsat; //Temperature in K + satprops[2] = dpsat*1000; //pressure in kPa->Pa + satprops[3] = ddlsat*dwlsat; //density of liquid phase mol/L ->g/L (kg/m3) + satprops[4] = ddvsat*dwvsat; //density of vapor phase mol/L ->g/L (kg/m3) + satprops[5] = dhlsat/dwlsat*1000; //enthalpy of liquid J/mol -> J/g e-3 -> J/kg + satprops[6] = dhvsat/dwvsat*1000; //enthalpy of vapor J/mol -> J/g e-3 -> J/kg + satprops[7] = dslsat/dwlsat*1000; //entropy of liquid J/molK -> J/gK e-3 -> J/kgK + satprops[8] = dsvsat/dwvsat*1000; //entropy of vapor J/molK -> J/gK e-3 -> J/kgK + satprops[9] = dsigma; //surface tension + +// satprops[12] = dwlsat/1000; //molecular weight g/mol -> kg/mol +// satprops[13] = dwvsat/1000; //molecular weight g/mol -> kg/mol + for (int ii=0;ii strsplit(std::string s, char del); +//std::string get_REFPROP_fluid_path(std::string rpPath); +//std::string resolve_error(std::string in1, long lerr, char* errormsg); +//bool load_REFPROP(char* error); + +#if defined(__cplusplus) +extern "C" { +#endif // __cplusplus + EXPCONV double props_REFPROP(char* what, char* statevars, char* fluidnames, double *ders, double *trns, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE, int calcTransport, int partialDersInputChoice); //declaration; + EXPCONV double satprops_REFPROP(char* what, char* statevar, char* fluidnames, double *satprops, double statevarval, double* x, int kph, char* REFPROP_PATH, char* errormsg, int DEBUGMODE,int calcTransport); //declaration; + EXPCONV double critprops_REFPROP(char* fluidnames, double *critprops, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE); //declaration; +#if defined(__cplusplus) +} +#endif // __cplusplus +#endif /*REFPROP_WRAPPER*/ diff --git a/_wrapper/src/refprop_wrapper.lib b/_wrapper/src/refprop_wrapper.lib new file mode 100644 index 0000000..edd941b Binary files /dev/null and b/_wrapper/src/refprop_wrapper.lib differ diff --git a/_wrapper/src/refpropwrappertest.cpp b/_wrapper/src/refpropwrappertest.cpp new file mode 100644 index 0000000..483f5f2 --- /dev/null +++ b/_wrapper/src/refpropwrappertest.cpp @@ -0,0 +1,275 @@ +#include +#include +#include +#include +#include "refprop_wrapper.h" +#include "refprop_library.h" +#include +#include + + + +//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); +//double density(char* fluidname_in, double p, double t); +//double density(double p, double t); +//char *str_replace(char *str, char *search, char *replace, long *count); + +int main(int argc, char* argv[]){ + double p,t,d; + char fluidname[255]; + char errormsg[255]; + double* x; + double *props; + double *ders; + double *trns; + double sumx; + int i; +// int nX = argc-5; + int DEBUG = 0; + + + +/* + int count; + printf ("This program was called with \"%s\".\n",argv[0]); + if (argc > 1) + { + for (count = 1; count < argc; count++) + { + printf("argv[%d] = %s\n", count, argv[count]); + } + } + else + { + printf("The command had no other arguments.\n"); + } +printf("argc is %li \n",argc); +*/ + + +/* + if (argc<5){ + printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); +// printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); + return 1; + } +*/ +// usage +// refpropwrappertest "pT" "isobutan|propane" 1e5 293 "c:\\Program Files (x86)\\REFPROP" .1 + +int nX=2; + + x = (double*) calloc(nX,sizeof(double)); + props=(double*) calloc(16+2*nX,sizeof(double)); + ders=(double*) calloc(21,sizeof(double)); + trns=(double*) calloc(3,sizeof(double)); + +x[0] = 0.5; +x[1] = 1.0-x[0]; +//x[2] = 1-x[1]; + + + + + +/* + sumx = 0; + for (i=0;i Contact -Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -", - revisions=" - -")); -end MediaTwoPhaseMixture; +within ; +package REFPROP2Modelica + constant String REFPROP_PATH = "C:\\Program Files (x86)\\REFPROP"; + // constant String REFPROP_PATH = "/opt/refprop"; + + + + + + annotation(version = "0.2", uses(Modelica(version = "3.2")), Documentation(info=" +

Documentation is found in the packages. Installation directions are found in both REFPROP packages.

+

Contact for original implementation:

+

Henning Francke

Helmholtz Centre Potsdam

GFZ German Research Centre for Geosciences

Telegrafenberg, D-14473 Potsdam

Germany

francke@gfz-potsdam.de

+


Contact for this version:

+

Jorrit Wronski

DTU Mechanical Engineering

Technical University of Denmark

Nils Koppels Allé

Building 403 Room 111

2800 Kgs. Lyngby

Denmark

jowr@mek.dtu.dk

+", + revisions = " + +")); +end REFPROP2Modelica; diff --git a/package.order b/package.order index 99b206b..885596b 100644 --- a/package.order +++ b/package.order @@ -1,6 +1,5 @@ -REFPROP_PATH -Examples -PartialMixtureTwoPhaseMedium -REFPROPMedium -Water_MixtureTwoPhase_pT -REFPROPMediumPureSubstance +REFPROP_PATH +Examples +Interfaces +Media +Testers diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..f496a59 --- /dev/null +++ b/readme.md @@ -0,0 +1,63 @@ +#Welcome to REFPROP2Modelica! +This piece of software enables the user to access the Refprop fluid property database from within Modelica. Even though the code base is not very mature yet, this package seems to be the only solution to access properties of mixtures from within Modelica on both Windows and Linux systems. The aim is to develop wrapper classes and integrate them with the `Media` framework inside Modelica. It has only been tested with Dymola so far. + +## Installation Instructions +You can use the provided makefiles to compile and install the wrapper. The process should be straightforward. You can get the latest release from https://github.com/jowr/REFPROP2Modelica/releases + +### Windows +Since I do not run Windows regularly, I am not able to test many things myself. Could you, dear Windows users, please +provide me with feedback? + +1. After downloading, unpack and rename the folder to `REFPROP2Modelica`. +2. Open `_wrapper\Makefile.bat` with a text editor and edit line 23 and 24 according to your system (Dymola 2013 FD01, Dymola 2014 or ...). +3. Run `_wrapper\Makefile.bat` from your Visual Studio console, tested with VS 2008 and VS 2010 Express. +4. Make sure to have the shared library `refprop.dll` available on your system. This can be done by going to (Right click)Computer > Properties > Advanced system settings > Environment Variables. In the bottom half of the window (called System variables), select 'Path' and click 'Edit...'. This will open a new window called Edit System Variable'. Add the REFPROP directory path with a leading semicolon at the end in 'Variable value'. This directory path could be, e.g., C:\Program Files\REFPROP\ or C:\Program Files (x86)\REFPROP depending on your operating system. +5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: `constant String REFPROP_PATH = "C:\\Program Files\\REFPROP\\";` or `constant String REFPROP_PATH = "C:\\Program Files (x86)\\REFPROP\\";` + + +### Linux +For installing on a Linux machine, please follow these instructions + +1. After downloading, unpack and rename the folder to `REFPROP2Modelica`. +2. Open a command prompt in `_wrapper`, then run `make all` and `sudo make install`. +3. Make sure to have the shared library `librefprop.so` available on your system. You might want to check https://github.com/jowr/librefprop.so for details. +4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: `constant String REFPROP_PATH = "/opt/refprop/";` +5. If you experience problems with older versions of this package, you can run `sudo make fixit` to create additonal aliases. This compiles and installs a dynamic library on your system. +6. ... and finally to remove the files from your system, please use `sudo make uninstall`. + +## General Remarks +Please note that you need a working and licensed copy of Refprop in order to use the software provided here. +This is not a replacement for Refprop, only a wrapper to use it with Modelica. + +## Links +If you are interested in this kind of software, you might also want to consider the following projects: + +1. https://github.com/Heineken/REFPROP2Modelica (The original version of this library) +2. https://github.com/thorade/HelmholtzMedia (A Modelica implementation the Helmholtz functions) +3. http://coolprop.sourceforge.net/ (A free fluid property library also based on Helmholtz formulation) + +# Usage notes on partial derivatives +There are four ways to compute partial derivatives determined by "partialDersInputChoice", an input the setState_phX() and setState_pTX() functions: + +1: none (default) + +2: partial derivatives of d wrt p,h,X +In two-phase region: numerical differentiation for all derivatives +In single phase region: dddX is numerical and others are analytical + +3: partial derivatives of d wrt p,h,X +In two-phase region: pseudo analytical (similar procedure as pure fluid - they give almost same result as method 2, and with less CPU effort). +In single phase region: dddX is numerical and others are analytical + +4: partial derivatives of d and h wrt p,T,X +In two-phase region: numerical differentiation for all derivatives +In single phase region: dddX is numerical and others are analytical + +The second and fourth methods compare exactly with stepping forward in u,d,X (the baseline with most CPU effort, due to tedious iteration in property functions at every time step, u,d,X -> T,p,h etc.). +Method 4 is guicker in the two-phase region compared to method 2, because T and P are equilibrium quantities, and thus the most typical flash function.. +Method 3 is fastest, but does not give correct dynamics and will cause mass convervation to fail. + +Note that the dddX derivative is the difference in dddX1|X2=const-dddX2|X1=const + +The partials works only for binary mixtures and have only been tested for NH3/water.. +See tester package.. \ No newline at end of file diff --git a/readme.txt b/readme.txt deleted file mode 100644 index 5444151..0000000 --- a/readme.txt +++ /dev/null @@ -1,6 +0,0 @@ -1. After downloading and unzipping rename folder containing these files to "MediaTwoPhaseMixture". -2. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.LIB to %DYMOLADIR%\\BIN\\LIB\ (%DYMOLADIR% is DYMOLA's program directory) -3. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.H to %DYMOLADIR%\\SOURCE\\ -4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the package). - Make sure you mask the backslashes. It should look something like - constant String REFPROP_PATH = "C:\\Program Files\\REFPROP\\\";