#include <core/ApiVersion.h>
#include <core/utils/ThreadManager.h>
#include <DEM/API.h>
#include <DEM/HostSideHelpers.hpp>
#include <DEM/utils/Samplers.hpp>
#include <cstdio>
#include <chrono>
#include <filesystem>
using namespace deme;
using namespace std::filesystem;
int main()
{
DEMSolver DEMSim;
DEMSim.SetVerbosity(STEP_METRIC);
// For general use cases, you want to set the verbosity to INFO: It's also a bit faster than STEP_METRIC.
// DEMSim.SetVerbosity(INFO);
DEMSim.SetOutputFormat(OUTPUT_FORMAT::CSV);
DEMSim.SetOutputContent(OUTPUT_CONTENT::ABSV);
DEMSim.SetMeshOutputFormat(MESH_FORMAT::VTK);
// If you don't need individual force information, then this option makes the solver run a bit faster.
DEMSim.SetNoForceRecord();
// E, nu, CoR, mu, Crr...
auto mat_type_mixer = DEMSim.LoadMaterial({{"E", 1e8}, {"nu", 0.3}, {"CoR", 0.6}, {"mu", 0.5}, {"Crr", 0.0}});
auto mat_type_granular = DEMSim.LoadMaterial({{"E", 1e8}, {"nu", 0.3}, {"CoR", 0.6}, {"mu", 0.2}, {"Crr", 0.0}});
// If you don't have this line, then mu between mixer material and granular material will be 0.35 (average of the
// two).
DEMSim.SetMaterialPropertyPair("mu", mat_type_mixer, mat_type_granular, 0.5);
float step_size = 5e-5;
const double world_size = 10;
const float chamber_height = world_size / 3.;
const float fill_height = chamber_height;
const float chamber_bottom = -world_size / 2.;
const float fill_bottom = chamber_bottom + chamber_height;
DEMSim.InstructBoxDomainDimension(world_size, world_size, world_size);
DEMSim.InstructBoxDomainBoundingBC("all", mat_type_granular);
auto mixer = DEMSim.AddWavefrontMeshObject((GET_DATA_PATH() / "mesh/Chute_Rotating.obj").string(), mat_type_mixer);
std::cout << "Total num of triangles: " << mixer->GetNumTriangles() << std::endl;
mixer->SetFamily(10);
mixer->InformCentroidPrincipal(make_float3(0, 0, 6.793), make_float4(0, 0, 0, 1));
double w1 = 3.14159;
double w2 = 1.0;
std::string angVel_x = "fabs(1.0 * cos(deme::PI * t))";
std::string angVel_y = "fabs(1.0 * sin(deme::PI * t))";
std::string angVel_z = "deme::PI";
std::string vel_x = "(1.0 * cos(1.0 * t) * sin(deme::PI * t) + sin(1.0 * t) * deme::PI * cos(deme::PI * t))";
std::string vel_y = "(-1.0 * cos(1.0 * t) * cos(deme::PI * t) + sin(1.0 * t) * deme::PI * sin(deme::PI * t))";
std::string vel_z = "0";
DEMSim.SetFamilyPrescribedAngVel(10, angVel_x, angVel_y, angVel_z);
DEMSim.SetFamilyPrescribedLinVel(10, vel_x, vel_y, vel_z);
float granular_rad = 0.005;
// Calculate its mass and MOI
float mass = 2.6e3 * 5.5886717; // in kg or g
float3 MOI = make_float3(2.928, 2.6029, 3.9908) * 2.6e3;
std::shared_ptr<DEMClumpTemplate> template_granular = DEMSim.LoadClumpType(mass, MOI, GetDEMEDataFile("clumps/3_clump.csv"), mat_type_granular);
template_granular->Scale(granular_rad);
// Track the mixer
auto mixer_tracker = DEMSim.Track(mixer);
DEMSim.SetInitTimeStep(step_size);
DEMSim.SetGravitationalAcceleration(make_float3(0, 0, -9.81));
// Initialize the simulation system
DEMSim.Initialize();
path out_dir = current_path();
out_dir += "/DEMdemo_RotatingChute";
create_directory(out_dir);
float sim_end = 2.0;
unsigned int fps = 20;
float frame_time = 1.0 / fps;
std::cout << "Output at " << fps << " FPS" << std::endl;
unsigned int currframe = 0;
// mixer_tracker->SetOriQ(make_float4(0, 0, 0, 1));
for (float t = 0; t < sim_end; t += frame_time) // 0.05迭代一次
{
std::cout << "Position: " << mixer_tracker->GetPos()[0] << " " << mixer_tracker->GetPos()[1] << " " << mixer_tracker->GetPos()[2] << std::endl;
std::vector<float> Qua = mixer_tracker->GetOriQ(); // x, y, z, w
// std::cout << Qua[0] << " " << Qua[1] << " " << Qua[2] << " " << Qua[3] << std::endl;
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.WriteMeshFile(std::string(meshfilename));
DEMSim.DoDynamics(frame_time);
}
std::cout << "DEMdemo_RotatingChute simulating complete!" << std::endl;
return 0;
}