Skip to content
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

Issue in Fluid.Dissipation function #1350

Closed
modelica-trac-importer opened this issue Jan 14, 2017 · 12 comments
Closed

Issue in Fluid.Dissipation function #1350

modelica-trac-importer opened this issue Jan 14, 2017 · 12 comments
Assignees
Labels
enhancement New feature or enhancement L: Fluid.Dissipation Issue addresses Modelica.Fluid.Dissipation

Comments

@modelica-trac-importer
Copy link

Reported by allanwittkopf on 11 Nov 2013 18:15 UTC
In the function dp_curvedOverall_MFLOW, there are two computations:

SI.Velocity v_lam=(-A2/2*IN_var.eta + 0.5*sqrt(max(MIN, (A2*IN_var.eta)^2 + 8   
          *zeta_LOC_sharp_turb*abs(dp)*IN_var.rho*d_hyd^2)))/zeta_LOC_sharp_turb/         
            IN_var.rho/d_hyd

SI.Velocity v_tra=(-A2/2*IN_var.eta + 0.5*sqrt(max(MIN, (A2*IN_var.eta)^2 + 8       
            *zeta_LOC_sharp_turb*abs(dp_lam_max)*IN_var.rho*d_hyd^2)))/
            zeta_LOC_sharp_turb/IN_var.rho/d_hyd

that have serious computational difficulties when A2/2*IN_var.eta >> 8*zeta_LOC_sharp_turb*abs(dp)*IN_var.rho*d_hyd^2

Setting

a=2*zeta_LOC_sharp_turb*abs(dp)*IN_var.rho*d_hyd^2
b=A2/2*IN_var.eta
c=zeta_LOC_sharp_turb*IN_var.rho*d_hyd

the first computation simplifies to:

