static void took(const char *name) { static clock_t last_time = clock(); clock_t t = clock(); assert(name); // so it'll count as being used... double peak = peak_memory()/1024.0/1024; printf("\t\t%s took %g seconds (peak memory: %g M)\n", name, (t-last_time)/double(CLOCKS_PER_SEC), peak); last_time = t; }
double check_peak(const char *name, const char *name2, FILE *out, double peakmin, double peakmax, double cpu = 0, double cpurat = 1.6) { printf("===> Testing %s of %s <===\n", name, name2); double cputime = get_time() - last_time; double peak = peak_memory()/1024.0/1024; if (cpu) printf("CPU time is %g s (%.0f%%, with memory use %.0f M)\n", cputime, (cputime - cpu)/cpu*100, peak); else printf("CPU time is %g s (with memory use %.0f M)\n", cputime, peak); if (peak < peakmin) { printf("FAIL: Peak memory use of %s %s should be at least %g (but it's %g)!\n", name, name2, peakmin, peak); retval++; } if (peak > peakmax) { printf("FAIL: Peak memory use of %s %s should be under %g (but it's %g)!\n", name, name2, peakmax, peak); retval++; } if (cpu) { if (cputime < cpu/cpurat) { printf("OOPS: CPU time of %s %s should be at least %g!\n", name, name2, cpu/cpurat); //retval++; numoops++; } if (cputime > cpu*cpurat) { printf("OOPS: CPU time of %s %s should be under %g!\n", name, name2, cpu*cpurat); //retval++; numoops++; } } if (out) { fprintf(out, "%g\t%g\n", peak, cputime); fflush(out); } reset_peak_memory(); last_time = get_time(); return cputime; }
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; }
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 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 **) { 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))); }