76 double mesh_size,
double R,
int N_target,
77 double padding, std::mt19937 &gen) {
78 std::vector<PackedParticle> particles;
79 std::uniform_real_distribution<double> u_r(-0.1 * R, 0.1 * R);
83 const double check_r = R;
84 const int rows =
static_cast<int>((max_y - in_rect[1]) / (2.0 * check_r));
85 const double rect_L = in_rect[3] - in_rect[0];
86 const int cols =
static_cast<int>(rect_L / (2.0 * check_r));
89 double x_old = in_rect[0];
90 double x_old_right = in_rect[3];
91 double y_old = in_rect[1];
92 const double cz = 0.0;
94 std::vector<double> cy_accptd;
95 cy_accptd.push_back(y_old);
97 std::vector<double> row_rads_prev{R, R};
98 for (
int i = 0; i < rows; ++i) {
102 std::vector<double> row_rads{R};
104 if (y_old + padding +
maxElem(row_rads) >= max_y)
110 if (num_p_cols > cols - 1 || j > 100 * N_target)
112 if (counter >= N_target)
117 x_old_right = in_rect[3];
120 const int p_zone =
static_cast<int>(gen() % 8);
122 double r = r0 + u_r(gen);
124 double cx = 0., cy = 0.;
126 std::uniform_real_distribution<double> rph(-0.1 * r0, 0.05 * r0);
127 std::uniform_real_distribution<double> rpv(-0.05 * r0, 0.05 * r0);
128 const double cx0 = x_old_right - padding - r;
130 cy = y_old + padding + r + rpv(gen);
132 std::uniform_real_distribution<double> rph(-0.05 * r0, 0.1 * r0);
133 std::uniform_real_distribution<double> rpv(-0.05 * r0, 0.05 * r0);
134 const double cx0 = x_old + padding + r;
136 cy = y_old + padding + r + rpv(gen);
141 std::uniform_real_distribution<double> orient(0.0, 2.0 * M_PI);
142 trial.theta = orient(gen);
143 particles.push_back(trial);
144 row_rads.push_back(trial.r);
145 cy_accptd.push_back(cy);
147 x_old_right = cx - trial.r;
149 x_old = cx + trial.r;
156 row_rads_prev = std::move(row_rads);
204 int argc,
char *argv[]) {
208 const std::vector<double> center = {0.0, 0.0, 0.0};
209 const double R = 0.001;
210 const double mesh_size = R / 5.0;
211 const double horizon = 2.0 * mesh_size;
213 const double Lin = 0.05;
214 const double Win = 0.04;
216 constexpr double wall_top_inset = 1e-7;
217 constexpr double annulus_inset = 1e-7;
219 constexpr double clearance_mesh = 1.5;
221 const double geom_pad = 0.25 * mesh_size;
222 const double plate_thickness = std::max(3.0 * mesh_size, 2.0 * mesh_size);
224 const double w_drum2d = R * 0.2;
226 const double final_time = 0.001;
227 size_t num_steps = 400;
229 num_steps =
static_cast<size_t>(std::stoul(input.
getCmdOption(
"-numSteps")));
231 const size_t num_outputs = 10;
232 const size_t dt_out_n = std::max<size_t>(1, num_steps / num_outputs);
233 const size_t test_dt_out_n = std::max<size_t>(1, dt_out_n / 10);
235 const double rho_wall = 600.;
236 const double poisson_wall = 0.25;
237 const double K_wall = 1.e+4;
240 const double KIc_wall = 5e+6;
241 const double Gc_wall =
material::toGc(KIc_wall, poisson_wall, E_wall);
243 const double rho_p = 600.;
244 const double poisson_p = poisson_wall;
245 const double K_p = 5.e+3;
248 const double KIc_p = 5e+6;
251 const double R_contact_factor = 0.95;
252 const double padding = 1.1 * R_contact_factor * mesh_size;
253 const int N_target = 500;
255 const std::vector<double> in_rect = {center[0] - 0.5 * Lin, center[1] - 0.5 * Win, center[2],
256 center[0] + 0.5 * Lin, center[1] + 0.5 * Win, center[2]};
258 std::mt19937 gen(30);
259 const double max_y = in_rect[4] - clearance_mesh * mesh_size;
260 std::vector<PackedParticle> packed =
263 throw std::runtime_error(
"compression_large_set_inbuilt_2mat2contact: particle pack is empty");
264 for (
auto &p : packed)
267 const double m = clearance_mesh * mesh_size;
271 const double delta_y = (in_rect[1] + m) - bb0.
min_y;
272 for (
auto &p : packed)
279 const double void_lox = bb.
min_x - m - geom_pad;
280 const double void_hix = bb.
max_x + m + geom_pad;
281 const double void_loy = in_rect[1];
283 const double plate_bottom_y = bb.
max_y + m + geom_pad;
284 double plate_top_y = plate_bottom_y + plate_thickness;
287 const double side = std::max(1.5 * horizon, 2.0 * mesh_size);
288 const double out_lox = void_lox - side;
289 const double out_hix = void_hix + side;
290 const double out_loy = void_loy - side;
291 const double out_hiy = plate_top_y + wall_top_inset + 2.5 * mesh_size;
293 std::vector<double> out_rect = {out_lox, out_loy, center[2], out_hix, out_hiy, center[2]};
296 const double void_hi_y = out_rect[4] - annulus_inset;
297 std::vector<double> remove_rect = {void_lox, void_loy, center[2], void_hix, void_hi_y, center[2]};
300 "[compression_large_set_inbuilt_2mat2contact] bbox(center±r) x∈[{:.6f},{:.6f}] y∈[{:.6f},{:.6f}]; "
301 "void x∈[{:.6f},{:.6f}] y_lo {:.6f}; plate y [{:.6f},{:.6f}]; void_hi {:.6f}; outer y∈[{:.6f},{:.6f}]\n",
302 bb.
min_x, bb.
max_x, bb.
min_y, bb.
max_y, void_lox, void_hix, void_loy, plate_bottom_y, plate_top_y,
303 void_hi_y, out_rect[1], out_rect[4]));
305 std::vector<double> moving_rect = {void_lox, plate_bottom_y, center[2], void_hix, plate_top_y, center[2]};
307 std::vector<double> fixed_container_params;
308 fixed_container_params.insert(fixed_container_params.end(), remove_rect.begin(), remove_rect.end());
309 fixed_container_params.insert(fixed_container_params.end(), out_rect.begin(), out_rect.end());
311 const size_t n_pack = packed.size();
312 const size_t n_wall_fixed = n_pack;
313 const size_t n_wall_moving = n_pack + 1;
314 const size_t n_total = n_pack + 2;
317 const double ell_a = 0.95 * R;
318 const double ell_b = 0.58 * R;
319 const double ell_theta = 0.35;
320 const double sq_half = R / std::sqrt(2.0);
322 const double rx = 0.82 * R;
323 const double ry = 0.62 * R;
325 std::vector<geom::GeomData> pGeomVec(10);
326 pGeomVec[0].d_geomName =
"circle";
327 pGeomVec[0].d_geomParams = {R, center[0], center[1], center[2]};
328 pGeomVec[1].d_geomName =
"triangle";
329 pGeomVec[1].d_geomParams = {R, center[0], center[1], center[2]};
330 pGeomVec[2].d_geomName =
"drum2d";
331 pGeomVec[2].d_geomParams = {R, w_drum2d, center[0], center[1], center[2]};
332 pGeomVec[3].d_geomName =
"hexagon";
333 pGeomVec[3].d_geomParams = {R, center[0], center[1], center[2]};
334 pGeomVec[4].d_geomName =
"ellipse";
335 pGeomVec[4].d_geomParams = {ell_a, ell_b, ell_theta, center[0], center[1], center[2]};
336 pGeomVec[5].d_geomName =
"rectangle";
337 pGeomVec[5].d_geomParams = {-rx, -ry, center[2], rx, ry, center[2]};
338 pGeomVec[6].d_geomName =
"square";
339 pGeomVec[6].d_geomParams = {-sq_half, -sq_half, center[2], sq_half, sq_half, center[2]};
340 pGeomVec[7].d_geomName =
"circle_minus_circle";
341 pGeomVec[7].d_geomParams = {center[0], center[1], center[2], R, 0.35 * R};
342 pGeomVec[8].d_geomName =
"rectangle_minus_rectangle";
343 pGeomVec[8].d_geomParams = fixed_container_params;
344 pGeomVec[9].d_geomName =
"rectangle";
345 pGeomVec[9].d_geomParams = moving_rect;
347 for (
auto &g : pGeomVec)
351 const util::Point cfix = pGeomVec[8].d_geom_p->center();
352 const util::Point cmov = pGeomVec[9].d_geom_p->center();
357 "central_difference",
true, 2,
"Multi_Particle", 0);
359 std::vector<std::string> out_tags = {
"Displacement",
"Velocity",
"Force",
"Force_Density",
"Damage_Z",
360 "Damage",
"Nodal_Volume",
"Zone_ID",
"Particle_ID",
"Fixity",
361 "Force_Fixity",
"Contact_Nodes",
"No_Fail_Node",
"Boundary_Node_Flag"};
366 true,
"zlib",
true, test_dt_out_n,
"0",
true);
371 {n_wall_fixed}, {},
"", {},
"", {},
372 {1, 2},
true,
"", {});
375 set2[
"Particle_List"] = std::vector<size_t>{n_wall_moving};
376 set2[
"Direction"] = std::vector<size_t>{2};
377 set2[
"Time_Function"] =
json{{
"Type",
"linear"}, {
"Parameters", std::vector<double>{-0.06}}};
378 set2[
"Spatial_Function"] =
json{{
"Type",
"constant"}};
379 bcDeckJson[
"Displacement_BC"][
"Set_2"] = set2;
381 json pDeckJson = json::object();
386 const char *mesh_names[] = {
"mesh_cir",
"mesh_tri",
"mesh_drum2d",
"mesh_hex",
387 "mesh_ellipse",
"mesh_rect",
"mesh_square",
"mesh_circirc",
388 "mesh_fixed_container",
"mesh_moving_container"};
389 for (
int zi = 0; zi < 10; ++zi) {
390 const std::string fname = (inp_dir / (std::string(mesh_names[zi]) +
".msh")).string();
391 meshRoot[
"Set_" + std::to_string(zi + 1)] =
392 json{{
"File", fname},
394 json{{
"Flag",
true}, {
"Info",
"gmsh_builtin_mesh"}, {
"Mesh_Size", mesh_size}, {
"Write_Mesh_File",
true}}}};
396 pDeckJson[
"Mesh"] = meshRoot;
403 pDeckJson[
"Material"] = matRoot;
405 const double Kn_pp =
KnFromBulk(K_p, K_p, horizon);
406 const double Kn_pw =
KnFromBulk(K_p, K_wall, horizon);
407 const double Kn_ww = 0.0;
409 const double beta_n_eps = 0.95;
410 const double friction_coeff = 0.5;
411 const bool damping_on =
true;
412 const bool friction_on =
false;
413 const double beta_n_factor = 100.;
414 const double Kn_factor = 1.;
417 const json j_contact_pp =
418 contactPairJson(R_contact_factor, damping_on, friction_on, Kn_pp, beta_n_eps, friction_coeff, Kn_factor,
420 const json j_contact_pw =
421 contactPairJson(R_contact_factor, damping_on, friction_on, Kn_pw, beta_n_eps, friction_coeff, Kn_factor,
423 const json j_contact_ww =
424 contactPairJson(R_contact_factor, damping_on, friction_on, Kn_ww, beta_n_eps, friction_coeff, Kn_factor,
428 contactRoot[
"Set_1_1"] = j_contact_pp;
429 contactRoot[
"Set_1_2"] = j_contact_pw;
430 contactRoot[
"Set_2_2"] = j_contact_ww;
431 pDeckJson[
"Contact"] = contactRoot;
436 pGenJson[
"Random_Rotation"] =
false;
437 pGenJson[
"Data"][
"N"] = n_total;
439 constexpr size_t k_mat_particle = 0;
440 constexpr size_t k_mat_wall = 1;
441 constexpr size_t k_contact_grains = 0;
442 constexpr size_t k_contact_wall = 1;
444 for (
size_t pi = 0; pi < n_pack; ++pi) {
445 const auto &p = packed[pi];
446 pGenJson[
"Data"][std::to_string(pi)] =
json{
447 {
"x", p.x}, {
"y", p.y}, {
"z", 0.0}, {
"theta", p.theta},
448 {
"s", 1.0}, {
"geom_id",
static_cast<size_t>(p.zone)},
449 {
"mat_id", k_mat_particle},
450 {
"contact_id", k_contact_grains},
454 pGenJson[
"Data"][std::to_string(n_pack)] =
json{{
"x", site_wall_fixed.
d_x},
455 {
"y", site_wall_fixed.
d_y},
459 {
"geom_id", size_t(8)},
460 {
"mat_id", k_mat_wall},
461 {
"contact_id", k_contact_wall}};
463 pGenJson[
"Data"][std::to_string(n_pack + 1)] =
json{{
"x", site_wall_moving.
d_x},
464 {
"y", site_wall_moving.
d_y},
468 {
"geom_id", size_t(9)},
469 {
"mat_id", k_mat_wall},
470 {
"contact_id", k_contact_wall}};
472 pDeckJson[
"Particle_Generation"] = pGenJson;
475 return json{{
"Comment",
476 "compression_large_set_inbuilt"},
477 {
"Model", modelDeckJson},
478 {
"Output", outputDeckJson},
479 {
"Force_BC", bcDeckJson[
"Force_BC"]},
480 {
"Displacement_BC", bcDeckJson[
"Displacement_BC"]},
481 {
"Particle", pDeckJson[
"Particle"]},
482 {
"Mesh", pDeckJson[
"Mesh"]},
483 {
"Material", pDeckJson[
"Material"]},
484 {
"Contact", pDeckJson[
"Contact"]},
485 {
"Neighbor", pDeckJson[
"Neighbor"]},
486 {
"Particle_Generation", pDeckJson[
"Particle_Generation"]}};
std::vector< PackedParticle > generateParticleLocations(const std::vector< double > &in_rect, double max_y, double mesh_size, double R, int N_target, double padding, std::mt19937 &gen)
json contactPairJson(double R_contact_factor, bool damping_on, bool friction_on, double Kn, double beta_n_eps, double friction_coeff, double Kn_factor, double beta_n_factor)