v_lam = (-b+sqrt(max(MIN/4,b^2)+a)/c

The issue is that if b is large, and a is small, the sum in the numerator suffers from severe catastrophic cancellation.

For simplicity, assume that b=3000, and a=1e-5 (and c=1), then computation at hardware precision gives v_lam = 0.166666666667e-9, while the accurate value for this expression is 0.167347025126e-9.
A modest increase of the value of b to 30000 results in v_lam=0.

Round-off errors of this type can wreak havoc with integrator error control.

As a workaround, I recoded the expressions for v_lam and v_tra to use a 1-term asymptotic expansion whenever abs(a)<2e-8*abs(b) as follows:

   SI.Velocity v_lam=if 8e8*abs(zeta_LOC_sharp_turb*abs(dp)*IN_var_rho*d_hyd^2)
   < abs(A2*IN_var_eta) then
      2*abs(dp)*d_hyd/A2/IN_var_eta
   else
      (-A2/2*IN_var_eta+1/2*sqrt(max(MIN,(A2*IN_var_eta)^2) +
      8*zeta_LOC_sharp_turb*abs(dp)*IN_var_rho*d_hyd^2))
      /zeta_LOC_sharp_turb/IN_var_rho/d_hyd

SI.Velocity v_tra=if 8e8*abs(zeta_LOC_sharp_turb*abs(dp_lam_max)*IN_var_rho
   *d_hyd^2) < abs(A2*IN_var_eta) then
      2*abs(dp_lam_max)*d_hyd/A2/IN_var_eta
   else
      (-A2/2*IN_var_eta+1/2*sqrt(max(MIN,(A2*IN_var_eta)^2 +
      8*zeta_LOC_sharp_turb*abs(dp_lam_max)*IN_var_rho*d_hyd^2)))
      /zeta_LOC_sharp_turb/IN_var_rho/d_hyd

and this repaired the behavior, giving 8 digits of accuracy overall, instead of 0 digits of accuracy when b>>a.

This might normally not be much of a concern, but when this component is used in a model, the sign of v_lam and v_tra are relevant to other conditionals, and having them jump to zero when they should still be a small positive value can present problems.

For a formal fix, it may be advisable to carry the expansion out to more than just 1 term, and increase the usage region, which could be used to attain ~ 11 digits of accuracy overall (for a 2 term expansion) or ~ 13 digits (for a 3-term expansion).


Migrated-From: https://trac.modelica.org/Modelica/ticket/1350

@modelica-trac-importer modelica-trac-importer added bug Critical/severe issue L: Fluid.Dissipation Issue addresses Modelica.Fluid.Dissipation labels Jan 14, 2017
@modelica-trac-importer
Copy link
Author

Comment by wischhusen on 14 Feb 2014 12:04 UTC

For simplicity, assume that b=3000, and a=1e-5 (and c=1), then computation at hardware precision gives v_lam = 0.166666666667e-9, while the accurate value for this expression is 0.167347025126e-9.
A modest increase of the value of b to 30000 results in v_lam=0.

I could not follow here. How did you calculate the correct solution? I receive the solution of 0.167347025126e-9 for b=30000 (and MIN=1e-15) using Dymola and Matlab.

The expansion you suggest is certainly correct but we could not determine any significant improvement w.r.t the current formular. Perhaps we need the capability to produce the right solution for the case you selected. Could you give us hints how to determine the failure?

@modelica-trac-importer
Copy link
Author

Comment by awittkop on 14 Feb 2014 16:50 UTC
I performed the initial comparison in Maple, as it has access to arbitrary precision, so can have the precision increased to validate the error in the result.

In Maple I receive the following:

f := proc(a,b,c,MIN) (-b+sqrt(max(MIN/4,b^2)+a))/c; end proc:
hwres := evalhf(f(1e-5,30000,1,1e-15));
-9
hwres := 0.167347025126218796 10

accres := evalf30;
-9
accres := 0.1666666666666662 10

The latter (accres) being the more correct answer computed using 30 Digits in floating point.

In Matlab I perform the same computation as above in hardware precision as follows:

a = 1e-5;
b = 30000;
c = 1.0;
MIN = 1e-15;
(-b+sqrt(max(MIN/4,b^2)+a))/c

ans =

1.6735e-10

The appears to be in complete agreement with the Maple hardware precision result (at least out to the digits that Matlab displays). The error then, as computed in Maple is:

abs(hwres-accres)/abs(accres);
0.004082150399

or 0.4%, meaning we only obtain 2 digits of accuracy for the actual computation.

In terms of a,b,c, and given that for large b, max(MIN/4,b2)=b2, the asymptotic expansion of the formula for a<<b is given by:

f_asympt := proc(a,b,c) a/(2*b*c); end proc:
hwres2 := evalhf(f_asympt(1e-5,30000,1));
-9
hwres2 := 0.166666666666666686 10

which one can see by eye gives a much more accurate result. This is also easily confirmed in Matlab via:

a = 1e-5;
b = 30000;
c = 1.0;
a/(2*b*c)

ans =

1.6667e-10

which is fully accurate to the displayed digits.

@modelica-trac-importer
Copy link
Author

Modified by beutlich on 21 May 2014 20:45 UTC

@modelica-trac-importer
Copy link
Author

Comment by wischhusen on 26 Jun 2014 13:24 UTC
The proposed procedure is plausible from the numerical point of view. Nevertheless, I believe that there are some issues which are not resolved completely:

  1. We move the accuracy step from 1e-8 to 1e-18 since dp in factor a is usually calculated by two integrator state variables (say p1 and p2) which are substracted. The maximum accuracy for substracting two almost identical non-zero pressures defines the location of the new step. At least there will be one at a much lower pressure difference.

  2. There is a new step at

8e8*abs(zeta_LOC_sharp_turb*abs(dp)*IN_var_rho*d_hyd^2)
   < abs(A2*IN_var_eta)

because the simplified solution does not match the exact solution (the rel. difference in your case is about 1e-9), such that the integrator will see another step here.

From the practical point of view we are talking about pressure differences of 1e-5 Pa (for liquid water) at the transition point between simplified and exact solution, which is not even close to the usual operating conditions (>> 1 Pa).

To investigate the impact of the proposed procedure on calculations with zero mass flow rates I would like to test it on a complexer, realistic application. The testing requires some more time. Therefore I propose to change the Milestone to 3.2.2. The current model, although it might be not numerically optimized, works well for existing applications.

@modelica-trac-importer modelica-trac-importer added enhancement New feature or enhancement and removed bug Critical/severe issue labels Jan 14, 2017
@modelica-trac-importer
Copy link
Author

Comment by wischhusen on 2 Dec 2014 08:27 UTC
Introduced the following expansion which worked fine with applications of this function.

  SI.Velocity v_lam=if 1e7*sqrt(abs(zeta_LOC_sharp_turb*abs(dp)*IN_var.rho*
      d_hyd^2)) < abs(A2*IN_var.eta) then 2*abs(dp)*d_hyd/A2/IN_var.eta else (-
      A2/2*IN_var.eta + 0.5*sqrt(max(MIN, (A2*IN_var.eta)^2 + 8*
      zeta_LOC_sharp_turb*abs(dp)*IN_var.rho*d_hyd^2)))/zeta_LOC_sharp_turb/
      IN_var.rho/d_hyd "Mean velocity in laminar regime (Re < Re_lam_leave)";
  SI.Velocity v_tra=if 1e7*sqrt(abs(zeta_LOC_sharp_turb*abs(dp_lam_max)*IN_var.rho
      *d_hyd^2)) < abs(A2*IN_var.eta) then 2*abs(dp_lam_max)*d_hyd/A2/IN_var.eta
       else (-A2/2*IN_var.eta + 0.5*sqrt(max(MIN, (A2*IN_var.eta)^2 + 8*
      zeta_LOC_sharp_turb*abs(dp_lam_max)*IN_var.rho*d_hyd^2)))/
      zeta_LOC_sharp_turb/IN_var.rho/d_hyd 
    "Mean velocity in transition regime (Re_lam_leave < Re_turb_min)";

@modelica-trac-importer
Copy link
Author

Changelog modified by wischhusen on 2 Dec 2014 08:27 UTC
MSL 3.2.1 build 3, Maintenance 3.2.1 and 3.2 build 16

@modelica-trac-importer
Copy link
Author

Comment by wischhusen on 2 Dec 2014 08:28 UTC
Fixed with b549257, 8ffdbb6 and 2f25bbd.

@modelica-trac-importer
Copy link
Author

Modified by beutlich on 2 Dec 2014 08:38 UTC

@modelica-trac-importer
Copy link
Author

Modified by beutlich on 19 Mar 2015 11:37 UTC

@modelica-trac-importer
Copy link
Author

Changelog removed by beutlich on 19 Mar 2015 11:37 UTC

@modelica-trac-importer
Copy link
Author

Modified by wischhusen on 27 Mar 2015 10:06 UTC

@modelica-trac-importer
Copy link
Author

Changelog modified by wischhusen on 27 Mar 2015 10:06 UTC
Introduced a numerical expansion for laminar and transition conditions to avoid numerical errors due to rounding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or enhancement L: Fluid.Dissipation Issue addresses Modelica.Fluid.Dissipation
Projects
None yet
Development

No branches or pull requests

2 participants