16#include <polysolve/nonlinear/Solver.hpp>
18#include <spdlog/sinks/stdout_color_sinks.h>
19#include <spdlog/sinks/basic_file_sink.h>
20#include <spdlog/sinks/ostream_sink.h>
31 spdlog::level::level_enum,
32 {{spdlog::level::level_enum::trace,
"trace"},
33 {spdlog::level::level_enum::debug,
"debug"},
34 {spdlog::level::level_enum::info,
"info"},
35 {spdlog::level::level_enum::warn,
"warning"},
36 {spdlog::level::level_enum::err,
"error"},
37 {spdlog::level::level_enum::critical,
"critical"},
38 {spdlog::level::level_enum::off,
"off"},
39 {spdlog::level::level_enum::trace, 0},
40 {spdlog::level::level_enum::debug, 1},
41 {spdlog::level::level_enum::info, 2},
42 {spdlog::level::level_enum::warn, 3},
43 {spdlog::level::level_enum::err, 3},
44 {spdlog::level::level_enum::critical, 4},
45 {spdlog::level::level_enum::off, 5}})
60 const std::string &log_file,
61 const spdlog::level::level_enum log_level,
62 const spdlog::level::level_enum file_log_level,
65 std::vector<spdlog::sink_ptr> sinks;
69 console_sink_ = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
73 if (!log_file.empty())
75 file_sink_ = std::make_shared<spdlog::sinks::basic_file_sink_mt>(log_file,
true);
82 spdlog::flush_every(std::chrono::seconds(3));
87 std::vector<spdlog::sink_ptr> sinks;
88 sinks.emplace_back(std::make_shared<spdlog::sinks::ostream_sink_mt>(os,
false));
93 const std::vector<spdlog::sink_ptr> &sinks,
94 const spdlog::level::level_enum log_level)
96 set_adjoint_logger(std::make_shared<spdlog::logger>(
"adjoint-polyfem", sinks.begin(), sinks.end()));
112 json args_in = p_args_in;
117 if (!output_dir.empty())
119 std::filesystem::create_directories(
output_dir);
123 std::string out_path_log = this->
args[
"output"][
"log"][
"path"];
124 if (!out_path_log.empty())
131 this->
args[
"output"][
"log"][
"level"],
132 this->
args[
"output"][
"log"][
"file_level"],
133 this->
args[
"output"][
"log"][
"quiet"]);
137 const int thread_in = this->
args[
"solver"][
"max_threads"];
146 max_threads <= 0 ? std::numeric_limits<unsigned int>::max() : max_threads);
151 diff_cache = std::make_shared<DiffCache>();
161 for (
int i = 0; i <
states.size(); ++i)
169 "State {}: transient linear problem is not supported in optimization.", i);
175 if (!state.
args[
"contact"][
"use_gcp_formulation"].get<
bool>()
176 && !state.
args[
"contact"][
"use_convergent_formulation"].get<
bool>())
179 "State {}: non-convergent contact formulation is not supported in optimization.", i);
183 if (state.
args[
"/solver/contact/barrier_stiffness"_json_pointer].is_string())
186 "State {}: only constant barrier stiffness is supported in optimization.", i);
191 if (state.
args.contains(
"boundary_conditions") && state.
args[
"boundary_conditions"].contains(
"rhs"))
193 const json &rhs = state.
args[
"boundary_conditions"][
"rhs"];
194 if (rhs.is_string() || (rhs.is_array() && rhs.size() > 0 && rhs[0].is_string()))
197 "State {}: only constant rhs over space is supported in optimization.", i);
202 for (
const auto &element_bases : state.
geom_bases())
204 for (
const auto &basis : element_bases.bases)
206 if (basis.order() > 1)
209 "State {}: high-order geometry basis is not supported in optimization.", i);
220 for (
const auto &arg :
args[
"parameters"])
239 std::vector<std::shared_ptr<solver::AdjointForm>> stopping_conditions;
240 for (
const auto &arg :
args[
"stopping_conditions"])
241 stopping_conditions.push_back(
244 nl_problem = std::make_unique<solver::AdjointNLProblem>(
264 args[
"solver"][
"nonlinear"],
265 args[
"solver"][
"linear"],
266 args[
"solver"][
"advanced"][
"characteristic_length"]);
std::vector< std::shared_ptr< State > > states
State used in the opt.
void solve(Eigen::VectorXd &x)
void initial_guess(Eigen::VectorXd &x)
void set_log_level(const spdlog::level::level_enum log_level)
change log level
void create_states(const int max_threads=-1)
create the opt states
json args
main input arguments containing all defaults
void init(const json &args, const bool strict_validation)
initialize the polyfem solver with a json settings
std::vector< std::shared_ptr< DiffCache > > diff_caches
spdlog::sink_ptr file_sink_
std::string root_path() const
void check_unsupported() const
Check and throw if any forward simulation State is not supported.
double eval(Eigen::VectorXd &x) const
std::vector< int > variable_sizes
variables
std::unique_ptr< solver::AdjointNLProblem > nl_problem
std::string output_dir
Directory for output files.
spdlog::sink_ptr console_sink_
logger sink to stdout
void init_logger(const std::string &log_file, const spdlog::level::level_enum log_level, const spdlog::level::level_enum file_log_level, const bool is_quiet)
initializing the logger
solver::VariableToSimulationGroup variable_to_simulations
void init_variables()
init variables
main class that contains the polyfem solver and all its state
const std::vector< basis::ElementBases > & geom_bases() const
Get a constant reference to the geometry mapping bases.
std::shared_ptr< assembler::Problem > problem
current problem, it contains rhs and bc
json args
main input arguments containing all defaults
bool is_contact_enabled() const
does the simulation have contact
bool is_problem_linear() const
Returns whether the system is linear. Collisions and pressure add nonlinearity to the problem.
void update(const Eigen::VectorXd &x)
Update parameters in simulators.
void set_logger(spdlog::logger &logger)
static GeogramUtils & instance()
void set_num_threads(const int max_threads)
std::vector< std::shared_ptr< State > > build_states(const std::string &root_path, const json &args, const size_t max_threads)
solver::VariableToSimulationGroup build_variable_to_simulation_group(const json &args, const std::vector< std::shared_ptr< State > > &states, const std::vector< std::shared_ptr< DiffCache > > &diff_caches, const std::vector< int > &variable_sizes)
std::shared_ptr< solver::AdjointForm > build_form(const json &args, const solver::VariableToSimulationGroup &var2sim, const std::vector< std::shared_ptr< State > > &states, const std::vector< std::shared_ptr< DiffCache > > &diff_caches)
NLOHMANN_JSON_SERIALIZE_ENUM(CollisionProxyTessellation, {{CollisionProxyTessellation::REGULAR, "regular"}, {CollisionProxyTessellation::IRREGULAR, "irregular"}})
std::string resolve_path(const std::string &path, const std::string &input_file_path, const bool only_if_exists=false)
spdlog::logger & adjoint_logger()
Retrieves the current logger for adjoint.
void set_adjoint_logger(std::shared_ptr< spdlog::logger > p_logger)
Setup a logger object to be used by adjoint Polyfem.
void log_and_throw_adjoint_error(const std::string &msg)
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)
static int compute_variable_size(const json &args, const std::vector< std::shared_ptr< State > > &states)