77 {1.0, 0.996}, {0.95, 0.925}, {0.9, 0.861}, {0.85, 0.801}, {0.8, 0.744}};
78 if (test_id < 1 || test_id > 5)
79 throw std::runtime_error(
"jha2021Table2Test must be 1..5");
80 return k[test_id - 1];
87 namespace fs = std::filesystem;
88 fs::path n = fs::absolute(dir).lexically_normal();
89 std::string s = n.string();
90 if (!s.empty() && s.back() !=
'/' && s.back() !=
'\\')
91 s += fs::path::preferred_separator;
96 const std::filesystem::path &mesh_file_1,
97 const std::filesystem::path &mesh_file_2,
98 double final_time,
size_t num_steps,
bool zero_ic,
99 double mesh_size_in,
double horizon_in,
bool damping_on,
100 double eps_n,
bool two_particle_test,
bool file_mesh,
101 double beta_n_factor,
102 const std::string &damping_law =
"com_and_node",
103 const std::string &friction_law =
"coulomb_simple",
104 bool friction_on =
false,
105 double friction_mu = -1.,
107 bool bottom_patch_bc =
false,
108 const std::string &mpi_strategy =
"auto") {
110 const std::vector<double> center = {0.0, 0.0, 0.0};
111 const double R1 = 0.001;
112 const double R2 = 0.001;
113 const double mesh_size =
114 mesh_size_in > 0. ? mesh_size_in : std::min(R1, R2) / 5.0;
115 const double horizon = horizon_in > 0. ? horizon_in : 3.0 * mesh_size;
116 const double particle_dist = 0.001;
118 const double poisson1 = 0.25;
119 const double rho1 = 1200.0;
120 const double K1 = 2.16e+7;
123 const double Gc1 = 50.0;
125 const double poisson2 = 0.25;
126 const double rho2 = 1200.0;
127 const double K2 = 2.16e+7;
130 const double Gc2 = 50.0;
132 const double R_contact_factor = 0.95;
136 const double friction_coeff = 0.5;
138 std::vector<double> p1_center = center;
139 std::vector<double> p2_center = center;
141 const double H0_drop = particle_dist;
143 const double top_gap = two_particle_test ? horizon : particle_dist;
145 const size_t dt_out_n = num_steps / 10;
147 json{{
"Dimension", 2},
148 {
"Final_Time", final_time},
149 {
"Time_Steps", num_steps},
150 {
"Discretization_Type",
json{{
"Spatial",
"finite_difference"}, {
"Time",
"central_difference"}}},
151 {
"Populate_ElementNodeConnectivity",
true},
152 {
"Quad_Approximation_Order", 2},
153 {
"Particle_Sim_Type",
"Multi_Particle"},
155 modelDeckJson[
"MPI_Strategy"] = mpi_strategy;
158 json{{
"File_Format",
"vtu"},
159 {
"Path", output_path_for_deck},
160 {
"Tags", std::vector<std::string>({
"Displacement",
"Velocity",
"Force",
"Damage_Z",
"Damage",
"Particle_ID"})},
161 {
"Output_Interval", dt_out_n},
163 {
"Perform_FE_Out",
true},
164 {
"Compress_Type",
"zlib"},
165 {
"Perform_Out",
true},
166 {
"Test_Output_Interval", 1},
168 {
"PVD_Collection",
true}});
171 json{{
"Displacement_BC_Sets", 1},
175 if (bottom_patch_bc) {
179 patch.
d_geomParams = {R1 - 1.1 * R1, -0.1 * R1, 0., R1 + 1.1 * R1, 0.35 * R1,
183 bcDeckJson[
"Displacement_BC"][
"Set_1"] =
json{
184 {
"Particle_List", json::array({0})},
185 {
"Region", {{
"Geometry", j_geom}}},
186 {
"Direction", json::array({1, 2})},
187 {
"Zero_Displacement",
true}};
189 bcDeckJson[
"Displacement_BC"][
"Set_1"] =
191 json{{
"Type",
"Displacement_BC"},
192 {
"Particle_List", {0}},
193 {
"Direction", {1, 2}},
194 {
"Zero_Displacement",
true}});
197 std::vector<double> ic_vel = {0.0, 0.0, 0.0};
199 const double fallen =
200 two_particle_test ? (H0_drop - top_gap) : (particle_dist - horizon);
202 ic_vel[1] = -std::sqrt(2.0 * std::abs(-10.0) * fallen);
207 {
"Particle_List", {1}},
208 {
"IC_Type",
"Constant_Velocity"},
209 {
"IC_Vector", ic_vel}});
211 auto pDeckJson =
json({});
213 std::vector<geom::GeomData> pGeomVec(2);
214 pGeomVec[0].d_geomName =
"circle";
215 pGeomVec[0].d_geomParams = {R1, p1_center[0], p1_center[1], p1_center[2]};
216 pGeomVec[1].d_geomName =
"circle";
217 pGeomVec[1].d_geomParams = {R2, p2_center[0], p2_center[1], p2_center[2]};
221 const std::string f1 = mesh_file_1.string();
222 const std::string f2 = mesh_file_2.string();
223 json meshSet1, meshSet2;
225 meshSet1 =
json({{
"File", f1}});
226 meshSet2 =
json({{
"File", f2}});
228 meshSet1 =
json({{
"File", f1},
231 {
"Info",
"gmsh_builtin_mesh"},
232 {
"Mesh_Size", mesh_size},
233 {
"Write_Mesh_File",
true}}}});
234 meshSet2 =
json({{
"File", f2},
237 {
"Info",
"gmsh_builtin_mesh"},
238 {
"Mesh_Size", mesh_size},
239 {
"Write_Mesh_File",
true}}}});
241 pDeckJson[
"Mesh"] =
json({{
"Sets", 2}, {
"Set_1", meshSet1}, {
"Set_2", meshSet2}});
245 json{{
"Type",
"PDState"},
246 {
"Is_Plane_Strain",
false},
247 {
"Horizon", horizon},
252 {
"Compute_From_Classical",
true},
253 {
"Influence_Function",
json{{
"Type", 0}}}});
255 json{{
"Type",
"PDState"},
256 {
"Is_Plane_Strain",
false},
257 {
"Horizon", horizon},
262 {
"Compute_From_Classical",
true},
263 {
"Influence_Function",
json{{
"Type", 0}}}});
264 pDeckJson[
"Material"] = pMatJson;
271 (friction_mu >= 0.) ? friction_mu
272 : (two_particle_test ? 0. : friction_coeff);
274 json{{
"Contact_Radius_Factor", R_contact_factor},
276 {
"Damping_On", damping_on},
278 {
"Friction_On", friction_on},
279 {
"Friction_Coeff", mu},
281 {
"Beta_n_Factor", beta_n_factor},
284 pContactJson[
"Set_1_1"] = contact_base;
285 pContactJson[
"Set_1_1"][
"Kn"] = Kn_11;
286 pContactJson[
"Set_1_1"][
"K"] = K1;
287 pContactJson[
"Set_1_2"] = contact_base;
288 pContactJson[
"Set_1_2"][
"Kn"] = Kn_12;
290 pContactJson[
"Set_2_2"] = contact_base;
291 pContactJson[
"Set_2_2"][
"Kn"] = Kn_22;
292 pContactJson[
"Set_2_2"][
"K"] = K2;
293 pContactJson[
"Damping_Law"] = damping_law;
294 pContactJson[
"Friction_Law"] = friction_law;
295 pDeckJson[
"Contact"] = pContactJson;
297 pDeckJson[
"Neighbor"] = two_particle_test
299 json{{
"Update_Criteria",
"simple_all"},
300 {
"Search_Factor", 5.0},
301 {
"Search_Interval", 1},
302 {
"Near_Bd_Nodes_Tol", 0.5}})
304 json{{
"Update_Criteria",
"simple_all"},
305 {
"Search_Factor", 10.0},
306 {
"Search_Interval", 40},
307 {
"Near_Bd_Nodes_Tol", 0.5}});
310 pGenJson[
"Random_Rotation"] =
false;
311 pGenJson[
"Data"][
"N"] = 2;
312 pGenJson[
"Data"][
"0"] = {
313 {
"x", R1}, {
"y", R1}, {
"z", 0.0},
314 {
"theta", 0.0}, {
"s", 1.0},
315 {
"geom_id", 0}, {
"mat_id", 0}, {
"contact_id", 0}
317 pGenJson[
"Data"][
"1"] = {
318 {
"x", R1}, {
"y", 2.0 * R1 + R2 + top_gap}, {
"z", 0.0},
319 {
"theta", two_particle_test ? M_PI / 2.0 : M_PI}, {
"s", 1.0},
320 {
"geom_id", 1}, {
"mat_id", 1}, {
"contact_id", 1}
322 pDeckJson[
"Particle_Generation"] = pGenJson;
324 auto j =
json({{
"Model", modelDeckJson},
325 {
"Output", outputDeckJson},
326 {
"Force_BC", bcDeckJson[
"Force_BC"]},
327 {
"Displacement_BC", bcDeckJson[
"Displacement_BC"]},
328 {
"IC", bcDeckJson[
"IC"]},
329 {
"Particle", pDeckJson[
"Particle"]},
330 {
"Mesh", pDeckJson[
"Mesh"]},
331 {
"Material", pDeckJson[
"Material"]},
332 {
"Contact", pDeckJson[
"Contact"]},
333 {
"Neighbor", pDeckJson[
"Neighbor"]},
334 {
"Particle_Generation", pDeckJson[
"Particle_Generation"]}});
335 if (two_particle_test)
336 j[
"Test"] =
json{{
"Test_Name",
"two_particle"}};
349 if (
data.d_particlesListTypeAll.size() < 2)
351 const auto *p0 =
data.d_particlesListTypeAll[0];
352 const auto *p1 =
data.d_particlesListTypeAll[1];
353 const double gap = p0->getXCenter().dist(p1->getXCenter()) -
354 p0->d_geom_p->boundingRadius() -
355 p1->d_geom_p->boundingRadius();
356 if (
data.currentStep() % 50 == 0)
360 const double leave = 1.0e-5;
361 const double significant = 0.05 *
d_H0;
366 }
else if (d_minGap < 0.3 * d_H0 && gap >
d_minGap + leave) {
371 }
else if (gap >
d_H1) {
384 const std::vector<std::pair<double, double>> &
samples()
const {
412 if (
data.d_particlesListTypeAll.size() < 2)
414 const auto *p0 =
data.d_particlesListTypeAll[0];
415 const auto *p1 =
data.d_particlesListTypeAll[1];
416 const double gap = p0->getXCenter().dist(p1->getXCenter()) -
417 p0->d_geom_p->boundingRadius() -
418 p1->d_geom_p->boundingRadius();
419 if (gap < 0.5 * 0.001)
421 const double vx = std::abs(p1->getVCenter().d_x);
448 std::filesystem::create_directories(
d_outDir /
"nodal");
450 d_os <<
"step,t,max_u,com1x,com1y\n";
456 const size_t nstep =
data.currentStep();
461 for (
const auto &u :
data.d_u)
462 max_u = std::max(max_u, u.length());
464 MPI_Allreduce(MPI_IN_PLACE, &max_u, 1, MPI_DOUBLE, MPI_MAX,
466 double com1x = 0., com1y = 0.;
467 if (
data.d_particlesListTypeParticle.size() > 1) {
468 const auto c =
data.d_particlesListTypeParticle[1]->getXCenter();
473 d_os << std::format(
"{},{:.12e},{:.12e},{:.12e},{:.12e}\n", nstep,
474 data.d_time, max_u, com1x, com1y);
483 if (
data.d_pdDofMpi) {
484 if (i >=
data.d_pdNodePartition.size())
486 return static_cast<int>(
data.d_pdNodePartition[i]) == rank;
489 for (
const auto *p :
data.d_particlesListTypeAll) {
490 const size_t i0 = p->d_globStart;
491 const size_t i1 = i0 + p->getNumNodes();
492 if (i < i0 || i >= i1)
502 const size_t n =
data.d_u.size();
503 std::vector<double> buf(6 * n, 0.);
504 for (
size_t i = 0; i < n; ++i) {
507 buf[6 * i + 0] =
data.d_u[i].d_x;
508 buf[6 * i + 1] =
data.d_u[i].d_y;
509 buf[6 * i + 2] =
data.d_u[i].d_z;
510 buf[6 * i + 3] =
data.d_v[i].d_x;
511 buf[6 * i + 4] =
data.d_v[i].d_y;
512 buf[6 * i + 5] =
data.d_v[i].d_z;
515 MPI_Allreduce(MPI_IN_PLACE, buf.data(),
static_cast<int>(buf.size()),
520 std::ofstream xr(
d_outDir /
"nodal" /
"x_ref.bin", std::ios::binary);
521 const uint32_t nn =
static_cast<uint32_t
>(n);
522 xr.write(
reinterpret_cast<const char *
>(&nn),
sizeof(nn));
523 for (
size_t i = 0; i < n; ++i) {
524 const double p[3] = {
data.d_xRef[i].d_x,
data.d_xRef[i].d_y,
526 xr.write(
reinterpret_cast<const char *
>(p),
sizeof(p));
531 d_outDir /
"nodal" / std::format(
"uv_{:06d}.bin", nstep);
532 std::ofstream os(path, std::ios::binary);
533 const char magic[4] = {
'P',
'D',
'U',
'V'};
534 const uint32_t step32 =
static_cast<uint32_t
>(nstep);
535 const uint32_t nn =
static_cast<uint32_t
>(n);
537 os.write(
reinterpret_cast<const char *
>(&step32),
sizeof(step32));
538 os.write(
reinterpret_cast<const char *
>(&nn),
sizeof(nn));
539 os.write(
reinterpret_cast<const char *
>(buf.data()),
540 static_cast<std::streamsize
>(buf.size() *
sizeof(double)));
549int main(
int argc,
char *argv[]) {
553 util::io::print(std::format(
"Initialized MPI. MPI size = {}, MPI rank = {}\n", mpiSize, mpiRank));
558 unsigned int nThreads;
562 nThreads = std::thread::hardware_concurrency();
563 util::io::print(std::format(
"Running test with default number of threads = {}\n", nThreads));
568#ifndef TWOP_CONTACT_EXAMPLE
569 double final_time = 0.002;
570 size_t num_steps = 6000;
572 double final_time = 0.012;
573 size_t num_steps = 36000;
575 bool zero_ic =
false;
576 double mesh_size_in = -1.;
577 double horizon_in = -1.;
578 bool assert_cr =
false;
581 bool damping_on =
false;
583 double beta_n_factor = 100.0;
584 std::string damping_law =
"com_and_node";
585 std::string friction_law =
"coulomb_simple";
586 bool friction_on =
false;
587 double friction_mu = -1.;
589 bool assert_lat =
false;
591 bool bottom_patch_bc =
false;
592 std::string mpi_strategy =
"auto";
593 bool write_mpi_metric =
false;
596 jha_test = std::stoi(input.
getCmdOption(
"-jha2021Table2Test"));
613 damping_on = c.eps < 1.0 - 1.0e-12;
616 final_time = std::stod(input.
getCmdOption(
"-finalTime"));
618 num_steps = std::stoul(input.
getCmdOption(
"-numSteps"));
622 mesh_size_in = std::stod(input.
getCmdOption(
"-meshSize"));
627 damping_on = eps_n < 1.0 - 1.0e-12;
630 beta_n_factor = std::stod(input.
getCmdOption(
"-betaNFactor"));
643 lat_min = std::stod(input.
getCmdOption(
"-assertLateralVx"));
653 bottom_patch_bc =
true;
657 write_mpi_metric =
true;
659 "final_time = {}, num_steps = {}, zero_ic = {}, eps_n = {}, C_bar = {}, "
660 "damping = {}, Damping_Law = {}, Friction_Law = {}, bottomPatchBC = {}, "
661 "MPI_Strategy = {}\n",
662 final_time, num_steps, zero_ic, eps_n, beta_n_factor, damping_on,
663 damping_law, friction_law, bottom_patch_bc, mpi_strategy));
665 namespace fs = std::filesystem;
666 const fs::path cwd = fs::current_path();
668 fs::path out_dir = cwd /
"out";
669 fs::path inp_dir = cwd /
"inp";
673 out_dir = p.is_absolute() ? std::move(p) : cwd / p;
677 inp_dir = p.is_absolute() ? std::move(p) : cwd / p;
680 inp_dir = out_dir.parent_path() /
"inp";
683 fs::create_directories(out_dir);
684 fs::create_directories(inp_dir);
686 const std::string output_path_for_deck = directoryPathWithTrailingSep(out_dir);
687 const fs::path mesh1 = inp_dir /
"mesh_cir_1.msh";
688 const fs::path mesh2 = inp_dir /
"mesh_cir_2.msh";
690 const bool file_mesh = jha_test > 0 && !inbuilt_mesh;
692#ifndef JHA2021_MESH_DIR
693 throw std::runtime_error(
"JHA2021_MESH_DIR is not set (v0.1.0 circ_damp meshes).");
695 const fs::path src(JHA2021_MESH_DIR);
696 fs::copy_file(src /
"mesh_cir_1.msh", mesh1, fs::copy_options::overwrite_existing);
697 fs::copy_file(src /
"mesh_cir_2.msh", mesh2, fs::copy_options::overwrite_existing);
698 util::io::print(std::format(
"Using v0.1.0 circ_damp meshes from {}\n", src.string()));
700 }
else if (jha_test > 0)
701 util::io::print(
"Using in-process Gmsh (gmsh_builtin_mesh) instead of frozen v0.1.0 .msh\n");
703 util::io::print(std::format(
"Output directory (VTU, log.txt): {}\n", fs::absolute(out_dir).
string()));
704 util::io::print(std::format(
"Input directory (input.json, meshes): {}\n", fs::absolute(inp_dir).
string()));
706 auto inputJson =
buildInputJson(output_path_for_deck, mesh1, mesh2, final_time,
707 num_steps, zero_ic, mesh_size_in, horizon_in,
708 damping_on, eps_n, jha_test > 0, file_mesh,
709 beta_n_factor, damping_law,
710 friction_law, friction_on, friction_mu,
711 ic_vx, bottom_patch_bc, mpi_strategy);
713 const fs::path input_json_path = inp_dir /
"input.json";
715 std::ofstream os(input_json_path);
717 throw std::runtime_error(
"Failed to open " + input_json_path.string() +
" for writing.");
718 os << inputJson.dump(2);
720 util::io::print(std::format(
"Wrote deck to {}\n", fs::absolute(input_json_path).
string()));
730 const auto &p1 = inputJson[
"Particle_Generation"][
"Data"][
"1"];
731 const auto &v = inputJson[
"IC"][
"Set_1"][
"Constant_Velocity"][
"Velocity_Vector"];
732 const double y1 = p1.at(
"y").get<
double>();
733 const double gap0 = y1 - 0.001 - 0.001 - 0.001;
735 "Table 2 kinematics: top y = {}, surface gap = {}, v_y = {}\n",
736 y1, gap0, v.at(1).get<
double>()));
739 auto deck = std::make_shared<inp::Input>(inputJson);
745 auto p = std::make_unique<RestitutionProbe>(0.001);
748 }
else if (assert_lat) {
749 auto p = std::make_unique<LateralProbe>(ic_vx);
752 }
else if (write_mpi_metric) {
753 const size_t ts_every = std::max<size_t>(1, num_steps / 100);
755 std::make_unique<MpiMetricTsProbe>(out_dir, ts_every));
761 dem.
d_Z.empty() ? 0.f : *std::max_element(dem.
d_Z.begin(), dem.
d_Z.end());
762 util::io::print(std::format(
"requireContact: max Damage_Z = {}\n", zmax));
764 util::io::print(
"requireContact: no damage; particles did not contact.\n");
771 const fs::path gap_csv = out_dir /
"gap.csv";
772 std::ofstream gs(gap_csv);
774 for (
const auto &s : probe->
samples())
775 gs << s.first <<
"," << s.second <<
"\n";
776 util::io::print(std::format(
"Wrote {}\n", fs::absolute(gap_csv).
string()));
778 const double cr = probe->
CR();
780 "assertCR: contacted={}, min_gap={} (t={}), H1={} (t={}), CR={}, ref={}, tol={}\n",
782 probe->
tH1(), cr, cr_ref, cr_tol));
785 "assertCR: CR > 1.02 on the 1 mm energy-equivalent drop "
786 "(surface gap = horizon, leftover height already in v_y). "
787 "Unphysical energy gain.\n");
790 if (!probe->
contacted() || std::abs(cr - cr_ref) > cr_tol) {
791 util::io::print(
"assertCR: coefficient of restitution out of range.\n");
798 const double vmax = lat_probe->
maxAbsVx();
799 const double ic = lat_probe->
icAbsVx();
801 "assertLateralVx: contacted={}, max|vx|={}, min|vx|_after_contact={}, "
802 "ic|vx|={}, slow_factor_max={}\n",
803 lat_probe->
contacted(), vmax, vmin, ic, lat_min));
809 if (!(ic > 0.) || !(vmin < lat_min * ic)) {
811 "assertLateralVx: friction did not slow lateral speed enough "
812 "(or kinematics missed).\n");
817 if (write_mpi_metric) {
819 for (
const auto &u : dem.
d_u)
820 max_u = std::max(max_u, u.length());
821 double com1x = 0., com1y = 0.;
828 MPI_Allreduce(MPI_IN_PLACE, &max_u, 1, MPI_DOUBLE, MPI_MAX,
835 std::ofstream os(out_dir /
"mpi_metric.txt");
836 os << std::format(
"{:.12e} {:.12e} {:.12e}\n", max_u, com1x, com1y);
838 "mpi_metric: max|u|={:.12e} grain1_com=({:.12e},{:.12e})\n", max_u,
int main(int argc, char *argv[])
double minAbsVxAfterContact() const
LateralProbe(double ic_abs_vx)
double d_minAbsVxAfterContact
void checkStop(data::ModelData &data) override
void checkStop(data::ModelData &data) override
MpiMetricTsProbe(std::filesystem::path out_dir, size_t interval)
static bool ownsNode(const data::ModelData &data, size_t i)
std::filesystem::path d_outDir
void dumpNodalUV(data::ModelData &data, size_t nstep)
void setPostprocess(std::unique_ptr< postprocess::Postprocess > p)
void run(std::shared_ptr< inp::Input > &deck)
RestitutionProbe(double H0)
std::vector< std::pair< double, double > > d_samples
const std::vector< std::pair< double, double > > & samples() const
void checkStop(data::ModelData &data) override
A class to store model data.
std::vector< float > d_Z
Damage at nodes.
std::vector< util::Point > d_u
Displacement of the nodes.
std::vector< particle::BaseParticle * > d_particlesListTypeParticle
List of particles.
Extra postprocessing and stop criteria (VTU writing is in rw::).
virtual void checkStop(data::ModelData &data)
nlohmann::ordered_json json
std::string directoryPathWithTrailingSep(const std::filesystem::path &dir)
json buildInputJson(const std::string &output_path_for_deck, const std::filesystem::path &mesh_file_1, const std::filesystem::path &mesh_file_2, double final_time, size_t num_steps, bool zero_ic, double mesh_size_in, double horizon_in, bool damping_on, double eps_n, bool two_particle_test, bool file_mesh, double beta_n_factor, const std::string &damping_law="com_and_node", const std::string &friction_law="coulomb_simple", bool friction_on=false, double friction_mu=-1., double ic_vx=0., bool bottom_patch_bc=false, const std::string &mpi_strategy="auto")
void writeGeometry(json &j, const geom::GeomData &geomData)
double toGE(double E, double nu)
Compute shear modulus from Young's modulus E and Poisson's ratio nu.
double toE(double K, double nu)
Compute Young's modulus E from Bulk modulus K and Poisson's ratio nu.
bool isLocallyOwned(const BaseParticle &p)
True if this rank updates / assembles forces for the particle. Walls are replicated on every rank....
void print(const T &msg, int nt=print_default_tab, int printMpiRank=print_default_mpi_rank)
Prints formatted information.
bool isMpiEnabled()
Function to check if MPI is enabled.
unsigned int getNThreads()
Get number of threads to be used by taskflow.
void initNThreads(unsigned int nThreads=std::thread::hardware_concurrency())
Initializes MpiStatus struct.
const MpiStatus * getMpiStatus()
Returns pointer to MpiStatus struct.
void initMpi(int argc=0, char *argv[]=nullptr)
Initializes MPI and also creates MpiStatus struct.
int mpiSize()
Get size (number) of processors.
int mpiRank()
get rank (id) of this processor
void finalizeMpi()
Call MPI_Finalize if this process initialized MPI.
MPI_Comm mpiComm()
Get MPI comm.
double normalContactStiffness(const double &K1, const double &K2, const double &horizon, int horizonPower=5)
Silling normal contact stiffness from two bulk moduli and the horizon.
double harmonicMean(const double &m1, const double &m2)
Input data for geometrical objects.
std::vector< double > d_geomParams
Zone parameters.
std::string d_geomName
Zone type.
static json getExampleJson(const json &given=json::object(), const geom::GeomData *region=nullptr)
Returns example JSON object for ModelDeck configuration.
static json getExampleJson(const json &given=json::object())
Returns example JSON object for ModelDeck configuration.
static json getExampleJson(const json &given=json::object())
Returns example JSON object for ModelDeck configuration.
static json getExampleJson(const json &given=json::object())
Returns the block with the given fields set.
static json getExampleJson(const std::string &)=delete
Returns example JSON object for ModelDeck configuration.
static json getExampleJson(const json &given=json::object())
Returns the block with the given fields set.
static json getExampleJson(const json &given=json::object())
Returns the block with the given fields set.
static json getParticleContactExampleJson(size_t nSets=0)
Returns example JSON object for ModelDeck configuration.
static json getParticleGeomExampleJson(std::vector< geom::GeomData > pGeomVec=std::vector< geom::GeomData >())
Returns example JSON object for ModelDeck configuration.
static json getParticleMaterialExampleJson(size_t nSets=0)
Returns example JSON object for ModelDeck configuration.
A structure to represent 3d vectors.
std::vector< double > toVec() const
Returns coordinate in stl form.
Jha2021Table2 jha2021Table2(int test_id)