def main_loop(): global energies, plt1_x_data, plt1_y_data, plt2_x_data, plt2_y_data, old_pressure integrate.integrate(int_steps) mayavi.update() # make sure the parameters are valid # not sure if this is necessary after using limit_range if controls.volume == 0: controls.volume = controls.min_vol if controls.number_of_particles == 0: controls.number_of_particles = 1 if controls.pressure == 0: controls.pressure = controls.min_press pressure = analyze.pressure(system) # update the parameters set in the GUI system.thermostat.set_langevin(kT=controls.temperature, gamma=1.0) if controls.ensemble == 'NPT': # reset Vkappa when target pressure has changed if old_pressure != controls.pressure: analyze.Vkappa(system, 'reset') old_pressure = controls.pressure newVkappa = analyze.Vkappa(system, 'read')['Vk1'] newVkappa = newVkappa if newVkappa > 0. else 4.0/(NPTGamma0*NPTGamma0*NPTInitPistonMass) pistonMass = limit_range(4.0/(NPTGamma0*NPTGamma0*newVkappa), NPTMinPistonMass, NPTMaxPistonMass) integrate.set_integrator_isotropic_npt(controls.pressure, pistonMass, cubic_box=True) controls.volume = system.box_l[0]**3. else: integrate.set_integrator_nvt() controls.pressure = pressure['total'] new_box = numpy.ones(3) * controls.volume**(1./3.) if numpy.any(numpy.array(system.box_l) != new_box): for i in range(system.n_part): system.part[i].pos *= new_box / system.box_l[0] system.box_l = new_box new_part = controls.number_of_particles if new_part > system.n_part: for i in range(system.n_part, new_part): system.part.add(id=i, pos=numpy.random.random(3) * system.box_l) elif new_part < system.n_part: for i in range(new_part, system.n_part): system.part[i].delete() # There should be no gaps in particle numbers assert system.n_part == system.max_part + 1 plt1_x_data = plot1.get_xdata() plt1_y_data = plot1.get_ydata() plt2_x_data = plot2.get_xdata() plt2_y_data = plot2.get_ydata() plt1_x_data = numpy.append(plt1_x_data[-plot_max_data_len+1:], system.time) if show_real_system_temperature: plt1_y_data = numpy.append(plt1_y_data[-plot_max_data_len+1:], 2./(3. * system.n_part)*analyze.energy(system)["ideal"]) else: plt1_y_data = numpy.append(plt1_y_data[-plot_max_data_len+1:], system.temperature) plt2_x_data = numpy.append(plt2_x_data[-plot_max_data_len+1:], system.time) plt2_y_data = numpy.append(plt2_y_data[-plot_max_data_len+1:], pressure['total'])
# # # Increase LJ cap # lj_cap = lj_cap + 10 # system.non_bonded_inter.set_force_cap(lj_cap) # mayavi.update() ############################################################# # Integration # ############################################################# # remove force capping #lj_cap = 0 # system.non_bonded_inter.set_force_cap(lj_cap) # get initial observables pressure = analyze.pressure(system) temperature = system.temperature # TODO: this is some terrible polynomial fit, replace it with a better expression # equation of state pyplot.subplot(131) pyplot.semilogy() pyplot.title("Phase diagram") pyplot.xlabel("Temperature") pyplot.ylabel("Pressure") pyplot.xlim(0.5, 2.0) pyplot.ylim(5e-5, 2e1) xx = numpy.linspace(0.5, 0.7, 200) pyplot.plot(xx, -6.726 * xx**4 + 16.92 * xx**3 - 15.85 * xx**2 + 6.563 * xx - 1.015, 'k-') xx = numpy.linspace(0.7, 1.3, 600)