NREL / EnergyPlus

EnergyPlus™ is a whole building energy simulation program that engineers, architects, and researchers use to model both energy consumption and water use in buildings.
https://energyplus.net
Other
1.15k stars 392 forks source link

Temperature out of range in "PsyTwbFnTdbWPb" routine #8502

Open tkdogan opened 3 years ago

tkdogan commented 3 years ago

In version EnergyPlusV9-4-0, I am getting the following error for a relatively simple ideal loads simulation that used to run without errors in EnergyPlusV9-0-1. Simulations are run on Win10. Climate is Boston TMY3.

Warning Temperature out of range [-100. to 200.] (PsyPsatFnTemp) ~~~ Routine=PsyTwbFnTdbWPb, Environment=CLIMATE STUDIO, at Simulation time=04/08 09:30 - 09:36 ~~~ Input Temperature=-674.16 Warning Temperature out of range [-100. to 200.] (PsyPsatFnTemp) ~~~ This error occurred 1 total times; ~~~ during Warmup 0 times; ~~~ during Sizing 0 times. ***** ~~~ Max=-674.164185 C Min=-674.164185 C

idf_file.zip

mjwitte commented 3 years ago

@tkdogan Please attach the v9-0-1 file as well. Thanks.

tkdogan commented 3 years ago

@mjwitte - I don't have that handy anymore but if it helps I can recreate it.

mjwitte commented 3 years ago

The warning occurs during weather data setup when calculating the wet-bulb temperature for dry-bulb=4.1C and humidity ratio = 0.00191... (dewpoint is -9.15) The wet-bulb function iterates on wet-bulb to find a solution. The -674.16C value shows up during the iterations (not sure why) and the final return for wet-bulb temperature is -0.5416C. This seems like a very dry condition for Boston in April, but I may be wrong. Anyways, assuming the same weather file was used with v9-0-1, I don't know why the warning appears now, but did not in 9.0.1. It's not impacting the simulations, it's just messy.

jmarrec commented 3 years ago

Related to https://github.com/NREL/EnergyPlus/issues/8828

jmarrec commented 3 years ago

Here are some debug messages during the successive iterations. The Regula-Falsi-like Iterate() method computes a very small DY, hence why it blows up. But it recovers from it.

Starting Simulation at 04/07/2013 for CLIMATE STUDIO

Initial Conditions:
 TDB  =4.15
   W  =0.0019108
Patm  =102000
tBoil =100.16
 WBT  =4.15

Starting iteration 1, current WBT = 4.15
PSatstar=822.099, Patm=102000
Wstar=0.00505377
WBT >= 0,  newW = star=0.00505377, deNum = 2491.35
error = -0.00314296

  Iterate() called, initial conditions:
         Tol   =0.0001
  X0 (WBT)     =4.15
  X1 (WBT-1)   =4.66207e-310
  Y0 (error)   =-0.00314296
  Y1 (error-1) =6.95284e-310
         Iter  =1
WBT = 4.565

Starting iteration 2, current WBT = 4.565
PSatstar=846.369, Patm=102000
Wstar=0.00520421
WBT >= 0,  newW = star=0.00520421, deNum = 2489.61
error = -0.00346271

  Iterate() called, initial conditions:
         Tol   =0.0001
  X0 (WBT)     =4.565
  X1 (WBT-1)   =4.15
  Y0 (error)   =-0.00346271
  Y1 (error-1) =-0.00314296
         Iter  =2
  std::abs(X0 - X1) = 0.415
  DY = -0.00031975
     num  = -2.26353e-05
     DY   = -0.00031975
  ResultX = 0.0707905

WBT = 0.0707905

Starting iteration 3, current WBT = 0.0707905
PSatstar=614.363, Patm=102000
Wstar=0.00376899
WBT >= 0,  newW = star=0.00376899, deNum = 2508.42
error = -0.000210826

  Iterate() called, initial conditions:
         Tol   =0.0001
  X0 (WBT)     =0.0707905
  X1 (WBT-1)   =4.565
  Y0 (error)   =-0.000210826
  Y1 (error-1) =-0.00346271
         Iter  =3
  std::abs(X0 - X1) = 4.49421
  DY = 0.00325188
     num  = -0.000717292
     DY   = 0.00325188
  ResultX = -0.220577

WBT = -0.220577

Starting iteration 4, current WBT = -0.220577
PSatstar=600.144, Patm=102000
Wstar=0.00368124
WBT < 0,  newW = star=0.00368124, deNum = 2838.18
error = -0.000210735

  Iterate() called, initial conditions:
         Tol   =0.0001
  X0 (WBT)     =-0.220577
  X1 (WBT-1)   =0.0707905
  Y0 (error)   =-0.000210735
  Y1 (error-1) =-0.000210826
         Iter  =4
  std::abs(X0 - X1) = 0.291368
  DY = 9.11075e-08
     num  = -6.14214e-05
+     DY   = 9.11075e-08    // This is very very small. Hence why it blows up.
  ResultX = -674.164

WBT = -674.164

Starting iteration 5, current WBT = -674.164
PSatstar=0.0017, Patm=102000
Wstar=1.03663e-08
WBT < 0,  newW = star=1.03663e-08, deNum = 4253.46
error = 0.162341

  Iterate() called, initial conditions:
         Tol   =0.0001
  X0 (WBT)     =-674.164
  X1 (WBT-1)   =-0.220577
  Y0 (error)   =0.162341
  Y1 (error-1) =-0.000210735
         Iter  =5
  std::abs(X0 - X1) = 673.944
  DY = 0.162552
     num  = -0.177879
     DY   = 0.162552
  ResultX = -1.09429

WBT = -1.09429

