44 namespace fs = std::filesystem;
45 fs::path n = fs::absolute(dir).lexically_normal();
46 std::string s = n.string();
47 if (!s.empty() && s.back() !=
'/' && s.back() !=
'\\')
48 s += fs::path::preferred_separator;
53 return g ==
"sphere" || g ==
"ellipsoid" || g ==
"cube" || g ==
"cuboid" || g ==
"cylinder" ||
54 g ==
"sphere_minus_sphere" || g ==
"cuboid_minus_cuboid" || g ==
"open_cuboid_channel_3d";
66 const std::filesystem::path &mesh_file_1,
67 const std::filesystem::path &mesh_file_2) {
69 const double s = 0.001;
70 const double mesh_size = s / 5.0;
71 const double horizon = 3.0 * mesh_size;
72 const double particle_dist = 0.001;
74 const double poisson1 = 0.25;
75 const double rho1 = 1200.0;
76 const double K1 = 2.16e+7;
79 const double Gc1 = 50.0;
81 const double poisson2 = 0.25;
82 const double rho2 = 1200.0;
83 const double K2 = 2.16e+7;
86 const double Gc2 = 50.0;
88 const double R_contact_factor = 0.95;
89 const double Kn_11 = 18.0 *
util::harmonicMean(K1, K1) / (M_PI * std::pow(horizon, 5));
90 const double Kn_22 = 18.0 *
util::harmonicMean(K2, K2) / (M_PI * std::pow(horizon, 5));
91 const double Kn_12 = 18.0 *
util::harmonicMean(K1, K2) / (M_PI * std::pow(horizon, 5));
92 const double beta_n_eps = 0.9;
93 const double friction_coeff = 0.5;
94 const double beta_n_factor = 100.0;
103 const double final_time = 0.0001;
104 const size_t num_steps = 1000;
105 const size_t dt_out_n = num_steps / 4;
108 "finite_difference",
"central_difference",
109 true, 2,
"Multi_Particle", 0);
112 std::vector<std::string>({
"Displacement",
"Velocity",
"Force",
"Damage_Z",
"Damage",
"Particle_ID"}),
113 dt_out_n, 2,
true,
"zlib",
true, 1,
"",
true);
118 {0}, {},
"", {},
"", {},
119 {1, 2},
true,
"", {});
121 const double free_fall_dist = particle_dist - horizon;
122 const double free_fall_vel = -std::sqrt(2.0 * std::abs(-10.0) * std::max(1e-30, free_fall_dist));
124 {1}, {},
"", {},
"", {},
125 {},
false,
"Constant_Velocity", {0.0, free_fall_vel, 0.0});
127 auto pDeckJson =
json({});
129 std::vector<geom::GeomData> pGeomVec(2);
130 pGeomVec[0].d_geomName = geomName;
131 pGeomVec[0].d_geomParams = gp_ref;
132 pGeomVec[1].d_geomName = geomName;
133 pGeomVec[1].d_geomParams = gp_ref;
137 const std::string f1 = mesh_file_1.string();
138 const std::string f2 = mesh_file_2.string();
139 auto meshSet1 =
json({{
"File", f1},
142 {
"Info",
"gmsh_builtin_mesh"},
143 {
"Mesh_Size", mesh_size},
144 {
"Write_Mesh_File",
true}}}});
145 auto meshSet2 =
json({{
"File", f2},
148 {
"Info",
"gmsh_builtin_mesh"},
149 {
"Mesh_Size", mesh_size},
150 {
"Write_Mesh_File",
true}}}});
151 pDeckJson[
"Mesh"] =
json({{
"Sets", 2}, {
"Set_1", meshSet1}, {
"Set_2", meshSet2}});
155 0, rho1, K1, G1, Gc1,
true, 1);
157 0, rho2, K2, G2, Gc2,
true, 1);
158 pDeckJson[
"Material"] = pMatJson;
163 Kn_11, beta_n_eps, friction_coeff, 1.0, beta_n_factor, 1.0, 0.0, 0.0);
165 pContactJson[
"Set_1_1"] = contact_base;
166 pContactJson[
"Set_1_1"][
"Kn"] = Kn_11;
167 pContactJson[
"Set_1_2"] = contact_base;
168 pContactJson[
"Set_1_2"][
"Kn"] = Kn_12;
169 pContactJson[
"Set_2_2"] = contact_base;
170 pContactJson[
"Set_2_2"][
"Kn"] = Kn_22;
171 pDeckJson[
"Contact"] = pContactJson;
176 pGenJson[
"Data"][
"N"] = 2;
183 if (model_dim == 2) {
184 pGenJson[
"Data"][
"0"] = {
185 {
"x", s}, {
"y", s}, {
"z", 0.0},
186 {
"theta", 0.0}, {
"s", 1.0},
187 {
"ax", 0.0}, {
"ay", 0.0}, {
"az", 1.0},
188 {
"geom_id", 0}, {
"mat_id", 0}, {
"contact_id", 0}
190 pGenJson[
"Data"][
"1"] = {
191 {
"x", s}, {
"y", 2.0 * s + particle_dist + s}, {
"z", 0.0},
192 {
"theta", M_PI}, {
"s", 1.0},
193 {
"ax", 0.0}, {
"ay", 0.0}, {
"az", 1.0},
194 {
"geom_id", 1}, {
"mat_id", 1}, {
"contact_id", 1}
197 pGenJson[
"Data"][
"0"] = {
198 {
"x", s}, {
"y", s}, {
"z", s},
199 {
"theta", 0.0}, {
"s", 1.0},
200 {
"ax", 0.0}, {
"ay", 0.0}, {
"az", 1.0},
201 {
"geom_id", 0}, {
"mat_id", 0}, {
"contact_id", 0}
203 pGenJson[
"Data"][
"1"] = {
204 {
"x", s}, {
"y", 2.0 * s + particle_dist + s}, {
"z", s},
205 {
"theta", M_PI}, {
"s", 1.0},
206 {
"ax", 0.0}, {
"ay", 0.0}, {
"az", 1.0},
207 {
"geom_id", 1}, {
"mat_id", 1}, {
"contact_id", 1}
210 pDeckJson[
"Particle_Generation"] = pGenJson;
212 return json({{
"Model", modelDeckJson},
213 {
"Output", outputDeckJson},
214 {
"Force_BC", bcDeckJson[
"Force_BC"]},
215 {
"Displacement_BC", bcDeckJson[
"Displacement_BC"]},
216 {
"IC", bcDeckJson[
"IC"]},
217 {
"Particle", pDeckJson[
"Particle"]},
218 {
"Mesh", pDeckJson[
"Mesh"]},
219 {
"Material", pDeckJson[
"Material"]},
220 {
"Contact", pDeckJson[
"Contact"]},
221 {
"Neighbor", pDeckJson[
"Neighbor"]},
222 {
"Particle_Generation", pDeckJson[
"Particle_Generation"]}});
227int main(
int argc,
char *argv[]) {
231 util::io::print(std::format(
"Initialized MPI. MPI size = {}, MPI rank = {}\n", mpiSize, mpiRank));
236 unsigned int nThreads;
240 nThreads = std::thread::hardware_concurrency();
241 util::io::print(std::format(
"Running test with default number of threads = {}\n", nThreads));
246 namespace fs = std::filesystem;
247 const fs::path cwd = fs::current_path();
249 fs::path run_base = cwd;
252 run_base = p.is_absolute() ? std::move(p) : cwd / p;
255 fs::path inp_base = run_base;
258 inp_base = p.is_absolute() ? std::move(p) : cwd / p;
261 std::vector<std::string> geometriesToRun;
264 util::io::print(
"twop_general_inbuilt: -allGeometries — running full geometry list.\n");
268 throw std::runtime_error(
269 "twop_general_inbuilt: -geometry \"" + g +
270 "\" is not in geom::acceptable_geometries.");
271 geometriesToRun = {g};
272 util::io::print(std::format(
"twop_general_inbuilt: single geometry = {}.\n", g));
274 geometriesToRun = {
"circle"};
275 util::io::print(
"twop_general_inbuilt: default geometry = circle (use -geometry <name> or -allGeometries).\n");
278 for (
const std::string &geomName : geometriesToRun) {
279 util::io::print(std::format(
"--- twop_general_inbuilt: geometry = {} ---\n", geomName));
281 const fs::path out_dir = run_base / geomName /
"out";
282 const fs::path inp_dir = inp_base / geomName /
"inp";
283 fs::create_directories(out_dir);
284 fs::create_directories(inp_dir);
286 const std::string output_path_for_deck = directoryPathWithTrailingSep(out_dir);
288 const fs::path mesh1 = inp_dir / (std::string(
"mesh_gen_1_") + geomName +
".msh");
289 const fs::path mesh2 = inp_dir / (std::string(
"mesh_gen_2_") + geomName +
".msh");
291 auto inputJson =
buildInputJson(geomName, output_path_for_deck, mesh1, mesh2);
293 const fs::path input_json_path = inp_dir / (std::string(
"input_") + geomName +
".json");
295 std::ofstream os(input_json_path);
297 throw std::runtime_error(
"Failed to open " + input_json_path.string() +
" for writing.");
298 os << inputJson.dump(2);
300 util::io::print(std::format(
"Output directory (VTU, log.txt): {}\n", fs::absolute(out_dir).
string()));
301 util::io::print(std::format(
"Input directory (input.json, meshes): {}\n", fs::absolute(inp_dir).
string()));
302 util::io::print(std::format(
"Wrote deck to {}\n", fs::absolute(input_json_path).
string()));
304 auto deck = std::make_shared<inp::Input>(inputJson);
void run(std::shared_ptr< inp::Input > &deck)
nlohmann::ordered_json json
std::string directoryPathWithTrailingSep(const std::filesystem::path &dir)
bool is3DGeometry(const std::string &g)
json buildInputJson(const std::string &geomName, const std::string &output_path_for_deck, const std::filesystem::path &mesh_file_1, const std::filesystem::path &mesh_file_2)
bool isAcceptableGeometryName(const std::string &g)
const std::vector< std::string > & getAcceptableGeometries()
Returns list of acceptable geometries for PeriDEM simulation.
std::vector< double > exampleGeomParams(const std::string &geom_type, const util::Point &c, double s)
Canonical parameter vector for examples, mesh generation tests, and demos.
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.
void print(const T &msg, int nt=print_default_tab, int printMpiRank=print_default_mpi_rank)
Prints formatted information.
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
double harmonicMean(const double &m1, const double &m2)
Input data for geometrical objects.
static json getExampleJson(std::string type="Foce_BC", bool isRegionActive=false, geom::GeomData regionGeomData=geom::GeomData(), std::vector< size_t > pList=std::vector< size_t >(), std::vector< size_t > pNotList=std::vector< size_t >(), std::string timeFnType="", std::vector< double > timeFnParams=std::vector< double >(), std::string spatialFnType="", std::vector< double > spatialFnParams=std::vector< double >(), std::vector< size_t > direction=std::vector< size_t >(), bool isDisplacementZero=false, std::string icType="", std::vector< double > icVec=std::vector< double >())
Returns example JSON object for ModelDeck configuration.
static json getExampleJson(size_t nForceSets=0, size_t nDispSets=0, size_t nICSets=0, bool gravityActive=false, util::Point gravity=util::Point())
Returns example JSON object for ModelDeck configuration.
static json getExampleJson(std::string materialType="PDState", bool isPlainStrain=false, double horizon=-1., double horizonMeshRatio=-1., double density=1., double K=0., double G=0., double Gc=0., bool computeParamsFromElastic=true, size_t influenceFnType=0, double E=-1.)
Returns example JSON object for ModelDeck configuration.
static json getExampleJson(size_t dim=2, double tFinal=1.0, size_t Nt=10, std::string spatialDiscretization="finite_difference", std::string timeDiscretization="central_difference", bool populateElementNodeConnectivity=true, size_t quadOrder=2, std::string particleSimType="Multi_Particle", int seed=0)
Returns example JSON object for ModelDeck configuration.
static json getExampleJson(std::string outFormat="vtu", std::string path="./", std::vector< std::string > outTags={"Displacement"}, size_t outputInterval=1, size_t debug=2, bool performFEOut=true, std::string compressType="zlib", bool performOut=true, size_t dtTestOut=1, std::string tagPPFile="", bool pvdCollection=false)
Returns example JSON object for ModelDeck configuration.
static json getExampleJson(std::string genMethod="From_File")
Returns example JSON object for ModelDeck configuration.
static json getExampleJson(std::string updateCriteria="simple_all", double sFactor=1., size_t neighUpdateInterval=1, double nearBdNodesTol=0.5)
Returns example JSON object for ModelDeck configuration.
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.