29#include <polysolve/nonlinear/BoxConstraintSolver.hpp>
32#include <polyfem/embedded_spec/polyfem_opt.hpp>
33#include <polyfem/embedded_spec/polyfem_objective.hpp>
48 spdlog::level::level_enum,
49 {{spdlog::level::level_enum::trace,
"trace"},
50 {spdlog::level::level_enum::debug,
"debug"},
51 {spdlog::level::level_enum::info,
"info"},
52 {spdlog::level::level_enum::warn,
"warning"},
53 {spdlog::level::level_enum::err,
"error"},
54 {spdlog::level::level_enum::critical,
"critical"},
55 {spdlog::level::level_enum::off,
"off"},
56 {spdlog::level::level_enum::trace, 0},
57 {spdlog::level::level_enum::debug, 1},
58 {spdlog::level::level_enum::info, 2},
59 {spdlog::level::level_enum::warn, 3},
60 {spdlog::level::level_enum::err, 3},
61 {spdlog::level::level_enum::critical, 4},
62 {spdlog::level::level_enum::off, 5}})
70 auto names = polysolve::nonlinear::Solver::available_solvers();
71 if (std::find(names.begin(), names.end(), solver_params[
"solver"]) != names.end())
72 return polysolve::nonlinear::Solver::create(solver_params, linear_solver_params, characteristic_length,
adjoint_logger());
74 names = polysolve::nonlinear::BoxConstraintSolver::available_solvers();
75 if (std::find(names.begin(), names.end(), solver_params[
"solver"]) != names.end())
76 return polysolve::nonlinear::BoxConstraintSolver::create(solver_params, linear_solver_params, characteristic_length,
adjoint_logger());
84 if (args.is_string() && args.get<std::string>() ==
"auto")
86 Eigen::VectorXd
x = var2sim.
data[0]->inverse_eval();
101 for (
const auto &arg : args)
103 const auto &arg_initial = arg[
"initial"];
104 Eigen::VectorXd tmp(variable_sizes[var]);
105 if (arg_initial.is_array() && arg_initial.size() > 0)
108 x.segment(accumulative, tmp.size()) = tmp;
110 else if (arg_initial.is_number())
112 tmp.setConstant(arg_initial.get<
double>());
113 x.segment(accumulative, tmp.size()) = tmp;
120 if (var2sim.
data.size() != 1)
122 logger().warn(
"Computing initial guess via inverse eval with multiple"
123 " variable to simulation. You should make sure var2sim maps one"
124 " to one to optimization parameter blocks in perfect order.");
126 x += var2sim.
data[var]->inverse_eval();
129 accumulative += tmp.size();
140 Eigen::MatrixXd sol, pressure;
148 for (
auto &arg : args)
151 else if (args.is_object())
154 const bool valid_input = jse.verify_json(args, rules);
158 logger().error(
"invalid objective json:\n{}", jse.log2str());
159 throw std::runtime_error(
"Invalid objective json file");
162 args = jse.inject_defaults(args, rules);
164 for (
auto &it : args.items())
166 if (it.key().find(
"objective") != std::string::npos)
174 json args_in = input_args;
180 jse.strict = strict_validation;
181 rules = jse::embed::polyfem_opt_spec::polyfem_opt::spec();
183 polysolve::linear::Solver::apply_default_solver(rules,
"/solver/linear");
186 if (args_in.contains(
"/solver/linear"_json_pointer))
187 polysolve::linear::Solver::select_valid_solver(args_in[
"solver"][
"linear"],
logger());
189 const bool valid_input = jse.verify_json(args_in, rules);
193 logger().error(
"invalid input json:\n{}", jse.log2str());
194 throw std::runtime_error(
"Invalid input json file");
197 json args = jse.inject_defaults(args_in, rules);
199 const json obj_rules = jse::embed::polyfem_objective_spec::polyfem_objective::spec();
209 if (args[
"number"].is_number())
211 return args[
"number"].get<
int>();
213 else if (args[
"number"].is_null() && args[
"initial"].size() > 0)
215 return args[
"initial"].size();
217 else if (args[
"number"].is_object())
219 auto selection = args[
"number"];
220 if (selection.contains(
"surface_selection"))
222 auto surface_selection = selection[
"surface_selection"].get<std::vector<int>>();
223 auto state_id = selection[
"state"];
224 std::set<int> node_ids = {};
225 for (
const auto &surface : surface_selection)
227 std::vector<int> ids;
229 for (
const auto &i : ids)
232 return node_ids.size() * states[state_id]->mesh->dimension();
234 else if (selection.contains(
"volume_selection"))
236 auto volume_selection = selection[
"volume_selection"].get<std::vector<int>>();
237 auto state_id = selection[
"state"];
238 std::set<int> node_ids = {};
239 for (
const auto &volume : volume_selection)
241 std::vector<int> ids;
243 for (
const auto &i : ids)
247 if (selection[
"exclude_boundary_nodes"])
249 std::vector<int> ids;
251 for (
const auto &i : ids)
255 return node_ids.size() * states[state_id]->mesh->dimension();
main class that contains the polyfem solver and all its state
void assemble_mass_mat()
assemble mass, step 4 of solve build mass matrix based on defined basis modifies mass (and maybe more...
void assemble_rhs()
compute rhs, step 3 of solve build rhs vector based on defined basis and given rhs of the problem mod...
void solve_problem(Eigen::MatrixXd &sol, Eigen::MatrixXd &pressure, UserPostStepCallback user_post_step={}, const InitialConditionOverride *ic_override=nullptr)
solves the problems
std::vector< std::shared_ptr< VariableToSimulation > > data
NLOHMANN_JSON_SERIALIZE_ENUM(CollisionProxyTessellation, {{CollisionProxyTessellation::REGULAR, "regular"}, {CollisionProxyTessellation::IRREGULAR, "irregular"}})
void apply_objective_json_spec(json &args, const json &rules)
spdlog::logger & logger()
Retrieves the current logger.
void compute_surface_node_ids(const legacy::State &state, const int surface_selection, std::vector< int > &node_ids)
void compute_volume_node_ids(const legacy::State &state, const int volume_selection, std::vector< int > &node_ids)
spdlog::logger & adjoint_logger()
Retrieves the current logger for adjoint.
void compute_total_surface_node_ids(const legacy::State &state, std::vector< int > &node_ids)
void log_and_throw_adjoint_error(const std::string &msg)
static void solve_pde(legacy::State &state)
static int compute_variable_size(const json &args, const std::vector< std::shared_ptr< legacy::State > > &states)
static std::shared_ptr< polysolve::nonlinear::Solver > make_nl_solver(const json &solver_params, const json &linear_solver_params, const double characteristic_length)
static json apply_opt_json_spec(const json &input_args, bool strict_validation)
static Eigen::VectorXd inverse_evaluation(const json &args, const int ndof, const std::vector< int > &variable_sizes, VariableToSimulationGroup &var2sim)