void test_energy(const char *name, Functional f, double kT, double true_energy, double fraccuracy = 1e-15) { printf("\n************"); for (unsigned i=0;i<strlen(name);i++) printf("*"); printf("\n* Testing %s *\n", name); for (unsigned i=0;i<strlen(name);i++) printf("*"); printf("************\n\n"); Lattice lat(Cartesian(0,.5,.5), Cartesian(.5,0,.5), Cartesian(.5,.5,0)); int resolution = 20; GridDescription gd(lat, resolution, resolution, resolution); Grid density(gd); density = 1e-3*(-500*r2(gd)).cwise().exp() + 1e-7*VectorXd::Ones(gd.NxNyNz); retval += f.run_finite_difference_test(name, kT, density); double e = f.integral(kT, density); printf("Energy = %.16g\n", e); printf("Fractional error = %g\n", (e - true_energy)/fabs(true_energy)); if (e < true_energy) { printf("FAIL: the energy is too low! (it is %.16g)\n", e); retval++; } if (!(fabs((e - true_energy)/true_energy) < fraccuracy)) { printf("FAIL: Error in the energy is too big!\n"); retval++; } }
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); }