angularsen / UnitsNet

Makes life working with units of measurement just a little bit better.
https://www.nuget.org/packages/UnitsNet/
MIT No Attribution
2.63k stars 383 forks source link

Proposal : Convertion b/w Pressure Measurement References #422

Closed gratestas closed 5 years ago

gratestas commented 6 years ago

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.

gojanpaolo commented 6 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?

angularsen commented 6 years ago

Sounds good to me, please briefly describe:

angularsen commented 6 years ago

@gratestas Waiting for your input to continue this discussion.

gratestas commented 6 years ago

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.

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.

gratestas commented 6 years ago

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.

gratestas commented 6 years ago

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:

angularsen commented 6 years ago

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:

Am I getting it right?

angularsen commented 5 years ago

Closing this due to inactivity, please reopen to continue the discussion.

MrFoged commented 5 years ago

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

tmilnthorp commented 5 years ago

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:

I use the term "reference" above, but Gauge could be substituted if we want.

tmilnthorp commented 5 years ago

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. 😃

angularsen commented 5 years ago

Good design proposal above.

  1. @tmilnthorp Do you still get the cyclic problem if you make the reference pressure nullable, like Pressure??

  2. 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.

MrFoged commented 5 years ago

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)

gratestas commented 5 years ago

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

angularsen commented 5 years ago

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 😄

MrFoged commented 5 years ago

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.

angularsen commented 5 years ago

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?

gratestas commented 5 years ago

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)

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

angularsen commented 5 years ago

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.

Provide code examples for typical calculations for Gauge vs Absolute vs Vacuum

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.

The third ctor parameter confuses me

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.

angularsen commented 5 years ago

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.

stale[bot] commented 5 years ago

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.

sequc82 commented 4 years ago

@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.

angularsen commented 4 years ago

@sequc82 Thanks for bringing the changes back into UnitsNet!