15#include <polysolve/linear/Solver.hpp>
16#include <polysolve/nonlinear/Solver.hpp>
21 Eigen::MatrixXd &solution,
24 const bool differentiable)
37 if (
args[
"geometry"].size() != 1)
44 updated_args[
"geometry"][0][
"mesh"] = std::filesystem::absolute(path).string();
45 updated_args[
"geometry"][0][
"unit"] =
"";
46 updated_args[
"geometry"][0][
"n_refs"] = 0;
47 updated_args[
"geometry"][0][
"advanced"][
"normalize_mesh"] =
false;
48 updated_args[
"geometry"][0][
"transformation"] = {
49 {
"dimensions",
nullptr}, {
"scale", 1}, {
"rotation",
nullptr}, {
"rotation_mode",
"xyz"}, {
"translation", json::array()}};
64 const std::string &path,
65 const Eigen::MatrixXd &solution,
67 const double dt)
const
81 assert(
mesh_ &&
"The mesh must be loaded before it is accessed");
87 assert(
problem &&
"The problem must be initialized before it is accessed");
93 assert(
problem &&
"The problem must be initialized before it is accessed");
110 assert(
primary_assembler_ &&
"The primary assembler must be initialized before it is accessed");
116 assert(
mass_assembler_ &&
"The mass assembler must be initialized before it is accessed");
139 Eigen::MatrixXd &solution,
146 Eigen::MatrixXd &velocity,
153 Eigen::MatrixXd &acceleration,
168 assert(
mesh_ &&
"Vertex positions can only be updated after loading a mesh");
200 const int discr_order,
201 const int discr_orderq,
202 const int geometry_discr_order)
const
212 Eigen::MatrixXd &solution,
236 args[
"solver"][
"advanced"][
"conservative_max_iter"],
241 args.value(
"/time/quasistatic"_json_pointer,
true),
mass_,
243 args[
"solver"][
"advanced"][
"lagged_regularization_weight"],
244 args[
"solver"][
"advanced"][
"lagged_regularization_iterations"],
246 args[
"contact"][
"enabled"],
248 args[
"contact"][
"dhat"],
249 avg_mass_,
args[
"contact"][
"use_convergent_formulation"] ? bool(
args[
"contact"][
"use_area_weighting"]) :
false,
250 args[
"contact"][
"use_convergent_formulation"] ? bool(
args[
"contact"][
"use_improved_max_operator"]) :
false,
251 args[
"contact"][
"use_convergent_formulation"] ? bool(
args[
"contact"][
"use_physical_barrier"]) :
false,
252 args[
"contact"][
"collision_set_type"].get<std::string>(),
253 args[
"contact"][
"skip_obstacles"].get<bool>(),
254 args[
"contact"][
"barrier"].get<std::string>(),
255 args[
"solver"][
"contact"][
"barrier_stiffness"],
256 args[
"solver"][
"contact"][
"initial_barrier_stiffness"],
257 args[
"solver"][
"contact"][
"dhat_epsilon_scale"],
258 args[
"solver"][
"contact"][
"CCD"][
"broad_phase"],
259 args[
"solver"][
"contact"][
"CCD"][
"tolerance"],
260 args[
"solver"][
"contact"][
"CCD"][
"max_iterations"],
262 args[
"contact"][
"use_gcp_formulation"],
263 args[
"contact"][
"alpha_t"],
264 args[
"contact"][
"alpha_n"],
265 args[
"contact"][
"use_adaptive_dhat"],
266 args[
"contact"][
"min_distance_ratio"],
267 args[
"contact"][
"use_esp_formulation"],
268 args[
"contact"][
"esp_params"],
269 args[
"contact"][
"adhesion"][
"adhesion_enabled"],
270 args[
"contact"][
"adhesion"][
"dhat_p"],
271 args[
"contact"][
"adhesion"][
"dhat_a"],
272 args[
"contact"][
"adhesion"][
"adhesion_strength"],
273 args[
"contact"][
"adhesion"][
"tangential_adhesion_coefficient"],
274 args[
"contact"][
"adhesion"][
"epsa"],
275 args[
"solver"][
"contact"][
"tangential_adhesion_iterations"],
278 args[
"contact"][
"friction_coefficient"],
279 args[
"contact"][
"epsv"],
280 args[
"solver"][
"contact"][
"friction_iterations"],
281 args[
"solver"][
"rayleigh_damping"],
282 args[
"solver"][
"augmented_lagrangian"][
"lumping"],
284 args[
"boundary_conditions"][
"periodic"], -1);
286 for (
const auto &form :
forms)
298 Eigen::MatrixXd &solution,
299 const bool init_lagging)
307 assert(
solve_data_.
nl_problem !=
nullptr &&
"Nonlinear forms must initialize the nonlinear problem before solving");
309 assert(solution.size() ==
rhs_.size());
318 logger().info(
"Lagging iteration 1:");
323 std::shared_ptr<polysolve::nonlinear::Solver> nl_solver =
324 polysolve::nonlinear::Solver::create(
325 args[
"solver"][
"augmented_lagrangian"][
"nonlinear"],
330 args[
"solver"][
"augmented_lagrangian"][
"initial_weight"],
331 args[
"solver"][
"augmented_lagrangian"][
"scaling"],
332 args[
"solver"][
"augmented_lagrangian"][
"max_weight"],
333 args[
"solver"][
"augmented_lagrangian"][
"eta"],
334 [&](
const Eigen::VectorXd &) {
335 solve_data_.update_barrier_stiffness(solution);
340 {{
"type", al_weight > 0 ?
"al" :
"rc"},
342 {
"info", nl_solver->info()}});
349 nl_problem, solution,
350 args[
"solver"][
"augmented_lagrangian"][
"nonlinear"],
354 nl_problem, solution,
355 args[
"solver"][
"nonlinear"],
358 if (
args[
"space"][
"advanced"][
"count_flipped_els_continuous"])
362 logger().debug(
"Flipped elements (cnt {}) : {}", invalid.size(), invalid);
367 Eigen::MatrixXd &solution,
372 (!initial_condition_override
373 || (initial_condition_override->
velocity.size() == 0
374 && initial_condition_override->
acceleration.size() == 0))
375 &&
"Static elasticity does not accept initial velocity or acceleration overrides");
386 if (initial_condition_override && initial_condition_override->
solution.size() != 0)
388 else if (solution.size() <= 0)
391 if (initial_condition_override && initial_condition_override->
solution.size() != 0)
392 assert(solution.cols() == 1 &&
"Static initial solution override must have exactly one column");
393 else if (solution.cols() != 1)
407 init_solve(solution, 1.0, initial_condition_override);
410 post_step(0, solution);
419 Eigen::MatrixXd &solution,
423 const bool save_stats =
args[
"output"][
"stats"];
433 if (initial_condition_override && initial_condition_override->
solution.size() != 0)
435 else if (solution.size() <= 0)
438 if (solution.cols() > 1)
439 solution.conservativeResize(Eigen::NoChange, 1);
444 post_step(0, solution);
447 std::unique_ptr<io::EnergyCSVWriter> energy_csv;
448 std::unique_ptr<io::RuntimeStatsCSVWriter> stats_csv;
453 "Saving nl stats to {} and {}",
457 stats_csv = std::make_unique<io::RuntimeStatsCSVWriter>(
465 energy_csv->write(save_i, solution);
471 double forward_solve_time = 0;
472 const double remeshing_time = 0;
473 const double global_relaxation_time = 0;
480 post_step(t, solution);
483 energy_csv->write(save_i, solution);
500 stats_csv->write(t, forward_solve_time, remeshing_time, global_relaxation_time);
#define POLYFEM_SCOPED_TIMER(...)
double characteristic_length() const
Caches basis evaluation and geometric mapping at every element.
void save_vtu(const std::string &path, const OutputSpace &space, const OutputFieldFunction &output_fields, const double t, const double dt, const ExportOptions &opts) const
saves the vtu file for time t
double solving_time
time to solve
json solver_info
information of the solver, eg num iteration, time, errors, etc the informations varies depending on t...
Eigen::Vector4d spectrum
spectrum of the stiffness matrix, enable only if POLYSOLVE_WITH_SPECTRA is ON (off by default)
virtual const std::filesystem::path & host_directory() const =0
Host directory used only as the base for ordinary filesystem outputs.
Applies geometry JSON semantics while delegating all decoding to MeshLoader.
std::unique_ptr< Mesh > load_fem(const json &geometry, bool non_conforming=false) const
Load and combine the enabled FEM entries in a geometry configuration.
Abstract mesh class to capture 2d/3d conforming and non-conforming meshes.
int n_elements() const
utitlity to return the number of elements, cells or faces in 3d and 2d
void solve_reduced(NLProblem &nl_problem, Eigen::MatrixXd &sol, std::shared_ptr< polysolve::nonlinear::Solver > nl_solver)
std::function< void(const double)> post_subsolve
void solve_al(NLProblem &nl_problem, Eigen::MatrixXd &sol, std::shared_ptr< polysolve::nonlinear::Solver > nl_solver)
bool uses_lagging() const
void init_lagging(const TVector &x) override
class to store time stepping data
void update_dt()
updates the dt inside the different forms
std::shared_ptr< solver::NLProblem > nl_problem
std::shared_ptr< solver::ContactForm > contact_form
std::vector< std::shared_ptr< solver::AugmentedLagrangianForm > > al_form
std::shared_ptr< time_integrator::ImplicitTimeIntegrator > time_integrator
void update_barrier_stiffness(const Eigen::VectorXd &x)
update the barrier stiffness for the forms
std::vector< std::shared_ptr< Form > > init_forms(const Units &units, const io::ResourceIO &resources, const int dim, const double t, const Eigen::VectorXi &in_node_to_node, const int n_bases, std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &geom_bases, const assembler::Assembler &assembler, assembler::AssemblyValsCache &ass_vals_cache, const assembler::AssemblyValsCache &mass_ass_vals_cache, const double jacobian_threshold, const solver::ElementInversionCheck check_inversion, const unsigned conservative_max_iter, const int n_pressure_bases, const std::vector< int > &boundary_nodes, const std::vector< mesh::LocalBoundary > &local_boundary, const std::vector< mesh::LocalBoundary > &local_neumann_boundary, const QuadratureOrders &n_boundary_samples, const Eigen::MatrixXd &rhs, const Eigen::MatrixXd &sol, const assembler::Density &density, const std::vector< mesh::LocalBoundary > &local_pressure_boundary, const std::unordered_map< int, std::vector< mesh::LocalBoundary > > &local_pressure_cavity, const std::shared_ptr< assembler::PressureAssembler > pressure_assembler, const bool ignore_inertia, const StiffnessMatrix &mass, const std::shared_ptr< assembler::ViscousDamping > damping_assembler, const double lagged_regularization_weight, const int lagged_regularization_iterations, const size_t obstacle_ndof, const std::vector< std::string > &hard_constraint_files, const std::vector< json > &soft_constraint_files, const json &zero_mean, const bool contact_enabled, const ipc::CollisionMesh &collision_mesh, const double dhat, const double avg_mass, const bool use_area_weighting, const bool use_improved_max_operator, const bool use_physical_barrier, const std::string &collision_set_type, const bool skip_obstacles, const std::string &barrier, const json &barrier_stiffness, const double initial_barrier_stiffness, const double dhat_epsilon_scale, const ipc::BroadPhaseMethod broad_phase, const double ccd_tolerance, const long ccd_max_iterations, const bool enable_shape_derivatives, const bool use_gcp_formulation, const double alpha_t, const double alpha_n, const bool use_adaptive_dhat, const double min_distance_ratio, const bool use_esp_formulation, json esp_params, const bool adhesion_enabled, const double dhat_p, const double dhat_a, const double Y, const double tangential_adhesion_coefficient, const double epsa, const int tangential_adhesion_iterations, const assembler::MacroStrainValue ¯o_strain_constraint, const bool periodic_contact, const Eigen::VectorXi &tiled_to_single, const double friction_coefficient, const double epsv, const int friction_iterations, const json &rayleigh_damping, const BCLumpingMode al_lumping=BCLumpingMode::ROW_SUM, const mesh::Mesh *periodic_mesh=nullptr, const std::vector< mesh::LocalBoundary > *periodic_local_boundary=nullptr, const json &periodic_conditions=json::array(), const int fe_space_id=-1)
Initialize the forms and return a vector of pointers to them.
std::vector< int > count_invalid(const int dim, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::VectorXd &u, const unsigned max_iter)
spdlog::logger & logger()
Retrieves the current logger.
std::array< int, 2 > QuadratureOrders
void log_and_throw_error(const std::string &msg)
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix