Skip to content

Proposal : Convertion b/w Pressure Measurement References #422

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gratestas opened this issue Mar 22, 2018 · 23 comments
Closed

Proposal : Convertion b/w Pressure Measurement References #422

gratestas opened this issue Mar 22, 2018 · 23 comments
Labels

Comments

@gratestas
Copy link
Contributor

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
Copy link
Contributor

gojanpaolo commented Mar 24, 2018

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
Copy link
Owner

Sounds good to me, please briefly describe:

  • The motivation for this change
  • Example conversions / usecases
  • Pseudo code implementation or bullet points to highlight the changes needed

@angularsen
Copy link
Owner

angularsen commented May 1, 2018

@gratestas Waiting for your input to continue this discussion.

@gratestas
Copy link
Contributor Author

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.

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

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.

  • The implication is that it is much more convenient and sufficient to work with maximum two-digits gauges. The gauge will start reading from 0 atm. Reservoirs are just the same except that it is open to the atmosphere and its surface will always be 0 atm relative to gauge.

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

    • So if it is desired to isolate internal process of a system from the external pressure disturbances, absolute reference is the preference.
    • However, if a certain pressure level needs to be instanteneously maintained relative to atmospheric pressure, gauge reference is better choice.

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.

  • When you take differential, you subtract the suction from discharge pressure. This makes life easier when both pressures are on the positive scale.
  • Another point is about mathematical simplification of calculations. Without going into math, the absence of atmospheric pressure term(as the fact that it is variable too) in an equation saves you from getting too complicated differential equation and decrease cost/iteration.

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
Copy link
Contributor Author

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
Copy link
Contributor Author

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:

  • the first parameter will be taken as the base reference unit and saved to the memory together with the local ambient value
  • then at the level where conversion is being done conversion equations are used

@angularsen
Copy link
Owner

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:

  • What is currently missing is a way to store the reference pressure (50 PSI relative to what)
  • Option A) Add 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?
  • Option B) Duplicate 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.
  • Option C) Add a wrapper like 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?

@angularsen
Copy link
Owner

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

@MrFoged
Copy link

MrFoged commented Mar 5, 2019

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
Copy link
Collaborator

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:

  • Add a PressureType enum (Absolute and Relative)
  • Add a Pressure ReferencePressure field
    • Could be absolute or relative itself!
  • When creating the current pressures, assume Absolute with ReferencePressure = Pressure.Zero.
    • Relative with 1atm would be a bad assumption.
    • It would also break the current behavior with math operations
  • Add a constructor to allow passing a reference temperature, and set PressureType to Relative
  • Add a static Pressure.FromReference(Pressure referencePressure) method with default parameter of 1 atm
  • Add ToAbsolute method
    • Absolute pressures return this
    • Relative pressures do a conversion
      • ReferencePressure.ToAbsolute could be chained n levels deep for this calculation.
  • Update arithmetic operations
    • Would need a way to override arithmetic operators
      • Add protected virtual Add/Subtract/etc methods and forward arithmetic operators?

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

@tmilnthorp tmilnthorp reopened this Mar 5, 2019
@tmilnthorp
Copy link
Collaborator

Hmmm, I just tried to play with a bit of code and got stuck immediately.

  • Adding a ReferencePressure member of type Pressure causes an error: Struct member 'Pressure.ReferencePressure' of type 'Pressure' causes a cycle in the struct layout

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
Copy link
Owner

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
Copy link

MrFoged commented Mar 6, 2019

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
Copy link
Contributor Author

gratestas commented Mar 8, 2019

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
Copy link
Owner

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
Copy link

MrFoged commented Mar 9, 2019

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
Copy link
Owner

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
Copy link
Contributor Author

gratestas commented Mar 11, 2019

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)
  • Add a pressure type enum
 public enum PressureReference
    {
        Undefined = 0,
        Absolute,
        Gauge,
        Vacuum,
    }
  • Add base reference property
public static PressureReference BaseReference { get; } = PressureReference.Absolute;
  • Add pressure property to be referenced to:
public static Pressure ReferencedPressure { get; set; } = new Pressure(1, PressureUnit.Atmosphere);
  • Add pressure reference typed Reference property with the back field the quantity was constructed with
 private readonly PressureReference? _reference;
public PressureReference Reference => _reference.GetValueOrDefault(BaseReference);
  • Add pressure property that would store value constructed with:
        private Pressure Pressure { get; }
  • Add AsBaseReference() method that would perform a corresponding mathematical operation and return a converted value according to selected pressure reference.
  • Add AsBaseNumericType(PressureReference reference) method that would use the baseReference value to make pressure conversion taking into account ReferencedPressure
  • Add As(PressureReference reference) method that would use the converted value from AsBaseNumericType() to return new instance of Pressure quantity.
  • Add three get methods to invoke 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

@angularsen
Copy link
Owner

angularsen commented Mar 12, 2019

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 #422 (comment)

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
Copy link
Owner

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
Copy link

stale bot commented Sep 24, 2019

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.

@stale stale bot added the wontfix label Sep 24, 2019
@stale stale bot closed this as completed Oct 1, 2019
@sequc82
Copy link
Contributor

sequc82 commented Dec 3, 2019

@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
Copy link
Owner

@sequc82 Thanks for bringing the changes back into UnitsNet!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants