double run_soft_sphere(double reduced_density, double temp) { Functional f = SoftFluid(sigma, 1, 0); const double mu = find_chemical_potential(OfEffectivePotential(f), temp, reduced_density*pow(2,-5.0/2.0)); printf("mu is %g for reduced_density = %g at temperature %g\n", mu, reduced_density, temp); //printf("Filling fraction is %g with functional %s at temperature %g\n", reduced_density, teff); //fflush(stdout); temperature = temp; //if (kT == 0) kT = ;1 Lattice lat(Cartesian(xmax,0,0), Cartesian(0,ymax,0), Cartesian(0,0,zmax)); GridDescription gd(lat, dx); Grid softspherepotential(gd); softspherepotential.Set(soft_sphere_potential); f = SoftFluid(sigma, 1, mu); // compute approximate energy with chemical potential mu const double approx_energy = f(temperature, reduced_density*pow(2,-5.0/2.0))*xmax*ymax*zmax; const double precision = fabs(approx_energy*1e-9); f = OfEffectivePotential(SoftFluid(sigma, 1, mu) + ExternalPotential(softspherepotential)); static Grid *potential = 0; potential = new Grid(gd); *potential = softspherepotential - temperature*log(reduced_density*pow(2,-5.0/2.0)/(1.0*radius*radius*radius))*VectorXd::Ones(gd.NxNyNz); // Bad starting guess printf("\tMinimizing to %g absolute precision from %g from %g...\n", precision, approx_energy, temperature); fflush(stdout); Minimizer min = Precision(precision, PreconditionedConjugateGradient(f, gd, temperature, potential, QuadraticLineMinimizer)); took("Setting up the variables"); for (int i=0; min.improve_energy(true) && i<100; i++) { } took("Doing the minimization"); min.print_info(); Grid density(gd, EffectivePotentialToDensity()(temperature, gd, *potential)); //printf("# per area is %g at filling fraction %g\n", density.sum()*gd.dvolume/dw/dw, reduced_density); char *plotname = (char *)malloc(1024); sprintf(plotname, "papers/fuzzy-fmt/figs/radial-wca-%06.4f-%04.2f.dat", temp, reduced_density); z_plot(plotname, Grid(gd, pow(2,5.0/2.0)*density)); free(plotname); { //double peak = peak_memory()/1024.0/1024; //double current = current_memory()/1024.0/1024; //printf("Peak memory use is %g M (current is %g M)\n", peak, current); } took("Plotting stuff"); printf("density %g gives ff %g for reduced_density = %g and T = %g\n", density(0,0,gd.Nz/2), density(0,0,gd.Nz/2)*4*M_PI/3, reduced_density, temp); return density(0, 0, gd.Nz/2)*4*M_PI/3; // return bulk filling fraction }
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++; } }
double pairdist_fischer(const Grid &gsigma, const Grid &n, const Grid &nA, const Grid &n3, const Grid &nbar_sokolowski, Cartesian r0, Cartesian r1) { // This implements the pair distribution function of Fischer and // Methfessel from the 1980 paper. The py_rdf below should be the // true radial distribution function for a homogeneous hard-sphere // fluid with packing fraction eta. const Cartesian r01 = Cartesian(r0 - r1); const double r = sqrt(r01.dot(r01)); const double eta = n3(Cartesian(0.5*(r0+r1))); return mc(eta, r, mc_r_step, g); }
double run_walls(double reduced_density, const char *name, Functional fhs, double teff) { double kT = teff; if (kT == 0) kT = 1; Functional f = OfEffectivePotential(fhs); const double zmax = width + 2*spacing; Lattice lat(Cartesian(dw,0,0), Cartesian(0,dw,0), Cartesian(0,0,zmax)); GridDescription gd(lat, dx); Grid constraint(gd); constraint.Set(notinwall); f = constrain(constraint, f); Grid potential(gd); potential = pow(2,-5.0/2.0)*(reduced_density*constraint + 1e-4*reduced_density*VectorXd::Ones(gd.NxNyNz)); potential = -kT*potential.cwise().log(); const double approx_energy = fhs(kT, reduced_density*pow(2,-5.0/2.0))*dw*dw*width; const double precision = fabs(approx_energy*1e-11); printf("\tMinimizing to %g absolute precision from %g from %g...\n", precision, approx_energy, kT); fflush(stdout); Minimizer min = Precision(precision, PreconditionedConjugateGradient(f, gd, kT, &potential, QuadraticLineMinimizer)); took("Setting up the variables"); if (strcmp(name, "hard") != 0 && false) { printf("For now, SoftFluid doesn't work properly, so we're skipping the\n"); printf("minimization at temperature %g.\n", teff); } else { for (int i=0;min.improve_energy(false) && i<100;i++) { } } took("Doing the minimization"); min.print_info(); Grid density(gd, EffectivePotentialToDensity()(kT, gd, potential)); //printf("# per area is %g at filling fraction %g\n", density.sum()*gd.dvolume/dw/dw, eta); char *plotname = (char *)malloc(1024); sprintf(plotname, "papers/fuzzy-fmt/figs/walls%s-%06.4f-%04.2f.dat", name, teff, reduced_density); z_plot(plotname, Grid(gd, density*pow(2,5.0/2.0))); free(plotname); took("Plotting stuff"); printf("density %g gives ff %g for reduced density = %g and T = %g\n", density(0,0,gd.Nz/2), density(0,0,gd.Nz/2)*4*M_PI/3, reduced_density, teff); return density(0, 0, gd.Nz/2)*4*M_PI/3; // return bulk filling fraction }
double pairdist_this_work_mc(const Grid &gsigma, const Grid &density, const Grid &nA, const Grid &n3, const Grid &nbar_sokolowski, Cartesian r0, Cartesian r1) { const Cartesian r01 = Cartesian(r0 - r1); const double r = sqrt(r01.dot(r01)); const double eta0 = gsigma_to_eta(gsigma(r0)); const double eta1 = gsigma_to_eta(gsigma(r1)); return (mc(eta0, r, mc_r_step, g) + mc(eta1, r, mc_r_step, g))/2; }
double notinwall(Cartesian r) { const double z = r.dot(Cartesian(0,0,1)); if (fabs(z) > cavitysize/2) { return 0; } else { return 1; } }
void Tile::initInteriorPolygon(int mazeWidth, int mazeHeight) { Meters halfWallWidth = Meters(P()->wallWidth()) / 2.0; Cartesian lowerLeftPoint = m_fullPolygon.getVertices().at(0); Cartesian upperLeftPoint = m_fullPolygon.getVertices().at(1); Cartesian upperRightPoint = m_fullPolygon.getVertices().at(2); Cartesian lowerRightPoint = m_fullPolygon.getVertices().at(3); m_interiorPolygon = Polygon({ lowerLeftPoint + Cartesian( halfWallWidth * (getX() == 0 ? 2 : 1), halfWallWidth * (getY() == 0 ? 2 : 1)), upperLeftPoint + Cartesian( halfWallWidth * (getX() == 0 ? 2 : 1), halfWallWidth * (getY() == mazeHeight - 1 ? -2 : -1)), upperRightPoint + Cartesian( halfWallWidth * (getX() == mazeWidth - 1 ? -2 : -1), halfWallWidth * (getY() == mazeHeight - 1 ? -2 : -1)), lowerRightPoint + Cartesian( halfWallWidth * (getX() == mazeWidth - 1 ? -2 : -1), halfWallWidth * (getY() == 0 ? 2 : 1))}); }
int main(int, char **) { FILE *o = fopen("paper/figs/constrained-water.dat", "w"); Functional f = OfEffectivePotential(SaftFluidSlow(water_prop.lengthscale, water_prop.epsilonAB, water_prop.kappaAB, water_prop.epsilon_dispersion, water_prop.lambda_dispersion, water_prop.length_scaling, 0)); double mu_satp = find_chemical_potential(f, water_prop.kT, water_prop.liquid_density); Lattice lat(Cartesian(width,0,0), Cartesian(0,width,0), Cartesian(0,0,zmax)); GridDescription gd(lat, 0.1); Grid potential(gd); Grid constraint(gd); constraint.Set(notinwall); f = constrain(constraint, OfEffectivePotential(SaftFluidSlow(water_prop.lengthscale, water_prop.epsilonAB, water_prop.kappaAB, water_prop.epsilon_dispersion, water_prop.lambda_dispersion, water_prop.length_scaling, mu_satp))); Minimizer min = Precision(0, PreconditionedConjugateGradient(f, gd, water_prop.kT, &potential, QuadraticLineMinimizer)); potential = water_prop.liquid_density*constraint + water_prop.vapor_density*VectorXd::Ones(gd.NxNyNz); //potential = water_prop.liquid_density*VectorXd::Ones(gd.NxNyNz); potential = -water_prop.kT*potential.cwise().log(); const int numiters = 50; for (int i=0;i<numiters && min.improve_energy(true);i++) { fflush(stdout); Grid density(gd, EffectivePotentialToDensity()(water_prop.kT, gd, potential)); density.epsNative1d("paper/figs/1d-constrained-plot.eps", Cartesian(0,0,0), Cartesian(0,0,zmax), water_prop.liquid_density, 1, "Y axis: , x axis: "); } min.print_info(); double energy = min.energy()/width/width; printf("Energy is %.15g\n", energy); double N = 0; { Grid density(gd, EffectivePotentialToDensity()(water_prop.kT, gd, potential)); for (int i=0;i<gd.NxNyNz;i++) N += density[i]*gd.dvolume; } N = N/width/width; printf("N is %.15g\n", N); Grid density(gd, EffectivePotentialToDensity()(water_prop.kT, gd, potential)); density.epsNative1d("paper/figs/1d-constrained-plot.eps", Cartesian(0,0,0), Cartesian(0,0,zmax), water_prop.liquid_density, 1, "Y axis: , x axis: "); //potential.epsNative1d("hard-wall-potential.eps", Cartesian(0,0,0), Cartesian(0,0,zmax), 1, 1); fclose(o); }
double pairdist_sokolowski(const Grid &gsigma, const Grid &n, const Grid &nA, const Grid &n3, const Grid &nbar_sokolowski, Cartesian r0, Cartesian r1) { // This implements the pair distribution function of Sokolowski and // Fischer from the 1992 paper. const Cartesian r01 = Cartesian(r0 - r1); const double r = sqrt(r01.dot(r01)); const double eta0 = nbar_sokolowski(r0)*(4.0/3.0*M_PI); const double eta1 = nbar_sokolowski(r1)*(4.0/3.0*M_PI); const double eta = (eta0 + eta1)/2.0; return mc(eta, r, mc_r_step, g); }
int main() { Lattice lat(Cartesian(0,.5,.5), Cartesian(.5,0,.5), Cartesian(.5,.5,0)); Cartesian middle(0.5,0.5,0.5); Relative middlerel = lat.toRelative(middle); Reciprocal recip(0.2,0,0); int resolution = 20; Grid foo(lat, resolution, resolution, resolution), bar(lat, resolution, resolution, resolution); foo.Set(gaussian); foo.epsSlice("demo.eps", Cartesian(1,0,0), Cartesian(0,1,0), Cartesian(-.5,-.5,.5), 150); foo.epsNativeSlice("native.eps", Cartesian(1,0,0), Cartesian(0,1,0), Cartesian(-.5,-.5,.5)); //std::cout << "and here is the foo" << (foo + 2*bar + foo.cwise()*bar); std::cout << "middle and middlerel are:\n" << middle << std::endl << middlerel << std::endl << lat.toCartesian(middlerel) << std::endl; std::cout << "middle dot recip: " << recip * middle << std::endl; return 0; }
std::pair<Cartesian, Cartesian> TileGraphicTextCache::getTileGraphicTextPosition( int x, int y, int numRows, int numCols, int row, int col) const { // Get the character position in the maze for the starting tile std::pair<Cartesian, Cartesian> textPosition = m_tileGraphicTextPositions.at( std::make_pair( std::make_pair(numRows, numCols), std::make_pair(row, col) ) ); // Now get the character position in the maze for *this* tile Meters tileLength = m_wallLength + m_wallWidth; Cartesian offset = Cartesian(tileLength * x, tileLength * y); Cartesian LL = textPosition.first + offset; Cartesian UR = textPosition.second + offset; return std::make_pair(LL, UR); }
QPair<Cartesian, Cartesian> TileGraphicTextCache::getTileGraphicTextPosition( int x, int y, int numRows, int numCols, int row, int col) const { // Get the character position in the maze for the starting tile QPair<Cartesian, Cartesian> textPosition = m_tileGraphicTextPositions.value( { {numRows, numCols}, {row, col} } ); // Now get the character position in the maze for *this* tile Meters tileLength = m_wallLength + m_wallWidth; Cartesian offset = Cartesian(tileLength * x, tileLength * y); Cartesian LL = textPosition.first + offset; Cartesian UR = textPosition.second + offset; return {LL, UR}; }
void Tile::initWallPolygons(int mazeWidth, int mazeHeight) { Cartesian outerLowerLeftPoint = m_fullPolygon.getVertices().at(0); Cartesian outerUpperLeftPoint = m_fullPolygon.getVertices().at(1); Cartesian outerUpperRightPoint = m_fullPolygon.getVertices().at(2); Cartesian outerLowerRightPoint = m_fullPolygon.getVertices().at(3); Cartesian innerLowerLeftPoint = m_interiorPolygon.getVertices().at(0); Cartesian innerUpperLeftPoint = m_interiorPolygon.getVertices().at(1); Cartesian innerUpperRightPoint = m_interiorPolygon.getVertices().at(2); Cartesian innerLowerRightPoint = m_interiorPolygon.getVertices().at(3); std::vector<Cartesian> northWall; northWall.push_back(innerUpperLeftPoint); northWall.push_back(Cartesian(innerUpperLeftPoint.getX(), outerUpperLeftPoint.getY())); northWall.push_back(Cartesian(innerUpperRightPoint.getX(), outerUpperRightPoint.getY())); northWall.push_back(innerUpperRightPoint); m_wallPolygons.insert(std::make_pair(Direction::NORTH, Polygon(northWall))); std::vector<Cartesian> eastWall; eastWall.push_back(innerLowerRightPoint); eastWall.push_back(innerUpperRightPoint); eastWall.push_back(Cartesian(outerUpperRightPoint.getX(), innerUpperRightPoint.getY())); eastWall.push_back(Cartesian(outerLowerRightPoint.getX(), innerLowerRightPoint.getY())); m_wallPolygons.insert(std::make_pair(Direction::EAST, Polygon(eastWall))); std::vector<Cartesian> southWall; southWall.push_back(Cartesian(innerLowerLeftPoint.getX(), outerLowerLeftPoint.getY())); southWall.push_back(innerLowerLeftPoint); southWall.push_back(innerLowerRightPoint); southWall.push_back(Cartesian(innerLowerRightPoint.getX(), outerLowerRightPoint.getY())); m_wallPolygons.insert(std::make_pair(Direction::SOUTH, Polygon(southWall))); std::vector<Cartesian> westWall; westWall.push_back(Cartesian(outerLowerLeftPoint.getX(), innerLowerLeftPoint.getY())); westWall.push_back(Cartesian(outerUpperLeftPoint.getX(), innerUpperLeftPoint.getY())); westWall.push_back(innerUpperLeftPoint); westWall.push_back(innerLowerLeftPoint); m_wallPolygons.insert(std::make_pair(Direction::WEST, Polygon(westWall))); }
void Tile::initCornerPolygons(int mazeWidth, int mazeHeight) { Cartesian outerLowerLeftPoint = m_fullPolygon.getVertices().at(0); Cartesian outerUpperLeftPoint = m_fullPolygon.getVertices().at(1); Cartesian outerUpperRightPoint = m_fullPolygon.getVertices().at(2); Cartesian outerLowerRightPoint = m_fullPolygon.getVertices().at(3); Cartesian innerLowerLeftPoint = m_interiorPolygon.getVertices().at(0); Cartesian innerUpperLeftPoint = m_interiorPolygon.getVertices().at(1); Cartesian innerUpperRightPoint = m_interiorPolygon.getVertices().at(2); Cartesian innerLowerRightPoint = m_interiorPolygon.getVertices().at(3); std::vector<Cartesian> lowerLeftCorner; lowerLeftCorner.push_back(outerLowerLeftPoint); lowerLeftCorner.push_back(Cartesian(outerLowerLeftPoint.getX(), innerLowerLeftPoint.getY())); lowerLeftCorner.push_back(innerLowerLeftPoint); lowerLeftCorner.push_back(Cartesian(innerLowerLeftPoint.getX(), outerLowerLeftPoint.getY())); m_cornerPolygons.push_back(Polygon(lowerLeftCorner)); std::vector<Cartesian> upperLeftCorner; upperLeftCorner.push_back(Cartesian(outerUpperLeftPoint.getX(), innerUpperLeftPoint.getY())); upperLeftCorner.push_back(outerUpperLeftPoint); upperLeftCorner.push_back(Cartesian(innerUpperLeftPoint.getX(), outerUpperLeftPoint.getY())); upperLeftCorner.push_back(innerUpperLeftPoint); m_cornerPolygons.push_back(Polygon(upperLeftCorner)); std::vector<Cartesian> upperRightCorner; upperRightCorner.push_back(innerUpperRightPoint); upperRightCorner.push_back(Cartesian(innerUpperRightPoint.getX(), outerUpperRightPoint.getY())); upperRightCorner.push_back(outerUpperRightPoint); upperRightCorner.push_back(Cartesian(outerUpperRightPoint.getX(), innerUpperRightPoint.getY())); m_cornerPolygons.push_back(Polygon(upperRightCorner)); std::vector<Cartesian> lowerRightCorner; lowerRightCorner.push_back(Cartesian(innerLowerRightPoint.getX(), outerLowerRightPoint.getY())); lowerRightCorner.push_back(innerLowerRightPoint); lowerRightCorner.push_back(Cartesian(outerLowerRightPoint.getX(), innerLowerRightPoint.getY())); lowerRightCorner.push_back(outerLowerRightPoint); m_cornerPolygons.push_back(Polygon(lowerRightCorner)); }
void path_plot(const char *fname, const Grid &density, const Grid &constraint) { fflush(stdout); FILE *out = fopen(fname, "w"); if (!out) { fprintf(stderr, "Unable to create file %s!\n", fname); // don't just abort? return; } fflush(stdout); const GridDescription gd = density.description(); const double z0 = spacing + dx; double radius_path = 2.005; int num = 100; for (int i=0; i<int((width/2.0-radius_path)/dx+0.5); i++) { const double x_path = i*dx; Cartesian r = Cartesian(width/2-x_path,0,z0); Cartesian r_opp_side = Cartesian(width/2-x_path,0,gd.Nz*dx-z0); const double g2_path = density(r)*constraint(r_opp_side)/density(r_opp_side)/constraint(r); fprintf(out,"%g\t%g\t%g\t%g\n", x_path, g2_path, z0, width/2-x_path); } fflush(stdout); for (int i=0; i<num ; i++) { double theta = i*M_PI/num/2.0; const double x_path = i*M_PI/num/2.0*radius_path + 8.0; Cartesian r = Cartesian(radius_path*cos(theta),0,z0+radius_path*sin(theta)); Cartesian r_opp_side = Cartesian(radius_path*cos(theta),0,gd.Nz*dx-z0-radius_path*sin(theta)); const double g2_path = density(r)*constraint(r_opp_side)/density(r_opp_side)/constraint(r); fprintf(out,"%g\t%g\t%g\t%g\n", x_path, g2_path, z0+radius_path*sin(theta), radius_path*cos(theta)); } fflush(stdout); for (int i=0; i<int(8.0/dx+0.5); i++) { double r1z = i*dx; const double x_path = i*dx + radius_path*M_PI/2.0 + 10.0-radius_path; Cartesian r = Cartesian(0,0,r1z+radius_path+z0); Cartesian r_opp_side = Cartesian(0,0,gd.Nz*dx-r1z-radius_path-z0); const double g2_path = density(r)*constraint(r_opp_side)/density(r_opp_side)/constraint(r); fprintf(out,"%g\t%g\t%g\t%g\n", x_path, g2_path, r1z+radius_path+z0, 0.0); } fflush(stdout); fclose(out); }
double N_from_mu(Minimizer *min, Grid *potential, const Grid &constraint, double mu) { Functional f = constrain(constraint, OfEffectivePotential(HS + IdealGas() + ChemicalPotential(mu))); double Nnow = 0; min->minimize(f, potential->description()); for (int i=0;i<numiters && min->improve_energy(false);i++) { Grid density(potential->description(), EffectivePotentialToDensity()(1, potential->description(), *potential)); Nnow = density.sum()*potential->description().dvolume; printf("Nnow is %g vs %g\n", Nnow, N); fflush(stdout); density.epsNativeSlice("papers/contact/figs/box.eps", Cartesian(0,ymax+2,0), Cartesian(0,0,zmax+2), Cartesian(0,-ymax/2-1,-zmax/2-1)); density.epsNativeSlice("papers/contact/figs/box-diagonal.eps", Cartesian(xmax+2,0,zmax+2), Cartesian(0,ymax+2,0), Cartesian(-xmax/2-1,-ymax/2-1,-zmax/2-1)); //sleep(3); } return Nnow; }
double surface_tension(Minimizer min, Functional f0, LiquidProperties prop, bool verbose, const char *plotname) { int numptspersize = 100; int size = 64; const int gas_size = 10; Lattice lat(Cartesian(1,0,0), Cartesian(0,1,0), Cartesian(0,0,size*prop.lengthscale)); GridDescription gd(lat, 1, 1, numptspersize*size); Grid potential(gd); // Set the density to range from vapor to liquid const double Veff_liquid = -prop.kT*log(prop.liquid_density); const double Veff_gas = -prop.kT*log(prop.vapor_density); for (int i=0; i<gd.NxNyNz*gas_size/size; i++) potential[i] = Veff_gas; for (int i=gd.NxNyNz*gas_size/size; i<gd.NxNyNz; i++) potential[i] = Veff_liquid; // Enable the following line for debugging... //f0.run_finite_difference_test("f0", prop.kT, potential); min.minimize(f0, gd, &potential); while (min.improve_energy(verbose)) if (verbose) { printf("Working on liberated interface...\n"); fflush(stdout); } const double Einterface = f0.integral(prop.kT, potential); double Ninterface = 0; Grid interface_density(gd, EffectivePotentialToDensity()(prop.kT, gd, potential)); for (int i=0;i<gd.NxNyNz;i++) Ninterface += interface_density[i]*gd.dvolume; if (verbose) printf("Got interface energy of %g.\n", Einterface); for (int i=0; i<gd.NxNyNz; i++) potential[i] = Veff_gas; min.minimize(f0, gd, &potential); while (min.improve_energy(verbose)) if (verbose) { printf("Working on gas...\n"); fflush(stdout); } const double Egas = f0.integral(prop.kT, potential); double Ngas = 0; { Grid density(gd, EffectivePotentialToDensity()(prop.kT, gd, potential)); for (int i=0;i<gd.NxNyNz;i++) Ngas += density[i]*gd.dvolume; } for (int i=0; i<gd.NxNyNz; i++) potential[i] = Veff_liquid; if (verbose) { printf("\n\n\nWorking on liquid...\n"); fflush(stdout); } min.minimize(f0, gd, &potential); while (min.improve_energy(verbose)) if (verbose) { printf("Working on liquid...\n"); fflush(stdout); } const double Eliquid = f0.integral(prop.kT, potential); double Nliquid = 0; { Grid density(gd, EffectivePotentialToDensity()(prop.kT, gd, potential)); for (int i=0;i<gd.NxNyNz;i++) Nliquid += density[i]*gd.dvolume; } const double X = Ninterface/Nliquid; // Fraction of volume effectively filled with liquid. const double surface_tension = (Einterface - Eliquid*X - Egas*(1-X))/2; if (verbose) { printf("\n\n"); printf("interface energy is %.15g\n", Einterface); printf("gas energy is %.15g\n", Egas); printf("liquid energy is %.15g\n", Eliquid); printf("Ninterface/liquid/gas = %g/%g/%g\n", Ninterface, Nliquid, Ngas); printf("X is %g\n", X); printf("surface tension is %.10g\n", surface_tension); } if (plotname) interface_density.Dump1D(plotname, Cartesian(0,0,0), Cartesian(0,0,size*prop.lengthscale)); return surface_tension; }
int main(int argc, char *argv[]) { if (argc == 5) { if (sscanf(argv[1], "%lg", &xmax) != 1) { printf("Got bad x argument: %s\n", argv[1]); return 1; } if (sscanf(argv[2], "%lg", &ymax) != 1) { printf("Got bad y argument: %s\n", argv[2]); return 1; } if (sscanf(argv[3], "%lg", &zmax) != 1) { printf("Got bad z argument: %s\n", argv[3]); return 1; } if (sscanf(argv[4], "%lg", &N) != 1) { printf("Got bad N argument: %s\n", argv[4]); return 1; } using_default_box = false; printf("Box is %g x %g x %g hard sphere diameters, and it holds %g of them\n", xmax, ymax, zmax, N); } char *datname = (char *)malloc(1024); sprintf(datname, "papers/contact/figs/box-%02.0f,%02.0f,%02.0f-%02.0f-energy.dat", xmax, ymax, zmax, N); FILE *o = fopen(datname, "w"); const double myvolume = (xmax+2)*(ymax+2)*(zmax+2); const double meandensity = N/myvolume; Functional f = OfEffectivePotential(HS + IdealGas()); double mu = find_chemical_potential(f, 1, meandensity); f = OfEffectivePotential(HS + IdealGas() + ChemicalPotential(mu)); Lattice lat(Cartesian(xmax+3,0,0), Cartesian(0,ymax+3,0), Cartesian(0,0,zmax+3)); GridDescription gd(lat, 0.05); Grid potential(gd); Grid constraint(gd); constraint.Set(notinwall); took("Setting the constraint"); printf("xmax = %g\nymax = %g\nzmax = %g\nmeandensity=%g\n", xmax, ymax, zmax, meandensity); f = constrain(constraint, f); constraint.epsNativeSlice("papers/contact/figs/box-constraint.eps", Cartesian(0,ymax+4,0), Cartesian(0,0,zmax+4), Cartesian(0,-ymax/2-2,-zmax/2-2)); printf("Constraint has become a graph!\n"); potential = meandensity*constraint + 1e-4*meandensity*VectorXd::Ones(gd.NxNyNz); potential = -potential.cwise().log(); Minimizer min = Precision(1e-6, PreconditionedConjugateGradient(f, gd, 1, &potential, QuadraticLineMinimizer)); double mumax = mu, mumin = mu, dmu = 4.0/N; double Nnow = N_from_mu(&min, &potential, constraint, mu); const double fraccuracy = 1e-3; if (fabs(Nnow/N - 1) > fraccuracy) { if (Nnow > N) { while (Nnow > N) { mumin = mumax; mumax += dmu; dmu *= 2; Nnow = N_from_mu(&min, &potential, constraint, mumax); // Grid density(gd, EffectivePotentialToDensity()(1, gd, potential)); // density = EffectivePotentialToDensity()(1, gd, potential); // density.epsNativeSlice("papers/contact/figs/box.eps", // Cartesian(0,ymax+2,0), Cartesian(0,0,zmax+2), // Cartesian(0,-ymax/2-1,-zmax/2-1)); // density.epsNativeSlice("papers/contact/figs/box-diagonal.eps", // Cartesian(xmax+2,0,zmax+2), Cartesian(0,ymax+2,0), // Cartesian(-xmax/2-1,-ymax/2-1,-zmax/2-1)); printf("mumax %g gives N %g\n", mumax, Nnow); took("Finding N from mu"); } printf("mu is between %g and %g\n", mumin, mumax); } else { while (Nnow < N) { mumax = mumin; if (mumin > dmu) { mumin -= dmu; dmu *= 2; } else if (mumin > 0) { mumin = -mumin; } else { mumin *= 2; } Nnow = N_from_mu(&min, &potential, constraint, mumin); // density = EffectivePotentialToDensity()(1, gd, potential); // density.epsNativeSlice("papers/contact/figs/box.eps", // Cartesian(0,ymax+2,0), Cartesian(0,0,zmax+2), // Cartesian(0,-ymax/2-1,-zmax/2-1)); // density.epsNativeSlice("papers/contact/figs/box-diagonal.eps", // Cartesian(xmax+2,0,zmax+2), Cartesian(0,ymax+2,0), // Cartesian(-xmax/2-1,-ymax/2-1,-zmax/2-1)); printf("mumin %g gives N %g\n", mumin, Nnow); took("Finding N from mu"); } printf("mu is between %g and %g\n", mumin, mumax); } while (fabs(N/Nnow-1) > fraccuracy) { mu = 0.5*(mumin + mumax); Nnow = N_from_mu(&min, &potential, constraint, mu); // density = EffectivePotentialToDensity()(1, gd, potential); // density.epsNativeSlice("papers/contact/figs/box.eps", // Cartesian(0,ymax+2,0), Cartesian(0,0,zmax+2), // Cartesian(0,-ymax/2-1,-zmax/2-1)); // density.epsNativeSlice("papers/contact/figs/box-diagonal.eps", // Cartesian(xmax+2,0,zmax+2), Cartesian(0,ymax+2,0), // Cartesian(-xmax/2-1,-ymax/2-1,-zmax/2-1)); printf("Nnow is %g vs %g with mu %g\n", Nnow, N, mu); took("Finding N from mu"); if (Nnow > N) { mumin = mu; } else { mumax = mu; } } } printf("N final is %g (vs %g) with mu = %g\n", Nnow, N, mu); double energy = min.energy(); printf("Energy is %.15g\n", energy); Grid density(gd, EffectivePotentialToDensity()(1, gd, potential)); double mean_contact_density = ContactDensitySimplest(1.0).integral(1, density)/myvolume; fprintf(o, "%g\t%g\t%g\t%.15g\t%.15g\n", xmax, ymax, zmax, energy, mean_contact_density); Grid energy_density(gd, f(1, gd, potential)); Grid contact_density(gd, ContactDensitySimplest(1.0)(1, gd, density)); Grid n0(gd, ShellConvolve(1)(1, density)); Grid wu_contact_density(gd, FuWuContactDensity(1.0)(1, gd, density)); char *plotname = (char *)malloc(1024); sprintf(plotname, "papers/contact/figs/box-100c--%02.0f,%02.0f,%02.0f-%02.0f.dat", xmax, ymax, zmax, N); plot_grids_100_center(plotname, density, energy_density, contact_density); sprintf(plotname, "papers/contact/figs/box-100s--%02.0f,%02.0f,%02.0f-%02.0f.dat", xmax, ymax, zmax, N); plot_grids_100_side(plotname, density, energy_density, contact_density); sprintf(plotname, "papers/contact/figs/box-110c--%02.0f,%02.0f,%02.0f-%02.0f.dat", xmax, ymax, zmax, N); plot_grids_110(plotname, density, energy_density, contact_density); sprintf(plotname, "papers/contact/figs/box-x-%02.0f,%02.0f,%02.0f-%02.0f.dat", xmax, ymax, zmax, N); x_plot(plotname, density, energy_density, contact_density, wu_contact_density); free(plotname); density.epsNativeSlice("papers/contact/figs/box.eps", Cartesian(0,ymax+2,0), Cartesian(0,0,zmax+2), Cartesian(0,-ymax/2-1,-zmax/2-1)); density.epsNativeSlice("papers/contact/figs/box-diagonal.eps", Cartesian(xmax+2,0,zmax+2), Cartesian(0,ymax+2,0), Cartesian(-xmax/2-1,-ymax/2-1,-zmax/2-1)); took("Plotting stuff"); fclose(o); }
double pairdist_this_work_short(const Grid &gsigma, const Grid &density, const Grid &nA, const Grid &n3, const Grid &nbar_sokolowski, Cartesian r0, Cartesian r1) { const Cartesian r01 = Cartesian(r0 - r1); const double r = sqrt(r01.dot(r01)); return (short_range_radial_distribution(gsigma(r0), r) + short_range_radial_distribution(gsigma(r1), r))/2; }
void run_with_eta(double eta, const char *name, Functional fhs) { // Generates a data file for the pair distribution function, for filling fraction eta // and distance of first sphere from wall of z0. Data saved in a table such that the // columns are x values and rows are z1 values. printf("Now starting run_with_eta with eta = %g name = %s\n", eta, name); Functional f = OfEffectivePotential(fhs + IdealGas()); double mu = find_chemical_potential(f, 1, eta/(4*M_PI/3)); f = OfEffectivePotential(fhs + IdealGas() + ChemicalPotential(mu)); Lattice lat(Cartesian(width,0,0), Cartesian(0,width,0), Cartesian(0,0,width)); GridDescription gd(lat, dx); Grid potential(gd); Grid constraint(gd); constraint.Set(notinsphere); f = constrain(constraint, f); potential = (eta*constraint + 1e-4*eta*VectorXd::Ones(gd.NxNyNz))/(4*M_PI/3); potential = -potential.cwise().log(); const double approx_energy = (fhs + IdealGas() + ChemicalPotential(mu))(1, eta/(4*M_PI/3))*uipow(width,3); const double precision = fabs(approx_energy*1e-10); //printf("Minimizing to %g absolute precision...\n", precision); { // Put mimizer in block so as to free it when we finish minimizing to save memory. Minimizer min = Precision(precision, PreconditionedConjugateGradient(f, gd, 1, &potential, QuadraticLineMinimizer)); for (int i=0;min.improve_energy(true) && i<100;i++) { double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); fflush(stdout); } took("Doing the minimization"); } Grid density(gd, EffectivePotentialToDensity()(1, gd, potential)); Grid gsigma(gd, gSigmaA(1.0)(1, gd, density)); Grid nA(gd, ShellConvolve(2)(1, density)/(4*M_PI*4)); Grid n3(gd, StepConvolve(1)(1, density)); Grid nbar_sokolowski(gd, StepConvolve(1.6)(1, density)); nbar_sokolowski /= (4.0/3.0*M_PI*ipow(1.6, 3)); // Create the walls directory if it doesn't exist. if (mkdir("papers/pair-correlation/figs/walls", 0777) != 0 && errno != EEXIST) { // We failed to create the directory, and it doesn't exist. printf("Failed to create papers/pair-correlation/figs/walls: %s", strerror(errno)); exit(1); // fail immediately with error code } // here you choose the values of z0 to use // dx is the resolution at which we compute the density. char *plotname = new char[4096]; for (double z0 = 2.1; z0 < 4.5; z0 += 2.1) { // For each z0, we now pick one of our methods for computing the // pair distribution function: for (int version = 0; version < numplots; version++) { sprintf(plotname, "papers/pair-correlation/figs/triplet%s-%s-%04.2f-%1.2f.dat", name, fun[version], eta, z0); FILE *out = fopen(plotname,"w"); FILE *xfile = fopen("papers/pair-correlation/figs/triplet-x.dat","w"); FILE *zfile = fopen("papers/pair-correlation/figs/triplet-z.dat","w"); // the +1 for z0 and z1 are to shift the plot over, so that a sphere touching the wall // is at z = 0, to match with the monte carlo data const Cartesian r0(0,0,z0); for (double x = 0; x < 4; x += dx) { for (double z1 = -4; z1 <= 9; z1 += dx) { const Cartesian r1(x,0,z1); double g2 = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1); double n_bulk = (3.0/4.0/M_PI)*eta; double g3 = g2*density(r0)*density(r1)/n_bulk/n_bulk; fprintf(out, "%g\t", g3); fprintf(xfile, "%g\t", x); fprintf(zfile, "%g\t", z1); } fprintf(out, "\n"); fprintf(xfile, "\n"); fprintf(zfile, "\n"); } fclose(out); fclose(xfile); fclose(zfile); } } delete[] plotname; took("Dumping the triplet dist plots"); const double ds = 0.01; // step size to use in path plots, FIXME increase for publication! const double delta = .1; //this is the value of radius of the //particle as it moves around the contact //sphere on its path char *plotname_path = new char[4096]; for (int version = 0; version < numplots; version++) { sprintf(plotname_path, "papers/pair-correlation/figs/triplet%s-path-%s-%04.2f.dat", name, fun[version], eta); FILE *out_path = fopen(plotname_path, "w"); if (!out_path) { fprintf(stderr, "Unable to create file %s!\n", plotname_path); return; } sprintf(plotname_path, "papers/pair-correlation/figs/triplet-back-contact-%s-%04.2f.dat", fun[version], eta); FILE *out_back = fopen(plotname_path, "w"); if (!out_back) { fprintf(stderr, "Unable to create file %s!\n", plotname_path); return; } fprintf(out_path, "# unused\tg3\tz\tx\n"); fprintf(out_back, "# unused\tg3\tz\tx\n"); const Cartesian r0(0,0, 2.0+delta); const double max_theta = M_PI*2.0/3; for (double z = 7; z >= 2*(2.0 + delta); z-=ds) { const Cartesian r1(0,0,z); double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1); double n_bulk = (3.0/4.0/M_PI)*eta; double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk; fprintf(out_path,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]); } for (double z = -7; z <= -(2.0 + delta); z+=ds) { const Cartesian r1(0,0,z); double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1); double n_bulk = (3.0/4.0/M_PI)*eta; double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk; fprintf(out_back,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]); } const double dtheta = ds/2; for (double theta = 0; theta <= max_theta; theta += dtheta){ const Cartesian r1((2.0+delta)*sin(theta), 0, (2.0+delta)*(1+cos(theta))); double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1); double n_bulk = (3.0/4.0/M_PI)*eta; double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk; fprintf(out_path,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]); } for (double theta = 0; theta <= max_theta; theta += dtheta){ const Cartesian r1((2.0+delta)*sin(theta), 0,-(2.0+delta)*cos(theta)); double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1); double n_bulk = (3.0/4.0/M_PI)*eta; double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk; fprintf(out_back,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]); } for (double x = (2.0+delta)*sqrt(3)/2; x<=6; x+=ds){ const Cartesian r1(x, 0, 1.0+delta/2); double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1); double n_bulk = (3.0/4.0/M_PI)*eta; double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk; fprintf(out_path,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]); fprintf(out_back,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]); } fclose(out_path); fclose(out_back); } for (int version = 0; version < numplots; version++) { sprintf(plotname_path, "papers/pair-correlation/figs/triplet-path-inbetween-%s-%04.2f.dat", fun[version], eta); FILE *out_path = fopen(plotname_path, "w"); if (!out_path) { fprintf(stderr, "Unable to create file %s!\n", plotname_path); return; } sprintf(plotname_path, "papers/pair-correlation/figs/triplet-back-inbetween-%s-%04.2f.dat", fun[version], eta); FILE *out_back = fopen(plotname_path, "w"); if (!out_back) { fprintf(stderr, "Unable to create file %s!\n", plotname_path); return; } fprintf(out_path, "# unused\tg3\tz\tx\n"); fprintf(out_back, "# unused\tg3\tz\tx\n"); const Cartesian r0(0,0, 4.0+2*delta); const double max_theta = M_PI; for (double z = 11; z >= 3*(2.0 + delta); z-=ds) { const Cartesian r1(0,0,z); double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1); double n_bulk = (3.0/4.0/M_PI)*eta; double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk; fprintf(out_path,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]); } for (double z = -10; z <= -(2.0 + delta); z+=ds) { const Cartesian r1(0,0,z); double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1); double n_bulk = (3.0/4.0/M_PI)*eta; double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk; fprintf(out_back,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]); } const double dtheta = ds/2; for (double theta = 0; theta <= max_theta; theta += dtheta){ const Cartesian r1((2.0+delta)*sin(theta), 0, (2.0+delta)*(2+cos(theta))); double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1); double n_bulk = (3.0/4.0/M_PI)*eta; double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk; fprintf(out_path,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]); } for (double theta = 0; theta <= max_theta; theta += dtheta){ const Cartesian r1((2.0+delta)*sin(theta), 0, -(2.0+delta)*cos(theta)); double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1); double n_bulk = (3.0/4.0/M_PI)*eta; double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk; fprintf(out_back,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]); } for (double x = 0; x>=-6; x-=ds){ const Cartesian r1(x, 0, 2.0+delta); double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1); double n_bulk = (3.0/4.0/M_PI)*eta; double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk; fprintf(out_path,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]); fprintf(out_back,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]); } fclose(out_path); fclose(out_back); } delete[] plotname_path; }
#include "generated/phi1.h" #include "generated/phi1-Veff.h" #include "generated/phi1-plus.h" #include "generated/phi2.h" #include "generated/phi2-Veff.h" #include "generated/phi3rf.h" #include "generated/phi3rf-Veff.h" #include "generated/almostrf.h" #include "generated/almostrfnokt.h" #include "handymath.h" int errors = 0; double a = 5; Lattice lat(Cartesian(0,a,a), Cartesian(a,0,a), Cartesian(a,a,0)); //Lattice lat(Cartesian(1.4*rmax,0,0), Cartesian(0,1.4*rmax,0), Cartesian(0,0,1.4*rmax)); GridDescription gd(lat, 0.2); 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);
QVector<float> TransformationMatrix::getZoomedMapTransformationMatrix( QPair<double, double> physicalMazeSize, QPair<int, int> zoomedMapPosition, QPair<int, int> zoomedMapSize, QPair<int, int> windowSize, double screenPixelsPerMeter, double zoomedMapScale, bool rotateZoomedMap, const Coordinate& initialMouseTranslation, const Coordinate& currentMouseTranslation, const Angle& currentMouseRotation) { // The purpose of this function is to produce a 4x4 matrix which, // when applied to the physical coordinate within the vertex shader, // transforms it into an OpenGL coordinate for the zoomed map. Note that // the zoomed map will likely not contain the entirety of the maze, so the // pixel coordinates will be outside of the map. // Step 1: Calculate the scaling matrix double physicalWidth = physicalMazeSize.first; double physicalHeight = physicalMazeSize.second; // Note that this is not literally the number of pixels per meter of the // screen. Rather, it's our desired number of pixels per simulation meter. double pixelsPerMeter = screenPixelsPerMeter * zoomedMapScale; double pixelWidth = pixelsPerMeter * physicalWidth; double pixelHeight = pixelsPerMeter * physicalHeight; QPair<double, double> openGlOrigin = mapPixelCoordinateToOpenGlCoordinate({0, 0}, windowSize); QPair<double, double> openGlMazeSize = mapPixelCoordinateToOpenGlCoordinate({pixelWidth, pixelHeight}, windowSize); double openGlWidth = openGlMazeSize.first - openGlOrigin.first; double openGlHeight = openGlMazeSize.second - openGlOrigin.second; double horizontalScaling = openGlWidth / physicalWidth; double verticalScaling = openGlHeight / physicalHeight; QVector<float> scalingMatrix = { static_cast<float>(horizontalScaling), 0.0, 0.0, 0.0, 0.0, static_cast<float>(verticalScaling), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, }; // Step 2: Construct the translation matrix. We must ensure that the mouse // starts (static translation) and stays (dynamic translation) at the // center of the screen. // Part A: Find the static translation, i.e., the translation that puts the // center of the mouse (i.e., the midpoint of the line connecting its // wheels) in the center of the zoomed map. double centerXPixels = initialMouseTranslation.getX().getMeters() * pixelsPerMeter; double centerYPixels = initialMouseTranslation.getY().getMeters() * pixelsPerMeter; double zoomedMapCenterXPixels = zoomedMapPosition.first + 0.5 * zoomedMapSize.first; double zoomedMapCenterYPixels = zoomedMapPosition.second + 0.5 * zoomedMapSize.second; double staticTranslationXPixels = zoomedMapCenterXPixels - centerXPixels; double staticTranslationYPixels = zoomedMapCenterYPixels - centerYPixels; QPair<double, double> staticTranslation = mapPixelCoordinateToOpenGlCoordinate({staticTranslationXPixels, staticTranslationYPixels}, windowSize); // Part B: Find the dynamic translation, i.e., the current translation of the mouse. Cartesian mouseTranslationDelta = Cartesian(currentMouseTranslation) - initialMouseTranslation; double dynamicTranslationXPixels = mouseTranslationDelta.getX().getMeters() * pixelsPerMeter; double dynamicTranslationYPixels = mouseTranslationDelta.getY().getMeters() * pixelsPerMeter; QPair<double, double> dynamicTranslation = mapPixelCoordinateToOpenGlCoordinate({dynamicTranslationXPixels, dynamicTranslationYPixels}, windowSize); // Combine the transalations and form the translation matrix double horizontalTranslation = staticTranslation.first - dynamicTranslation.first + openGlOrigin.first; double verticalTranslation = staticTranslation.second - dynamicTranslation.second + openGlOrigin.second; QVector<float> translationMatrix = { 1.0, 0.0, 0.0, static_cast<float>(horizontalTranslation), 0.0, 1.0, 0.0, static_cast<float>(verticalTranslation), 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, }; // Step 3: Construct a few other transformation matrices needed for // rotating the maze. In order to properly rotate the maze, we must first // translate the center of the mouse to the origin. Then we have to unscale // it, rotate it, scale it, and then translate it back to the proper // location. Hence all of the matrices. // We subtract Degrees(90) here since we want forward to face NORTH double theta = (Degrees(currentMouseRotation) - Degrees(90)).getRadiansZeroTo2pi(); QVector<float> rotationMatrix = { static_cast<float>( std::cos(theta)), static_cast<float>(std::sin(theta)), 0.0, 0.0, static_cast<float>(-std::sin(theta)), static_cast<float>(std::cos(theta)), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, }; QVector<float> inverseScalingMatrix = { static_cast<float>(1.0/horizontalScaling), 0.0, 0.0, 0.0, 0.0, static_cast<float>(1.0/verticalScaling), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, }; QPair<double, double> zoomedMapCenterOpenGl = mapPixelCoordinateToOpenGlCoordinate({zoomedMapCenterXPixels, zoomedMapCenterYPixels}, windowSize); QVector<float> translateToOriginMatrix = { 1.0, 0.0, 0.0, static_cast<float>(zoomedMapCenterOpenGl.first), 0.0, 1.0, 0.0, static_cast<float>(zoomedMapCenterOpenGl.second), 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, }; QVector<float> inverseTranslateToOriginMatrix = { 1.0, 0.0, 0.0, static_cast<float>(-zoomedMapCenterOpenGl.first), 0.0, 1.0, 0.0, static_cast<float>(-zoomedMapCenterOpenGl.second), 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, }; QVector<float> zoomedMapCameraMatrix = multiply4x4Matrices(translationMatrix, scalingMatrix); if (rotateZoomedMap) { zoomedMapCameraMatrix = multiply4x4Matrices(translateToOriginMatrix, multiply4x4Matrices(scalingMatrix, multiply4x4Matrices(rotationMatrix, multiply4x4Matrices(inverseScalingMatrix, multiply4x4Matrices(inverseTranslateToOriginMatrix, zoomedMapCameraMatrix))))); } return zoomedMapCameraMatrix; }
double run_walls(double eta, const char *name, Functional fhs, double teff) { //printf("Filling fraction is %g with functional %s at temperature %g\n", eta, name, teff); //fflush(stdout); double kT = teff; if (kT == 0) kT = 1; Functional f = OfEffectivePotential(fhs); const double zmax = width + 2*spacing; Lattice lat(Cartesian(dw,0,0), Cartesian(0,dw,0), Cartesian(0,0,zmax)); GridDescription gd(lat, dx); Grid constraint(gd); constraint.Set(notinwall); f = constrain(constraint, f); // We reuse the potential, which should give us a better starting // guess on each calculation. static Grid *potential = 0; if (strcmp(name, "hard") == 0) { // start over for each potential delete potential; potential = 0; } if (!potential) { potential = new Grid(gd); *potential = (eta*constraint + 1e-4*eta*VectorXd::Ones(gd.NxNyNz))/(4*M_PI/3); *potential = -kT*potential->cwise().log(); } // FIXME below I use the HS energy because of issues with the actual // functional. const double approx_energy = fhs(kT, eta/(4*M_PI/3))*dw*dw*width; const double precision = fabs(approx_energy*1e-5); printf("\tMinimizing to %g absolute precision from %g from %g...\n", precision, approx_energy, kT); fflush(stdout); Minimizer min = Precision(precision, PreconditionedConjugateGradient(f, gd, kT, potential, QuadraticLineMinimizer)); took("Setting up the variables"); for (int i=0;min.improve_energy(false) && i<100;i++) { } took("Doing the minimization"); min.print_info(); Grid density(gd, EffectivePotentialToDensity()(kT, gd, *potential)); //printf("# per area is %g at filling fraction %g\n", density.sum()*gd.dvolume/dw/dw, eta); char *plotname = (char *)malloc(1024); sprintf(plotname, "papers/fuzzy-fmt/figs/walls%s-%06.4f-%04.2f.dat", name, teff, eta); z_plot(plotname, Grid(gd, 4*M_PI*density/3)); free(plotname); { GridDescription gdj = density.description(); double sep = gdj.dz*gdj.Lat.a3().norm(); int div = gdj.Nz; int mid = int (div/2.0); double Ntot_per_A = 0; double mydist = 0; for (int j=0; j<mid; j++){ Ntot_per_A += density(0,0,j)*sep; mydist += sep; } double Extra_per_A = Ntot_per_A - eta/(4.0/3.0*M_PI)*width/2; FILE *fout = fopen("papers/fuzzy-fmt/figs/wallsfillingfracInfo.txt", "a"); fprintf(fout, "walls%s-%04.2f.dat - If you want to match the bulk filling fraction of figs/walls%s-%04.2f.dat, than the number of extra spheres per area to add is %04.10f. So you'll want to multiply %04.2f by your cavity volume and divide by (4/3)pi. Then add %04.10f times the Area of your cavity to this number\n", name, eta, name, eta, Extra_per_A, eta, Extra_per_A); int wallslen = 20; double Extra_spheres = (eta*wallslen*wallslen*wallslen/(4*M_PI/3) + Extra_per_A*wallslen*wallslen); fprintf (fout, "For filling fraction %04.02f and walls of length %d you'll want to use %.0f spheres.\n\n", eta, wallslen, Extra_spheres); fclose(fout); } { //double peak = peak_memory()/1024.0/1024; //double current = current_memory()/1024.0/1024; //printf("Peak memory use is %g M (current is %g M)\n", peak, current); } took("Plotting stuff"); printf("density %g gives ff %g for eta = %g and T = %g\n", density(0,0,gd.Nz/2), density(0,0,gd.Nz/2)*4*M_PI/3, eta, teff); return density(0, 0, gd.Nz/2)*4*M_PI/3; // return bulk filling fraction }
int main(int argc, char *argv[]) { if (argc > 1) { if (sscanf(argv[1], "%lg", &diameter) != 1) { printf("Got bad argument: %s\n", argv[1]); return 1; } diameter *= nm; using_default_diameter = false; printf("Diameter is %g bohr\n", diameter); } const double ptransition =(3.0*M_PI-4.0)*(diameter/2.0)/2.0; const double dmax = ptransition + 0.6*nm; double zmax = 2*diameter+dmax+2*nm; double ymax = 2*diameter+dmax+2*nm; char *datname = new char[1024]; snprintf(datname, 1024, "papers/water-saft/figs/four-rods-in-water-%04.1fnm.dat", diameter/nm); FILE *o = fopen(datname, "w"); delete[] datname; Functional f = OfEffectivePotential(WaterSaft(new_water_prop.lengthscale, new_water_prop.epsilonAB, new_water_prop.kappaAB, new_water_prop.epsilon_dispersion, new_water_prop.lambda_dispersion, new_water_prop.length_scaling, 0)); double n_1atm = pressure_to_density(f, new_water_prop.kT, atmospheric_pressure, 0.001, 0.01); double mu_satp = find_chemical_potential(f, new_water_prop.kT, n_1atm); f = OfEffectivePotential(WaterSaft(new_water_prop.lengthscale, new_water_prop.epsilonAB, new_water_prop.kappaAB, new_water_prop.epsilon_dispersion, new_water_prop.lambda_dispersion, new_water_prop.length_scaling, mu_satp)); const double EperVolume = f(new_water_prop.kT, -new_water_prop.kT*log(n_1atm)); const double EperCell = EperVolume*(zmax*ymax - 4*0.25*M_PI*diameter*diameter)*width; //Functional X = Xassociation(new_water_prop.lengthscale, new_water_prop.epsilonAB, // new_water_prop.kappaAB, new_water_prop.epsilon_dispersion, // new_water_prop.lambda_dispersion, // new_water_prop.length_scaling); Functional S = OfEffectivePotential(EntropySaftFluid2(new_water_prop.lengthscale, new_water_prop.epsilonAB, new_water_prop.kappaAB, new_water_prop.epsilon_dispersion, new_water_prop.lambda_dispersion, new_water_prop.length_scaling)); //dmax, dstep already in bohrs (so it doesn't need to be converted from nm) double dstep = 0.25*nm; for (distance=0.0*nm; distance<=dmax; distance += dstep) { if ((distance >= ptransition - 0.5*nm) && (distance <= ptransition + 0.05*nm)) { if (distance >= ptransition - 0.25*nm) { dstep = 0.03*nm; } else { dstep = 0.08*nm; } } else { dstep = 0.25*nm; } Lattice lat(Cartesian(width,0,0), Cartesian(0,ymax,0), Cartesian(0,0,zmax)); GridDescription gd(lat, 0.2); printf("Grid is %d x %d x %d\n", gd.Nx, gd.Ny, gd.Nz); Grid potential(gd); Grid constraint(gd); constraint.Set(notinwall); f = OfEffectivePotential(WaterSaft(new_water_prop.lengthscale, new_water_prop.epsilonAB, new_water_prop.kappaAB, new_water_prop.epsilon_dispersion, new_water_prop.lambda_dispersion, new_water_prop.length_scaling, mu_satp)); f = constrain(constraint, f); printf("Diameter is %g bohr (%g nm)\n", diameter, diameter/nm); printf("Distance between rods = %g bohr (%g nm)\n", distance, distance/nm); potential = new_water_prop.liquid_density*constraint + 400*new_water_prop.vapor_density*VectorXd::Ones(gd.NxNyNz); //potential = new_water_prop.liquid_density*VectorXd::Ones(gd.NxNyNz); potential = -new_water_prop.kT*potential.cwise().log(); const double surface_tension = 5e-5; // crude guess from memory... const double surfprecision = 1e-5*(4*M_PI*diameter)*width*surface_tension; // five digits accuracy const double bulkprecision = 1e-12*fabs(EperCell); // but there's a limit on our precision for small rods const double precision = bulkprecision + surfprecision; printf("Precision limit from surface tension is to %g based on %g and %g\n", precision, surfprecision, bulkprecision); Minimizer min = Precision(precision, PreconditionedConjugateGradient(f, gd, new_water_prop.kT, &potential, QuadraticLineMinimizer)); const int numiters = 200; for (int i=0;i<numiters && min.improve_energy(false);i++) { fflush(stdout); // { // double peak = peak_memory()/1024.0/1024; // double current = current_memory()/1024.0/1024; // printf("Peak memory use is %g M (current is %g M)\n", peak, current); // } } Grid potential2(gd); Grid constraint2(gd); constraint2.Set(notinmiddle); potential2 = new_water_prop.liquid_density*(constraint2.cwise()*constraint) + 400*new_water_prop.vapor_density*VectorXd::Ones(gd.NxNyNz); potential2 = -new_water_prop.kT*potential2.cwise().log(); Minimizer min2 = Precision(1e-12, PreconditionedConjugateGradient(f, gd, new_water_prop.kT, &potential2, QuadraticLineMinimizer)); for (int i=0;i<numiters && min2.improve_energy(false);i++) { fflush(stdout); // { // double peak = peak_memory()/1024.0/1024; // double current = current_memory()/1024.0/1024; // printf("Peak memory use is %g M (current is %g M)\n", peak, current); // } } char *plotnameslice = new char[1024]; snprintf(plotnameslice, 1024, "papers/water-saft/figs/four-rods-%04.1f-%04.2f.dat", diameter/nm, distance/nm); printf("The bulk energy per cell should be %g\n", EperCell); double energy; if (min.energy() < min2.energy()) { energy = (min.energy() - EperCell)/width; Grid density(gd, EffectivePotentialToDensity()(new_water_prop.kT, gd, potential)); printf("Using liquid in middle initially.\n"); plot_grids_yz_directions(plotnameslice, density); { double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); } } else { energy = (min2.energy() - EperCell)/width; Grid density(gd, EffectivePotentialToDensity()(new_water_prop.kT, gd, potential2)); printf("Using vapor in middle initially.\n"); plot_grids_yz_directions(plotnameslice, density); { double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); } } printf("Liquid energy is %.15g. Vapor energy is %.15g\n", min.energy(), min2.energy()); fprintf(o, "%g\t%.15g\n", distance/nm, energy); //Grid entropy(gd, S(new_water_prop.kT, potential)); //Grid Xassoc(gd, X(new_water_prop.kT, density)); //plot_grids_y_direction(plotnameslice, density, energy_density, entropy, Xassoc); //Grid energy_density(gd, f(new_water_prop.kT, gd, potential)); delete[] plotnameslice; } fclose(o); { double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); } }
int main(int, char **argv) { const double kT = 1e-3; Lattice lat(Cartesian(0,5,5), Cartesian(5,0,5), Cartesian(5,5,0)); Cartesian plotcorner(-5, -5, 0), plotx(10,0,0), ploty(0,10,0); int resolution = 200; GridDescription gd(lat, resolution, resolution, resolution); Grid foo(gd), bar(gd), ref(gd); printf("Running Set(gaussian)...\n"); foo.Set(gaussian); const double integrate_foo = Identity().integral(kT, foo); printf("Original integrates to %.15g\n", integrate_foo); printf("Original Maximum is %g\n", foo.maxCoeff()); int retval = 0; if (integrate_foo < 0) { printf("Integral of original is negative (which may throw off tests): %g\n", integrate_foo); retval++; } //mkdir("tests/vis", 0777); //foo.epsNativeSlice("tests/vis/unblurred.eps", plotx, ploty, plotcorner); printf("Running Gaussian(10)...\n"); bar = Gaussian(10)(kT, foo); printf("Gaussian(10) integrates to %.15g\n", Identity().integral(kT, bar)); if (fabs(Identity().integral(kT, bar)/integrate_foo-1) > 1e-6) { printf("Error in Gaussian(10) is too large: %g\n", Identity().integral(kT, bar)/integrate_foo-1); retval++; } //bar.epsNativeSlice("tests/vis/gaussian-width-10.eps", plotx, ploty, plotcorner); printf("Gaussian(1) integrates to %g\n", Identity().integral(kT, bar)); printf("Running Gaussian(1)...\n"); bar = Gaussian(1)(kT, foo); if (fabs(Identity().integral(kT, bar)/integrate_foo-1) > 1e-6) { printf("Error in Gaussian(1) is too large: %g\n", Identity().integral(kT, bar)/integrate_foo-1); retval++; } //bar.epsNativeSlice("tests/vis/gaussian-width-1.eps", plotx, ploty, plotcorner); printf("Running StepConvolve(1)...\n"); bar = StepConvolve(1)(kT, foo); printf("StepConvolve(1) integrates to %.15g\n", Identity().integral(kT, bar)); printf("StepConvolve(1) Maximum is %g\n", bar.maxCoeff()); if (fabs(bar.maxCoeff()/integrate_foo-1) > 1e-6) { printf("FAIL: Max of StepConvolve(1) is wrong: %g\n", bar.maxCoeff()/integrate_foo - 1); retval++; } printf("StepConvolve(1) Minimum is %g\n", bar.minCoeff()); if (bar.minCoeff()/integrate_foo < -1e-9) { printf("Min of StepConvolve(1) is wrong: %g\n", bar.minCoeff()/integrate_foo); retval++; } const double fourpiover3 = 4*M_PI/3; if (fabs((Identity().integral(kT, bar)/integrate_foo-fourpiover3)/fourpiover3) > 1e-6) { printf("Integral of StepConvolve(1) is wrong: %g\n", (Identity().integral(kT, bar)/integrate_foo-fourpiover3)/fourpiover3); retval++; } //bar.epsNativeSlice("tests/vis/step-1.eps", plotx, ploty, plotcorner); printf("Running StepConvolve(2)...\n"); bar = StepConvolve(2)(kT, foo); printf("StepConvolve(2) Maximum is %g\n", bar.maxCoeff()); printf("StepConvolve(2) integrates to %.15g\n", Identity().integral(kT, bar)); if (fabs((Identity().integral(kT, bar)/integrate_foo-fourpiover3*8)/fourpiover3/8) > 1e-6) { printf("Integral of StepConvolve(2) is wrong: %g\n", (Identity().integral(kT, bar)/integrate_foo-fourpiover3*8)/fourpiover3/8); retval++; } if (fabs((bar.maxCoeff()-integrate_foo)/integrate_foo) > 1e-6) { printf("Max of StepConvolve(2) is wrong: %g\n", (bar.maxCoeff()-integrate_foo)/integrate_foo); retval++; } printf("StepConvolve(2) Minimum is %g\n", bar.minCoeff()); if (bar.minCoeff()/integrate_foo < -1e-9) { printf("Min of StepConvolve(2) is wrong: %g\n", bar.minCoeff()/integrate_foo); retval++; } //bar.epsNativeSlice("tests/vis/step-2.eps", plotx, ploty, plotcorner); printf("Running StepConvolve(3)...\n"); bar = StepConvolve(3)(kT, foo); printf("StepConvolve(3) Maximum is %g\n", bar.maxCoeff()); printf("StepConvolve(3) integrates to %.15g\n", Identity().integral(kT, bar)); if (fabs((Identity().integral(kT, bar)/integrate_foo-fourpiover3*27)/fourpiover3/27) > 1e-6) { printf("Integral of StepConvolve(3) is wrong: %g\n", (Identity().integral(kT, bar)/integrate_foo-fourpiover3*27)/fourpiover3/27); retval++; } if (fabs((bar.maxCoeff()-integrate_foo)/integrate_foo) > 1e-6) { printf("Max of StepConvolve(3) is wrong: %g\n", (bar.maxCoeff()-integrate_foo)/integrate_foo); retval++; } printf("StepConvolve(3) Minimum is %g\n", bar.minCoeff()); if (fabs(bar.minCoeff()/integrate_foo) < -1e-9) { printf("Min of StepConvolve(3) is wrong: %g\n", bar.minCoeff()/integrate_foo); retval++; } //bar.epsNativeSlice("tests/vis/step-3.eps", plotx, ploty, plotcorner); const double fourpi = 4*M_PI; printf("Running ShellConvolve(1)...\n"); bar = ShellConvolve(1)(kT, foo); printf("ShellConvolve(1) integrates to %.15g\n", Identity().integral(kT, bar)); printf("ShellConvolve(1) Maximum is %g\n", bar.maxCoeff()); if (fabs((Identity().integral(kT, bar)/integrate_foo-fourpi)/fourpi) > 1e-6) { printf("Integral of ShellConvolve(1) is wrong: %g\n", (Identity().integral(kT, bar)/integrate_foo-fourpi)/fourpi); retval++; } printf("ShellConvolve(1) Minimum is %g\n", bar.minCoeff()); if (bar.minCoeff()/integrate_foo < -1e-9) { printf("Min of ShellConvolve(1) is wrong: %g\n", bar.minCoeff()/integrate_foo); retval++; } //bar.epsNativeSlice("tests/vis/shell-1.eps", plotx, ploty, plotcorner); printf("Running ShellPrimeConvolve(1)...\n"); bar = ShellPrimeConvolve(1)(kT, foo); printf("ShellPrimeConvolve(1) integrates to %.15g\n", Identity().integral(kT, bar)); printf("ShellPrimeConvolve(1) Maximum is %g\n", bar.maxCoeff()); //bar.epsNativeSlice("tests/vis/shellPrime-1.eps", plotx, ploty, plotcorner); printf("Running ShellConvolve(3)...\n"); bar = ShellConvolve(3)(kT, foo); printf("ShellConvolve(3) Maximum is %g\n", bar.maxCoeff()); printf("ShellConvolve(3) integrates to %.15g\n", Identity().integral(kT, bar)); if (fabs((Identity().integral(kT, bar)/integrate_foo-fourpi*9)/fourpi/9) > 1e-6) { printf("Integral of ShellConvolve(3) is wrong: %g\n", (Identity().integral(kT, bar)/integrate_foo-fourpi*9)/fourpi/9); retval++; } printf("ShellConvolve(3) Minimum is %g\n", bar.minCoeff()); if (bar.minCoeff()/integrate_foo < -1e-9) { printf("Min of ShellConvolve(3) is wrong: %g\n", bar.minCoeff()/integrate_foo); retval++; } //bar.epsNativeSlice("tests/vis/shell-3.eps", plotx, ploty, plotcorner); printf("Running yShellConvolve(1)...\n"); bar = yShellConvolve(1)(kT, foo); printf("yShellConvolve(1) integrates to %.15g\n", Identity().integral(kT, bar)); printf("yShellConvolve(1) Maximum is %g\n", bar.maxCoeff()); printf("yShellConvolve(1) Minimum is %g\n", bar.minCoeff()); if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-6) { printf("Integral of yShellConvolve(1) is wrong: %g\n", Identity().integral(kT, bar)/integrate_foo-fourpi); retval++; } //bar.epsNativeSlice("tests/vis/y-shell-1.eps", plotx, ploty, plotcorner); Functional ysh = yShellConvolve(1), sh = ShellConvolve(1); { Grid scalarsh(gd, ShellConvolve(1)(kT, foo)); if (bar.maxCoeff() > scalarsh.maxCoeff()) { printf("FAIL: max of vector shell greater than scalar shell!\n"); retval++; } if (-bar.minCoeff() > scalarsh.maxCoeff()) { printf("FAIL: min of vector shell greater in magnitude than scalar shell!\n"); retval++; } } printf("Running xShellConvolve(3)...\n"); ref = ShellConvolve(3)(kT, foo); bar = xShellConvolve(3)(kT, foo); printf("xShellConvolve(3) Maximum is %g\n", bar.maxCoeff()); printf("xShellConvolve(3) integrates to %.15g\n", Identity().integral(kT, bar)); if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-6) { printf("Integral of xShellConvolve(3) is wrong: %g\n", Identity().integral(kT, bar)/integrate_foo); retval++; } double mymax = ref.maxCoeff(); if (fabs(bar.maxCoeff() - mymax)/mymax > 2e-3) { printf("problem with xShellConvolve max: %g != %g (error of %g)\n", bar.maxCoeff(), mymax, (bar.maxCoeff() - mymax)/mymax); retval++; exit(1); } if (fabs((bar.minCoeff() + mymax)/mymax) > 2e-3) { printf("problem with xShellConvolve min: %g != minus %g (error of %g)\n", bar.minCoeff(), mymax, (bar.minCoeff() + mymax)/mymax); retval++; exit(1); } //bar.epsNativeSlice("tests/vis/x-shell-3.eps", plotx, ploty, plotcorner); for (int i=0;i<gd.NxNyNz;i++) { if ((fabs(bar[i]) - fabs(ref[i]))/mymax > 1e-11) { printf("FAIL: x shell is bigger in magnitude than shell by %g out of %g compared with %g!\n", fabs(bar[i]) - fabs(ref[i]), fabs(ref[i]), mymax); retval++; } } printf("Running VectorDensityX(3)...\n"); ref = n2Density(3)(kT, foo); bar = VectorDensityX(3)(kT, foo); printf("VectorDensityX(3) Maximum is %g\n", bar.maxCoeff()); printf("VectorDensityX(3) integrates to %.15g\n", Identity().integral(kT, bar)); if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-6) { printf("Integral of VectorDensityX(3) is wrong: %g\n", Identity().integral(kT, bar)/integrate_foo); retval++; } //bar.epsNativeSlice("tests/vis/x-vector-3.eps", plotx, ploty, plotcorner); mymax = ref.maxCoeff(); if (fabs(bar.maxCoeff() - mymax)/mymax > 2e-3) { printf("problem with VectorDensityX max: %g != %g (error of %g)\n", bar.maxCoeff(), mymax, (bar.maxCoeff() - mymax)/mymax); retval++; exit(1); } if (fabs((bar.minCoeff() + mymax)/mymax) > 2e-3) { printf("problem with VectorDensityX min: %g != minus %g (error of %g)\n", bar.minCoeff(), mymax, (bar.minCoeff() + mymax)/mymax); retval++; exit(1); } for (int i=0;i<gd.NxNyNz;i++) { if ((fabs(bar[i]) - fabs(ref[i]))/mymax > 1e-11) { printf("FAIL: x shell is bigger in magnitude than shell by %g out of %g compared with %g!\n", fabs(bar[i]) - fabs(ref[i]), fabs(ref[i]), mymax); retval++; } } printf("Running xyShellConvolve(1)...\n"); ref = xShellConvolve(1)(kT, foo); bar = xyShellConvolve(1)(kT, foo); printf("xyShellConvolve(1) integrates to %.15g\n", Identity().integral(kT, bar)); printf("xyShellConvolve(1) Maximum is %g\n", bar.maxCoeff()); if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-6) { printf("Integral of xyShellConvolve(1) is wrong: %g\n", Identity().integral(kT, bar)/integrate_foo-fourpi); retval++; } //bar.epsNativeSlice("tests/vis/xy-shell-1.eps", plotx, ploty, plotcorner); mymax = ref.maxCoeff(); for (int i=0;i<gd.NxNyNz;i++) { if ((fabs(bar[i]) - fabs(ref[i]))/mymax > 1e-11) { printf("FAIL: xy shell is bigger in magnitude than x shell by %g out of %g!\n", fabs(bar[i]) - fabs(ref[i]), fabs(ref[i])); retval++; } } printf("Running xxShellConvolve(2)...\n"); ref = xShellConvolve(2)(kT, foo).cwise().abs() + 1./3*ShellConvolve(2)(kT, foo); bar = xxShellConvolve(2)(kT, foo); printf("xxShellConvolve(2) integrates to %.15g\n", Identity().integral(kT, bar)); printf("xxShellConvolve(2) Maximum is %g\n", bar.maxCoeff()); if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-14) { printf("FAIL: Integral of xxShellConvolve(2) is wrong: %g\n", Identity().integral(kT, bar)/integrate_foo); retval++; } //bar.epsNativeSlice("tests/vis/xx-shell-2.eps", plotx, ploty, plotcorner); //bar.epsNativeSlice("tests/vis/xx-shell-2.eps", Cartesian(0,10,0), Cartesian(0,0,10), Cartesian(0,0,0)); mymax = ref.maxCoeff(); for (int i=0;i<gd.NxNyNz;i++) { if ((fabs(bar[i]) - fabs(ref[i]))/mymax > 1e-12) { printf("FAIL: xx shell is bigger in magnitude than x shell by %g out of %g compared with %g!\n", fabs(bar[i]) - fabs(ref[i]), fabs(ref[i]), mymax); retval++; } } printf("Running TensorDensityXX(2)...\n"); ref = VectorDensityX(2)(kT, foo).cwise().abs() + 1./3*n2Density(2)(kT, foo); bar = TensorDensityXX(2)(kT, foo); printf("TensorDensityXX(2) integrates to %.15g\n", Identity().integral(kT, bar)); printf("TensorDensityXX(2) Maximum is %g\n", bar.maxCoeff()); if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-14) { printf("FAIL: Integral of xxShellConvolve(2) is wrong: %g\n", Identity().integral(kT, bar)/integrate_foo); retval++; } //bar.epsNativeSlice("tests/vis/xx-tensor-2.eps", plotx, ploty, plotcorner); mymax = ref.maxCoeff(); double shellmax = n2Density(3)(kT, foo).maxCoeff(); if (fabs(bar.maxCoeff() - 2*shellmax/3)/(2*shellmax/3) > 1e-2) { printf("problem with TensorDensityXX max: %g != %g (error of %g)\n", bar.maxCoeff(), 2*shellmax/3, (bar.maxCoeff() - 2*shellmax/3)/(2*shellmax/3)); retval++; exit(1); } for (int i=0;i<gd.NxNyNz;i++) { if ((fabs(bar[i]) - fabs(ref[i]))/mymax > 1e-12) { printf("FAIL: xx shell is bigger in magnitude than x shell by %g out of %g compared with %g!\n", fabs(bar[i]) - fabs(ref[i]), fabs(ref[i]), mymax); retval++; } } printf("Running zxShellConvolve(3)...\n"); Functional zxsh = zxShellConvolve(3); bar = zxsh(kT, foo); printf("zxShellConvolve(3) Maximum is %g\n", bar.maxCoeff()); printf("zxShellConvolve(3) integrates to %.15g\n", Identity().integral(kT, bar)); if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-6) { printf("Integral of zxShellConvolve(3) is wrong: %g\n", Identity().integral(kT, bar)/integrate_foo); retval++; } //bar.epsNativeSlice("tests/vis/zx-shell-3.eps", plotx, ploty, Cartesian(-5,-5,0.5)); if (retval == 0) printf("\n%s passes!\n", argv[0]); else printf("\n%s fails %d tests!\n", argv[0], retval); return retval; }
std::map< std::pair<std::pair<int, int>, std::pair<int, int>>, std::pair<Cartesian, Cartesian>> TileGraphicTextCache::buildPositionCache( double borderFraction, TileTextAlignment tileTextAlignment) { // The tile graphic text could look like either of the following, depending // on the layout, boarder, and max size // // col // *-*---------------------------*-* *-*---------------------------*-* // *-*--------------------------[B]* *-*--------------------------[B]* // | | | | | | | | // | | *------------------[D] | | | | *------------------[D] | | // | | | | | | | | | | | | | | | // | | | | | | | | | | | | | | | // | | | | 00 | 01 | | | | | | |----|----|----|----| | | // row | | | |____|____| | | | or | | | | | | | | | // | | | | | | | | | | | | 00 | 01 | 02 | 03 | | | // | | | | | | | | | | | [E]---|----|----|----| | | // | | | | 10 | 11 | | | | | | | | | | // | | | | | | | | | | | | | | | // | | [C]--[E]-------------* | | | | [C]------------------* | | // | | | | | | | | // *[A]--------------------------*-* *[A]--------------------------*-* // *-*---------------------------*-* *-*---------------------------*-* std::map< std::pair<std::pair<int, int>, std::pair<int, int>>, std::pair<Cartesian, Cartesian>> positionCache; int maxRows = m_tileGraphicTextMaxSize.first; int maxCols = m_tileGraphicTextMaxSize.second; // First we get the unscaled diagonal Cartesian A = Cartesian(m_wallWidth / 2.0, m_wallWidth / 2.0); Cartesian B = A + Cartesian(m_wallLength, m_wallLength); Cartesian C = A + Cartesian(m_wallLength, m_wallLength) * borderFraction; Cartesian D = B - Cartesian(m_wallLength, m_wallLength) * borderFraction; Cartesian CD = D - C; // We assume that each character is twice as tall as it is wide, and we scale accordingly Meters characterWidth = CD.getX() / static_cast<double>(maxCols); Meters characterHeight = CD.getY() / static_cast<double>(maxRows); if (characterWidth * 2.0 < characterHeight) { characterHeight = characterWidth * 2.0; } else { characterWidth = characterHeight / 2.0; } // Now we get the scaled diagonal (note that we'll only shrink in at most one direction) Cartesian scalingOffset = Cartesian( (CD.getX() - characterWidth * maxCols) / 2.0, (CD.getY() - characterHeight * maxRows) / 2.0 ); Cartesian E = C + scalingOffset; // For all numbers of rows displayed for (int numRows = 0; numRows <= maxRows; numRows += 1) { // For all numbers of columns displayed for (int numCols = 0; numCols <= maxCols; numCols += 1) { // For each visible row and col for (int row = 0; row <= maxRows; row += 1) { for (int col = 0; col <= maxCols; col += 1) { Cartesian LL = Cartesian(Meters(0), Meters(0)); Cartesian UR = Cartesian(Meters(0), Meters(0)); if (row < numRows && col < numCols) { double rowOffset = 0.0; if (ContainerUtilities::setContains(CENTER_STAR_ALIGNMENTS, tileTextAlignment)) { rowOffset = static_cast<double>(maxRows - numRows) / 2.0; } else if (ContainerUtilities::setContains(UPPER_STAR_ALIGNMENTS, tileTextAlignment)) { rowOffset = static_cast<double>(maxRows - numRows); } double colOffset = 0.0; if (ContainerUtilities::setContains(STAR_CENTER_ALIGNMENTS, tileTextAlignment)) { colOffset = static_cast<double>(maxCols - numCols) / 2.0; } else if (ContainerUtilities::setContains(STAR_RIGHT_ALIGNMENTS, tileTextAlignment)) { colOffset = static_cast<double>(maxCols - numCols); } LL = Cartesian( Meters(E.getX() + characterWidth * (col + colOffset)), Meters(E.getY() + characterHeight * ((numRows - row - 1) + rowOffset)) ); UR = Cartesian( Meters(E.getX() + characterWidth * (col + colOffset + 1)), Meters(E.getY() + characterHeight * ((numRows - row - 1) + rowOffset + 1)) ); } positionCache.insert( std::make_pair( std::make_pair( // The number of rows/cols to be drawn std::make_pair(numRows, numCols), // The row and col of the current character std::make_pair(row, col) ), // The lower left and upper right texture coordinate std::make_pair(LL, UR) ) ); } } } } return positionCache; }
int main(int, char **) { for (double eta = 0.3; eta < 0.35; eta += 0.1) { // Generates a data file for the pair distribution function, for filling fraction eta // and distance of first sphere from wall of z0. Data saved in a table such that the // columns are x values and rows are z1 values. printf("Now starting sphere_with_wall with eta = %g\n",eta); Lattice lat(Cartesian(width,0,0), Cartesian(0,width,0), Cartesian(0,0,width+2*spacing)); GridDescription gd(lat, dx); //the resolution here dramatically affects our memory use Functional f = OfEffectivePotential(WB + IdealGas()); double mu = find_chemical_potential(f, 1, eta/(4*M_PI/3)); f = OfEffectivePotential(WB + IdealGas() + ChemicalPotential(mu)); Grid potential(gd); Grid constraint(gd); constraint.Set(*notinwall_or_sphere); constraint.epsNativeSlice("myconstraint.eps", Cartesian(0, 0, 2*(width+2*spacing)), Cartesian(2*width, 0, 0), Cartesian(0, 0, 0)); f = constrain(constraint, f); potential = (eta*constraint + 1e-4*eta*VectorXd::Ones(gd.NxNyNz))/(4*M_PI/3); potential = -potential.cwise().log(); const double approx_energy = (WB + IdealGas() + ChemicalPotential(mu))(1, eta/(4*M_PI/3))*dw*dw*width; const double precision = fabs(approx_energy*1e-4); //printf("Minimizing to %g absolute precision...\n", precision); Minimizer min = Precision(precision, PreconditionedConjugateGradient(f, gd, 1, &potential, QuadraticLineMinimizer)); { double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); fflush(stdout); } for (int i=0; min.improve_energy(true) && i<100; i++) { double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); fflush(stdout); } Grid density(gd, EffectivePotentialToDensity()(1, gd, potential)); char *plotname = new char[1024]; sprintf(plotname, "papers/pair-correlation/figs/walls/wallsWB-sphere-dft-%04.2f.dat", eta); pair_plot(plotname, density); delete[] plotname; char *plotname_path = new char[1024]; sprintf(plotname_path, "papers/pair-correlation/figs/walls/wallsWB-sphere-dft-path-%04.2f.dat", eta); path_plot(plotname_path, density, constraint); delete[] plotname_path; fflush(stdout); { double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); fflush(stdout); } fflush(stdout); } fflush(stdout); // Just create this file so make knows we have run. if (!fopen("papers/pair-correlation/figs/walls_sphere.dat", "w")) { printf("Error creating walls.dat!\n"); return 1; } fflush(stdout); return 1; }
int main(int argc, char *argv[]) { clock_t start_time = clock(); if (argc == 3) { if (sscanf(argv[2], "%lg", &temperature) != 1) { printf("Got bad argument: %s\n", argv[2]); return 1; } temperature *= kB; bool good_element = false; for (int i=0; i<numelements; i++) { if (strcmp(elements[i], argv[1]) == 0) { sigma = sigmas[i]; epsilon = epsilons[i]; good_element = true; } } if (!good_element) { printf("Bad element: %s\n", argv[1]); return 1; } } else { printf("Need element and temperature.\n"); return 1; } char *datname = (char *)malloc(1024); sprintf(datname, "papers/water-saft/figs/hughes-lj-%s-%gK-energy.dat", argv[1], temperature/kB); 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 n_1atm = pressure_to_density(f, temperature, lj_pressure, 0.001, 0.01); double mu = find_chemical_potential(f, temperature, n_1atm); 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, mu)); Functional S = OfEffectivePotential(EntropySaftFluid2(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)); const double EperVolume = f(temperature, -temperature*log(n_1atm)); const double EperNumber = EperVolume/n_1atm; const double SperNumber = S(temperature, -temperature*log(n_1atm))/n_1atm; const double EperCell = EperVolume*(zmax*ymax*xmax - (4*M_PI/3)*sigma*sigma*sigma); Lattice lat(Cartesian(xmax,0,0), Cartesian(0,ymax,0), Cartesian(0,0,zmax)); GridDescription gd(lat, 0.20); Grid potential(gd); Grid externalpotential(gd); externalpotential.Set(externalpotentialfunction); 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, mu) + ExternalPotential(externalpotential)); Functional X = WaterX(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, mu); Functional HB = HughesHB(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, mu); externalpotential.epsNativeSlice("papers/water-saft/figs/hughes-lj-potential.eps", Cartesian(0,ymax,0), Cartesian(0,0,zmax), Cartesian(0,ymax/2,zmax/2)); printf("Done outputting hughes-lj-potential.eps\n"); potential = 0*externalpotential - temperature*log(n_1atm)*VectorXd::Ones(gd.NxNyNz); // ??? double energy; { const double surface_tension = 5e-5; // crude guess from memory... const double surfprecision = 1e-4*M_PI*sigma*sigma*surface_tension; // four digits precision const double bulkprecision = 1e-12*fabs(EperCell); // but there's a limit on our precision const double precision = (bulkprecision + surfprecision)*1e-6; Minimizer min = Precision(precision, PreconditionedConjugateGradient(f, gd, temperature, &potential, QuadraticLineMinimizer)); const int numiters = 200; for (int i=0;i<numiters && min.improve_energy(true);i++) { double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); fflush(stdout); { char* name = new char[1000]; sprintf(name, "papers/water-saft/figs/hughes-lj-%s-%gK-density-%d.eps", argv[1], temperature/kB, i); Grid density(gd, EffectivePotentialToDensity()(temperature, gd, potential)); density.epsNativeSlice(name, Cartesian(0,ymax,0), Cartesian(0,0,zmax), Cartesian(0,ymax/2,zmax/2)); } Grid gradient(gd, potential); gradient *= 0; f.integralgrad(temperature, potential, &gradient); char* gradname = new char[1000]; sprintf(gradname, "papers/water-saft/figs/hughes-lj-%s-%gK-gradient-%d.eps", argv[1], temperature/kB, i); gradient.epsNativeSlice(gradname, Cartesian(0,ymax,0), Cartesian(0,0,zmax), Cartesian(0,ymax/2,zmax/2)); Grid density(gd, EffectivePotentialToDensity()(temperature, gd, potential)); char *plotname = (char *)malloc(1024); sprintf(plotname, "papers/water-saft/figs/hughes-lj-%s-%gK-%d.dat", argv[1], temperature/kB, i); plot_grids_y_direction(plotname, density, gradient); // Grid gradient(gd, potential); // gradient *= 0; // f.integralgrad(temperature, potential, &gradient); // sprintf(name, "papers/water-saft/figs/lj-%s-%d-gradient-big.eps", argv[1], i); // gradient.epsNativeSlice("papers/water-saft/figs/lj-gradient-big.eps", // Cartesian(0,ymax,0), Cartesian(0,0,zmax), // Cartesian(0,ymax/2,zmax/2)); // sprintf(name, "papers/water-saft/figs/lj-%s-%d-big.dat", argv[1], i); // plot_grids_y_direction(name, density, gradient); } double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); energy = min.energy(); printf("Total energy is %.15g\n", energy); // Here we free the minimizer with its associated data structures. } { double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); } Grid gradient(gd, potential); gradient *= 0; f.integralgrad(temperature, potential, &gradient); gradient.epsNativeSlice("papers/water-saft/figs/hughes-lj-gradient.eps", Cartesian(0,ymax,0), Cartesian(0,0,zmax), Cartesian(0,ymax/2,zmax/2)); double entropy = S.integral(temperature, potential); Grid density(gd, EffectivePotentialToDensity()(temperature, gd, potential)); // Grid zeroed_out_density(gd, density.cwise()*constraint); // this is zero inside the sphere! Grid X_values(gd, X(temperature, gd, density)); //Grid H_bonds_grid(gd, zeroed_out_density.cwise()*(4*(VectorXd::Ones(gd.NxNyNz)-X_values))); //const double broken_H_bonds = (HB(temperature, n_1atm)/n_1atm)*zeroed_out_density.integrate() - H_bonds_grid.integrate(); //printf("Number of water molecules is %g\n", density.integrate()); printf("The bulk energy per cell should be %g\n", EperCell); printf("The bulk energy based on number should be %g\n", EperNumber*density.integrate()); printf("The bulk entropy is %g/N\n", SperNumber); Functional otherS = EntropySaftFluid2(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); printf("The bulk entropy (haskell) = %g/N\n", otherS(temperature, n_1atm)/n_1atm); //printf("My entropy is %g when I would expect %g\n", entropy, entropy - SperNumber*density.integrate()); double hentropy = otherS.integral(temperature, density); otherS.print_summary(" ", hentropy, "total entropy"); printf("My haskell entropy is %g, when I would expect = %g, difference is %g\n", hentropy, otherS(temperature, n_1atm)*density.integrate()/n_1atm, hentropy - otherS(temperature, n_1atm)*density.integrate()/n_1atm); FILE *o = fopen(datname, "w"); fprintf(o, "%g\t%.15g\t%.15g\t%.15g\n", temperature/kB, energy - EperNumber*density.integrate(), temperature*(entropy - SperNumber*density.integrate()), temperature*(hentropy - otherS(temperature, n_1atm)*density.integrate()/n_1atm)); fclose(o); char *plotname = (char *)malloc(1024); sprintf(plotname, "papers/water-saft/figs/hughes-lj-%s-%gK.dat", argv[1], temperature/kB); //plot_grids_y_direction(plotname, density, X_values); plot_grids_y_direction(plotname, density, gradient); free(plotname); double peak = peak_memory()/1024.0/1024; printf("Peak memory use is %g M\n", peak); double oldN = density.integrate(); density = n_1atm*VectorXd::Ones(gd.NxNyNz);; double hentropyb = otherS.integral(temperature, density); printf("bulklike thingy has %g molecules\n", density.integrate()); otherS.print_summary(" ", hentropyb, "bulk-like entropy"); printf("entropy difference is %g\n", hentropy - hentropyb*oldN/density.integrate()); clock_t end_time = clock(); double seconds = (end_time - start_time)/double(CLOCKS_PER_SEC); double hours = seconds/60/60; printf("Entire calculation took %.0f hours %.0f minutes\n", hours, 60*(hours-floor(hours))); }
int main(int argc, char *argv[]) { clock_t start_time = clock(); if (argc > 1) { if (sscanf(argv[1], "%lg", &diameter) != 1) { printf("Got bad argument: %s\n", argv[1]); return 1; } diameter *= nm; using_default_diameter = false; } printf("Diameter is %g bohr = %g nm\n", diameter, diameter/nm); const double padding = 1*nm; xmax = ymax = zmax = diameter + 2*padding; char *datname = (char *)malloc(1024); sprintf(datname, "papers/hughes-saft/figs/sphere-%04.2fnm-energy.dat", diameter/nm); 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 n_1atm = pressure_to_density(f, hughes_water_prop.kT, atmospheric_pressure, 0.001, 0.01); double mu_satp = find_chemical_potential(f, hughes_water_prop.kT, n_1atm); 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, mu_satp)); Functional S = OfEffectivePotential(EntropySaftFluid2(new_water_prop.lengthscale, new_water_prop.epsilonAB, new_water_prop.kappaAB, new_water_prop.epsilon_dispersion, new_water_prop.lambda_dispersion, new_water_prop.length_scaling)); const double EperVolume = f(hughes_water_prop.kT, -hughes_water_prop.kT*log(n_1atm)); const double EperNumber = EperVolume/n_1atm; const double SperNumber = S(hughes_water_prop.kT, -hughes_water_prop.kT*log(n_1atm))/n_1atm; const double EperCell = EperVolume*(zmax*ymax*xmax - (M_PI/6)*diameter*diameter*diameter); //for (diameter=0*nm; diameter<3.0*nm; diameter+= .1*nm) { Lattice lat(Cartesian(xmax,0,0), Cartesian(0,ymax,0), Cartesian(0,0,zmax)); GridDescription gd(lat, 0.2); Grid potential(gd); Grid constraint(gd); constraint.Set(notinwall); 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, mu_satp)); f = constrain(constraint, f); //constraint.epsNativeSlice("papers/hughes-saft/figs/sphere-constraint.eps", // Cartesian(0,ymax,0), Cartesian(0,0,zmax), // Cartesian(0,ymax/2,zmax/2)); //printf("Constraint has become a graph!\n"); potential = hughes_water_prop.liquid_density*constraint + 100*hughes_water_prop.vapor_density*VectorXd::Ones(gd.NxNyNz); //potential = hughes_water_prop.liquid_density*VectorXd::Ones(gd.NxNyNz); potential = -hughes_water_prop.kT*potential.cwise().log(); double energy; { const double surface_tension = 5e-5; // crude guess from memory... const double surfprecision = 1e-4*M_PI*diameter*diameter*surface_tension; // four digits precision const double bulkprecision = 1e-12*fabs(EperCell); // but there's a limit on our precision for small spheres const double precision = bulkprecision + surfprecision; Minimizer min = Precision(precision, PreconditionedConjugateGradient(f, gd, hughes_water_prop.kT, &potential, QuadraticLineMinimizer)); printf("\nDiameter of sphere = %g bohr (%g nm)\n", diameter, diameter/nm); const int numiters = 200; for (int i=0;i<numiters && min.improve_energy(true);i++) { //fflush(stdout); //Grid density(gd, EffectivePotentialToDensity()(hughes_water_prop.kT, gd, potential)); //density.epsNativeSlice("papers/hughes-saft/figs/sphere.eps", // Cartesian(0,ymax,0), Cartesian(0,0,zmax), // Cartesian(0,ymax/2,zmax/2)); //sleep(3); double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); } double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); energy = min.energy(); printf("Total energy is %.15g\n", energy); // Here we free the minimizer with its associated data structures. } { double peak = peak_memory()/1024.0/1024; double current = current_memory()/1024.0/1024; printf("Peak memory use is %g M (current is %g M)\n", peak, current); } double entropy = S.integral(hughes_water_prop.kT, potential); Grid density(gd, EffectivePotentialToDensity()(hughes_water_prop.kT, gd, potential)); printf("Number of water molecules is %g\n", density.integrate()); printf("The bulk energy per cell should be %g\n", EperCell); printf("The bulk energy based on number should be %g\n", EperNumber*density.integrate()); printf("The bulk entropy is %g/N\n", SperNumber); Functional otherS = EntropySaftFluid2(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); printf("The bulk entropy (haskell) = %g/N\n", otherS(hughes_water_prop.kT, n_1atm)/n_1atm); //printf("My entropy is %g when I would expect %g\n", entropy, entropy - SperNumber*density.integrate()); double hentropy = otherS.integral(hughes_water_prop.kT, density); otherS.print_summary(" ", hentropy, "total entropy"); printf("My haskell entropy is %g, when I would expect = %g, difference is %g\n", hentropy, otherS(hughes_water_prop.kT, n_1atm)*density.integrate()/n_1atm, hentropy - otherS(hughes_water_prop.kT, n_1atm)*density.integrate()/n_1atm); FILE *o = fopen(datname, "w"); //fprintf(o, "%g\t%.15g\n", diameter/nm, energy - EperCell); fprintf(o, "%g\t%.15g\t%.15g\t%.15g\t%.15g\n", diameter/nm, energy - EperNumber*density.integrate(), energy - EperCell, hughes_water_prop.kT*(entropy - SperNumber*density.integrate()), hughes_water_prop.kT*(hentropy - otherS(hughes_water_prop.kT, n_1atm)*density.integrate()/n_1atm)); fclose(o); char *plotname = (char *)malloc(1024); sprintf(plotname, "papers/hughes-saft/figs/sphere-%04.2f.dat", diameter/nm); plot_grids_y_direction(plotname, density); free(plotname); //density.epsNativeSlice("papers/hughes-saft/figs/sphere.eps", // Cartesian(0,ymax,0), Cartesian(0,0,zmax), // Cartesian(0,ymax/2,zmax/2)); double peak = peak_memory()/1024.0/1024; printf("Peak memory use is %g M\n", peak); double oldN = density.integrate(); density = n_1atm*VectorXd::Ones(gd.NxNyNz);; double hentropyb = otherS.integral(hughes_water_prop.kT, density); printf("bulklike thingy has %g molecules\n", density.integrate()); otherS.print_summary(" ", hentropyb, "bulk-like entropy"); printf("entropy difference is %g\n", hentropy - hentropyb*oldN/density.integrate()); // } clock_t end_time = clock(); double seconds = (end_time - start_time)/double(CLOCKS_PER_SEC); double hours = seconds/60/60; printf("Entire calculation took %.0f hours %.0f minutes\n", hours, 60*(hours-floor(hours))); }
int main(int, char **argv) { { // Here I set this test to continue running on its current cpu. // This is a slightly hokey trick to try to avoid any timings // variation due to NUMA and the process bouncing from one CPU to // another. Ideally we'd figure out a better way to decide on // which CPU to use for real jobs. cpu_set_t cpus; CPU_ZERO(&cpus); CPU_SET(sched_getcpu(), &cpus); int err = sched_setaffinity(0, sizeof(cpu_set_t), &cpus); if (err != 0) { printf("Error from sched_setaffinity: %d\n", err); } } // Let's figure out which machine we're running on (since we only // want to test CPU time if we have timings for this particular // machine). gethostname(hn, 80); const double kT = hughes_water_prop.kT; // room temperature in Hartree const double eta_one = 3.0/(4*M_PI*R*R*R); const double nliquid = 0.324*eta_one; Functional n = EffectivePotentialToDensity(); const double mu = find_chemical_potential(HardSpheres(R)(n) + IdealGasOfVeff(), kT, nliquid); // Here we set up the lattice. const double rmax = rcav*2; Lattice lat(Cartesian(0,rmax,rmax), Cartesian(rmax,0,rmax), Cartesian(rmax,rmax,0)); //Lattice lat(Cartesian(1.4*rmax,0,0), Cartesian(0,1.4*rmax,0), Cartesian(0,0,1.4*rmax)); GridDescription gd(lat, 0.2); last_time = get_time(); Grid external_potential(gd); // Do some pointless stuff so we can get some sort of gauge as to // how fast this CPU is, for comparison with other tests. for (int i=0; i<10; i++) { // Do this more times, to get a more consistent result... external_potential = external_potential.Ones(gd.NxNyNz); external_potential = external_potential.cwise().exp(); external_potential = 13*external_potential + 3*external_potential.cwise().square(); external_potential.fft(); // compute and toss the fft... } // And now let's set the external_potential up as we'd like it. external_potential.Set(incavity); external_potential *= 1e9; check_peak("Setting", "external potential", NULL, 7, 8); Grid constraint(gd); constraint.Set(notincavity); //Functional f1 = f0 + ExternalPotential(external_potential); Functional ff = constrain(constraint, IdealGasOfVeff() + (HardSpheres(R) + ChemicalPotential(mu))(n)); Grid potential(gd, external_potential + 0.005*VectorXd::Ones(gd.NxNyNz)); double eps = hughes_water_prop.epsilonAB; double kappa = hughes_water_prop.kappaAB; ff = OfEffectivePotential(SaftFluid2(R, eps, kappa, hughes_water_prop.epsilon_dispersion, hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling, mu)); check_a_functional("SaftFluid2", ff, potential); //ff = OfEffectivePotential(SaftFluid(R, eps, kappa, hughes_water_prop.epsilon_dispersion, // hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling, mu)); //check_a_functional("SaftFluid", ff, potential); //ff = Association2(R, eps, kappa, hughes_water_prop.epsilon_dispersion, // hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling); //check_a_functional("Association2", ff, potential); //ff = Association(R, eps, kappa, hughes_water_prop.epsilon_dispersion, // hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling); //check_a_functional("Association", ff, potential); //ff = Dispersion2(R, hughes_water_prop.epsilon_dispersion, // hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling); //check_a_functional("Dispersion2", ff, potential); //ff = Dispersion(R, hughes_water_prop.epsilon_dispersion, // hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling); //check_a_functional("Dispersion", ff, potential); ff = constrain(constraint, (HardSpheresWBnotensor(R) + ChemicalPotential(mu))(n) + IdealGasOfVeff()); check_a_functional("HardSpheresWBnotensor", ff, potential); //ff = constrain(constraint, (HardSpheresNoTensor(R) + ChemicalPotential(mu))(n) + IdealGasOfVeff()); //check_a_functional("HardSphereNoTensor", ff, potential); ff = constrain(constraint, (HardSpheresNoTensor2(R) + ChemicalPotential(mu))(n) + IdealGasOfVeff()); check_a_functional("HardSpheresNoTensor2", ff, potential); if (numoops == 0) { printf("\n%s has no oopses!\n", argv[0]); } else { printf("\n%s sort of fails %d tests!\n", argv[0], numoops); } if (retval == 0) { printf("\n%s passes!\n", argv[0]); } else { printf("\n%s fails %d tests!\n", argv[0], retval); return retval; } }