void compare_functionals(const Functional &f1, const Functional &f2, double kT, const Grid &n, double fraccuracy = 1e-15, double x = 0.001, double fraccuracydoub = 1e-15) { printf("\n************"); for (unsigned i=0;i<f1.get_name().size();i++) printf("*"); printf("\n* Testing %s *\n", f1.get_name().c_str()); for (unsigned i=0;i<f1.get_name().size();i++) printf("*"); printf("************\n\n"); printf("First energy:\n"); double f1n = f1.integral(kT, n); print_double("first energy is: ", f1n); printf("\n"); f1.print_summary("", f1n, f1.get_name().c_str()); printf("Second energy:\n"); double f2n = f2.integral(kT, n); print_double("second energy is: ", f2n); printf("\n"); f2.print_summary("", f2n, f2.get_name().c_str()); if (fabs(f1n/f2n - 1) > fraccuracy) { printf("E1 = %g\n", f1n); printf("E2 = %g\n", f2n); printf("FAIL: Error in f(n) is %g\n", f1n/f2n - 1); errors++; } Grid gr1(gd), gr2(gd); gr1.setZero(); gr2.setZero(); f1.integralgrad(kT, n, &gr1); f2.integralgrad(kT, n, &gr2); double err = (gr1-gr2).cwise().abs().maxCoeff(); double mag = gr1.cwise().abs().maxCoeff(); if (err/mag > fraccuracy) { printf("FAIL: Error in grad %s is %g as a fraction of %g\n", f1.get_name().c_str(), err/mag, mag); errors++; } errors += f1.run_finite_difference_test(f1.get_name().c_str(), kT, n); double f1x = f1(kT, x); double f2x = f2(kT, x); if (1 - fabs(f1x/f2x) > fraccuracydoub) { printf("FAIL: Error in double %s is %g as a fraction of %g\n", f1.get_name().c_str(), 1 - fabs(f1x/f2x), f2x); errors++; } double f1p = f1.derive(kT, x); double f2p = f2.derive(kT, x); if (1 - fabs(f1p/f2p) > fraccuracydoub) { printf("FAIL: Error in derive double %s is %g as a fraction of %g\n", f1.get_name().c_str(), 1 - fabs(f1p/f2p), f2p); errors++; } //errors += f2.run_finite_difference_test("other version", n); }
int main(int, char **argv) { Functional n = EffectivePotentialToDensity(); double Veff = -hughes_water_prop.kT*log(hughes_water_prop.liquid_density); const double nmin = 1e-11, nmax = 0.007; { double ngas = 2e-5; double mu = find_chemical_potential(IdealGasOfVeff(), hughes_water_prop.kT, ngas); test_eos("ideal gas", IdealGasOfVeff() + ChemicalPotential(mu)(n), ngas, ngas*hughes_water_prop.kT); } test_eos("quadratic", 0.5*sqr(n) - n, 1.0, 0.5, 2e-6); test_pressure("quadratic(2)", 0.5*sqr(n) - n, 2, 2); test_pressure("quadratic(3)", 0.5*sqr(n) - n, 3, 4.5); { //FILE *o = fopen("ideal-gas.dat", "w"); //equation_of_state(o, IdealGasOfVeff(), hughes_water_prop.kT, nmin, nmax); //fclose(o); } { FILE *o = fopen("dispersion.dat", "w"); //equation_of_state(o, DispersionSAFT(hughes_water_prop.lengthscale, hughes_water_prop.kT, // hughes_water_prop.epsilon_dispersion, // hughes_water_prop.lambda_dispersion)(n), // hughes_water_prop.kT, nmin, nmax); fclose(o); printf("Got dispersion!\n"); Functional f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale, hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB, hughes_water_prop.epsilon_dispersion, hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling, 0)); const double n_1atm = pressure_to_density(f, hughes_water_prop.kT, atmospheric_pressure, 0.001, 0.01); printf("density at 1 atmosphere is %g\n", n_1atm); printf("error in density at 1 atmosphere is %g\n", n_1atm/hughes_water_prop.liquid_density - 1); if (fabs(n_1atm/hughes_water_prop.liquid_density - 1) > 0.01) { printf("FAIL! error in water density is too big! %g\n", n_1atm/hughes_water_prop.liquid_density - 1); retval++; } test_pressure("saft at 1 atm", f, n_1atm, atmospheric_pressure); { printf("working onfoo\n"); double nv = coexisting_vapor_density(f, hughes_water_prop.kT, hughes_water_prop.liquid_density); printf("predicted vapor density: %g\n", nv); printf("actual vapor density: %g\n", hughes_water_prop.vapor_density); } if (0) { o = fopen("saft-fluid.dat", "w"); double mu = f.derive(hughes_water_prop.kT, Veff)*hughes_water_prop.kT/hughes_water_prop.liquid_density; // convert from derivative w.r.t. V equation_of_state(o, f + ChemicalPotential(mu)(n), hughes_water_prop.kT, nmin, nmax); fclose(o); } { double nl, nv, mu; saturated_liquid_vapor(f, hughes_water_prop.kT, 1e-14, 0.0017, 0.0055, &nl, &nv, &mu, 1e-5); printf("saturated water density is %g\n", nl); printf("1 atm water density ? is %g\n", hughes_water_prop.liquid_density); if (fabs(nl/hughes_water_prop.liquid_density - 1) > 0.1) { printf("FAIL: error in saturated water density is too big! %g\n", nl/hughes_water_prop.liquid_density - 1); retval++; } printf("predicted saturated vapor density: %g\n", nv); printf("actual vapor density: %g\n", hughes_water_prop.vapor_density); //double mu = f.derive(-hughes_water_prop.kT*log(nl))*hughes_water_prop.kT/nl; // convert from derivative w.r.t. V //o = fopen("saft-fluid-saturated.dat", "w"); //equation_of_state(o, f + ChemicalPotential(mu)(n), hughes_water_prop.kT, nmin, 1.1*nl); //fclose(o); double pv = pressure(f, hughes_water_prop.kT, nv); printf("vapor pressure is %g\n", pv); if (fabs(pv/hughes_water_prop.kT/nv - 1) > 1e-3) { printf("FAIL: error in vapor pressure, steam isn't ideal gas? %g\n", pv/hughes_water_prop.kT/nv - 1); retval++; } } { o = fopen("room-temperature.dat", "w"); Functional f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale, hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB, hughes_water_prop.epsilon_dispersion, hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling, 0)); double mufoo = find_chemical_potential(f, hughes_water_prop.kT, hughes_water_prop.liquid_density); f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale, hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB, hughes_water_prop.epsilon_dispersion, hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling, mufoo)); double nl, nv, mu; saturated_liquid_vapor(f, hughes_water_prop.kT, 1e-14, 0.0017, 0.0055, &nl, &nv, &mu, 1e-5); for (double dens=0.1*nv; dens<=1.2*nl; dens *= 1.01) { double V = -hughes_water_prop.kT*log(dens); double Vl = -hughes_water_prop.kT*log(nl); fprintf(o, "%g\t%g\t%g\n", dens, f(hughes_water_prop.kT, V), f(hughes_water_prop.kT, Vl) - (dens-nl)*mu); } fclose(o); printf("Finished plotting room-temperature.dat...\n"); } } { FILE *o = fopen("hard-sphere-fluid.dat", "w"); Functional f = HardSpheresWBnotensor(hughes_water_prop.lengthscale)(n) + IdealGasOfVeff(); double mu = f.derive(hughes_water_prop.kT, Veff)*hughes_water_prop.kT/hughes_water_prop.liquid_density; // convert from derivative w.r.t. V equation_of_state(o, f + ChemicalPotential(mu)(n), hughes_water_prop.kT, nmin, nmax); fclose(o); } if (retval == 0) { printf("\n%s passes!\n", argv[0]); } else { printf("\n%s fails %d tests!\n", argv[0], retval); return retval; } }