/**
 * Verify calculation of the derivatives of halite properties by comparing with finite
 * differences
 */
TEST_F(NaClFluidPropertiesTest, derivatives)
{
  const Real tol = REL_TOL_DERIVATIVE;

  const Real p = 30.0e6;
  const Real T = 300.0;

  DERIV_TEST(_fp->rho_from_p_T, p, T, tol);
  DERIV_TEST(_fp->e_from_p_T, p, T, tol);
  DERIV_TEST(_fp->h_from_p_T, p, T, tol);
  DERIV_TEST(_fp->k_from_p_T, p, T, tol);
}
/**
 * Verify calculation of the derivatives of all properties by comparing with finite
 * differences
 */
TEST_F(MethaneFluidPropertiesTest, derivatives)
{
  const Real tol = REL_TOL_DERIVATIVE;

  const Real p = 10.0e6;
  Real T = 350.0;

  DERIV_TEST(_fp->rho, _fp->rho_from_p_T, p, T, tol);
  DERIV_TEST(_fp->mu, _fp->mu_dpT, p, T, tol);
  DERIV_TEST(_fp->e, _fp->e_dpT, p, T, tol);
  DERIV_TEST(_fp->h, _fp->h_dpT, p, T, tol);
  DERIV_TEST(_fp->k, _fp->k_dpT, p, T, tol);

  // Test derivative of enthalpy for T > 755 as well as it has a different formulation
  T = 800.0;
  DERIV_TEST(_fp->h, _fp->h_dpT, p, T, tol);

  // Henry's constant
  T = 350.0;
  const Real dT = 1.0e-4;

  Real dKh_dT_fd = (_fp->henryConstant(T + dT) - _fp->henryConstant(T - dT)) / (2.0 * dT);
  Real Kh = 0.0, dKh_dT = 0.0;
  _fp->henryConstant_dT(T, Kh, dKh_dT);
  REL_TEST(Kh, _fp->henryConstant(T), REL_TOL_SAVED_VALUE);
  REL_TEST(dKh_dT_fd, dKh_dT, REL_TOL_DERIVATIVE);
}
TEST_F(IdealGasFluidPropertiesTest, testAll)
{
  const Real T = 120. + 273.15; // K
  const Real p = 101325;        // Pa

  const Real rho = _fp->rho_from_p_T(p, T);
  const Real v = 1 / rho;
  const Real e = _fp->e_from_p_rho(p, rho);
  const Real s = _fp->s_from_v_e(v, e);
  const Real h = _fp->h_from_p_T(p, T);

  Real e_inv = _fp->e_from_T_v(T, v);
  REL_TEST(e_inv, e, 10.0 * REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->e_from_T_v, T, v, 10.0 * REL_TOL_DERIVATIVE);
  Real p_inv = _fp->p_from_T_v(T, v);
  REL_TEST(p_inv, p, 10.0 * REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->p_from_T_v, T, v, 10.0 * REL_TOL_DERIVATIVE);
  REL_TEST(_fp->h_from_T_v(T, v), h, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->h_from_T_v, T, v, 10.0 * REL_TOL_DERIVATIVE);
  REL_TEST(_fp->s_from_T_v(T, v), s, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->s_from_T_v, T, v, 10.0 * REL_TOL_DERIVATIVE);
  REL_TEST(_fp->cv_from_T_v(T, v), _fp->cv(), REL_TOL_CONSISTENCY);

  REL_TEST(_fp->p_from_h_s(h, s), p, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->p_from_h_s, h, s, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->rho_from_p_s(p, s), rho, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->rho_from_p_s, p, s, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->p_from_v_e(v, e), p, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->p_from_v_e, v, e, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->T_from_v_e(v, e), T, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->T_from_v_e, v, e, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->c_from_v_e(v, e), 398.896207251962, REL_TOL_SAVED_VALUE);
  REL_TEST(_fp->cp_from_v_e(v, e), 987.13756097561, REL_TOL_SAVED_VALUE);
  REL_TEST(_fp->cv_from_v_e(v, e), 700.09756097561, REL_TOL_SAVED_VALUE);
  REL_TEST(_fp->mu_from_v_e(v, e), 0.0, 1e-15);
  REL_TEST(_fp->k_from_v_e(v, e), 0.0, 1e-15);

  REL_TEST(_fp->beta_from_p_T(p, T), 2.54355843825512e-3, REL_TOL_SAVED_VALUE);

  REL_TEST(_fp->s_from_v_e(v, e), 2.58890011905277e3, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->s_from_v_e, v, e, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->rho_from_p_T(p, T), 0.897875065343506, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->rho_from_p_T, p, T, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->v_from_p_T(p, T), 1.0 / 0.897875065343506, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->v_from_p_T, p, T, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->e_from_p_rho(p, rho), 2.75243356097561e5, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->e_from_p_rho, p, rho, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->h_from_p_T(p, T), 3.88093132097561e5, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->h_from_p_T, p, T, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->s_from_p_T(p, T), 2.588900119052767e3, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->s_from_p_T, p, T, REL_TOL_DERIVATIVE);
  ABS_TEST(_fp->s_from_h_p(h, p), 2.588900119052767e3, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->s_from_h_p, h, p, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->e_from_p_T(p, T), 2.75243356097561e5, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->e_from_p_T, p, T, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->molarMass(), 34.522988492890422, REL_TOL_SAVED_VALUE);

  ABS_TEST(_fp->T_from_p_h(p, h), T, REL_TOL_CONSISTENCY);
}
TEST_F(IdealGasFluidPropertiesTest, testAll)
{
  // Test when R and gamma are provided
  Real T = 120. + 273.15; // K
  Real p = 101325;        // Pa

  const Real rho = _fp->rho_from_p_T(p, T);
  const Real v = 1.0 / rho;
  const Real e = _fp->e_from_p_rho(p, rho);
  const Real s = _fp->s_from_v_e(v, e);
  const Real h = _fp->h_from_p_T(p, T);

  Real e_inv = _fp->e_from_T_v(T, v);
  REL_TEST(e_inv, e, 10.0 * REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->e_from_T_v, T, v, 10.0 * REL_TOL_DERIVATIVE);
  Real p_inv = _fp->p_from_T_v(T, v);
  REL_TEST(p_inv, p, 10.0 * REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->p_from_T_v, T, v, 10.0 * REL_TOL_DERIVATIVE);
  REL_TEST(_fp->h_from_T_v(T, v), h, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->h_from_T_v, T, v, 10.0 * REL_TOL_DERIVATIVE);
  REL_TEST(_fp->s_from_T_v(T, v), s, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->s_from_T_v, T, v, 10.0 * REL_TOL_DERIVATIVE);
  REL_TEST(_fp->cv_from_T_v(T, v), _fp->cv_from_v_e(v, e), REL_TOL_CONSISTENCY);

  REL_TEST(_fp->p_from_h_s(h, s), p, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->p_from_h_s, h, s, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->rho_from_p_s(p, s), rho, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->rho_from_p_s, p, s, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->p_from_v_e(v, e), p, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->p_from_v_e, v, e, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->T_from_v_e(v, e), T, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->T_from_v_e, v, e, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->c_from_v_e(v, e), 398.896207251962, REL_TOL_SAVED_VALUE);
  REL_TEST(_fp->cp_from_v_e(v, e), 987.13756097561, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->cp_from_v_e, v, e, REL_TOL_DERIVATIVE);
  REL_TEST(_fp->cv_from_v_e(v, e), 700.09756097561, REL_TOL_SAVED_VALUE);
  REL_TEST(_fp->mu_from_v_e(v, e), 18.23e-6, 1e-15);
  REL_TEST(_fp->k_from_v_e(v, e), 25.68e-3, 1e-15);

  REL_TEST(_fp->beta_from_p_T(p, T), 2.54355843825512e-3, REL_TOL_SAVED_VALUE);

  REL_TEST(_fp->s_from_v_e(v, e), 2.58890011905277e3, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->s_from_v_e, v, e, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->rho_from_p_T(p, T), 0.897875065343506, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->rho_from_p_T, p, T, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->v_from_p_T(p, T), 1.0 / 0.897875065343506, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->v_from_p_T, p, T, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->e_from_p_rho(p, rho), 2.75243356098e5, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->e_from_p_rho, p, rho, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->h_from_p_T(p, T), 3.88093132097561e5, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->h_from_p_T, p, T, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->s_from_p_T(p, T), 2.588900119052767e3, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->s_from_p_T, p, T, REL_TOL_DERIVATIVE);
  ABS_TEST(_fp->s_from_h_p(h, p), 2.588900119052767e3, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->s_from_h_p, h, p, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->e_from_p_T(p, T), 2.75243356097561e5, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->e_from_p_T, p, T, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->molarMass(), 0.0289662061037, REL_TOL_SAVED_VALUE);

  ABS_TEST(_fp->T_from_p_h(p, h), T, REL_TOL_CONSISTENCY);

  REL_TEST(_fp->mu_from_p_T(p, T), 18.23e-6, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->mu_from_p_T, p, T, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->k_from_p_T(p, T), 25.68e-3, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->k_from_p_T, p, T, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->cv_from_p_T(p, T), 700.09756097561, REL_TOL_SAVED_VALUE);
  REL_TEST(_fp->cp_from_p_T(p, T), 987.13756097561, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->cp_from_p_T, p, T, REL_TOL_DERIVATIVE);

  // Test when R and gamma are not provided
  const Real molar_mass = 0.029;
  const Real cv = 718.0;
  const Real cp = 1005.0;
  const Real thermal_conductivity = 0.02568;
  const Real entropy = 1767.24985689;
  const Real viscosity = 18.23e-6;
  Real henry = 0.0;
  const Real R = 8.3144598;

  const Real tol = REL_TOL_CONSISTENCY;

  p = 1.0e6;
  T = 300.0;

  REL_TEST(_fp_pT->beta_from_p_T(p, T), 1.0 / T, tol);
  REL_TEST(_fp_pT->cp_from_p_T(p, T), cp, tol);
  REL_TEST(_fp_pT->cv_from_p_T(p, T), cv, tol);
  REL_TEST(_fp_pT->c_from_p_T(p, T), std::sqrt(cp * R * T / (cv * molar_mass)), tol);
  REL_TEST(_fp_pT->k_from_p_T(p, T), thermal_conductivity, tol);
  REL_TEST(_fp_pT->k_from_p_T(p, T), thermal_conductivity, tol);
  REL_TEST(_fp_pT->s_from_p_T(p, T), entropy, tol);

  REL_TEST(_fp_pT->rho_from_p_T(p, T), p * molar_mass / (R * T), tol);
  REL_TEST(_fp_pT->e_from_p_T(p, T), cv * T, tol);
  REL_TEST(_fp_pT->mu_from_p_T(p, T), viscosity, tol);
  REL_TEST(_fp_pT->mu_from_p_T(p, T), viscosity, tol);
  REL_TEST(_fp_pT->h_from_p_T(p, T), cp * T, tol);
  ABS_TEST(_fp_pT->henryConstant(T), henry, tol);

  DERIV_TEST(_fp_pT->rho_from_p_T, p, T, REL_TOL_DERIVATIVE);
  DERIV_TEST(_fp_pT->mu_from_p_T, p, T, REL_TOL_DERIVATIVE);
  DERIV_TEST(_fp_pT->e_from_p_T, p, T, REL_TOL_DERIVATIVE);
  DERIV_TEST(_fp_pT->h_from_p_T, p, T, REL_TOL_DERIVATIVE);
  DERIV_TEST(_fp_pT->k_from_p_T, p, T, REL_TOL_DERIVATIVE);

  Real dhenry_dT;
  _fp_pT->henryConstant(T, henry, dhenry_dT);
  ABS_TEST(dhenry_dT, 0.0, tol);
}
TEST_F(StiffenedGasFluidPropertiesTest, testAll)
{
  const Real T = 20. + 273.15; // K
  const Real p = 101325;       // Pa

  const Real rho = _fp->rho_from_p_T(p, T);
  const Real v = 1 / rho;
  const Real e = _fp->e_from_p_rho(p, rho);
  const Real s = _fp->s_from_v_e(v, e);
  const Real h = _fp->h_from_p_T(p, T);

  Real e_inv = _fp->e_from_T_v(T, v);
  REL_TEST(e_inv, e, 10.0 * REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->e_from_T_v, T, v, 10.0 * REL_TOL_DERIVATIVE);
  Real p_inv = _fp->p_from_T_v(T, v);
  REL_TEST(p_inv, p, 10.0 * REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->p_from_T_v, T, v, 10.0 * REL_TOL_DERIVATIVE);
  REL_TEST(_fp->h_from_T_v(T, v), h, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->h_from_T_v, T, v, 10.0 * REL_TOL_DERIVATIVE);
  REL_TEST(_fp->s_from_T_v(T, v), s, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->s_from_T_v, T, v, 10.0 * REL_TOL_DERIVATIVE);
  REL_TEST(_fp->cv_from_T_v(T, v), _fp->cv_from_v_e(v, e), REL_TOL_CONSISTENCY);

  REL_TEST(_fp->p_from_h_s(h, s), p, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->p_from_h_s, h, s, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->rho_from_p_s(p, s), rho, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->rho_from_p_s, p, s, 1e-5);

  REL_TEST(_fp->p_from_v_e(v, e), p, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->p_from_v_e, v, e, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->T_from_v_e(v, e), T, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->T_from_v_e, v, e, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->c_from_v_e(v, e), 1.299581997797754e3, REL_TOL_SAVED_VALUE);
  REL_TEST(_fp->cp_from_v_e(v, e), 4267.6, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->cp_from_v_e, v, e, REL_TOL_DERIVATIVE);
  REL_TEST(_fp->cv_from_v_e(v, e), 1816, REL_TOL_SAVED_VALUE);
  REL_TEST(_fp->mu_from_v_e(v, e), 0.001, 1e-15);
  REL_TEST(_fp->k_from_v_e(v, e), 0.6, 1e-15);

  REL_TEST(_fp->beta_from_p_T(p, T), 3.411222923418045e-3, REL_TOL_SAVED_VALUE);

  REL_TEST(_fp->s_from_v_e(v, e), -2.656251807629821e4, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->s_from_v_e, v, e, 1e-5);

  ABS_TEST(_fp->rho_from_p_T(p, T), 1.391568186319449e3, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->rho_from_p_T, p, T, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->v_from_p_T(p, T), 1.0 / 1.391568186319449e3, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->v_from_p_T, p, T, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->e_from_p_rho(p, rho), 8.397412646416598e4, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->e_from_p_rho, p, rho, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->h_from_p_T(p, T), 8.404693999999994e4, 1e-10);
  DERIV_TEST(_fp->h_from_p_T, p, T, REL_TOL_DERIVATIVE);

  ABS_TEST(_fp->s_from_p_T(p, T), -2.6562518076298216e4, 4 * REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->s_from_p_T, p, T, REL_TOL_DERIVATIVE);
  ABS_TEST(_fp->s_from_h_p(h, p), -2.6562518076298216e4, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->s_from_h_p, h, p, 1e-5);

  ABS_TEST(_fp->e_from_p_T(p, T), 8.397412646416575e4, 1e-10);
  DERIV_TEST(_fp->e_from_p_T, p, T, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->T_from_p_h(p, h), T, REL_TOL_CONSISTENCY);

  REL_TEST(_fp->mu_from_p_T(p, T), 0.001, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->mu_from_p_T, p, T, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->k_from_p_T(p, T), 0.6, REL_TOL_CONSISTENCY);
  DERIV_TEST(_fp->k_from_p_T, p, T, REL_TOL_DERIVATIVE);

  REL_TEST(_fp->cv_from_p_T(p, T), 1816, REL_TOL_SAVED_VALUE);
  REL_TEST(_fp->cp_from_p_T(p, T), 4267.6, REL_TOL_SAVED_VALUE);
  DERIV_TEST(_fp->cp_from_p_T, p, T, REL_TOL_DERIVATIVE);
}