Closed gratestas closed 5 years ago
I believe this will be a good addition to the library. What will be your specific use cases for this feature?
For the implementation, I'm thinking this will be a new quantity class (e.g. ReferencePressure
or something like that) since the calculations to convert between the different pressure references will not really fit inside the Pressure
class.
If we need to convert the two quantities to each other, we can edit their CustomCode implementations. Or just write extension methods?
Sounds good to me, please briefly describe:
@gratestas Waiting for your input to continue this discussion.
Only for the sake of avoiding misunderstandings, I go into the details:
Pressure is a state function, for its measurement depends on environmental factors such as ambient pressure, elevation above sea level and local weather conditions. For two persons located in the different environment to speak of the same pressure, one must relate it to a reference. There are three basis reference: absolute, gauge, vacuum.
Therefore, to obtain consistent and qualitative data, the reference measurement is crucial.
Here it is why. Tanks, pumps, compressors and turbines are sensitive to pressure changes and the choice upon the relative measurement reference.
Tanks/containers contain pressurised fluids surface of which is referenced to atmospheric pressure.
Another aspect to consider is the fact that during the year, the atmospheric pressure of the specific location changes enough to damage a working system.
Pumps, though, have a different story. When you have a tank communicating with a pump you better go for absolute reference since the pump's performance depends on the differential pressure between the suction and discharge nozzles. Suction nozzle pulls fluid to the vacuum (negative) pressure, whereas discharge nozzle adds positive pressure to the fluid.
Simply put, a particular system is more convenient and efficient to design relative to one reference, whereas another system would be more manageable under the other one. Such implementation will bring less confusion, less effort, more effectiveness, more power.
Conversion examples as follows:
Absolute = Atmospheric + Gauge
Absolute = Atmospheric - Vacuum
Gauge = Absolute - Atmospheric
Vacuum = Atmpospheric - Absolute
Here local atmospheric pressure will be always passed parameter.
I was thinking that the implementation can be viewed, at least, by two ways. One of them is to create a quantity for each type like Absolute/Gauge/Vacuum-Pressure and introduce convenient extension methods to swap between them. The other one is to create single quantity, as @gojanpaolo proposed, like ReferencePressure
and then to define corresponding units projected from each of pressure units.
For instance, for PoundPerSquaredInch (psi)
(psia) -> PoundPerSquaredInchAbsolute
(psig) -> PoundPerSquaredInchGauge
(psiv) -> PoundPerSquaredInchVacuum
and the same pattern applies for remained units. In my opinion, the last one seems more reasonable. In fact, it preserves consistency with the regular convention in the industry which is good.
Pseudo code implementation example
public static ReferencePressure ToGauge( this ReferencePressure absolute, Pressure localAmbient )
{
return ReferencePressure.ToGauge( absolute, localAmbient);
}
public static ReferencePressure ToGauge( ReferencePressure reference, Pressure localAmbient )
{
return ReferencePressure.FromPascalGauge(reference.PascalAbsolute - localAmbient.Pascal);
}
Problem
However, I'd like you to pay attention to the fact that if someone would like to pass input of ReferencePressure
type, there is no way to set the unique rule for interchanging Absolute -> Gauge
or Absolute->Vacuum
since it includes all of them. At least I cannot figure it out. Maybe you will.
Instead
I thought, then, about Pressure
quantity class itself and suggested that maybe all of three reference pressures can be put under it and put through conversion by extension methi. The units of Pressure
will be accommodated like
Pascal
PascalAbsolute
PascalGauge
PascalVacuum
and the same for the others. Yet it will triple the list. Further, the conversion of references may be done on the level of normal conversion (I am not acquainted with the UnitsNet structure very well yet). If I am not mistaken, the only difference will be in that here there will be two pass parameters. For instance,
var pressure = Pressure.FromPascalAbsolute(value, localAmbient);
var convertedPressure = pressure.PascalGauge;
that gives main idea something like:
public static FromPascalAbsolute(double pressure, Pressure localAmbient)
{
_baseUnit = pressure ;
_localAtmosphere = localAmbient;
return new Pressure( _baseUnit, PressureUnit.PascalAbsolute)
}
public static ToPascalGauge( )
{
_gauge = _baseUnit - _localAtmosphere;
return new Pressure( _gauge, PressureUnit.PascalGauge)
}
public static ToPascalVacuum( )
{
_vacuum = localAtmosphere - _baseUnit;
return new Pressure( _vacuum , PressureUnit.PascalVacuum)
}
Again, I am not acquainted with the UnitsNet structure very well, but I will spare some time to understand it better to be able to implement it or at least to assist the implementation.
The bullet points here would be:
Awesome explanation, thanks. I don't have enough time to digest it all right now, will have to spend more time reading it and getting familiar with the concepts.
Initial thoughts/understanding:
PressureReference
field to Pressure
quantity, and when constructing pressure quantities specify the reference. Not compatible with current code generation scheme, I think it requires adding a special case. Also a breaking change unless we let the default reference value be say Gauge? Pressure
units to get PascalV
(Vacuum) and PascalA
(Absolute) variants, and either reusing existing units for Gauge or adding those too (PascalG
). Compatible with code generation, but generates a lot of duplicate code.RefPressure
var p = new RefPressure(Pressure.FromPascals(1), PressureReference.Gauge);
Pressure pg = p.Gauge; // 1 Pa
Pressure pa = p.Absolute; // Something else
Pressure pv = p.Vacuum; // Something else
You won't get as nice syntax, but it saves a lot of code duplication.
Am I getting it right?
Closing this due to inactivity, please reopen to continue the discussion.
I could also use this feature as i'm right now switching between absolute- and relative (gauge) pressure in a way that would have been better as a inbuilt feature in UnitsNet. Hope you will look into this again some day.
When I work with pressure I always show using this notation: BarG - (Gauge Pressure) Pressure reading relative to current atmospheric pressure. BarA - (Absolute Pressure) Pressure reading relative to absolute vacuum. The Vacuum pressure is a new concept for me (Been in the business of working with pressure in +5 years and have never even hear of it) Does people even use it anymore?
How should it be done? Invent a special case for pressure or adding new units to the pressure unit - I dont know what would be easiest/best
Correct me if I'm wrong, but it seems to boil down to relative vs absolute pressures. Absolute is to absolute vacuum, relative is to some other pressure. That other pressure for gauge is usually 1 atm but not necessarily. What if we're on the moon?
I loathe the idea of creating a new unit for relative vs absolute. I would propose the following:
return this
I use the term "reference" above, but Gauge could be substituted if we want.
Hmmm, I just tried to play with a bit of code and got stuck immediately.
I tried deriving a new RefencePressure class from Pressure. I forgot that's also a no-go with structs.
I think for my suggestion we'd have to move to class instead of struct. Please. 😃
Good design proposal above.
@tmilnthorp Do you still get the cyclic problem if you make the reference pressure nullable, like Pressure?
?
Is it an option to use a wrapper class type, which holds Pressure Value
and Pressure ReferenceValue
?
I suspect the struct
vs class
discussion is not getting resolved anytime soon, but yep, the arguments for class
is starting to pile on by now.
That other pressure for gauge is usually 1 atm but not necessarily. What if we're on the moon?
On earth we have defined it to be exactly 1 atm or 101325 Pa so it is a constant when switching between absolute- and relative. In the real world it of cause is not constant but we dont have to worry about that.
In my experience engineers tent to use absolute pressure and people on the floor tent to use relative. Engineer wants to use a system that also work on the moon hence absolute pressure. Workers want a system that shows '0' pressure when all the valves are open (They dont care about that the real pressure is ~1 atm)
Is it an option to use a wrapper class type, which holds Pressure Value and Pressure ReferenceValue?
Actually, I followed this way(except it is still a struct) with success and integrated it into the project I work on. It seems to work good so far. And I was going to post it here. @angularsen
Great!
Yes, although I'm a newbie in the domain of pressure, it somehow feels awkward to build in the concepts of relative and absolute measures into Pressure
. Pressure is about representing a pressure measurement, its value and unit, and converting between units. To convert between different reference pressures is an application-specific thing. I mean, we could add it to UnitsNet, but I have a gut-feeling it should be its own type and wrap the two values as per bullet point 2 above.
Another thing I'm curious about. You are talking about relative vs absolute pressure values. In my mind, there is no such thing as an absolute pressure measurement. Everything is relative. You measure the pressure difference between two levels, always. I guess there are conventions that one often measures relative to 1 atmosphere, but it is by no means absolute as in the example of the moon or possibly even way lower levels if the theory of false vacuum turns out to be true - although our universe as we know it may collapse as a result of it 😄
Another thing I'm curious about. You are talking about relative vs absolute pressure values. In my mind, there is no such thing as an absolute pressure measurement. Everything is relative. You measure the pressure difference between two levels, always.
In a way you are right: "absolute pressure" is relative to absolute vacuum "relative pressure" is relative to atmosphere pressure
I think some day the whole world would agree about only using absolute pressure however we are not here yet and until then we will have to convert between both pressure units and absolute/relative pressure. It would sure make my life easier if UnitNet also could handle absolute/relative pressure.
Most physical pressure gauges shows the pressure as relative pressure therefore a lot of people are used to relative pressure.
I see, thanks for explaining. Well, I'm all for simplifying this and making the change into UnitsNet, but we need a design proposal first.
If I understand it right, due to limitations on struct
we can't really do option 1 above, so I guess we are left with option 2 of adding a wrapper type? Anyone want to be the champion and draft up a design proposal and follow up with a pull request when we agree on a design?
I'd like to propose the following as to create the instance of reference pressure in the form of:
new ReferencePressure(Pressure pressure, PressureReference reference, Pressure referencedPressure)`
new ReferencePressure(Pressure pressure, PressureReference reference)
public enum PressureReference
{
Undefined = 0,
Absolute,
Gauge,
Vacuum,
}
public static PressureReference BaseReference { get; } = PressureReference.Absolute;
public static Pressure ReferencedPressure { get; set; } = new Pressure(1, PressureUnit.Atmosphere);
private readonly PressureReference? _reference;
public PressureReference Reference => _reference.GetValueOrDefault(BaseReference);
private Pressure Pressure { get; }
AsBaseReference()
method that would perform a corresponding mathematical operation and return a converted value according to selected pressure reference. AsBaseNumericType(PressureReference reference)
method that would use the baseReference
value to make pressure conversion taking into account ReferencedPressure
As(PressureReference reference)
method that would use the converted value from AsBaseNumericType()
to return new instance of Pressure
quantity.As()
method
public Pressure Gauge => As(PressureReference.Gauge);
public Pressure Absolute => As(PressureReference.Absolute);
public Pressure Vacuum => As(PressureReference.Vacuum);
This implementation will allow making conversion operations in the following form:
ReferencePressure refPressure = new ReferencePressure(Pressure.FromAtmospheres(3), PressureReference.Absolute, Pressure.FromAtmosphere(2));
double pressure = refPressure.Gauge.Atmosphere;
with the preservation of Quantity type after conversion operations. If everyone comes to the agreement, I will create a pull request @angularsen
Thanks @gratestas , this is helpful. Although, me not being familiar with pressure engineering, I do struggle a bit to see how and why this will all be used.
I know you have already gone into great detail earlier so I had to refresh my mind a bit re-reading earlier posts, in particular this https://github.com/angularsen/UnitsNet/issues/422#issuecomment-386918885
Pressure is a state function, for its measurement depends on environmental factors such as ambient pressure, elevation above sea level and local weather conditions. For two persons located in the different environment to speak of the same pressure, one must relate it to a reference. There are three basis reference: absolute, gauge, vacuum.
- Absolute is zero-referenced to the total vacuum.
- Gauge refers to a level of the local atmospheric pressure.
- Vacuum is the negative of the gauge.
Tanks/containers contain pressurised fluids surface of which is referenced to atmospheric pressure. [...] The gauge will start reading from 0 atm.
Pumps, though, have a different story. When you have a tank communicating with a pump you better go for absolute reference since the pump's performance depends on the differential pressure between the suction and discharge nozzles.
So this helps put some context to why we want these three different references.
I think this would help understand the design proposal a lot better.
Try using real life examples like tanks, pumps and other relatable concepts and write some short pseudo code with Assert.Equals()
statements to show calculations for Gauge/Absolute/Vacuum variants as well as all or most of the constructors and methods/properties you suggest adding. Don't create full unit tests or bother about accurate numbers, just illustrate how this will be used.
new ReferencePressure(Pressure.FromAtmospheres(3), PressureReference.Absolute, Pressure.FromAtmosphere(2));
Being a novice in pressure, this is not intuitive to me. Are we creating a pressure measurement of 3 atmospheres in absolute reference (0 being total vacuum)? What is the third parameter? It seems like a pressure value it should be relative to, but we specify Absolute here and I thought that was always relative to the absolute vacuum level. As you can probably tell, I'm just confused :-) Some calculation examples as mentioned already would probably clear things up a lot.
Just following up here, do you still intend to pursue this idea? In my last comment I have some questions and suggestions for how to move this forward.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
@angularsen It looks like @gratestas may have actually implemented this in a project titled Units by @YektaMirkan, which appears to be a fork of UnitsNet that is not a child of UnitsNet back on Jan. 21, 2019. Anybody, please correct me if I am wrong.
@sequc82 Thanks for bringing the changes back into UnitsNet!
Hi, I have thought whether conversion feature of one pressure measurement reference to another (absolute, gauge, vacuum, barometric) will fit the UnitsNet's standards and enrich it.
Regarding the matter, it is widely used feature in fluid dynamics. So, in case it is valued as worth to think about, I'd like to discuss the situation in details.