227 {
228
231 util::io::print(std::format(
"Initialized MPI. MPI size = {}, MPI rank = {}\n", mpiSize, mpiRank));
233
235
236 unsigned int nThreads;
237 if (input.cmdOptionExists("-nThreads"))
238 nThreads = std::stoi(input.getCmdOption("-nThreads"));
239 else {
240 nThreads = std::thread::hardware_concurrency();
241 util::io::print(std::format(
"Running test with default number of threads = {}\n", nThreads));
242 }
245
246 namespace fs = std::filesystem;
247 const fs::path cwd = fs::current_path();
248
249 fs::path run_base = cwd;
250 if (input.cmdOptionExists("-outputDir")) {
251 fs::path p = input.getCmdOption("-outputDir");
252 run_base = p.is_absolute() ? std::move(p) : cwd / p;
253 }
254
255 fs::path inp_base = run_base;
256 if (input.cmdOptionExists("-inputDir")) {
257 fs::path p = input.getCmdOption("-inputDir");
258 inp_base = p.is_absolute() ? std::move(p) : cwd / p;
259 }
260
261 std::vector<std::string> geometriesToRun;
262 if (input.cmdOptionExists("-allGeometries")) {
264 util::io::print(
"twop_general_inbuilt: -allGeometries — running full geometry list.\n");
265 } else if (input.cmdOptionExists("-geometry")) {
266 const std::string g = input.getCmdOption("-geometry");
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));
273 } else {
274 geometriesToRun = {"circle"};
275 util::io::print(
"twop_general_inbuilt: default geometry = circle (use -geometry <name> or -allGeometries).\n");
276 }
277
278 for (const std::string &geomName : geometriesToRun) {
279 util::io::print(std::format(
"--- twop_general_inbuilt: geometry = {} ---\n", geomName));
280
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);
285
287
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");
290
291 auto inputJson =
buildInputJson(geomName, output_path_for_deck, mesh1, mesh2);
292
293 const fs::path input_json_path = inp_dir / (std::string("input_") + geomName + ".json");
294 {
295 std::ofstream os(input_json_path);
296 if (!os)
297 throw std::runtime_error("Failed to open " + input_json_path.string() + " for writing.");
298 os << inputJson.dump(2);
299 }
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()));
303
304 auto deck = std::make_shared<inp::Input>(inputJson);
305
307 dem.run(deck);
308 }
309
310 return EXIT_SUCCESS;
311}
std::string directoryPathWithTrailingSep(const std::filesystem::path &dir)
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::string printStr(const T &msg, int nt=print_default_tab)
Returns formatted string for output.
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