// Copyright (c) 2021, SBEL GPU Development Team // Copyright (c) 2021, University of Wisconsin - Madison // // SPDX-License-Identifier: BSD-3-Clause #include #include #include #include #include #include #include #include using namespace deme; using namespace std::filesystem; int main() { DEMSolver DEMSim; DEMSim.SetVerbosity(INFO); DEMSim.SetOutputFormat(OUTPUT_FORMAT::CSV); DEMSim.SetOutputContent(OUTPUT_CONTENT::ABSV); DEMSim.SetMeshOutputFormat(MESH_FORMAT::VTK); DEMSim.EnsureKernelErrMsgLineNum(); // E, nu, CoR, mu, Crr... auto mat_type_ball = DEMSim.LoadMaterial({{"E", 1e10}, {"nu", 0.3}, {"CoR", 0.3}, {"mu", 0.3}, {"Crr", 0.01}}); auto mat_type_terrain = DEMSim.LoadMaterial({{"E", 5e9}, {"nu", 0.3}, {"CoR", 0.2}, {"mu", 0.3}, {"Crr", 0.01}}); float step_size = 2e-6; double world_size = 0.5; DEMSim.InstructBoxDomainDimension(world_size, world_size, world_size); DEMSim.InstructBoxDomainBoundingBC("top_open", mat_type_terrain); DEMSim.SetCoordSysOrigin("center"); auto projectile = DEMSim.AddWavefrontMeshObject("./screw.obj", mat_type_ball); std::cout << "Total num of triangles: " << projectile->GetNumTriangles() << std::endl; projectile->SetInitPos(make_float3(-world_size/3, -world_size/2, world_size/2 )); float ball_mass = 2.6e3 * 4.0 / 3.0 * 3.1416; projectile->SetMass(ball_mass); projectile->SetMOI(make_float3(ball_mass * 2.0 / 5.0, ball_mass * 2.0 / 5.0, ball_mass * 2.0 / 5.0)); projectile->SetFamily(1); // Track the projectile auto proj_tracker = DEMSim.Track(projectile); ////////////////////////////////////////////////////////////////////////////////////// //Particles: float terrain_rad = 0.01; auto template_terrain = DEMSim.LoadSphereType(terrain_rad * terrain_rad * terrain_rad * 2.6e3 * 4.0 / 3.0 * 3.14, terrain_rad, mat_type_terrain); std::cout << "template_terrain loaded: " << std::endl; float sample_halfheight = world_size / 8.0; float3 sample_center = make_float3(world_size / 2.0, world_size / 2.0, sample_halfheight + 0.05); float sample_halfwidth = world_size / 2.0 * 0.95; float spacing = 2.02*terrain_rad; PDSampler sampler(spacing); // Sample and add particles auto particles_xyz = sampler.SampleBox(sample_center, make_float3(sample_halfwidth, sample_halfwidth, sample_halfheight)); std::cout << "particles sampled " << std::endl; auto particles = DEMSim.AddClumps(template_terrain, particles_xyz); std::cout << "terrain loaded: " << std::endl; // Create a inspector to find out stuff auto max_z_finder = DEMSim.CreateInspector("clump_max_z"); auto min_z_finder = DEMSim.CreateInspector("clump_min_z"); float max_z; float min_z; DEMSim.SetInitTimeStep(step_size); DEMSim.SetGravitationalAcceleration(make_float3(0, 0, -9.81)); // If you want to use a large UpdateFreq then you have to expand spheres to ensure safety DEMSim.SetCDUpdateFreq(20); // DEMSim.SetExpandFactor(1e-3); DEMSim.SetMaxVelocity(15.); DEMSim.SetExpandSafetyMultiplier(1.1); DEMSim.SetInitBinSize(2 * terrain_rad); DEMSim.Initialize(); path out_dir = current_path(); out_dir += "/DemoOutput_ScrewDrop"; create_directory(out_dir); float sim_end = 0.40; unsigned int fps = 20; float frame_time = 1.0 / fps; std::cout << "Output at " << fps << " FPS" << std::endl; unsigned int currframe = 0; for (float t = 0; t < sim_end; t += frame_time) { std::cout << "Frame: " << currframe << std::endl; char filename[200], meshfilename[200], cnt_filename[200]; sprintf(filename, "%s/DEMdemo_output_%04d.csv", out_dir.c_str(), currframe); sprintf(meshfilename, "%s/DEMdemo_mesh_%04d.vtk", out_dir.c_str(), currframe); // sprintf(cnt_filename, "%s/Contact_pairs_%04d.csv", out_dir.c_str(), currframe); DEMSim.WriteSphereFile(std::string(filename)); DEMSim.WriteMeshFile(std::string(meshfilename)); // DEMSim.WriteContactFile(std::string(cnt_filename)); currframe++; DEMSim.DoDynamicsThenSync(frame_time); DEMSim.ShowThreadCollaborationStats(); } std::cout << "DEMdemo_BallDrop exiting..." << std::endl; return 0; }