def load_mpm_state(solver: MPMSolver, save_dir: str): if not solver.use_g2p2g: raise NotImplementedError # load particle information state = np.load(save_dir) resume_frame = state['frame'] phase = state['input_grid'] num_particle = state['position'].shape[0] # assert(num_particle == ) print(f"we have {num_particle} particles !") solver.n_particles[None] = num_particle solver.input_grid = phase copyback_dynamic_nd(solver, state['position'], solver.x) copyback_dynamic_nd(solver, state['velocity'], solver.v) copyback_dynamic(solver, state['material'], solver.material) copyback_dynamic(solver, state['color'], solver.color) copyback_matrix(state['F'], solver.F, solver) if solver.support_plasticity: copyback_dynamic(solver, state['p_Jp'], solver.Jp) copyback_grid(state['grid_v_idx'], state['grid_v_val'], solver.grid_v[phase], solver) print(f'load {resume_frame}th frame from {save_dir}!') return resume_frame
def save_mpm_state(solver: MPMSolver, frame: int, save_dir: str): """ Save MPM middle state as a npz file :param solver: :param frame: :param save_dir: :return: """ if not solver.use_g2p2g: raise NotImplementedError particles = solver.particle_info() # particle information # other meta data phase = solver.input_grid # save grid_v count_activate(solver.grid_v[phase]) print(f"we have {count[None]} nodes activated") np_grid_idx = np.ndarray((count[None], solver.dim), dtype=np.float32) np_grid_val = np.ndarray((count[None], solver.dim), dtype=np.float32) copy_grid(np_grid_idx, np_grid_val, solver.grid_v[phase], solver) # save deformation gradient np_F = np.ndarray((solver.n_particles[None], solver.dim, solver.dim), dtype=np.float32) copy_matrix(np_F, solver.F, solver) particles['F'] = np_F if mpm.support_plasticity: np_j = np.ndarray((solver.n_particles[None], ), dtype=np.float32) solver.copy_dynamic(np_j, solver.Jp) particles['p_Jp'] = np_j np.savez(save_dir, frame=frame, input_grid=phase, grid_v_idx=np_grid_idx, grid_v_val=np_grid_val, **particles) print(f'save {frame}th frame to {save_dir}') return
for i, face in enumerate(elements['vertex_indices']): assert len(face) == 3 for d in range(3): triangles[i, d * 3 + 0] = x[face[d]] * scale + offset[0] triangles[i, d * 3 + 1] = y[face[d]] * scale + offset[1] triangles[i, d * 3 + 2] = z[face[d]] * scale + offset[2] print('loaded') return triangles # Use 512 for final simulation/render R = 256 mpm = MPMSolver(res=(R, R, R), size=1, unbounded=True, dt_scale=0.5, E_scale=8) mpm.add_surface_collider(point=(0, 0, 0), normal=(0, 1, 0), surface=mpm.surface_slip, friction=0.5) triangles = load_mesh('taichi.ply', scale=0.04, offset=(0.5, 0.5, 0.5)) triangles_small = load_mesh('taichi.ply', scale=0.0133, offset=(0.5, 0.5, 0.5)) mpm.set_gravity((0, -25, 0)) def visualize(particles): np_x = particles['position'] / 1.0
import numpy as np import os import utils from engine.mpm_solver import MPMSolver write_to_disk = False if write_to_disk: os.makedirs('outputs', exist_ok=True) # Try to run on GPU ti.init(arch=ti.cuda, device_memory_GB=4.0) gui = ti.GUI("Taichi Elements", res=512, background_color=0x112F41) mpm = MPMSolver(res=(64, 64, 64), size=1) mpm.set_gravity((0, -20, 0)) mpm.add_sphere_collider(center=(0.25, 0.5, 0.5), radius=0.1, surface=mpm.surface_slip) mpm.add_sphere_collider(center=(0.5, 0.5, 0.5), radius=0.1, surface=mpm.surface_sticky) mpm.add_sphere_collider(center=(0.75, 0.5, 0.5), radius=0.1, surface=mpm.surface_separate) for frame in range(1500): mpm.add_cube((0.2, 0.8, 0.45), (0.1, 0.03, 0.1),
import taichi as ti import numpy as np import utils from engine.mpm_solver import MPMSolver write_to_disk = False # Try to run on GPU ti.init(arch=ti.cuda, kernel_profiler=True) gui = ti.GUI("MPM Benchmark", res=256, background_color=0x112F41) mpm = MPMSolver(res=(256, 256, 256), size=1, unbounded=False) particles = np.fromfile('benchmark_particles.bin', dtype=np.float32) particles = particles.reshape(len(particles) // 3, 3) print(len(particles)) mpm.add_particles(particles=particles, material=MPMSolver.material_elastic, color=0xFFFF00) mpm.set_gravity((0, -20, 0)) for frame in range(1500): mpm.step(3e-3) particles = mpm.particle_info() np_x = particles['position'] / 1.0 # simple camera transform screen_x = ((np_x[:, 0] + np_x[:, 2]) / 2**0.5) - 0.2
import taichi as ti import numpy as np import utils from engine.mpm_solver import MPMSolver write_to_disk = False # Try to run on GPU ti.init(arch=ti.cuda, device_memory_GB=2.0, use_unified_memory=False) gui = ti.GUI("Taichi Elements", res=512, background_color=0x112F41) mpm = MPMSolver(res=(64, 64, 64), size=10) mpm.add_ellipsoid(center=[2, 4, 3], radius=1, material=MPMSolver.material_snow, velocity=[0, -10, 0]) mpm.add_cube(lower_corner=[2, 6, 3], cube_size=[1, 1, 3], material=MPMSolver.material_elastic) mpm.add_cube(lower_corner=[2, 8, 3], cube_size=[1, 1, 3], material=MPMSolver.material_sand) mpm.set_gravity((0, -50, 0)) for frame in range(1500): mpm.step(4e-3) colors = np.array([0x068587, 0xED553B, 0xEEEEF0, 0xFFFF00], dtype=np.uint32)
print(args) return args args = parse_args() write_to_disk = args.out_dir is not None if write_to_disk: os.mkdir(f'{args.out_dir}') ti.init(arch=ti.cuda) # Try to run on GPU n = 256 gui = ti.GUI("Taichi Elements", res=n, background_color=0x112F41) activate_vis = ti.Vector.field(3, dtype=ti.f32, shape=[n, n]) mpm = MPMSolver(res=(n, n)) for i in range(3): mpm.add_cube(lower_corner=[0.2 + i * 0.1, 0.3 + i * 0.1], cube_size=[0.1, 0.1], material=MPMSolver.material_elastic) @ti.kernel def block_active(vs_field: ti.template(), solver: ti.template()): for I in ti.grouped(vs_field): blk_I = I // solver.leaf_block_size - solver.block_offset if ti.is_active(solver.block, blk_I) and (I % solver.leaf_block_size).min() != 0: vs_field[I] = [0.11, 0.22, 0.25] else:
import taichi as ti import numpy as np import utils from engine.mpm_solver import MPMSolver write_to_disk = False ti.init(arch=ti.cuda) # Try to run on GPU gui = ti.GUI("Taichi MLS-MPM-99", res=512, background_color=0x112F41) mpm = MPMSolver(res=(256, 256)) mpm.set_gravity([0, 0]) mpm.add_ellipsoid(center=[0.25, 0.45], radius=0.07, velocity=[1, 0], color=0xAAAAFF, material=MPMSolver.material_snow) mpm.add_ellipsoid(center=[0.75, 0.52], radius=0.07, velocity=[-1, 0], color=0xFFAAAA, material=MPMSolver.material_snow) for frame in range(500): mpm.step(8e-3) particles = mpm.particle_info() gui.circles(particles['position'], radius=1.5, color=particles['color']) gui.show(f'{frame:06d}.png' if write_to_disk else None)
import numpy as np import os import time import utils from engine.mpm_solver import MPMSolver write_to_disk = True if write_to_disk: output_dir = "/home/blatny/repos/taichi_elements/demo/output/sim_1/" os.makedirs(os.path.dirname(output_dir), exist_ok=True) ti.init(arch=ti.cpu) gui = ti.GUI("Taichi Elements", res=512, background_color=0x112F41) mpm = MPMSolver(res=(32, 32, 32), size=10) mpm.add_ellipsoid(center=[2, 4, 3], radius=1, material=MPMSolver.material_snow, velocity=[0, -10, 0]) mpm.set_gravity((0, -50, 0)) start_t = time.time() for frame in range(3): print(f'frame: {frame}') t = time.time() mpm.step(4e-3) # colors = np.array([0x068587, 0xED553B, 0xEEEEF0, 0xFFFF00], dtype=np.uint32)
import taichi as ti import numpy as np import utils from engine.mpm_solver import MPMSolver write_to_disk = False ti.init(arch=ti.cuda) # Try to run on GPU gui = ti.GUI("Taichi MLS-MPM-99", res=512, background_color=0x112F41) mpm = MPMSolver(res=(128, 128)) mpm.add_ellipsoid(center=[0.4, 0.4], radius=[0.2, 0.2], material=MPMSolver.material_snow) for frame in range(500): mpm.step(8e-3) colors = np.array([0x068587, 0xED553B, 0xEEEEF0, 0xFFFF00], dtype=np.uint32) particles = mpm.particle_info() gui.circles(particles['position'], radius=1.5, color=colors[particles['material']]) gui.show(f'{frame:06d}.png' if write_to_disk else None)
def main(): parser = parse_mpm() args = parser.parse_args() simulation_trajectories = [] if args.material == 'water': material = MPMSolver.material_water elif args.material == 'elastic': material = MPMSolver.material_elastic elif args.material == 'snow': material = MPMSolver.material_snow elif args.material == 'sand': material = MPMSolver.material_sand for sim_i in range(args.num_sims): ti.init(arch=ti.cuda) # Try to run on GPU gui = ti.GUI("Taichi MLS-MPM-99", res=512, background_color=0x112F41) mpm = MPMSolver(res=(128, 128)) mpm.E = args.young # init condition n_samples = args.ncubes * 10 lower_corner_candidates = np.random.uniform(0.2, 0.8, size=(n_samples, 2)) cube_size_candidates = np.random.uniform(0.06, 0.15, size=(n_samples, 2)) lower_corners = [] cube_sizes = [] num_cubes = args.ncubes for s in range(1, n_samples): if not cube_overlap( lower_corner_candidates[:s], cube_size_candidates[:s], lower_corner_candidates[s], cube_size_candidates[s]): lower_corners.append(lower_corner_candidates[s]) cube_sizes.append(cube_size_candidates[s]) if len(lower_corners) == num_cubes: break for i in range(len(lower_corners)): mpm.add_cube(lower_corner=lower_corners[i], cube_size=cube_sizes[i], material=material) simulation_trajectories.append(simulate(mpm, gui, args)) #rollout(simulation_trajectories[0], gui, args.gui_particle_radius) #cluster_scene(simulation_trajectories[-1][0]) if (sim_i + 1) % 1 == 0: print('Simulated {} trajectories.'.format(sim_i + 1)) data_path = os.path.join('../data/', args.dataset_name) if not os.path.exists(data_path): os.makedirs(data_path) if (sim_i + 1) % 100 == 0 or sim_i + 1 == args.num_sims: print(len(simulation_trajectories)) with open( '../data/{}/{}_{}.pkl'.format(args.dataset_name, args.material, sim_i // 100), 'wb') as f: pkl.dump(simulation_trajectories, f) simulation_trajectories = []
triangles[i, d * 3 + 1] = y[face[d]] * scale[1] + offset[1] triangles[i, d * 3 + 2] = z[face[d]] * scale[2] + offset[2] print('loaded') return triangles # Use 512 for final simulation/render # R = 256 R = 128 count = ti.field(ti.i32, shape=()) mpm = MPMSolver(res=(R, R, R), size=1, unbounded=True, dt_scale=1, quant=True, use_g2p2g=True, support_plasticity=False) mpm.add_surface_collider(point=(0, 0, 0), normal=(0, 1, 0), surface=mpm.surface_slip, friction=0.5) mpm.add_surface_collider(point=(0, 1.9, 0), normal=(0, -1, 0), surface=mpm.surface_slip, friction=0.5) for d in [0, 2]:
for i, face in enumerate(elements['vertex_indices']): assert len(face) == 3 for d in range(3): triangles[i, d * 3 + 0] = x[face[d]] * scale + offset[0] triangles[i, d * 3 + 1] = y[face[d]] * scale + offset[1] triangles[i, d * 3 + 2] = z[face[d]] * scale + offset[2] print('loaded') return triangles # Use 512 for final simulation/render R = 256 mpm = MPMSolver(res=(R, R, R), size=1, unbounded=True, dt_scale=1) mpm.add_surface_collider(point=(0, 0, 0), normal=(0, 1, 0), surface=mpm.surface_slip, friction=0.5) triangles = load_mesh('taichi.ply', scale=0.02, offset=(0.5, 0.6, 0.5)) mpm.set_gravity((0, -25, 0)) def visualize(particles): np_x = particles['position'] / 1.0 # simple camera transform
if write_to_disk: # output_dir = create_output_folder(args.out_dir) output_dir = args.out_dir os.makedirs(f'{output_dir}/particles') os.makedirs(f'{output_dir}/previews') print("Writing 2D vis and binary particle data to folder", output_dir) else: output_dir = None # Use 512 for final simulation/render R = args.res mpm = MPMSolver(res=(R, R, R), size=1, unbounded=True, dt_scale=1, quant=True, use_g2p2g=True, support_plasticity=False) mpm.add_surface_collider(point=(0, 0, 0), normal=(0, 1, 0), surface=mpm.surface_slip, friction=0.5) mpm.add_surface_collider(point=(0, 1.9, 0), normal=(0, -1, 0), surface=mpm.surface_slip, friction=0.5) bound = 1.9
os.makedirs(f'{output_dir}/particles') os.makedirs(f'{output_dir}/previews') print("Writing 2D vis and binary particle data to folder", output_dir) tee = Tee(fn=f'{output_dir}/log.txt', mode='w') print(args) else: output_dir = None # Use 512 for final simulation/render R = args.res thickness = 2 mpm = MPMSolver(res=(R, R, R), size=1, unbounded=True, dt_scale=1, quant=True, use_g2p2g=False, support_plasticity=True, water_density=1.5) mpm.add_surface_collider(point=(0, 0, 0), normal=(0, 1, 0), surface=mpm.surface_slip, friction=0.5) mpm.add_surface_collider(point=(0, 1.9, 0), normal=(0, -1, 0), surface=mpm.surface_slip, friction=0.5) bound = 1.9
import taichi as ti import numpy as np import utils import math from engine.mpm_solver import MPMSolver write_to_disk = False ti.init(arch=ti.cuda) # Try to run on GPU gui = ti.GUI("Taichi MLS-MPM-99", res=512, background_color=0x112F41) mpm = MPMSolver(res=(128, 128), unbounded=True) mpm.add_surface_collider(point=(0, 0), normal=(0.3, 1), surface=mpm.surface_slip) for i in range(3): mpm.add_cube(lower_corner=[0.2 + i * 0.1, 0.3 + i * 0.1], cube_size=[0.1, 0.1], material=MPMSolver.material_elastic) for frame in range(500): mpm.step(8e-3) if frame < 100: mpm.add_cube(lower_corner=[0.1, 0.4], cube_size=[0.01, 0.05], velocity=[1, 0], material=MPMSolver.material_sand) if 10 < frame < 100: mpm.add_cube(lower_corner=[0.3, 0.7],
import taichi as ti import numpy as np import utils from engine.mpm_solver import MPMSolver write_to_disk = False # Try to run on GPU ti.init(arch=ti.cuda, device_memory_GB=3.0) gui = ti.GUI("Taichi Elements", res=512, background_color=0x112F41) mpm = MPMSolver(res=(64, 64, 64), size=1) triangles = np.fromfile('suzanne.npy', dtype=np.float32) triangles = np.reshape(triangles, (len(triangles) // 9, 9)) * 0.306 + 0.501 mpm.add_mesh(triangles=triangles, material=MPMSolver.material_elastic, color=0xFFFF00) mpm.set_gravity((0, -20, 0)) for frame in range(1500): mpm.step(4e-3) particles = mpm.particle_info() np_x = particles['position'] / 1.0 # simple camera transform screen_x = ((np_x[:, 0] + np_x[:, 2]) / 2**0.5) - 0.2 screen_y = (np_x[:, 1])
np_x = particles['position'] / 1.0 # simple camera transform screen_x = np_x[:, 0] screen_y = np_x[:, 1] screen_pos = np.stack([screen_x, screen_y], axis=-1) gui.circles(screen_pos, radius=0.8, color=particles['color']) gui.show() # Use 512 for final simulation/render R = 64 mpm = MPMSolver(res=(R, R, R), size=1, unbounded=True, dt_scale=0.5, E_scale=8, max_num_particles=max_num_particles) mpm.add_surface_collider(point=(0, 0, 0), normal=(0, 1, 0), surface=mpm.surface_slip, friction=3.5) mpm.set_gravity((0, -25, 0)) counter = 0 start_t = time.time() addParticlesCount = 2000 for frame in range(15000): print(f'frame {frame}')