Skip to content

Commit

Permalink
Merge pull request #8946 from LipingWang/Branch_TradeOff_CSpline
Browse files Browse the repository at this point in the history
Add the cubic spline interpolation option for PerformancePrecisionTradeoffs
  • Loading branch information
Myoldmopar authored Aug 19, 2021
2 parents 8a3e50f + 74636cb commit d763b10
Show file tree
Hide file tree
Showing 9 changed files with 738 additions and 124 deletions.

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions idd/Energy+.idd.in
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ PerformancePrecisionTradeoffs,
\key Mode05
\key Mode06
\key Mode07
\key Mode08
\key Advanced
\default Normal
N1, \field MaxZoneTempDiff
Expand Down
4 changes: 2 additions & 2 deletions src/EnergyPlus/PsychCacheData.hh
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ constexpr Int64 psatcache_mask = psatcache_size - 1;
#endif
#ifdef EP_cache_PsyTsatFnPb
constexpr int tsatcache_size = 1024 * 1024;
constexpr int tsatprecision_bits = 24;
constexpr int tsatprecision_bits = 24; // 20
constexpr Int64 tsatcache_mask = tsatcache_size - 1;
#endif
#ifdef EP_cache_PsyTsatFnHPb
Expand Down Expand Up @@ -191,4 +191,4 @@ struct PsychrometricCacheData : BaseGlobalStruct

} // namespace EnergyPlus

