94int main(
int argc,
char **argv)
98 CLI::App command_line{
"polyfem"};
100 command_line.ignore_case();
101 command_line.ignore_underscore();
104 unsigned max_threads = std::numeric_limits<unsigned>::max();
105 command_line.add_option(
"--max_threads", max_threads,
"Maximum number of threads");
107 auto input = command_line.add_option_group(
"input");
109 std::string json_file =
"";
110 input->add_option(
"-j,--json", json_file,
"Simulation JSON file")->check(CLI::ExistingFile);
112 std::string yaml_file =
"";
113 input->add_option(
"-y,--yaml", yaml_file,
"Simulation YAML file")->check(CLI::ExistingFile);
115 std::string hdf5_file =
"";
116 input->add_option(
"--hdf5", hdf5_file,
"Simulation HDF5 file")->check(CLI::ExistingFile);
118 std::string checkpoint_file =
"";
119 auto *checkpoint_option = input->add_option(
"--checkpoint", checkpoint_file,
"Versioned PolyFEM checkpoint")->check(CLI::ExistingFile);
120 bool checkpoint_reorder =
false;
121 command_line.add_flag(
122 "--checkpoint-reorder", checkpoint_reorder,
123 "Reorder checkpoint state from its saved input-node ordering")
124 ->needs(checkpoint_option);
126 input->require_option(1);
128 std::string output_dir =
"";
129 command_line.add_option(
"-o,--output_dir", output_dir,
"Directory for output files")->check(CLI::ExistingDirectory | CLI::NonexistentPath);
131 bool is_strict =
true;
132 command_line.add_flag(
"-s,--strict_validation,!--ns,!--no_strict_validation", is_strict,
"Disables strict validation of input JSON");
134 bool fallback_solver =
false;
135 command_line.add_flag(
"--enable_overwrite_solver", fallback_solver,
"If solver in input is not present, falls back to default.");
137 const std::vector<std::pair<std::string, spdlog::level::level_enum>>
138 SPDLOG_LEVEL_NAMES_TO_LEVELS = {
139 {
"trace", spdlog::level::trace},
140 {
"debug", spdlog::level::debug},
141 {
"info", spdlog::level::info},
142 {
"warning", spdlog::level::warn},
143 {
"error", spdlog::level::err},
144 {
"critical", spdlog::level::critical},
145 {
"off", spdlog::level::off}};
146 spdlog::level::level_enum log_level = spdlog::level::debug;
147 command_line.add_option(
"--log_level", log_level,
"Log level")
148 ->transform(CLI::CheckedTransformer(SPDLOG_LEVEL_NAMES_TO_LEVELS, CLI::ignore_case));
150 CLI11_PARSE(command_line, argc, argv);
153 if (!json_file.empty() || !yaml_file.empty())
160 if (in_args.contains(
"states"))
162#ifndef POLYFEM_WITH_OPTIMIZATION
165 return optimization_simulation(command_line, *loaded.
resources, max_threads, is_strict, log_level, in_args);
170 is_strict, fallback_solver, log_level, in_args);
172 else if (!hdf5_file.empty())
177 is_strict, fallback_solver, log_level, in_args);
182 in_args = checkpoint.
config();
184 is_strict, fallback_solver, log_level, in_args);
190 const std::string &output_dir,
191 const unsigned max_threads,
192 const bool is_strict,
193 const bool fallback_solver,
194 const spdlog::level::level_enum &log_level,
199 logger().error(
"No input file specified!");
200 return command_line.exit(CLI::RequiredError(
"--json or --hdf5"));
203 json tmp = json::object();
204 if (
has_arg(command_line,
"log_level"))
205 tmp[
"/output/log/level"_json_pointer] = int(log_level);
206 if (
has_arg(command_line,
"max_threads"))
207 tmp[
"/solver/max_threads"_json_pointer] = max_threads;
208 if (
has_arg(command_line,
"output_dir"))
209 tmp[
"/output/directory"_json_pointer] = std::filesystem::absolute(output_dir);
210 if (
has_arg(command_line,
"enable_overwrite_solver"))
211 tmp[
"/solver/linear/enable_overwrite_solver"_json_pointer] = fallback_solver;
212 assert(tmp.is_object());
213 in_args.merge_patch(tmp);
215 const std::string checkpoint_path =
216 in_args.contains(
"/input/checkpoint/path"_json_pointer)
217 ? in_args[
"/input/checkpoint/path"_json_pointer].get<std::string>()
219 if (!checkpoint_path.empty())
221 const std::filesystem::path path = std::filesystem::path(checkpoint_path).is_absolute()
222 ? std::filesystem::path(checkpoint_path)
226 continuation[
"input"][
"checkpoint"][
"path"] =
"";
227 continuation[
"input"][
"checkpoint"][
"reorder"] =
228 in_args.contains(
"/input/checkpoint/reorder"_json_pointer)
229 ? in_args[
"/input/checkpoint/reorder"_json_pointer].get<
bool>()
232 command_line, checkpoint, output_dir, max_threads,
233 is_strict, fallback_solver, log_level, continuation);
241 const std::string &output_dir,
242 const unsigned max_threads,
243 const bool is_strict,
244 const bool fallback_solver,
245 const spdlog::level::level_enum &log_level,
248 json tmp = json::object();
249 if (
has_arg(command_line,
"log_level"))
250 tmp[
"/output/log/level"_json_pointer] = int(log_level);
251 if (
has_arg(command_line,
"max_threads"))
252 tmp[
"/solver/max_threads"_json_pointer] = max_threads;
253 if (
has_arg(command_line,
"output_dir"))
254 tmp[
"/output/directory"_json_pointer] = std::filesystem::absolute(output_dir);
255 if (
has_arg(command_line,
"enable_overwrite_solver"))
256 tmp[
"/solver/linear/enable_overwrite_solver"_json_pointer] = fallback_solver;
257 if (
has_arg(command_line,
"checkpoint-reorder"))
258 tmp[
"/input/checkpoint/reorder"_json_pointer] =
true;
259 in_args.merge_patch(tmp);
int run_forward_simulation(State &state)
int main(int argc, char **argv)
int forward_simulation_with_varform_state(const io::ResourceIO &resources, json &in_args, const bool is_strict)
int forward_simulation(const CLI::App &command_line, const io::ResourceIO &resources, const std::string &output_dir, const unsigned max_threads, const bool is_strict, const bool fallback_solver, const spdlog::level::level_enum &log_level, json &in_args)
bool has_arg(const CLI::App &command_line, const std::string &value)