Starting iteration 6, current WBT = -1.09429
PSatstar=558.286, Patm=102000
Wstar=0.00342308
WBT < 0,  newW = star=0.00342308, deNum = 2840.02
error = 0.000357134

  Iterate() called, initial conditions:
         Tol   =0.0001
  X0 (WBT)     =-1.09429
  X1 (WBT-1)   =-674.164
  Y0 (error)   =0.000357134
  Y1 (error-1) =0.162341
         Iter  =6
  std::abs(X0 - X1) = 673.07
  DY = -0.161984
     num  = -0.0631191
     DY   = -0.161984
  ResultX = 0.389663

WBT = 0.389663

Starting iteration 7, current WBT = 0.389663
PSatstar=628.733, Patm=102000
Wstar=0.0038577
WBT >= 0,  newW = star=0.0038577, deNum = 2507.09
error = -0.000427249

  Iterate() called, initial conditions:
         Tol   =0.0001
  X0 (WBT)     =0.389663
  X1 (WBT-1)   =-1.09429
  Y0 (error)   =-0.000427249
  Y1 (error-1) =0.000357134
         Iter  =7
  std::abs(X0 - X1) = 1.48395
  DY = -0.000784383
     num  = 0.000328371
     DY   = -0.000784383
  ResultX = -0.418637

WBT = -0.418637

Starting iteration 8, current WBT = -0.418637
PSatstar=590.413, Patm=102000
Wstar=0.0036212
WBT < 0,  newW = star=0.0036212, deNum = 2838.6
error = -8.04332e-05

  Iterate() called, initial conditions:
         Tol   =0.0001
  X0 (WBT)     =-0.418637
  X1 (WBT-1)   =0.389663
  Y0 (error)   =-8.04332e-05
  Y1 (error-1) =-0.000427249
         Iter  =8
  std::abs(X0 - X1) = 0.8083
  DY = 0.000346815
     num  = -0.000210204
     DY   = 0.000346815
  ResultX = -0.606097

WBT = -0.606097

Starting iteration 9, current WBT = -0.606097
PSatstar=581.334, Patm=102000
Wstar=0.00356521
WBT < 0,  newW = star=0.00356521, deNum = 2838.99
error = 4.20364e-05

  Iterate() called, initial conditions:
         Tol   =0.0001
  X0 (WBT)     =-0.606097
  X1 (WBT-1)   =-0.418637
  Y0 (error)   =4.20364e-05
  Y1 (error-1) =-8.04332e-05
         Iter  =9
  std::abs(X0 - X1) = 0.18746
  DY = 0.00012247
     num  = -6.63483e-05
     DY   = 0.00012247
  ResultX = -0.541753

WBT = -0.541753

Starting iteration 10, current WBT = -0.541753
PSatstar=584.436, Patm=102000
Wstar=0.00358434
WBT < 0,  newW = star=0.00358434, deNum = 2838.86
error = 9.34546e-08

  Iterate() called, initial conditions:
         Tol   =0.0001
  X0 (WBT)     =-0.541753
  X1 (WBT-1)   =-0.606097
  Y0 (error)   =9.34546e-08
  Y1 (error-1) =4.20364e-05
         Iter  =10
  std::abs(X0 - X1) = 0.0643438
  DY = -4.1943e-05
     num  = 2.27167e-05
     DY   = -4.1943e-05
  ResultX = -0.54161

WBT = -0.54161

Starting iteration 11, current WBT = -0.54161
PSatstar=584.443, Patm=102000
Wstar=0.00358438
WBT < 0,  newW = star=0.00358438, deNum = 2838.86
error = -1.03543e-10

  Iterate() called, initial conditions:
         Tol   =0.0001
  X0 (WBT)     =-0.54161
  X1 (WBT-1)   =-0.541753
  Y0 (error)   =-1.03543e-10
  Y1 (error-1) =9.34546e-08
         Iter  =11
  std::abs(X0 - X1) = 0.000143367
  DY = -9.35582e-08
     num  = 5.0672e-08
     DY   = -9.35582e-08
  ResultX = -0.54161

WBT = -0.54161

Starting iteration 12, current WBT = -0.54161
PSatstar=584.443, Patm=102000
Wstar=0.00358438
WBT < 0,  newW = star=0.00358438, deNum = 2838.86
error = -2.86308e-12

  Iterate() called, initial conditions:
         Tol   =0.0001
  X0 (WBT)     =-0.54161
  X1 (WBT-1)   =-0.54161
  Y0 (error)   =-2.86308e-12
  Y1 (error-1) =-1.03543e-10
         Iter  =12
  std::abs(X0 - X1) = 1.58667e-07
WBT = -0.54161
Converged. breaking.
jmarrec commented 3 years ago

I'm not sure what to do here, but I don't think the PsyPsatFnTemp should throw warnings during iteration. If it's called directly with bad temperatures, sure, but here this is not affecting the end result.

We could also change the algorithm we use to solve (the Iterate() method) to use something like a bisect method.

rraustad commented 3 years ago

The secant method is extremely efficient. Far better than bisect because for a continuous function it will hit the target with only a few iterations, if that continuous function is relatively smooth (no inflections). The latent degradation model is an example of where secant method could easily fail on max iterations but not actually fail. I would think about a way to put off warnings until convergence is not reached. For example, a warning should only be reported if max iterations is reached and the warning persists. Or if the cause of the warning causes the solution to fail. In this case is did not cause the solution to fail. This is similar to SolveRoot's int &Flag argument (arg 4 here) where a warning is reported after iterations are complete.

https://github.com/NREL/EnergyPlus/blob/c18d89d4f13f376998ffefb6d13668be0a964229/src/EnergyPlus/Autosizing/WaterHeatingCoilUASizing.cc#L79-L85