From 55aade4776e331e5e8be8e5fe58b18b7bd711cad Mon Sep 17 00:00:00 2001 From: Ian Bell Date: Sat, 21 Mar 2015 18:44:21 -0600 Subject: [PATCH] c_p works with PH BICUBIC Signed-off-by: Ian Bell --- src/Backends/Tabular/BicubicBackend.cpp | 43 +++++++++++++++++++++ src/Backends/Tabular/BicubicBackend.h | 50 +++++++++++++++++++++++-- src/Backends/Tabular/TTSEBackend.h | 27 ++++++++++++- src/Backends/Tabular/TabularBackends.h | 32 ++++++++++++++++ 4 files changed, 147 insertions(+), 5 deletions(-) diff --git a/src/Backends/Tabular/BicubicBackend.cpp b/src/Backends/Tabular/BicubicBackend.cpp index 71d41656..65dee09e 100644 --- a/src/Backends/Tabular/BicubicBackend.cpp +++ b/src/Backends/Tabular/BicubicBackend.cpp @@ -300,5 +300,48 @@ double CoolProp::BicubicBackend::evaluate_single_phase(SinglePhaseGriddedTableDa } return val; } +/// Use the single_phase table to evaluate an output +double CoolProp::BicubicBackend::evaluate_single_phase_derivative(SinglePhaseGriddedTableData &table, std::vector > &coeffs, parameters output, double x, double y, std::size_t i, std::size_t j, std::size_t Nx, std::size_t Ny) +{ + // Get the cell + CellCoeffs &cell = coeffs[i][j]; + + // Get the alpha coefficients + const std::vector &alpha = cell.get(output); + + // Normalized value in the range (0, 1) + double xhat = (x - table.xvec[i])/(table.xvec[i+1] - table.xvec[i]); + double yhat = (y - table.yvec[j])/(table.yvec[j+1] - table.yvec[j]); + double dxhatdx = 1/(table.xvec[i+1] - table.xvec[i]); + double dyhatdy = 1/(table.yvec[j+1] - table.yvec[j]); + + // Calculate the output value desired + double val = 0; + if (Nx == 1 && Ny == 0){ + for (std::size_t l = 1; l < 4; ++l) + { + for(std::size_t m = 0; m < 4; ++m) + { + val += alpha[m*4+l]*l*pow(xhat, l-1)*pow(yhat, m); + } + } + // val is now dz/dxhat|yhat + return val*dxhatdx; + } + else if (Ny == 1 && Nx == 0){ + for (std::size_t l = 0; l < 4; ++l) + { + for(std::size_t m = 1; m < 4; ++m) + { + val += alpha[m*4+l]*pow(xhat, l)*m*pow(yhat, m-1); + } + } + // val is now dz/dyhat|xhat + return val*dyhatdy; + } + else{ + throw ValueError("Invalid input"); + } +} #endif // !defined(NO_TABULAR_BACKENDS) \ No newline at end of file diff --git a/src/Backends/Tabular/BicubicBackend.h b/src/Backends/Tabular/BicubicBackend.h index f86086b9..29c860cf 100644 --- a/src/Backends/Tabular/BicubicBackend.h +++ b/src/Backends/Tabular/BicubicBackend.h @@ -127,15 +127,60 @@ class BicubicBackend : public TabularBackend std::string backend_name(void){return "BicubicBackend";} /// Build the \f$a_{i,j}\f$ coefficients for bicubic interpolation void build_coeffs(SinglePhaseGriddedTableData &table, std::vector > &coeffs); + /** Update the state + */ void update(CoolProp::input_pairs input_pair, double val1, double val2); + + /** + * @brief Evaluate a derivative in terms of the native inputs of the table + * @param table A reference to the table to be used + * @param coeffs A reference to the matrix of the coefficients + * @param output The output variable + * @param x The + * @param y + * @param i + * @param j + * @param Nx The number of derivatives with respect to x with y held constant + * @param Ny The number of derivatives with respect to y with x held constant + * @return + */ + double evaluate_single_phase_derivative(SinglePhaseGriddedTableData &table, std::vector > &coeffs, parameters output, double x, double y, std::size_t i, std::size_t j, std::size_t Nx, std::size_t Ny); + double evaluate_single_phase_phmolar_derivative(parameters output, std::size_t i, std::size_t j, std::size_t Nx, std::size_t Ny){ + return evaluate_single_phase_derivative(single_phase_logph, coeffs_ph, output, _hmolar, _p, i, j, Nx, Ny); + }; + double evaluate_single_phase_pT_derivative(parameters output, std::size_t i, std::size_t j, std::size_t Nx, std::size_t Ny){ + return evaluate_single_phase_derivative(single_phase_logpT, coeffs_pT, output, _T, _p, i, j, Nx, Ny); + }; + + /** + * @brief + * @param table A reference to the table that is to be used + * @param coeffs A reference to the matrix of bicubic coefficients + * @param output What output is desired + * @param x The x value for the native inputs + * @param y + * @param i + * @param j + * @return + */ double evaluate_single_phase(SinglePhaseGriddedTableData &table, std::vector > &coeffs, parameters output, double x, double y, std::size_t i, std::size_t j); - double evaluate_single_phase_transport(SinglePhaseGriddedTableData &table, parameters output, double x, double y, std::size_t i, std::size_t j); - double evaluate_single_phase_phmolar(parameters output, std::size_t i, std::size_t j){ + double evaluate_single_phase_phmolar(parameters output, std::size_t i, std::size_t j){ return evaluate_single_phase(single_phase_logph, coeffs_ph, output, _hmolar, _p, i, j); }; double evaluate_single_phase_pT(parameters output, std::size_t i, std::size_t j){ return evaluate_single_phase(single_phase_logpT, coeffs_pT, output, _T, _p, i, j); }; + + /** + * @brief Evaluate the single-phase transport properties using linear interpolation. Works well except for near the critical point + * @param table A reference to the table to be used + * @param output The output parameter, viscosity or conductivity + * @param x The + * @param y + * @return + */ + double evaluate_single_phase_transport(SinglePhaseGriddedTableData &table, parameters output, double x, double y, std::size_t i, std::size_t j); + double evaluate_single_phase_phmolar_transport(parameters output, std::size_t i, std::size_t j){ return evaluate_single_phase_transport(single_phase_logph, output, _hmolar, _p, i, j); }; @@ -144,7 +189,6 @@ class BicubicBackend : public TabularBackend }; }; -double do_one(); } #endif // BICUBICBACKEND_H diff --git a/src/Backends/Tabular/TTSEBackend.h b/src/Backends/Tabular/TTSEBackend.h index dfaa39f3..4833664c 100644 --- a/src/Backends/Tabular/TTSEBackend.h +++ b/src/Backends/Tabular/TTSEBackend.h @@ -22,11 +22,34 @@ class TTSEBackend : public TabularBackend return evaluate_single_phase(single_phase_logpT, output, _T, _p, i, j); } double evaluate_single_phase_phmolar_transport(parameters output, std::size_t i, std::size_t j){ - throw evaluate_single_phase_transport(single_phase_logph, output, _hmolar, _p, i, j); + return evaluate_single_phase_transport(single_phase_logph, output, _hmolar, _p, i, j); } double evaluate_single_phase_pT_transport(parameters output, std::size_t i, std::size_t j){ - throw evaluate_single_phase_transport(single_phase_logpT, output, _T, _p, i, j); + return evaluate_single_phase_transport(single_phase_logpT, output, _T, _p, i, j); } + + /** + * @brief Evaluate a derivative in terms of the native inputs of the table + * @param table A reference to the table to be used + * @param coeffs A reference to the matrix of the coefficients + * @param output The output variable + * @param x The + * @param y + * @param i + * @param j + * @param Nx The number of derivatives with respect to x with y held constant + * @param Ny The number of derivatives with respect to y with x held constant + * @return + */ + double evaluate_single_phase_derivative(SinglePhaseGriddedTableData &table, parameters output, double x, double y, std::size_t i, std::size_t j, std::size_t Nx, std::size_t Ny){ + throw NotImplementedError("Not yet implemented"); + } + double evaluate_single_phase_phmolar_derivative(parameters output, std::size_t i, std::size_t j, std::size_t Nx, std::size_t Ny){ + return evaluate_single_phase_derivative(single_phase_logph, output, _hmolar, _p, i, j, Nx, Ny); + }; + double evaluate_single_phase_pT_derivative(parameters output, std::size_t i, std::size_t j, std::size_t Nx, std::size_t Ny){ + return evaluate_single_phase_derivative(single_phase_logpT, output, _T, _p, i, j, Nx, Ny); + }; }; } // namespace CoolProp diff --git a/src/Backends/Tabular/TabularBackends.h b/src/Backends/Tabular/TabularBackends.h index 3450d150..ce453401 100644 --- a/src/Backends/Tabular/TabularBackends.h +++ b/src/Backends/Tabular/TabularBackends.h @@ -424,6 +424,8 @@ class TabularBackend : public AbstractState virtual double evaluate_single_phase_pT(parameters output, std::size_t i, std::size_t j) = 0; virtual double evaluate_single_phase_phmolar_transport(parameters output, std::size_t i, std::size_t j) = 0; virtual double evaluate_single_phase_pT_transport(parameters output, std::size_t i, std::size_t j) = 0; + virtual double evaluate_single_phase_phmolar_derivative(parameters output, std::size_t i, std::size_t j, std::size_t Nx, std::size_t Ny) = 0; + virtual double evaluate_single_phase_pT_derivative(parameters output, std::size_t i, std::size_t j, std::size_t Nx, std::size_t Ny) = 0; /// Returns the path to the tables that shall be written std::string path_to_tables(void); @@ -495,6 +497,14 @@ class TabularBackend : public AbstractState return pure_saturation.evaluate(iHmolar, _p, _Q, cached_saturation_iL, cached_saturation_iV); } } + CoolPropDbl calc_cpmolar(void){ + if (using_single_phase_table){ + return calc_first_partial_deriv(iHmolar, iT, iP); + } + else{ + throw ValueError("table not selected"); + } + } CoolPropDbl calc_viscosity(void){ if (using_single_phase_table){ @@ -522,6 +532,28 @@ class TabularBackend : public AbstractState return pure_saturation.evaluate(iconductivity, _p, _Q, cached_saturation_iL, cached_saturation_iV); } } + CoolPropDbl calc_first_partial_deriv(parameters Of, parameters Wrt, parameters Constant){ + if (using_single_phase_table){ + switch(selected_table){ + case SELECTED_PH_TABLE: { + if (Of == iHmolar && Wrt == iT && Constant == iP){ + double val = 1/(evaluate_single_phase_phmolar_derivative(iT,cached_single_phase_i, cached_single_phase_j,1,0)); + return val; + } + else{ + throw ValueError("This derivative output not yet supported"); + } + } + case SELECTED_PT_TABLE: throw ValueError("No P-T derivatives yet"); + case SELECTED_NO_TABLE: throw ValueError("table not selected"); + } + return _HUGE; // not needed, will never be hit, just to make compiler happy + } + else{ + return pure_saturation.evaluate(iconductivity, _p, _Q, cached_saturation_iL, cached_saturation_iV); + } + + }; TabularBackend(shared_ptr AS){ using_single_phase_table = false;