Closed Mathadon closed 7 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).
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:
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.
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.
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.
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..
@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.
I tested the implementation with min
and it is ~15% slower!
@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.
The overshoot can be avoided by using cubicHermite
. I tested an implementation that seems to work. I'll make a pull request.
Old and new implementations:
New:
Old:
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
.
Can you apply the change to the pressure independent damper from https://github.com/ibpsa/modelica/pull/697#pullrequestreview-32778626?
okay, but @mwetter let's review the implementation I'm proposing first
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.
Let's use the spline as it is only evaluated in a small region.
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?