/** * Verify that the default molar mass is correctly returned */ TEST_F(IdealGasFluidPropertiesTest, molarMass) { // Test calculation of molar mass given R_specific const Real molar_mass = 8.3144598 / 287.04; ABS_TEST(_fp->molarMass(), molar_mass, REL_TOL_SAVED_VALUE); // Test default molar mass when R_specific isn't specified ABS_TEST(_fp_pT->molarMass(), 2.9e-2, REL_TOL_SAVED_VALUE); }
void CO2FluidPropertiesTest::derivatives() { Real p = 1.0e6; Real T = 350.0; // Finite differencing parameters Real dp = 1.0e1; Real dT = 1.0e-4; // density Real drho_dp_fd = (_fp->rho(p + dp, T) - _fp->rho(p - dp, T)) / (2.0 * dp); Real drho_dT_fd = (_fp->rho(p, T + dT) - _fp->rho(p, T - dT)) / (2.0 * dT); Real rho = 0.0, drho_dp = 0.0, drho_dT = 0.0; _fp->rho_dpT(p, T, rho, drho_dp, drho_dT); ABS_TEST("rho", rho, _fp->rho(p, T), 1.0e-15); REL_TEST("drho_dp", drho_dp, drho_dp_fd, 1.0e-6); REL_TEST("drho_dT", drho_dT, drho_dT_fd, 1.0e-6); // enthalpy Real dh_dp_fd = (_fp->h(p + dp, T) - _fp->h(p - dp, T)) / (2.0 * dp); Real dh_dT_fd = (_fp->h(p, T + dT) - _fp->h(p, T - dT)) / (2.0 * dT); Real h = 0.0, dh_dp = 0.0, dh_dT = 0.0; _fp->h_dpT(p, T, h, dh_dp, dh_dT); ABS_TEST("h", h, _fp->h(p, T), 1.0e-15); REL_TEST("dh_dp", dh_dp, dh_dp_fd, 1.0e-6); REL_TEST("dh_dT", dh_dT, dh_dT_fd, 1.0e-6); // internal energy Real de_dp_fd = (_fp->e(p + dp, T) - _fp->e(p - dp, T)) / (2.0 * dp); Real de_dT_fd = (_fp->e(p, T + dT) - _fp->e(p, T - dT)) / (2.0 * dT); Real e = 0.0, de_dp = 0.0, de_dT = 0.0; _fp->e_dpT(p, T, e, de_dp, de_dT); ABS_TEST("e", e, _fp->e(p, T), 1.0e-15); REL_TEST("de_dp", de_dp, de_dp_fd, 1.0e-6); REL_TEST("de_dT", de_dT, de_dT_fd, 1.0e-6); // Viscosity rho = 15.105; T = 360.0; Real drho = 1.0e-4; Real dmu_drho_fd = (_fp->mu(rho + drho, T) - _fp->mu(rho - drho, T)) / (2.0 * drho); Real dmu_dT_fd = (_fp->mu(rho, T + dT) - _fp->mu(rho, T - dT)) / (2.0 * dT); Real mu = 0.0, dmu_drho = 0.0, dmu_dT = 0.0; _fp->mu_drhoT(rho, T, mu, dmu_drho, dmu_dT); ABS_TEST("mu", mu, _fp->mu(rho, T), 1.0e-15); REL_TEST("dmu_dp", dmu_drho, dmu_drho_fd, 1.0e-6); REL_TEST("dmu_dT", dmu_dT, dmu_dT_fd, 1.0e-6); }
/* * Verify calculation of the Duan and Sun activity coefficient and its derivatives wrt * pressure, temperature and salt mass fraction */ TEST_F(PorousFlowBrineCO2Test, activityCoefficientCO2Brine) { const Real p = 10.0e6; Real T = 350.0; Real Xnacl = 0.1; const Real dp = 1.0e-1; const Real dT = 1.0e-6; const Real dx = 1.0e-8; // Low temperature regime Real gamma, dgamma_dp, dgamma_dT, dgamma_dX; _fp->activityCoefficient(p, T, Xnacl, gamma, dgamma_dp, dgamma_dT, dgamma_dX); ABS_TEST(gamma, 1.43276649338, 1.0e-8); Real gamma_2, dgamma_2_dp, dgamma_2_dT, dgamma_2_dX; _fp->activityCoefficient(p + dp, T, Xnacl, gamma_2, dgamma_2_dp, dgamma_2_dT, dgamma_2_dX); Real dgamma_dp_fd = (gamma_2 - gamma) / dp; REL_TEST(dgamma_dp, dgamma_dp_fd, 1.0e-6); _fp->activityCoefficient(p, T + dT, Xnacl, gamma_2, dgamma_2_dp, dgamma_2_dT, dgamma_2_dX); Real dgamma_dT_fd = (gamma_2 - gamma) / dT; REL_TEST(dgamma_dT, dgamma_dT_fd, 1.0e-6); _fp->activityCoefficient(p, T, Xnacl + dx, gamma_2, dgamma_2_dp, dgamma_2_dT, dgamma_2_dX); Real dgamma_dX_fd = (gamma_2 - gamma) / dx; REL_TEST(dgamma_dX, dgamma_dX_fd, 1.0e-6); // High temperature regime T = 523.15; _fp->activityCoefficientHighTemp(T, Xnacl, gamma, dgamma_dT, dgamma_dX); ABS_TEST(gamma, 1.50047006243, 1.0e-8); _fp->activityCoefficientHighTemp(T + dT, Xnacl, gamma_2, dgamma_2_dT, dgamma_2_dX); dgamma_dT_fd = (gamma_2 - gamma) / dT; REL_TEST(dgamma_dT, dgamma_dT_fd, 1.0e-6); _fp->activityCoefficientHighTemp(T, Xnacl + dx, gamma_2, dgamma_2_dT, dgamma_2_dX); dgamma_dX_fd = (gamma_2 - gamma) / dx; REL_TEST(dgamma_dX, dgamma_dX_fd, 1.0e-6); // Check that both formulations return gamma = 1 for Xnacl = 0 Xnacl = 0.0; T = 350.0; _fp->activityCoefficient(p, T, Xnacl, gamma, dgamma_dp, dgamma_dT, dgamma_dX); ABS_TEST(gamma, 1.0, 1.0e-12); T = 523.15; _fp->activityCoefficientHighTemp(T, Xnacl, gamma, dgamma_dT, dgamma_dX); ABS_TEST(gamma, 1.0, 1.0e-12); }
/** * Verify calculation of the NACL properties the solid halite phase. * Density data from Brown, "The NaCl pressure standard", J. Appl. Phys., 86 (1999). * * Values for cp and enthalpy are difficult to compare against. Instead, the * values provided by the BrineFluidProperties UserObject were compared against * simple correlations, eg. from NIST sodium chloride data. * * Values for thermal conductivity from Urqhart and Bauer, * Experimental determination of single-crystal halite thermal conductivity, * diffusivity and specific heat from -75 C to 300 C, Int. J. Rock Mech. * and Mining Sci., 78 (2015) */ TEST_F(NaClFluidPropertiesTest, halite) { // Density and cp Real p0, p1, p2, T0, T1, T2; const Real tol = REL_TOL_EXTERNAL_VALUE; p0 = 30.0e6; p1 = 60.0e6; p2 = 80.0e6; T0 = 300.0; T1 = 500.0; T2 = 700.0; REL_TEST(_fp->rho_from_p_T(p0, T0), 2167.88, tol); REL_TEST(_fp->rho_from_p_T(p1, T1), 2116.0, tol); REL_TEST(_fp->rho_from_p_T(p2, T2), 2056.8, tol); REL_TEST(_fp->cp_from_p_T(p0, T0), 0.865e3, 40.0 * tol); REL_TEST(_fp->cp_from_p_T(p1, T1), 0.922e3, 40.0 * tol); REL_TEST(_fp->cp_from_p_T(p2, T2), 0.979e3, 40.0 * tol); // Test enthalpy at the triple point pressure of water Real pt = 611.657; ABS_TEST(_fp->h_from_p_T(pt, 273.16), 0.0, tol); REL_TEST(_fp->h_from_p_T(pt, 573.15), 271.13e3, tol); REL_TEST(_fp->h_from_p_T(pt, 673.15), 366.55e3, tol); // Thermal conductivity (function of T only) REL_TEST(_fp->k_from_p_T(p0, 323.15), 5.488, 10.0 * tol); REL_TEST(_fp->k_from_p_T(p0, 423.15), 3.911, 10.0 * tol); REL_TEST(_fp->k_from_p_T(p0, 523.15), 3.024, 20.0 * tol); }
/** * Verify calculation of the derivatives in all regions by comparing with finite * differences */ TEST_F(Water97FluidPropertiesTest, derivatives) { // Region 1 Real p = 3.0e6; Real T = 300.0; regionDerivatives(p, T, 1.0e-6); // Region 2 p = 3.5e3; T = 300.0; regionDerivatives(p, T, 1.0e-6); // Region 3 p = 26.0e6; T = 650.0; regionDerivatives(p, T, 1.0e-2); // Region 4 (saturation curve) T = 300.0; Real dT = 1.0e-4; Real dpSat_dT_fd = (_fp->vaporPressure(T + dT) - _fp->vaporPressure(T - dT)) / (2.0 * dT); Real pSat = 0.0, dpSat_dT = 0.0; _fp->vaporPressure_dT(T, pSat, dpSat_dT); REL_TEST("dvaporPressure_dT", dpSat_dT, dpSat_dT_fd, 1.0e-6); // Region 5 p = 30.0e6; T = 1500.0; regionDerivatives(p, T, 1.0e-6); // Viscosity Real rho = 998.0, drho_dp = 0.0, drho_dT = 0.0; T = 298.15; Real drho = 1.0e-4; Real dmu_drho_fd = (_fp->mu_from_rho_T(rho + drho, T) - _fp->mu_from_rho_T(rho - drho, T)) / (2.0 * drho); Real mu = 0.0, dmu_drho = 0.0, dmu_dT = 0.0; _fp->mu_drhoT_from_rho_T(rho, T, drho_dT, mu, dmu_drho, dmu_dT); ABS_TEST("mu", mu, _fp->mu_from_rho_T(rho, T), 1.0e-15); REL_TEST("dmu_dp", dmu_drho, dmu_drho_fd, 1.0e-6); // To properly test derivative wrt temperature, use p and T and calculate density, // so that the change in density wrt temperature is included p = 1.0e6; dT = 1.0e-4; _fp->rho_dpT(p, T, rho, drho_dp, drho_dT); _fp->mu_drhoT_from_rho_T(rho, T, drho_dT, mu, dmu_drho, dmu_dT); Real dmu_dT_fd = (_fp->mu_from_rho_T(_fp->rho(p, T + dT), T + dT) - _fp->mu_from_rho_T(_fp->rho(p, T - dT), T - dT)) / (2.0 * dT); REL_TEST("dmu_dT", dmu_dT, dmu_dT_fd, 1.0e-6); }
/* * Verify calculation of the H2O and CO2 activity coefficients and their derivative * wrt temperature */ TEST_F(PorousFlowBrineCO2Test, activityCoefficients) { const Real xco2 = 0.01; Real T = 350.0; Real gammaH2O = _fp->activityCoefficientH2O(T, xco2); Real gammaCO2 = _fp->activityCoefficientCO2(T, xco2); ABS_TEST(gammaH2O, 1.0, 1.0e-10); ABS_TEST(gammaCO2, 1.0, 1.0e-10); T = 450.0; gammaH2O = _fp->activityCoefficientH2O(T, xco2); gammaCO2 = _fp->activityCoefficientCO2(T, xco2); ABS_TEST(gammaH2O, 1.00022113664, 1.0e-10); ABS_TEST(gammaCO2, 0.956736800255, 1.0e-10); }
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); 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_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); 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, 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.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, REL_TOL_SAVED_VALUE); 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); }
/** * Test iterative calculation of equilibrium mass fractions in the elevated * temperature regime */ TEST_F(PorousFlowBrineCO2Test, solveEquilibriumMoleFractionHighTemp) { Real p = 20.0e6; Real T = 473.15; Real Xnacl = 0.0; Real yh2o, xco2; Real co2_density = _co2_fp->rho(p, T); _fp->solveEquilibriumMoleFractionHighTemp(p, T, Xnacl, co2_density, xco2, yh2o); ABS_TEST(yh2o, 0.161429471353, 1.0e-10); ABS_TEST(xco2, 0.0236967010229, 1.0e-10); // Mass fraction equivalent to molality of 2 p = 30.0e6; T = 423.15; Xnacl = 0.105; _fp->solveEquilibriumMoleFractionHighTemp(p, T, Xnacl, co2_density, xco2, yh2o); ABS_TEST(yh2o, 0.0468195468869, 1.0e-10); ABS_TEST(xco2, 0.023664581533, 1.0e-10); // Mass fraction equivalent to molality of 4 T = 523.15; Xnacl = 0.189; co2_density = _co2_fp->rho(p, T); _fp->solveEquilibriumMoleFractionHighTemp(p, T, Xnacl, co2_density, xco2, yh2o); ABS_TEST(yh2o, 0.253292227782, 1.0e-10); ABS_TEST(xco2, 0.016834474171, 1.0e-10); }
/* * Verify calculation of the equilibrium constants and their derivatives wrt temperature */ TEST_F(PorousFlowBrineCO2Test, equilibriumConstants) { Real T = 350.0; const Real dT = 1.0e-6; Real K0H2O, dK0H2O_dT, K0CO2, dK0CO2_dT; _fp->equilibriumConstantH2O(T, K0H2O, dK0H2O_dT); _fp->equilibriumConstantCO2(T, K0CO2, dK0CO2_dT); ABS_TEST(K0H2O, 0.412597711705, 1.0e-10); ABS_TEST(K0CO2, 74.0435888596, 1.0e-10); Real K0H2O_2, dK0H2O_2_dT, K0CO2_2, dK0CO2_2_dT; _fp->equilibriumConstantH2O(T + dT, K0H2O_2, dK0H2O_2_dT); _fp->equilibriumConstantCO2(T + dT, K0CO2_2, dK0CO2_2_dT); Real dK0H2O_dT_fd = (K0H2O_2 - K0H2O) / dT; Real dK0CO2_dT_fd = (K0CO2_2 - K0CO2) / dT; REL_TEST(dK0H2O_dT, dK0H2O_dT_fd, 1.0e-6); REL_TEST(dK0CO2_dT, dK0CO2_dT_fd, 1.0e-6); // Test the high temperature formulation T = 450.0; _fp->equilibriumConstantH2O(T, K0H2O, dK0H2O_dT); _fp->equilibriumConstantCO2(T, K0CO2, dK0CO2_dT); ABS_TEST(K0H2O, 8.75944517916, 1.0e-10); ABS_TEST(K0CO2, 105.013867434, 1.0e-10); _fp->equilibriumConstantH2O(T + dT, K0H2O_2, dK0H2O_2_dT); _fp->equilibriumConstantCO2(T + dT, K0CO2_2, dK0CO2_2_dT); dK0H2O_dT_fd = (K0H2O_2 - K0H2O) / dT; dK0CO2_dT_fd = (K0CO2_2 - K0CO2) / dT; REL_TEST(dK0H2O_dT, dK0H2O_dT_fd, 1.0e-6); REL_TEST(dK0CO2_dT, dK0CO2_dT_fd, 1.0e-5); }
/* * Verify calculation of the partial density of CO2 and its derivative wrt temperature */ TEST_F(PorousFlowBrineCO2Test, partialDensity) { const Real T = 473.15; const Real dT = 1.0e-6; Real partial_density, dpartial_density_dT; _fp->partialDensityCO2(T, partial_density, dpartial_density_dT); ABS_TEST(partial_density, 893.332, 1.0e-3); Real partial_density_2, dpartial_density_2_dT; _fp->partialDensityCO2(T + dT, partial_density_2, dpartial_density_2_dT); Real dpartial_density_dT_fd = (partial_density_2 - partial_density) / dT; REL_TEST(dpartial_density_dT, dpartial_density_dT_fd, 1.0e-6); }
/* * Verify calculation of total mass fraction given a gas saturation */ TEST_F(PorousFlowWaterNCGTest, totalMassFraction) { const Real p = 1.0e6; const Real T = 350.0; const Real s = 0.2; Real Z = _fp->totalMassFraction(p, T, s); // Test that the saturation calculated in this fluid state using Z is equal to s FluidStatePhaseEnum phase_state; std::vector<FluidStateProperties> fsp(2, FluidStateProperties(2)); _fp->massFractions(p, T, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::TWOPHASE); _fp->gasProperties(p, T, fsp); Real liquid_pressure = p + _pc->capillaryPressure(1.0 - s); _fp->liquidProperties(liquid_pressure, T, fsp); _fp->saturationTwoPhase(p, T, Z, fsp); ABS_TEST(fsp[1].saturation, s, 1.0e-8); }
/* * Verify calculation of the fugacity coefficients */ TEST_F(PorousFlowBrineCO2Test, fugacityCoefficients) { // Test the low temperature formulation Real p = 40.0e6; Real T = 350.0; Real Xnacl = 0.0; Real co2_density, dco2_density_dp, dco2_density_dT; _co2_fp->rho_dpT(p, T, co2_density, dco2_density_dp, dco2_density_dT); Real phiH2O, dphiH2O_dp, dphiH2O_dT; Real phiCO2, dphiCO2_dp, dphiCO2_dT; _fp->fugacityCoefficientsLowTemp(p, T, co2_density, dco2_density_dp, dco2_density_dT, phiCO2, dphiCO2_dp, dphiCO2_dT, phiH2O, dphiH2O_dp, dphiH2O_dT); ABS_TEST(phiCO2, 0.401938, 1.0e-6); ABS_TEST(phiH2O, 0.0898968, 1.0e-6); // Test the high temperature formulation T = 423.15; Real xco2, yh2o; co2_density = _co2_fp->rho(p, T); _fp->solveEquilibriumMoleFractionHighTemp(p, T, Xnacl, co2_density, xco2, yh2o); phiH2O = _fp->fugacityCoefficientH2OHighTemp(p, T, co2_density, xco2, yh2o); phiCO2 = _fp->fugacityCoefficientCO2HighTemp(p, T, co2_density, xco2, yh2o); ABS_TEST(phiH2O, 0.156304067968, 1.0e-10); ABS_TEST(phiCO2, 0.641936764138, 1.0e-10); // Test that the same results are returned in fugacityCoefficientsHighTemp() Real phiCO2_2, phiH2O_2; _fp->fugacityCoefficientsHighTemp(p, T, co2_density, xco2, yh2o, phiCO2_2, phiH2O_2); ABS_TEST(phiH2O, phiH2O_2, 1.0e-12); ABS_TEST(phiCO2, phiCO2_2, 1.0e-12); }
/* * Verify calculation of total mass fraction given a gas saturation */ TEST_F(PorousFlowBrineCO2Test, totalMassFraction) { const Real p = 1.0e6; const Real T = 350.0; const Real Xnacl = 0.1; const Real s = 0.2; Real Z = _fp->totalMassFraction(p, T, Xnacl, s); // Test that the saturation calculated in this fluid state using Z is equal to s FluidStatePhaseEnum phase_state; const unsigned int np = _fp->numPhases(); const unsigned int nc = _fp->numComponents(); std::vector<FluidStateProperties> fsp(np, FluidStateProperties(nc)); _fp->massFractions(p, T, Xnacl, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::TWOPHASE); _fp->gasProperties(p, T, fsp); Real liquid_pressure = p + _pc->capillaryPressure(1.0 - s); _fp->liquidProperties(liquid_pressure, T, Xnacl, fsp); _fp->saturationTwoPhase(p, T, Xnacl, Z, fsp); ABS_TEST(fsp[1].saturation, s, 1.0e-8); }
/** * Verify that the methods that return multiple properties in one call return identical * values as the individual methods */ TEST_F(NaClFluidPropertiesTest, combined) { const Real tol = REL_TOL_SAVED_VALUE; const Real p = 1.0e6; const Real T = 300.0; // Single property methods Real rho, drho_dp, drho_dT; _fp->rho_from_p_T(p, T, rho, drho_dp, drho_dT); Real e, de_dp, de_dT; _fp->e_from_p_T(p, T, e, de_dp, de_dT); // Combined property methods Real rho2, drho2_dp, drho2_dT, e2, de2_dp, de2_dT; _fp->rho_e_from_p_T(p, T, rho2, drho2_dp, drho2_dT, e2, de2_dp, de2_dT); ABS_TEST(rho, rho2, tol); ABS_TEST(drho_dp, drho2_dp, tol); ABS_TEST(drho_dT, drho2_dT, tol); ABS_TEST(e, e2, tol); ABS_TEST(de_dp, de2_dp, tol); ABS_TEST(de_dT, de2_dT, tol); }
/* * Verify calculation of gas density, viscosity, enthalpy and derivatives */ TEST_F(PorousFlowWaterNCGTest, gasProperties) { const Real p = 1.0e6; const Real T = 350.0; FluidStatePhaseEnum phase_state; std::vector<FluidStateProperties> fsp(2, FluidStateProperties(2)); // Gas region Real Z = 0.995; _fp->massFractions(p, T, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::GAS); // Verify fluid density, viscosity and enthalpy _fp->gasProperties(p, T, fsp); Real gas_density = fsp[1].density; Real gas_viscosity = fsp[1].viscosity; Real gas_enthalpy = fsp[1].enthalpy; Real density = _ncg_fp->rho_from_p_T(Z * p, T) + _water_fp->rho_from_p_T(_water_fp->vaporPressure(T), T); Real viscosity = Z * _ncg_fp->mu(Z * p, T) + (1.0 - Z) * _water_fp->mu(_water_fp->vaporPressure(T), T); Real enthalpy = Z * _ncg_fp->h(Z * p, T) + (1.0 - Z) * _water_fp->h(_water_fp->vaporPressure(T), T); ABS_TEST(gas_density, density, 1.0e-8); ABS_TEST(gas_viscosity, viscosity, 1.0e-8); ABS_TEST(gas_enthalpy, enthalpy, 1.0e-8); // Verify derivatives Real ddensity_dp = fsp[1].ddensity_dp; Real ddensity_dT = fsp[1].ddensity_dT; Real ddensity_dZ = fsp[1].ddensity_dZ; Real dviscosity_dp = fsp[1].dviscosity_dp; Real dviscosity_dT = fsp[1].dviscosity_dT; Real dviscosity_dZ = fsp[1].dviscosity_dZ; Real denthalpy_dp = fsp[1].denthalpy_dp; Real denthalpy_dT = fsp[1].denthalpy_dT; Real denthalpy_dZ = fsp[1].denthalpy_dZ; const Real dp = 1.0e-1; _fp->gasProperties(p + dp, T, fsp); Real rho1 = fsp[1].density; Real mu1 = fsp[1].viscosity; Real h1 = fsp[1].enthalpy; _fp->gasProperties(p - dp, T, fsp); Real rho2 = fsp[1].density; Real mu2 = fsp[1].viscosity; Real h2 = fsp[1].enthalpy; REL_TEST(ddensity_dp, (rho1 - rho2) / (2.0 * dp), 1.0e-6); REL_TEST(dviscosity_dp, (mu1 - mu2) / (2.0 * dp), 1.0e-6); REL_TEST(denthalpy_dp, (h1 - h2) / (2.0 * dp), 1.0e-6); const Real dT = 1.0e-3; _fp->gasProperties(p, T + dT, fsp); rho1 = fsp[1].density; mu1 = fsp[1].viscosity; h1 = fsp[1].enthalpy; _fp->gasProperties(p, T - dT, fsp); rho2 = fsp[1].density; mu2 = fsp[1].viscosity; h2 = fsp[1].enthalpy; REL_TEST(ddensity_dT, (rho1 - rho2) / (2.0 * dT), 1.0e-6); REL_TEST(dviscosity_dT, (mu1 - mu2) / (2.0 * dT), 1.0e-6); REL_TEST(denthalpy_dT, (h1 - h2) / (2.0 * dT), 1.0e-6); // Note: mass fraction changes with Z const Real dZ = 1.0e-8; _fp->massFractions(p, T, Z + dZ, phase_state, fsp); _fp->gasProperties(p, T, fsp); rho1 = fsp[1].density; mu1 = fsp[1].viscosity; h1 = fsp[1].enthalpy; _fp->massFractions(p, T, Z - dZ, phase_state, fsp); _fp->gasProperties(p, T, fsp); rho2 = fsp[1].density; mu2 = fsp[1].viscosity; h2 = fsp[1].enthalpy; REL_TEST(ddensity_dZ, (rho1 - rho2) / (2.0 * dZ), 1.0e-6); REL_TEST(dviscosity_dZ, (mu1 - mu2) / (2.0 * dZ), 1.0e-6); REL_TEST(denthalpy_dZ, (h1 - h2) / (2.0 * dZ), 1.0e-6); // Check derivatives in the two phase region as well. Note that the mass fractions // vary with pressure and temperature in this region Z = 0.45; _fp->massFractions(p, T, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::TWOPHASE); _fp->gasProperties(p, T, fsp); ddensity_dp = fsp[1].ddensity_dp; ddensity_dT = fsp[1].ddensity_dT; ddensity_dZ = fsp[1].ddensity_dZ; dviscosity_dp = fsp[1].dviscosity_dp; dviscosity_dT = fsp[1].dviscosity_dT; dviscosity_dZ = fsp[1].dviscosity_dZ; denthalpy_dp = fsp[1].denthalpy_dp; denthalpy_dT = fsp[1].denthalpy_dT; denthalpy_dZ = fsp[1].denthalpy_dZ; _fp->massFractions(p + dp, T, Z, phase_state, fsp); _fp->gasProperties(p + dp, T, fsp); rho1 = fsp[1].density; mu1 = fsp[1].viscosity; h1 = fsp[1].enthalpy; _fp->massFractions(p - dp, T, Z, phase_state, fsp); _fp->gasProperties(p - dp, T, fsp); rho2 = fsp[1].density; mu2 = fsp[1].viscosity; h2 = fsp[1].enthalpy; REL_TEST(ddensity_dp, (rho1 - rho2) / (2.0 * dp), 1.0e-6); REL_TEST(dviscosity_dp, (mu1 - mu2) / (2.0 * dp), 1.0e-6); REL_TEST(denthalpy_dp, (h1 - h2) / (2.0 * dp), 1.0e-6); _fp->massFractions(p, T + dT, Z, phase_state, fsp); _fp->gasProperties(p, T + dT, fsp); rho1 = fsp[1].density; mu1 = fsp[1].viscosity; h1 = fsp[1].enthalpy; _fp->massFractions(p, T - dT, Z, phase_state, fsp); _fp->gasProperties(p, T - dT, fsp); rho2 = fsp[1].density; mu2 = fsp[1].viscosity; h2 = fsp[1].enthalpy; REL_TEST(ddensity_dT, (rho1 - rho2) / (2.0 * dT), 1.0e-6); REL_TEST(dviscosity_dT, (mu1 - mu2) / (2.0 * dT), 1.0e-6); REL_TEST(denthalpy_dT, (h1 - h2) / (2.0 * dT), 1.0e-6); _fp->massFractions(p, T, Z + dZ, phase_state, fsp); _fp->gasProperties(p, T, fsp); rho1 = fsp[1].density; mu1 = fsp[1].viscosity; h1 = fsp[1].enthalpy; _fp->massFractions(p, T, Z - dZ, phase_state, fsp); _fp->gasProperties(p, T, fsp); rho2 = fsp[1].density; mu2 = fsp[1].viscosity; h2 = fsp[1].enthalpy; ABS_TEST(ddensity_dZ, (rho1 - rho2) / (2.0 * dZ), 1.0e-6); ABS_TEST(dviscosity_dT, (mu1 - mu2) / (2.0 * dZ), 1.0e-6); ABS_TEST(denthalpy_dZ, (h1 - h2) / (2.0 * dZ), 1.0e-6); }
/** * Test that the molar mass is correctly returned */ TEST_F(NaClFluidPropertiesTest, molarMass) { ABS_TEST(_fp->molarMass(), 58.443e-3, REL_TOL_SAVED_VALUE); }
/** * Verify that triple point properties are correctly returned */ TEST_F(NaClFluidPropertiesTest, triplePointProperties) { ABS_TEST(_fp->triplePointPressure(), 50.0, REL_TOL_SAVED_VALUE); ABS_TEST(_fp->triplePointTemperature(), 1073.85, REL_TOL_SAVED_VALUE); }
/** * Verify that critical properties are correctly returned */ TEST_F(NaClFluidPropertiesTest, criticalProperties) { ABS_TEST(_fp->criticalPressure(), 1.82e7, REL_TOL_SAVED_VALUE); ABS_TEST(_fp->criticalTemperature(), 3841.15, REL_TOL_SAVED_VALUE); ABS_TEST(_fp->criticalDensity(), 108.43, REL_TOL_SAVED_VALUE); }
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); }
/* * Verify calculation of gas density, viscosity enthalpy, and derivatives. Note that as * these properties don't depend on mass fraction, only the gas region needs to be * tested (the calculations are identical in the two phase region) */ TEST_F(PorousFlowBrineCO2Test, gasProperties) { const Real p = 1.0e6; const Real T = 350.0; const Real Xnacl = 0.1; FluidStatePhaseEnum phase_state; const unsigned int np = _fp->numPhases(); const unsigned int nc = _fp->numComponents(); std::vector<FluidStateProperties> fsp(np, FluidStateProperties(nc)); // Gas region Real Z = 0.995; _fp->massFractions(p, T, Xnacl, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::GAS); // Verify fluid density, viscosity and enthalpy _fp->gasProperties(p, T, fsp); Real gas_density = fsp[1].density; Real gas_viscosity = fsp[1].viscosity; Real gas_enthalpy = fsp[1].enthalpy; Real density = _co2_fp->rho(p, T); Real viscosity = _co2_fp->mu(p, T); Real enthalpy = _co2_fp->h(p, T); ABS_TEST(gas_density, density, 1.0e-8); ABS_TEST(gas_viscosity, viscosity, 1.0e-8); ABS_TEST(gas_enthalpy, enthalpy, 1.0e-8); // Verify derivatives Real ddensity_dp = fsp[1].ddensity_dp; Real ddensity_dT = fsp[1].ddensity_dT; Real ddensity_dZ = fsp[1].ddensity_dZ; Real dviscosity_dp = fsp[1].dviscosity_dp; Real dviscosity_dT = fsp[1].dviscosity_dT; Real dviscosity_dZ = fsp[1].dviscosity_dZ; Real denthalpy_dp = fsp[1].denthalpy_dp; Real denthalpy_dT = fsp[1].denthalpy_dT; Real denthalpy_dZ = fsp[1].denthalpy_dZ; const Real dp = 1.0e-1; _fp->gasProperties(p + dp, T, fsp); Real rho1 = fsp[1].density; Real mu1 = fsp[1].viscosity; Real h1 = fsp[1].enthalpy; _fp->gasProperties(p - dp, T, fsp); Real rho2 = fsp[1].density; Real mu2 = fsp[1].viscosity; Real h2 = fsp[1].enthalpy; REL_TEST(ddensity_dp, (rho1 - rho2) / (2.0 * dp), 1.0e-6); REL_TEST(dviscosity_dp, (mu1 - mu2) / (2.0 * dp), 1.0e-6); REL_TEST(denthalpy_dp, (h1 - h2) / (2.0 * dp), 1.0e-6); const Real dT = 1.0e-3; _fp->gasProperties(p, T + dT, fsp); rho1 = fsp[1].density; mu1 = fsp[1].viscosity; h1 = fsp[1].enthalpy; _fp->gasProperties(p, T - dT, fsp); rho2 = fsp[1].density; mu2 = fsp[1].viscosity; h2 = fsp[1].enthalpy; REL_TEST(ddensity_dT, (rho1 - rho2) / (2.0 * dT), 1.0e-6); REL_TEST(dviscosity_dT, (mu1 - mu2) / (2.0 * dT), 1.0e-6); REL_TEST(denthalpy_dT, (h1 - h2) / (2.0 * dT), 1.0e-6); // Note: mass fraction changes with Z const Real dZ = 1.0e-8; _fp->massFractions(p, T, Xnacl, Z + dZ, phase_state, fsp); _fp->gasProperties(p, T, fsp); rho1 = fsp[1].density; mu1 = fsp[1].viscosity; h1 = fsp[1].enthalpy; _fp->massFractions(p, T, Xnacl, Z - dZ, phase_state, fsp); _fp->gasProperties(p, T, fsp); rho2 = fsp[1].density; mu2 = fsp[1].viscosity; h2 = fsp[1].enthalpy; ABS_TEST(ddensity_dZ, (rho1 - rho2) / (2.0 * dZ), 1.0e-8); ABS_TEST(dviscosity_dZ, (mu1 - mu2) / (2.0 * dZ), 1.0e-8); ABS_TEST(denthalpy_dZ, (h1 - h2) / (2.0 * dZ), 1.0e-6); }
/** * Verify that the methods that return multiple properties in one call return identical * values as the individual methods */ TEST_F(IdealGasFluidPropertiesTest, combined) { const Real p = 1.0e6; const Real T = 300.0; const Real tol = REL_TOL_CONSISTENCY; // Single property methods Real rho, drho_dp, drho_dT; _fp_pT->rho_from_p_T(p, T, rho, drho_dp, drho_dT); Real mu, dmu_dp, dmu_dT; _fp_pT->mu_from_p_T(p, T, mu, dmu_dp, dmu_dT); Real e, de_dp, de_dT; _fp_pT->e_from_p_T(p, T, e, de_dp, de_dT); // Combined property methods Real rho2, drho2_dp, drho2_dT, mu2, dmu2_dp, dmu2_dT, e2, de2_dp, de2_dT; _fp_pT->rho_mu_from_p_T(p, T, rho2, mu2); ABS_TEST(rho, rho2, tol); ABS_TEST(mu, mu2, tol); _fp_pT->rho_mu_from_p_T(p, T, rho2, drho2_dp, drho2_dT, mu2, dmu2_dp, dmu2_dT); ABS_TEST(rho, rho2, tol); ABS_TEST(drho_dp, drho2_dp, tol); ABS_TEST(drho_dT, drho2_dT, tol); ABS_TEST(mu, mu2, tol); ABS_TEST(dmu_dp, dmu2_dp, tol); ABS_TEST(dmu_dT, dmu2_dT, tol); _fp_pT->rho_e_from_p_T(p, T, rho2, drho2_dp, drho2_dT, e2, de2_dp, de2_dT); ABS_TEST(rho, rho2, tol); ABS_TEST(drho_dp, drho2_dp, tol); ABS_TEST(drho_dT, drho2_dT, tol); ABS_TEST(e, e2, tol); ABS_TEST(de_dp, de2_dp, tol); ABS_TEST(de_dT, de2_dT, tol); }
/* * Verify calculation of actual mass fraction and derivatives depending on value of * total mass fraction */ TEST_F(PorousFlowWaterNCGTest, MassFraction) { const Real p = 1.0e6; const Real T = 350.0; FluidStatePhaseEnum phase_state; std::vector<FluidStateProperties> fsp(2, FluidStateProperties(2)); // Liquid region Real Z = 0.0001; _fp->massFractions(p, T, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::LIQUID); // Verfify mass fraction values Real Xncg = fsp[0].mass_fraction[1]; Real Yncg = fsp[1].mass_fraction[1]; Real Xh2o = fsp[0].mass_fraction[0]; Real Yh2o = fsp[1].mass_fraction[0]; ABS_TEST(Xncg, Z, 1.0e-8); ABS_TEST(Yncg, 0.0, 1.0e-8); ABS_TEST(Xh2o, 1.0 - Z, 1.0e-8); ABS_TEST(Yh2o, 0.0, 1.0e-8); // Verify derivatives Real dXncg_dp = fsp[0].dmass_fraction_dp[1]; Real dXncg_dT = fsp[0].dmass_fraction_dT[1]; Real dXncg_dZ = fsp[0].dmass_fraction_dZ[1]; Real dYncg_dp = fsp[1].dmass_fraction_dp[1]; Real dYncg_dT = fsp[1].dmass_fraction_dT[1]; Real dYncg_dZ = fsp[1].dmass_fraction_dZ[1]; ABS_TEST(dXncg_dp, 0.0, 1.0e-8); ABS_TEST(dXncg_dT, 0.0, 1.0e-8); ABS_TEST(dXncg_dZ, 1.0, 1.0e-8); ABS_TEST(dYncg_dp, 0.0, 1.0e-8); ABS_TEST(dYncg_dT, 0.0, 1.0e-8); ABS_TEST(dYncg_dZ, 0.0, 1.0e-8); // Gas region Z = 0.995; _fp->massFractions(p, T, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::GAS); // Verfify mass fraction values Xncg = fsp[0].mass_fraction[1]; Yncg = fsp[1].mass_fraction[1]; Xh2o = fsp[0].mass_fraction[0]; Yh2o = fsp[1].mass_fraction[0]; ABS_TEST(Xncg, 0.0, 1.0e-8); ABS_TEST(Yncg, Z, 1.0e-8); ABS_TEST(Xh2o, 0.0, 1.0e-8); ABS_TEST(Yh2o, 1.0 - Z, 1.0e-8); // Verify derivatives dXncg_dp = fsp[0].dmass_fraction_dp[1]; dXncg_dT = fsp[0].dmass_fraction_dT[1]; dXncg_dZ = fsp[0].dmass_fraction_dZ[1]; dYncg_dp = fsp[1].dmass_fraction_dp[1]; dYncg_dT = fsp[1].dmass_fraction_dT[1]; dYncg_dZ = fsp[1].dmass_fraction_dZ[1]; ABS_TEST(dXncg_dp, 0.0, 1.0e-8); ABS_TEST(dXncg_dT, 0.0, 1.0e-8); ABS_TEST(dXncg_dZ, 0.0, 1.0e-8); ABS_TEST(dYncg_dp, 0.0, 1.0e-8); ABS_TEST(dYncg_dT, 0.0, 1.0e-8); ABS_TEST(dYncg_dZ, 1.0, 1.0e-8); // Two phase region. In this region, the mass fractions and derivatives can // be verified using the equilibrium mass fraction derivatives that have // been verified above Z = 0.45; _fp->massFractions(p, T, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::TWOPHASE); // Equilibrium mass fractions and derivatives Real Xncg_eq, dXncg_dp_eq, dXncg_dT_eq, Yh2o_eq, dYh2o_dp_eq, dYh2o_dT_eq; _fp->equilibriumMassFractions( p, T, Xncg_eq, dXncg_dp_eq, dXncg_dT_eq, Yh2o_eq, dYh2o_dp_eq, dYh2o_dT_eq); // Verfify mass fraction values Xncg = fsp[0].mass_fraction[1]; Yncg = fsp[1].mass_fraction[1]; Xh2o = fsp[0].mass_fraction[0]; Yh2o = fsp[1].mass_fraction[0]; ABS_TEST(Xncg, Xncg_eq, 1.0e-8); ABS_TEST(Yncg, 1.0 - Yh2o_eq, 1.0e-8); ABS_TEST(Xh2o, 1.0 - Xncg_eq, 1.0e-8); ABS_TEST(Yh2o, Yh2o_eq, 1.0e-8); // Verify derivatives wrt p and T dXncg_dp = fsp[0].dmass_fraction_dp[1]; dXncg_dT = fsp[0].dmass_fraction_dT[1]; dXncg_dZ = fsp[0].dmass_fraction_dZ[1]; dYncg_dp = fsp[1].dmass_fraction_dp[1]; dYncg_dT = fsp[1].dmass_fraction_dT[1]; dYncg_dZ = fsp[1].dmass_fraction_dZ[1]; ABS_TEST(dXncg_dp, dXncg_dp_eq, 1.0e-8); ABS_TEST(dXncg_dT, dXncg_dT_eq, 1.0e-8); ABS_TEST(dXncg_dZ, 0.0, 1.0e-8); ABS_TEST(dYncg_dp, -dYh2o_dp_eq, 1.0e-8); ABS_TEST(dYncg_dT, -dYh2o_dT_eq, 1.0e-8); ABS_TEST(dYncg_dZ, 0.0, 1.0e-8); // Use finite differences to verify derivative wrt Z is unaffected by Z const Real dZ = 1.0e-8; _fp->massFractions(p, T, Z + dZ, phase_state, fsp); Real Xncg1 = fsp[0].mass_fraction[1]; Real Yncg1 = fsp[1].mass_fraction[1]; _fp->massFractions(p, T, Z - dZ, phase_state, fsp); Real Xncg2 = fsp[0].mass_fraction[1]; Real Yncg2 = fsp[1].mass_fraction[1]; ABS_TEST(dXncg_dZ, (Xncg1 - Xncg2) / (2.0 * dZ), 1.0e-8); ABS_TEST(dYncg_dZ, (Yncg1 - Yncg2) / (2.0 * dZ), 1.0e-8); }
/* * Verify calculation of actual mass fraction and derivatives depending on value of * total mass fraction */ TEST_F(PorousFlowBrineCO2Test, MassFraction) { const Real p = 1.0e6; const Real T = 350.0; const Real Xnacl = 0.1; FluidStatePhaseEnum phase_state; const unsigned int np = _fp->numPhases(); const unsigned int nc = _fp->numComponents(); std::vector<FluidStateProperties> fsp(np, FluidStateProperties(nc)); // Liquid region Real Z = 0.0001; _fp->massFractions(p, T, Xnacl, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::LIQUID); // Verfify mass fraction values Real Xco2 = fsp[0].mass_fraction[1]; Real Yco2 = fsp[1].mass_fraction[1]; Real Xh2o = fsp[0].mass_fraction[0]; Real Yh2o = fsp[1].mass_fraction[0]; Real Xnacl2 = fsp[0].mass_fraction[2]; ABS_TEST(Xco2, Z, 1.0e-8); ABS_TEST(Yco2, 0.0, 1.0e-8); ABS_TEST(Xh2o, 1.0 - Z, 1.0e-8); ABS_TEST(Yh2o, 0.0, 1.0e-8); ABS_TEST(Xnacl2, Xnacl, 1.0e-8); // Verify derivatives Real dXco2_dp = fsp[0].dmass_fraction_dp[1]; Real dXco2_dT = fsp[0].dmass_fraction_dT[1]; Real dXco2_dX = fsp[0].dmass_fraction_dX[1]; Real dXco2_dZ = fsp[0].dmass_fraction_dZ[1]; Real dYco2_dp = fsp[1].dmass_fraction_dp[1]; Real dYco2_dT = fsp[1].dmass_fraction_dT[1]; Real dYco2_dX = fsp[1].dmass_fraction_dX[1]; Real dYco2_dZ = fsp[1].dmass_fraction_dZ[1]; Real dXnacl_dX = fsp[0].dmass_fraction_dX[2]; ABS_TEST(dXco2_dp, 0.0, 1.0e-8); ABS_TEST(dXco2_dT, 0.0, 1.0e-8); ABS_TEST(dXco2_dX, 0.0, 1.0e-8); ABS_TEST(dXco2_dZ, 1.0, 1.0e-8); ABS_TEST(dYco2_dp, 0.0, 1.0e-8); ABS_TEST(dYco2_dT, 0.0, 1.0e-8); ABS_TEST(dYco2_dX, 0.0, 1.0e-8); ABS_TEST(dYco2_dZ, 0.0, 1.0e-8); ABS_TEST(dXnacl_dX, 1.0, 1.0e-8); // Gas region Z = 0.995; _fp->massFractions(p, T, Xnacl, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::GAS); // Verfify mass fraction values Xco2 = fsp[0].mass_fraction[1]; Yco2 = fsp[1].mass_fraction[1]; Xh2o = fsp[0].mass_fraction[0]; Yh2o = fsp[1].mass_fraction[0]; Real Ynacl = fsp[1].mass_fraction[2]; ABS_TEST(Xco2, 0.0, 1.0e-8); ABS_TEST(Yco2, Z, 1.0e-8); ABS_TEST(Xh2o, 0.0, 1.0e-8); ABS_TEST(Yh2o, 1.0 - Z, 1.0e-8); ABS_TEST(Ynacl, 0.0, 1.0e-8); // Verify derivatives dXco2_dp = fsp[0].dmass_fraction_dp[1]; dXco2_dT = fsp[0].dmass_fraction_dT[1]; dXco2_dX = fsp[0].dmass_fraction_dX[1]; dXco2_dZ = fsp[0].dmass_fraction_dZ[1]; dYco2_dp = fsp[1].dmass_fraction_dp[1]; dYco2_dT = fsp[1].dmass_fraction_dT[1]; dYco2_dX = fsp[1].dmass_fraction_dX[1]; dYco2_dZ = fsp[1].dmass_fraction_dZ[1]; Real dYnacl_dX = fsp[1].dmass_fraction_dX[2]; ABS_TEST(dXco2_dp, 0.0, 1.0e-8); ABS_TEST(dXco2_dT, 0.0, 1.0e-8); ABS_TEST(dXco2_dX, 0.0, 1.0e-8); ABS_TEST(dXco2_dZ, 0.0, 1.0e-8); ABS_TEST(dYco2_dp, 0.0, 1.0e-8); ABS_TEST(dYco2_dT, 0.0, 1.0e-8); ABS_TEST(dYco2_dX, 0.0, 1.0e-8); ABS_TEST(dYnacl_dX, 0.0, 1.0e-8); ABS_TEST(dYco2_dX, 0.0, 1.0e-8); // Two phase region. In this region, the mass fractions and derivatives can // be verified using the equilibrium mass fraction derivatives that have // been verified above Z = 0.45; _fp->massFractions(p, T, Xnacl, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::TWOPHASE); // Equilibrium mass fractions and derivatives Real Xco2_eq, dXco2_dp_eq, dXco2_dT_eq, dXco2_dX_eq, Yh2o_eq, dYh2o_dp_eq, dYh2o_dT_eq, dYh2o_dX_eq; _fp->equilibriumMassFractions(p, T, Xnacl, Xco2_eq, dXco2_dp_eq, dXco2_dT_eq, dXco2_dX_eq, Yh2o_eq, dYh2o_dp_eq, dYh2o_dT_eq, dYh2o_dX_eq); // Verfify mass fraction values Xco2 = fsp[0].mass_fraction[1]; Yco2 = fsp[1].mass_fraction[1]; Xh2o = fsp[0].mass_fraction[0]; Yh2o = fsp[1].mass_fraction[0]; ABS_TEST(Xco2, Xco2_eq, 1.0e-8); ABS_TEST(Yco2, 1.0 - Yh2o_eq, 1.0e-8); ABS_TEST(Xh2o, 1.0 - Xco2_eq, 1.0e-8); ABS_TEST(Yh2o, Yh2o_eq, 1.0e-8); // Verify derivatives wrt p, T dXco2_dp = fsp[0].dmass_fraction_dp[1]; dXco2_dT = fsp[0].dmass_fraction_dT[1]; dXco2_dX = fsp[0].dmass_fraction_dX[1]; dXco2_dZ = fsp[0].dmass_fraction_dZ[1]; dYco2_dp = fsp[1].dmass_fraction_dp[1]; dYco2_dT = fsp[1].dmass_fraction_dT[1]; dYco2_dX = fsp[1].dmass_fraction_dX[1]; dYco2_dZ = fsp[1].dmass_fraction_dZ[1]; ABS_TEST(dXco2_dp, dXco2_dp_eq, 1.0e-8); ABS_TEST(dXco2_dT, dXco2_dT_eq, 1.0e-8); ABS_TEST(dXco2_dX, dXco2_dX_eq, 1.0e-8); ABS_TEST(dXco2_dZ, 0.0, 1.0e-8); ABS_TEST(dYco2_dp, -dYh2o_dp_eq, 1.0e-8); ABS_TEST(dYco2_dT, -dYh2o_dT_eq, 1.0e-8); ABS_TEST(dYco2_dX, -dYh2o_dX_eq, 1.0e-8); ABS_TEST(dYco2_dZ, 0.0, 1.0e-8); // Use finite differences to verify derivative wrt Z is unaffected by Z const Real dZ = 1.0e-8; _fp->massFractions(p, T, Xnacl, Z + dZ, phase_state, fsp); Real Xco21 = fsp[0].mass_fraction[1]; Real Yco21 = fsp[1].mass_fraction[1]; _fp->massFractions(p, T, Xnacl, Z - dZ, phase_state, fsp); Real Xco22 = fsp[0].mass_fraction[1]; Real Yco22 = fsp[1].mass_fraction[1]; ABS_TEST(dXco2_dZ, (Xco21 - Xco22) / (2.0 * dZ), 1.0e-8); ABS_TEST(dYco2_dZ, (Yco21 - Yco22) / (2.0 * dZ), 1.0e-8); }
/** * Verify that triple point properties are correctly returned */ TEST_F(MethaneFluidPropertiesTest, triplePointProperties) { ABS_TEST(_fp->triplePointPressure(), 1.169e4, REL_TOL_SAVED_VALUE); ABS_TEST(_fp->triplePointTemperature(), 90.67, REL_TOL_SAVED_VALUE); }
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); }
/* * Verify calculation of liquid density, viscosity, enthalpy, and derivatives */ TEST_F(PorousFlowBrineCO2Test, liquidProperties) { const Real p = 1.0e6; const Real T = 350.0; const Real Xnacl = 0.1; FluidStatePhaseEnum phase_state; const unsigned int np = _fp->numPhases(); const unsigned int nc = _fp->numComponents(); std::vector<FluidStateProperties> fsp(np, FluidStateProperties(nc)); // Liquid region Real Z = 0.0001; _fp->massFractions(p, T, Xnacl, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::LIQUID); // Verify fluid density and viscosity _fp->liquidProperties(p, T, Xnacl, fsp); Real liquid_density = fsp[0].density; Real liquid_viscosity = fsp[0].viscosity; Real liquid_enthalpy = fsp[0].enthalpy; Real co2_partial_density, dco2_partial_density_dT; _fp->partialDensityCO2(T, co2_partial_density, dco2_partial_density_dT); Real brine_density = _brine_fp->rho(p, T, Xnacl); Real density = 1.0 / (Z / co2_partial_density + (1.0 - Z) / brine_density); Real viscosity = _brine_fp->mu(p, T, Xnacl); Real brine_enthalpy = _brine_fp->h(p, T, Xnacl); Real hdis, dhdis_dT; _fp->enthalpyOfDissolution(T, hdis, dhdis_dT); Real co2_enthalpy = _co2_fp->h(p, T); Real enthalpy = (1.0 - Z) * brine_enthalpy + Z * (co2_enthalpy + hdis); ABS_TEST(liquid_density, density, 1.0e-12); ABS_TEST(liquid_viscosity, viscosity, 1.0e-12); ABS_TEST(liquid_enthalpy, enthalpy, 1.0e-12); // Verify fluid density and viscosity derivatives Real ddensity_dp = fsp[0].ddensity_dp; Real ddensity_dT = fsp[0].ddensity_dT; Real ddensity_dZ = fsp[0].ddensity_dZ; Real ddensity_dX = fsp[0].ddensity_dX; Real dviscosity_dp = fsp[0].dviscosity_dp; Real dviscosity_dT = fsp[0].dviscosity_dT; Real dviscosity_dZ = fsp[0].dviscosity_dZ; Real dviscosity_dX = fsp[0].dviscosity_dX; Real denthalpy_dp = fsp[0].denthalpy_dp; Real denthalpy_dT = fsp[0].denthalpy_dT; Real denthalpy_dZ = fsp[0].denthalpy_dZ; Real denthalpy_dX = fsp[0].denthalpy_dX; // Derivatives wrt pressure const Real dp = 1.0; _fp->liquidProperties(p + dp, T, Xnacl, fsp); Real rho1 = fsp[0].density; Real mu1 = fsp[0].viscosity; Real h1 = fsp[0].enthalpy; _fp->liquidProperties(p - dp, T, Xnacl, fsp); Real rho2 = fsp[0].density; Real mu2 = fsp[0].viscosity; Real h2 = fsp[0].enthalpy; REL_TEST(ddensity_dp, (rho1 - rho2) / (2.0 * dp), 1.0e-4); REL_TEST(dviscosity_dp, (mu1 - mu2) / (2.0 * dp), 1.0e-5); REL_TEST(denthalpy_dp, (h1 - h2) / (2.0 * dp), 1.0e-4); // Derivatives wrt temperature const Real dT = 1.0e-4; _fp->liquidProperties(p, T + dT, Xnacl, fsp); rho1 = fsp[0].density; mu1 = fsp[0].viscosity; h1 = fsp[0].enthalpy; _fp->liquidProperties(p, T - dT, Xnacl, fsp); rho2 = fsp[0].density; mu2 = fsp[0].viscosity; h2 = fsp[0].enthalpy; REL_TEST(ddensity_dT, (rho1 - rho2) / (2.0 * dT), 1.0e-6); REL_TEST(dviscosity_dT, (mu1 - mu2) / (2.0 * dT), 1.0e-6); REL_TEST(denthalpy_dT, (h1 - h2) / (2.0 * dT), 1.0e-6); // Derivatives wrt Xnacl const Real dx = 1.0e-8; _fp->liquidProperties(p, T, Xnacl + dx, fsp); rho1 = fsp[0].density; mu1 = fsp[0].viscosity; h1 = fsp[0].enthalpy; _fp->liquidProperties(p, T, Xnacl - dx, fsp); rho2 = fsp[0].density; mu2 = fsp[0].viscosity; h2 = fsp[0].enthalpy; REL_TEST(ddensity_dX, (rho1 - rho2) / (2.0 * dx), 1.0e-6); REL_TEST(dviscosity_dX, (mu1 - mu2) / (2.0 * dx), 1.0e-6); REL_TEST(denthalpy_dX, (h1 - h2) / (2.0 * dx), 1.0e-6); // Derivatives wrt Z const Real dZ = 1.0e-8; _fp->massFractions(p, T, Xnacl, Z + dZ, phase_state, fsp); _fp->liquidProperties(p, T, Xnacl, fsp); rho1 = fsp[0].density; mu1 = fsp[0].viscosity; h1 = fsp[0].enthalpy; _fp->massFractions(p, T, Xnacl, Z - dZ, phase_state, fsp); _fp->liquidProperties(p, T, Xnacl, fsp); rho2 = fsp[0].density; mu2 = fsp[0].viscosity; h2 = fsp[0].enthalpy; REL_TEST(ddensity_dZ, (rho1 - rho2) / (2.0 * dZ), 1.0e-6); ABS_TEST(dviscosity_dZ, (mu1 - mu2) / (2.0 * dZ), 1.0e-6); REL_TEST(denthalpy_dZ, (h1 - h2) / (2.0 * dZ), 1.0e-6); // Two-phase region Z = 0.045; _fp->massFractions(p, T, Xnacl, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::TWOPHASE); // Verify fluid density and viscosity derivatives _fp->liquidProperties(p, T, Xnacl, fsp); ddensity_dp = fsp[0].ddensity_dp; ddensity_dT = fsp[0].ddensity_dT; ddensity_dX = fsp[0].ddensity_dX; ddensity_dZ = fsp[0].ddensity_dZ; dviscosity_dp = fsp[0].dviscosity_dp; dviscosity_dT = fsp[0].dviscosity_dT; dviscosity_dX = fsp[0].dviscosity_dX; dviscosity_dZ = fsp[0].dviscosity_dZ; denthalpy_dp = fsp[0].denthalpy_dp; denthalpy_dT = fsp[0].denthalpy_dT; denthalpy_dZ = fsp[0].denthalpy_dZ; denthalpy_dX = fsp[0].denthalpy_dX; // Derivatives wrt pressure _fp->massFractions(p + dp, T, Xnacl, Z, phase_state, fsp); _fp->liquidProperties(p + dp, T, Xnacl, fsp); rho1 = fsp[0].density; mu1 = fsp[0].viscosity; h1 = fsp[0].enthalpy; _fp->massFractions(p - dp, T, Xnacl, Z, phase_state, fsp); _fp->liquidProperties(p - dp, T, Xnacl, fsp); rho2 = fsp[0].density; mu2 = fsp[0].viscosity; h2 = fsp[0].enthalpy; REL_TEST(ddensity_dp, (rho1 - rho2) / (2.0 * dp), 1.0e-4); REL_TEST(dviscosity_dp, (mu1 - mu2) / (2.0 * dp), 1.0e-5); REL_TEST(denthalpy_dp, (h1 - h2) / (2.0 * dp), 1.0e-4); // Derivatives wrt temperature _fp->massFractions(p, T + dT, Xnacl, Z, phase_state, fsp); _fp->liquidProperties(p, T + dT, Xnacl, fsp); rho1 = fsp[0].density; mu1 = fsp[0].viscosity; h1 = fsp[0].enthalpy; _fp->massFractions(p, T - dT, Xnacl, Z, phase_state, fsp); _fp->liquidProperties(p, T - dT, Xnacl, fsp); rho2 = fsp[0].density; mu2 = fsp[0].viscosity; h2 = fsp[0].enthalpy; REL_TEST(ddensity_dT, (rho1 - rho2) / (2.0 * dT), 1.0e-6); REL_TEST(dviscosity_dT, (mu1 - mu2) / (2.0 * dT), 1.0e-6); REL_TEST(denthalpy_dT, (h1 - h2) / (2.0 * dT), 1.0e-6); // Derivatives wrt Xnacl _fp->massFractions(p, T, Xnacl + dx, Z, phase_state, fsp); _fp->liquidProperties(p, T, Xnacl + dx, fsp); rho1 = fsp[0].density; mu1 = fsp[0].viscosity; h1 = fsp[0].enthalpy; _fp->massFractions(p, T, Xnacl - dx, Z, phase_state, fsp); _fp->liquidProperties(p, T, Xnacl - dx, fsp); rho2 = fsp[0].density; mu2 = fsp[0].viscosity; h2 = fsp[0].enthalpy; REL_TEST(ddensity_dX, (rho1 - rho2) / (2.0 * dx), 1.0e-6); REL_TEST(dviscosity_dX, (mu1 - mu2) / (2.0 * dx), 1.0e-6); REL_TEST(denthalpy_dX, (h1 - h2) / (2.0 * dx), 1.0e-6); // Derivatives wrt Z _fp->massFractions(p, T, Xnacl, Z + dZ, phase_state, fsp); _fp->liquidProperties(p, T, Xnacl, fsp); rho1 = fsp[0].density; mu1 = fsp[0].viscosity; h1 = fsp[0].enthalpy; _fp->massFractions(p, T, Xnacl, Z - dZ, phase_state, fsp); _fp->liquidProperties(p, T, Xnacl, fsp); rho2 = fsp[0].density; mu2 = fsp[0].viscosity; h2 = fsp[0].enthalpy; ABS_TEST(ddensity_dZ, (rho1 - rho2) / (2.0 * dZ), 1.0e-6); ABS_TEST(dviscosity_dZ, (mu1 - mu2) / (2.0 * dZ), 1.0e-6); ABS_TEST(denthalpy_dZ, (h1 - h2) / (2.0 * dZ), 1.0e-6); }
/** * Verify that critical properties are correctly returned */ TEST_F(MethaneFluidPropertiesTest, criticalProperties) { ABS_TEST(_fp->criticalPressure(), 4.5992e6, REL_TOL_SAVED_VALUE); ABS_TEST(_fp->criticalTemperature(), 190.564, REL_TOL_SAVED_VALUE); ABS_TEST(_fp->criticalDensity(), 162.66, REL_TOL_SAVED_VALUE); }
/* * Verify calculation of liquid density, viscosity, enthalpy and derivatives. Note that as * density and viscosity don't depend on mass fraction, only the liquid region needs to be * tested (the calculations are identical in the two phase region). The enthalpy does depend * on mass fraction, so should be tested in the two phase region as well as the liquid region */ TEST_F(PorousFlowWaterNCGTest, liquidProperties) { const Real p = 1.0e6; const Real T = 350.0; std::vector<FluidStateProperties> fsp(2, FluidStateProperties(2)); // Verify fluid density and viscosity _fp->liquidProperties(p, T, fsp); Real liquid_density = fsp[0].density; Real liquid_viscosity = fsp[0].viscosity; Real density = _water_fp->rho_from_p_T(p, T); Real viscosity = _water_fp->mu(p, T); ABS_TEST(liquid_density, density, 1.0e-12); ABS_TEST(liquid_viscosity, viscosity, 1.0e-12); // Verify derivatives Real ddensity_dp = fsp[0].ddensity_dp; Real ddensity_dT = fsp[0].ddensity_dT; Real ddensity_dZ = fsp[0].ddensity_dZ; Real dviscosity_dp = fsp[0].dviscosity_dp; Real dviscosity_dT = fsp[0].dviscosity_dT; Real dviscosity_dZ = fsp[0].dviscosity_dZ; Real denthalpy_dp = fsp[0].denthalpy_dp; Real denthalpy_dT = fsp[0].denthalpy_dT; Real denthalpy_dZ = fsp[0].denthalpy_dZ; const Real dp = 1.0; _fp->liquidProperties(p + dp, T, fsp); Real rho1 = fsp[0].density; Real mu1 = fsp[0].viscosity; Real h1 = fsp[0].enthalpy; _fp->liquidProperties(p - dp, T, fsp); Real rho2 = fsp[0].density; Real mu2 = fsp[0].viscosity; Real h2 = fsp[0].enthalpy; REL_TEST(ddensity_dp, (rho1 - rho2) / (2.0 * dp), 1.0e-6); REL_TEST(dviscosity_dp, (mu1 - mu2) / (2.0 * dp), 1.0e-5); REL_TEST(denthalpy_dp, (h1 - h2) / (2.0 * dp), 1.0e-5); const Real dT = 1.0e-4; _fp->liquidProperties(p, T + dT, fsp); rho1 = fsp[0].density; mu1 = fsp[0].viscosity; h1 = fsp[0].enthalpy; _fp->liquidProperties(p, T - dT, fsp); rho2 = fsp[0].density; mu2 = fsp[0].viscosity; h2 = fsp[0].enthalpy; REL_TEST(ddensity_dT, (rho1 - rho2) / (2.0 * dT), 1.0e-6); REL_TEST(dviscosity_dT, (mu1 - mu2) / (2.0 * dT), 1.0e-6); REL_TEST(denthalpy_dT, (h1 - h2) / (2.0 * dT), 1.0e-5); Real Z = 0.0001; const Real dZ = 1.0e-8; FluidStatePhaseEnum phase_state; _fp->massFractions(p, T, Z, phase_state, fsp); _fp->liquidProperties(p, T, fsp); denthalpy_dp = fsp[0].denthalpy_dp; denthalpy_dT = fsp[0].denthalpy_dT; denthalpy_dZ = fsp[0].denthalpy_dZ; _fp->massFractions(p, T, Z + dZ, phase_state, fsp); _fp->liquidProperties(p, T, fsp); h1 = fsp[0].enthalpy; _fp->massFractions(p, T, Z - dZ, phase_state, fsp); _fp->liquidProperties(p, T, fsp); h2 = fsp[0].enthalpy; REL_TEST(denthalpy_dZ, (h1 - h2) / (2.0 * dZ), 1.0e-6); // Density and viscosity don't depend on Z, so derivatives should be 0 ABS_TEST(ddensity_dZ, 0.0, 1.0e-12); ABS_TEST(dviscosity_dZ, 0.0, 1.0e-12); // Check enthalpy calculations in the two phase region as well. Note that the mass fractions // vary with pressure and temperature in this region Z = 0.45; _fp->massFractions(p, T, Z, phase_state, fsp); _fp->liquidProperties(p, T, fsp); denthalpy_dp = fsp[0].denthalpy_dp; denthalpy_dT = fsp[0].denthalpy_dT; denthalpy_dZ = fsp[0].denthalpy_dZ; _fp->massFractions(p + dp, T, Z, phase_state, fsp); _fp->liquidProperties(p + dp, T, fsp); h1 = fsp[0].enthalpy; _fp->massFractions(p - dp, T, Z, phase_state, fsp); _fp->liquidProperties(p - dp, T, fsp); h2 = fsp[0].enthalpy; REL_TEST(denthalpy_dp, (h1 - h2) / (2.0 * dp), 1.0e-5); _fp->massFractions(p, T + dT, Z, phase_state, fsp); _fp->liquidProperties(p, T + dT, fsp); h1 = fsp[0].enthalpy; _fp->massFractions(p, T - dT, Z, phase_state, fsp); _fp->liquidProperties(p, T - dT, fsp); h2 = fsp[0].enthalpy; REL_TEST(denthalpy_dT, (h1 - h2) / (2.0 * dT), 1.0e-5); _fp->massFractions(p, T, Z + dZ, phase_state, fsp); _fp->liquidProperties(p, T, fsp); h1 = fsp[0].enthalpy; _fp->massFractions(p, T, Z - dZ, phase_state, fsp); _fp->liquidProperties(p, T, fsp); h2 = fsp[0].enthalpy; ABS_TEST(denthalpy_dZ, (h1 - h2) / (2.0 * dZ), 1.0e-5); }
/** * Test that the molar mass is correctly returned */ TEST_F(MethaneFluidPropertiesTest, molarMass) { ABS_TEST(_fp->molarMass(), 16.0425e-3, REL_TOL_SAVED_VALUE); }
/* * Verify calculation of gas saturation and derivatives in the two-phase region */ TEST_F(PorousFlowWaterNCGTest, twoPhase) { const Real p = 1.0e6; const Real T = 350.0; FluidStatePhaseEnum phase_state; std::vector<FluidStateProperties> fsp(2, FluidStateProperties(2)); // In the two-phase region, the mass fractions are the equilibrium values, so // a temporary value of Z can be used (as long as it corresponds to the two-phase // region) Real Z = 0.45; _fp->massFractions(p, T, Z, phase_state, fsp); EXPECT_EQ(phase_state, FluidStatePhaseEnum::TWOPHASE); // Calculate Z that gives a saturation of 0.25 Real gas_saturation = 0.25; Real liquid_pressure = p + _pc->capillaryPressure(1.0 - gas_saturation); // Calculate gas density and liquid density _fp->gasProperties(p, T, fsp); _fp->liquidProperties(liquid_pressure, T, fsp); // The mass fraction that corresponds to a gas_saturation = 0.25 Z = (gas_saturation * fsp[1].density * fsp[1].mass_fraction[1] + (1.0 - gas_saturation) * fsp[0].density * fsp[0].mass_fraction[1]) / (gas_saturation * fsp[1].density + (1.0 - gas_saturation) * fsp[0].density); // Calculate the gas saturation and derivatives _fp->saturationTwoPhase(p, T, Z, fsp); ABS_TEST(fsp[1].saturation, gas_saturation, 1.0e-8); // Test the derivatives const Real dp = 1.0e-1; gas_saturation = fsp[1].saturation; Real dgas_saturation_dp = fsp[1].dsaturation_dp; Real dgas_saturation_dT = fsp[1].dsaturation_dT; Real dgas_saturation_dZ = fsp[1].dsaturation_dZ; _fp->massFractions(p + dp, T, Z, phase_state, fsp); _fp->gasProperties(p + dp, T, fsp); _fp->saturationTwoPhase(p + dp, T, Z, fsp); Real gsat1 = fsp[1].saturation; _fp->massFractions(p - dp, T, Z, phase_state, fsp); _fp->gasProperties(p - dp, T, fsp); _fp->saturationTwoPhase(p - dp, T, Z, fsp); Real gsat2 = fsp[1].saturation; REL_TEST(dgas_saturation_dp, (gsat1 - gsat2) / (2.0 * dp), 1.0e-6); // Derivative wrt T const Real dT = 1.0e-4; _fp->massFractions(p, T + dT, Z, phase_state, fsp); _fp->gasProperties(p, T + dT, fsp); _fp->saturationTwoPhase(p, T + dT, Z, fsp); gsat1 = fsp[1].saturation; _fp->massFractions(p, T - dT, Z, phase_state, fsp); _fp->gasProperties(p, T - dT, fsp); _fp->saturationTwoPhase(p, T - dT, Z, fsp); gsat2 = fsp[1].saturation; REL_TEST(dgas_saturation_dT, (gsat1 - gsat2) / (2.0 * dT), 1.0e-6); // Derivative wrt Z const Real dZ = 1.0e-8; _fp->massFractions(p, T, Z, phase_state, fsp); _fp->gasProperties(p, T, fsp); _fp->saturationTwoPhase(p, T, Z + dZ, fsp); gsat1 = fsp[1].saturation; _fp->saturationTwoPhase(p, T, Z - dZ, fsp); gsat2 = fsp[1].saturation; REL_TEST(dgas_saturation_dZ, (gsat1 - gsat2) / (2.0 * dZ), 1.0e-6); }