Skip to content

Commit

Permalink
Vapor quality of fluids and mixtures becomes nullable (not null only …
Browse files Browse the repository at this point in the history
…in two-phase or saturated state). Added check of CoolProp outputs
  • Loading branch information
portyanikhin committed Sep 15, 2021
1 parent dd779fb commit 2b3992e
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 21 deletions.
21 changes: 17 additions & 4 deletions SharpProp.Tests/Fluids/TestFluid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,30 @@ public void TestUpdate([Values] FluidsList name, [Values(1e7, 1e8)] double press
}
}

[Test(ExpectedResult = "Invalid input!")]
[Test(ExpectedResult = "Need to define 2 unique inputs!")]
public string? TestUpdateThrows()
{
var exception =
Assert.Throws<ArgumentException>(() => _water.Update(Input.Pressure(101325), Input.Pressure(101325)));
return exception?.Message;
}

private double? HighLevelInterface(string output)
private double? HighLevelInterface(string outputKey)
{
try
{
double value;
if (_fraction.HasValue)
return CP.PropsSImulti(new StringVector {output}, "P", new DoubleVector {_pressure}, "T",
{
value = CP.PropsSImulti(new StringVector {outputKey}, "P", new DoubleVector {_pressure}, "T",
new DoubleVector {_temperature}, _fluid.Name.CoolPropBackend(),
new StringVector {_fluid.Name.CoolPropName()},
new DoubleVector {_fraction.Value})[0][0];
return CP.PropsSI(output, "P", _pressure, "T", _temperature, CoolPropHighLevelName(_fluid.Name));
return CheckedValue(value, outputKey);
}

value = CP.PropsSI(outputKey, "P", _pressure, "T", _temperature, CoolPropHighLevelName(_fluid.Name));
return CheckedValue(value, outputKey);
}
catch (ApplicationException)
{
Expand All @@ -121,5 +127,12 @@ private static string CoolPropHighLevelName(FluidsList name) =>
name.CoolPropBackend() == "HEOS"
? name.CoolPropName()
: $"{name.CoolPropBackend()}::{name.CoolPropName()}";

private static double? CheckedValue(double value, string outputKey)
{
if (double.IsInfinity(value) || double.IsNaN(value) || outputKey == "Q" && value is < 0 or > 1)
return null;
return value;
}
}
}
2 changes: 1 addition & 1 deletion SharpProp.Tests/HumidAir/TestHumidAir.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void TestWithState()
return exception?.Message;
}

