ibpsa / modelica-ibpsa

Modelica library for building and district energy systems developed within IBPSA Project 1
https://ibpsa.github.io/project1
143 stars 84 forks source link

Pressure-independent valve model #156

Closed Mathadon closed 7 years ago

Mathadon commented 9 years ago

The Annex60/Building library does not seem to contain a model for a pressure-independent valve (example: http://www.belimo.ch/pdf/e/r2p_2_e.pdf). These valves supply a desired mass flow rate regardless of the supplied pressure (as long as the pressure is high enough). I intend to make such a model. Is this something that I should make a pull request for?

mwetter commented 9 years ago

This would be useful. Similar components also exist for air dampers. I created a new branch issue156_pressureIndValve, please add the model, unit tests and reference result onto that branch (or a pull request for this branch).

Mathadon commented 9 years ago

The current implementation of the valve has bad numerics since multiple solution to the flow problem may exist. This is because the used spliceFunction generates a local maximum in the curve. I think I fixed the problem by just using a regular min function. However this implementation is not very smooth. Otherwise we could create a custom polynomial transition or offset the spliceFunction input x as follows: x=dp-dp_min-deltax*dp_nominal_pos. This gives the following result: screen shot 2015-02-16 at 09 56 56

or we could do both and switch to the use of min when deltax==0.

I prefer the last option: combine min and an offset for x since I'm not familiar with the creation of these polynomials. The downside is that the error can be quite large for typical values of deltax.

mwetter commented 9 years ago

I suggest to use a polynomial unless you can proof formally (not by simulation) that offsetting the splice function always works for any values of dp, dp_min, deltax and dp_nominal_pos.

You can construct a polynomial by assuming a form such as y = a + b*x + c*x^2 + d*x^3. (or maybe y = a + b*x^2 + c*x^4 + d * x^6. Then, impose that at two points near the non-differentiability, the polynomial must have the same function value and the same first derivative. This gives you four conditions for the coefficients.

Mathadon commented 9 years ago

The problem is that the polynomial is a function of dp_min and m_flow_set so coefficients a, b, c, d cannot be constant unless x and y are somehow made dimensionless. I looked into it earlier but I did not find a proper solution. I'll need to look into this again later.

Mathadon commented 8 years ago

Essentially we need a function dp = f(m_flow) that satisfies:

f(m_flow_set) = k*m_flow_set^2
f'(m_flow_set) = 2*k*m_flow_set
f(m_flow_set*(1+deltax)) = k*m_flow_set^2 * (1+ deltax2)
f'(m_flow_set*(1+deltax)) = slope

with deltax, deltax2 and slope parameters, but more importantly m_flow_set is a variable.

Therefore solving f(x) = a + b*x^2 + c*x^4 + d * x^6 is not easy since its coefficients depend on m_flow_set. I had another look at it yesterday and I don't know how to solve this.

So far we have not had any problems with the current implementation. But an alternative may be to use min(,) instead of a spliceFunction( , , ). We could add a constant/parameter that allows switching between the two implementations. The user can then switch when either of the two implementations generates problems..

mwetter commented 8 years ago

@Mathadon I don't quite understand why solving f(x) = a + b*x^2 + c*x^4 + d * x^6 is not easy. If I understand you right, then x = m_flow_set, f(x) is the pressure drop you want, and then, with the other 3 conditions, you have a linear system of equations for a, b, c, d? Maybe this is best solved by email in a LaTeX file.

I don't like to have "switches" to choose the implementation in case of problems. Users won't know where the problem originates, which switch to use (from_dp, steadystate vs dynamic balances, linearization of pressure drop etc.). This would increase complexity.

If we were to use min instead of spliceFunction (or better regStep) then the flow network is not differentiable anymore and hence a Newton solver may have problems.

Mathadon commented 8 years ago

I tested the implementation with min and it is ~15% slower!

mwetter commented 8 years ago

@Mathadon : I merged your pull request and added two fixme in the code. See the code for the next steps/what is not yet clear. Once the implementation is clear, it should be easy to replace the min and max with smooth approximations that have no over-shoot, using a similar approach as above.

Mathadon commented 7 years ago

The overshoot can be avoided by using cubicHermite. I tested an implementation that seems to work. I'll make a pull request.

Mathadon commented 7 years ago

Old and new implementations:

New: screen shot 2017-04-14 at 09 59 12

Old: screen shot 2017-04-14 at 09 59 44

Mathadon commented 7 years ago

One remaining issue is that m_flow and dp are used to transition from one curve to the other. One one side of the transition the m_flow curve is very flat, while one the other it is quite steep. This causes the value of from_dp (which determines whether m_flow or dp is used) to have a large effect on the shape of the transition. This is illustrated by the differences in the green and the blue curves. In the examples above this effect is however enlarged due to the relatively large value of l2=0.05.

dhblum commented 7 years ago

Can you apply the change to the pressure independent damper from https://github.com/ibpsa/modelica/pull/697#pullrequestreview-32778626?

Mathadon commented 7 years ago

okay, but @mwetter let's review the implementation I'm proposing first

Mathadon commented 7 years ago

We could also use something like

CMin_flow = C1_flow + C2_flow - ((C1_flow)^10 + (C2_flow)^10)^(1/10);

instead of the quintic Hermite spline. This could lead to less operations, less function evaluations and could lead to cleaner code.

mwetter commented 7 years ago

Let's use the spline as it is only evaluated in a small region.