#endif // PsychCacheData_hh_INCLUDED
#endif // PsychCacheData_hh_INCLUDED
117 changes: 71 additions & 46 deletions src/EnergyPlus/Psychrometrics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1345,58 +1345,63 @@ namespace Psychrometrics {
return state.dataPsychrometrics->tSat_Save;
}
state.dataPsychrometrics->Press_Save = Press;
if (state.dataPsychrometrics->useInterpolationPsychTsatFnPb) {
int n_sample = 1651; // sample bin size = 64 Pa; continous sample size = 1651
// CSpline interpolation
tSat = CSplineint(n_sample, Press); // Cubic spline interpolation
iter = 0;
} else {
// Uses an iterative process to determine the saturation temperature at a given
// pressure by correlating saturated water vapor as a function of temperature.

// Uses an iterative process to determine the saturation temperature at a given
// pressure by correlating saturated water vapor as a function of temperature.
// Initial guess of boiling temperature
tSat = 100.0;
iter = 0;

// Initial guess of boiling temperature
tSat = 100.0;
iter = 0;
// If above 1555000,set value of Temp corresponding to Saturation Pressure of 1555000 Pascal.
if (Press >= 1555000.0) {
tSat = 200.0;
// If below 0.0017,set value of Temp corresponding to Saturation Pressure of 0.0017 Pascal.
} else if (Press <= 0.0017) {
tSat = -100.0;

// If above 1555000,set value of Temp corresponding to Saturation Pressure of 1555000 Pascal.
if (Press >= 1555000.0) {
tSat = 200.0;
// If below 0.0017,set value of Temp corresponding to Saturation Pressure of 0.0017 Pascal.
} else if (Press <= 0.0017) {
tSat = -100.0;
// Setting Value of PsyTsatFnPb= 0C, due to non-continuous function for Saturation Pressure at 0C.
} else if ((Press > 611.000) && (Press < 611.25)) {
tSat = 0.0;

// Setting Value of PsyTsatFnPb= 0C, due to non-continuous function for Saturation Pressure at 0C.
} else if ((Press > 611.000) && (Press < 611.25)) {
tSat = 0.0;
} else {
// Iterate to find the saturation temperature
// of water given the total pressure

// Set iteration loop parameters
// make sure these are initialized
Real64 pSat; // Pressure corresponding to temp. guess
Real64 error; // Deviation of dependent variable in iteration
Real64 X1; // Previous value of independent variable in ITERATE
Real64 Y1; // Previous value of dependent variable in ITERATE
Real64 ResultX; // ResultX is the final Iteration result passed back to the calling routine
bool const CalledFrom_empty(CalledFrom.empty());
int icvg; // Iteration convergence flag
for (iter = 1; iter <= itmax; ++iter) {

// Calculate saturation pressure for estimated boiling temperature
pSat = PsyPsatFnTemp(
state, tSat, (CalledFrom_empty ? PsyRoutineNames[static_cast<int>(PsychrometricFunction::TsatFnPb)] : CalledFrom));

// Compare with specified pressure and update estimate of temperature
error = Press - pSat;
Iterate(ResultX, convTol, tSat, error, X1, Y1, iter, icvg);
tSat = ResultX;
// If converged leave loop iteration
if (icvg == 1) break;

// Water temperature not converged, repeat calculations with new
// estimate of water temperature
}

} else {
// Iterate to find the saturation temperature
// of water given the total pressure

// Set iteration loop parameters
// make sure these are initialized
Real64 pSat; // Pressure corresponding to temp. guess
Real64 error; // Deviation of dependent variable in iteration
Real64 X1; // Previous value of independent variable in ITERATE
Real64 Y1; // Previous value of dependent variable in ITERATE
Real64 ResultX; // ResultX is the final Iteration result passed back to the calling routine
bool const CalledFrom_empty(CalledFrom.empty());
int icvg; // Iteration convergence flag
for (iter = 1; iter <= itmax; ++iter) {

// Calculate saturation pressure for estimated boiling temperature
pSat =
PsyPsatFnTemp(state, tSat, (CalledFrom_empty ? PsyRoutineNames[static_cast<int>(PsychrometricFunction::TsatFnPb)] : CalledFrom));

// Compare with specified pressure and update estimate of temperature
error = Press - pSat;
Iterate(ResultX, convTol, tSat, error, X1, Y1, iter, icvg);
tSat = ResultX;
// If converged leave loop iteration
if (icvg == 1) break;

// Water temperature not converged, repeat calculations with new
// estimate of water temperature
// Saturation temperature has not converged after maximum specified
// iterations. Print error message, set return error flag, and RETURN
}

// Saturation temperature has not converged after maximum specified
// iterations. Print error message, set return error flag, and RETURN

} // End If for the Pressure Range Checking

#ifdef EP_psych_stats
Expand Down Expand Up @@ -1439,6 +1444,26 @@ namespace Psychrometrics {

return Temp;
}
Real64 CSplineint(int const n, // sample data size
const Real64 &x) // given value of x
{ // Cubic Spline interpolation
// Reference: Numerical Recipies in C (pp.97)
Real64 A, B, y;
// find location of x in arrays without searching since array bins are equally sized
int x_int = static_cast<int>(x);
//********continous sample start
int j = (x_int >> 6) - 1; // sample bin 64, sample size=1651
if (j < 0) j = 0;
if (j > (n - 2)) j = n - 2;
static constexpr Real64 h(64); // sample bin 64, sample size=1651
//********continous sample end
int tsat_fn_pb_x_j1 = 64 * (j + 1); // sample data for pressure
A = (tsat_fn_pb_x_j1 - x) / h;
B = 1 - A;
y = A * tsat_fn_pb_y[j] + B * tsat_fn_pb_y[j + 1] +
((A * A * A - A) * (tsat_fn_pb_d2y[j]) + (B * B * B - B) * (tsat_fn_pb_d2y[j + 1])) * (h * h) * 0.1666666667;
return y;
}

} // namespace Psychrometrics

Expand Down
Loading

2 comments on commit d763b10

@nrel-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

develop (Myoldmopar) - Win64-Windows-10-VisualStudio-16: OK (2378 of 2378 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

develop (Myoldmopar) - x86_64-MacOS-10.15-clang-11.0.0: OK (2399 of 2399 tests passed, 0 test warnings)

Build Badge Test Badge

Please sign in to comment.