[Test(ExpectedResult = "Invalid humid air state!")]
[Test(ExpectedResult = "Invalid or not defined state!")]
public string? TestInvalidState()
{
var exception = Assert.Throws<ArgumentException>(() =>
Expand Down
14 changes: 14 additions & 0 deletions SharpProp.Tests/SharpProp.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@
<IsPackable>false</IsPackable>

<Nullable>enable</Nullable>

<PackageVersion>1.0.3</PackageVersion>

<Title>SharpProp.Tests</Title>

<Authors>Vladimir Portyanikhin</Authors>

<Description>Unit tests for SharpProp</Description>

<Copyright>Copyright (c) Vladimir Portyanikhin 2021</Copyright>

<PackageProjectUrl>https://github.com/portyanikhin/SharpProp</PackageProjectUrl>

<RepositoryUrl>https://github.com/portyanikhin/SharpProp</RepositoryUrl>
</PropertyGroup>

<ItemGroup>
Expand Down
21 changes: 16 additions & 5 deletions SharpProp/Fluids/AbstractFluid.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using CoolProp;
using SharpProp.Validators;

namespace SharpProp
{
Expand All @@ -17,6 +18,7 @@ public abstract partial class AbstractFluid
/// <param name="firstInput">First input property</param>
/// <param name="secondInput">Second input property</param>
/// <returns>A new fluid object with a defined state</returns>
/// <exception cref="ArgumentException">Need to define 2 unique inputs!</exception>
public virtual AbstractFluid WithState(IKeyedInput<parameters> firstInput, IKeyedInput<parameters> secondInput)
{
var fluid = Factory();
Expand All @@ -29,7 +31,7 @@ public virtual AbstractFluid WithState(IKeyedInput<parameters> firstInput, IKeye
/// </summary>
/// <param name="firstInput">First input property</param>
/// <param name="secondInput">Second input property</param>
/// <exception cref="ArgumentException">Invalid input!</exception>
/// <exception cref="ArgumentException">Need to define 2 unique inputs!</exception>
public void Update(IKeyedInput<parameters> firstInput, IKeyedInput<parameters> secondInput)
{
Reset();
Expand Down Expand Up @@ -57,9 +59,12 @@ protected virtual void Reset()
{
try
{
return KeyedOutput(key);
var value = KeyedOutput(key);
if (key is parameters.iQ && value is < 0 or > 1)
return null;
return value;
}
catch (ApplicationException)
catch (Exception e) when (e is ApplicationException or ArgumentException)
{
return null;
}
Expand All @@ -70,7 +75,13 @@ protected virtual void Reset()
/// </summary>
/// <param name="key">Key of output</param>
/// <returns>A not nullable keyed output</returns>
protected double KeyedOutput(parameters key) => Backend.keyed_output(key);
/// <exception cref="ArgumentException">Invalid or not defined state!</exception>
protected double KeyedOutput(parameters key)
{
var value = Backend.keyed_output(key);
OutputsValidator.Validate(value);
return value;
}

private static (input_pairs inputPair, double firstValue, double secondValue) GenerateUpdatePair(
IKeyedInput<parameters> firstInput, IKeyedInput<parameters> secondInput)
Expand All @@ -79,7 +90,7 @@ private static (input_pairs inputPair, double firstValue, double secondValue) Ge
var swap = !inputPair.HasValue;
if (swap) inputPair = GetInputPair(secondInput, firstInput);
if (!inputPair.HasValue)
throw new ArgumentException("Invalid input!");
throw new ArgumentException("Need to define 2 unique inputs!");

return !swap
? ((input_pairs) inputPair, firstValue: firstInput.Value, secondValue: secondInput.Value)
Expand Down
2 changes: 1 addition & 1 deletion SharpProp/Fluids/FluidProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public abstract partial class AbstractFluid
/// <summary>
/// Mass vapor quality [-]
/// </summary>
public double Quality => _quality ??= KeyedOutput(parameters.iQ);
public double? Quality => _quality ??= NullableKeyedOutput(parameters.iQ);

/// <summary>
/// Sound speed [m/s]
Expand Down
7 changes: 4 additions & 3 deletions SharpProp/HumidAir/HumidAir.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using CoolProp;
using SharpProp.Validators;

namespace SharpProp
{
Expand All @@ -14,6 +15,7 @@ public partial class HumidAir
/// <param name="secondInput">Second input property</param>
/// <param name="thirdInput">Third input property</param>
/// <returns>A new <see cref="HumidAir" /> object with a defined state</returns>
/// <exception cref="ArgumentException">Need to define 3 unique inputs!</exception>
public static HumidAir WithState(IKeyedInput<string> fistInput, IKeyedInput<string> secondInput,
IKeyedInput<string> thirdInput)
{
Expand Down Expand Up @@ -53,14 +55,13 @@ protected virtual void Reset()
/// <param name="key">Key of output</param>
/// <returns>A not nullable keyed output</returns>
/// <exception cref="ArgumentException">Need to define 3 unique inputs!</exception>
/// <exception cref="ArgumentException">Invalid humid air state!</exception>
/// <exception cref="ArgumentException">Invalid or not defined state!</exception>
protected double KeyedOutput(string key)
{
CheckInputs();
var value = CP.HAPropsSI(key, _inputs[0].CoolPropKey, _inputs[0].Value,
_inputs[1].CoolPropKey, _inputs[1].Value, _inputs[2].CoolPropKey, _inputs[2].Value);
if (double.IsPositiveInfinity(value) || double.IsNegativeInfinity(value) || double.IsNaN(value))
throw new ArgumentException("Invalid humid air state!");
OutputsValidator.Validate(value);
return value;
}

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 7 additions & 7 deletions SharpProp/SharpProp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryUrl>https://github.com/portyanikhin/SharpProp</RepositoryUrl>
<PackageTags>native cross-platform CoolProp fluids mixtures humid air thermophysical properties thermodynamics</PackageTags>
<PackageVersion>1.0.2</PackageVersion>
<PackageVersion>1.0.3</PackageVersion>
</PropertyGroup>

<ItemGroup>
Expand All @@ -21,14 +21,14 @@
<Pack>true</Pack>
</None>
<None Update="native\libs\libCoolProp.so">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<PackagePath>build\</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<PackagePath>build\</PackagePath>
<Pack>true</Pack>
</None>
<None Update="native\libs\libCoolProp.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<PackagePath>build\</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<PackagePath>build\</PackagePath>
<Pack>true</Pack>
</None>
</ItemGroup>

Expand Down
1 change: 1 addition & 0 deletions SharpProp/SharpProp.csproj.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=enums/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=fluids/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=humidair/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=inputs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=interfaces/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
17 changes: 17 additions & 0 deletions SharpProp/Validators/OutputsValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;

namespace SharpProp.Validators
{
internal static class OutputsValidator
{
/// <summary>
/// Validates the CoolProp output
/// </summary>
/// <exception cref="ArgumentException">Invalid or not defined state!</exception>
public static void Validate(double value)
{
if (double.IsInfinity(value) || double.IsNaN(value))
throw new ArgumentException("Invalid or not defined state!");
}
}
}

0 comments on commit 2b3992e

Please sign in to comment.