def run(neighbor_facilitator=None): global containers, lstats, p lj_method = "dm" if neighbor_facilitator is None else "nl" # LJ method used either distance matrix or neighbor list info_for_naming = params_tostring(p) header = "Starting at {t}".format(t=time_now()) print header print "-" * len(header) print "running with", info_for_naming # Get the initial problem container and meta init_container, p.y_funnel_bottom, p.anchor_ixs = problems.hourglass(**p.__dict__) p.num_grains = init_container.num_particles - len(p.anchor_ixs) # Boundary so particles keep recirculating # Need to have enough x space that grains and anchors don't init on top of each other posns = init_container.positions xl, yb = np.min(posns, axis=0) # left, bottom xr, yt = np.max(posns, axis=0) # right, top xlim, ylim = [(xl - p.diam, xr + p.diam), (yb - 2 * p.diam, yt + p.diam)] if p.use_bounds: init_container.bounds = [xlim, ylim] forces = [ problems.GravityForce(g=p.gravity_magnitude), problems.LJRepulsiveAndDampingForce(cutoff_dist=p.diam, viscous_damping_magnitude=p.viscous_damping_magnitude), problems.FakeStatsForce(), ] w = distance(*xlim) h = distance(*ylim) a_ratio = w / h # figsize must be integers or animation will error saving to file! fh = int(figheight) figsize = (int(a_ratio * fh) + 1, fh) containers = [init_container] integrator = VerletIntegrator() integrator.sim_wide_params = p integrator.forces = forces run_func = RunFunc(p) graphical.animate_with_live_integration( containers, integrator, dt, xlim, ylim, figsize, particle_radius, frame_show_modulus, num_frames_to_bootstrap, info_for_naming, save_animation, show_animation, run_func, anim_save_kwargs=anim_save_kwargs, sim_wide_params=p, ) stats = problems.SimStats(info_for_naming, containers, p) lstats.append(stats) if p.dump_data: stats.write_csvs(p.data_dump_modulus) stats.write_plots(p.data_dump_modulus, show=False) # graphical.plot_sand(stats.times, stats.???, gravity_magnitude=stats.gravity_magnitude, info_for_naming=info_for_naming, show=False) print "all params:", p