11#include <unsupported/Eigen/SparseExtra>
13#include <polysolve/linear/FEMSolver.hpp>
21 const std::string full_mat_path =
args[
"output"][
"data"][
"full_mat"];
22 if (full_mat_path.empty())
25 Eigen::saveMarket(stiffness, full_mat_path);
41 const Eigen::MatrixXd &solution,
44 const std::vector<std::pair<std::string, std::shared_ptr<solver::Form>>> named_forms{
56 logger().info(
"Assembling stiffness mat...");
67 stats.
mat_size = (
long long)stiffness.rows() * (
long long)stiffness.cols();
74 const std::unique_ptr<polysolve::linear::Solver> &solver,
77 const bool compute_spectrum,
83 const int problem_dim =
problem->is_scalar() ? 1 :
mesh_->dimension();
94 args[
"output"][
"data"][
"stiffness_mat"],
102 const auto error = (A *
x - b).norm();
104 logger().error(
"Solver error: {}", error);
106 logger().debug(
"Solver error: {}", error);
111 assert(sol.cols() == 1);
119 t,
problem->is_time_dependent() ?
args[
"time"][
"dt"].get<
double>() : 0.0,
121 args[
"solver"][
"advanced"][
"jacobian_threshold"],
122 args[
"solver"][
"advanced"][
"check_inversion"],
123 args[
"solver"][
"advanced"][
"conservative_max_iter"]);
130 false,
problem->is_time_dependent());
133 if (
problem->is_time_dependent())
140 Eigen::MatrixXd solution, velocity, acceleration;
142 solution.col(0) = sol;
143 assert(solution.rows() == sol.size());
145 assert(velocity.rows() == sol.size());
147 assert(acceleration.rows() == sol.size());
148 if (solution.cols() != velocity.cols() || solution.cols() != acceleration.cols())
151 "Incompatible initial-condition history for transient solve: "
152 "solution has {} columns, velocity has {}, acceleration has {}.",
153 solution.cols(), velocity.cols(), acceleration.cols());
169 auto solver = polysolve::linear::Solver::create(
args[
"solver"][
"linear"],
logger());
170 logger().info(
"{}...", solver->name());
179 Eigen::VectorXd b =
rhs_;
187 assert(
problem->is_time_dependent());
191 auto solver = polysolve::linear::Solver::create(
args[
"solver"][
"linear"],
logger());
192 logger().info(
"{}...", solver->name());
198 Eigen::MatrixXd current_rhs =
rhs_;
205 const double time =
t0 + t *
dt;
219 std::vector<mesh::LocalBoundary>(), current_rhs, sol, time);
222 Eigen::VectorXd b = current_rhs;
238 Eigen::MatrixXd &sol,
243 (
problem->is_time_dependent() || !initial_condition_override
244 || (initial_condition_override->
velocity.size() == 0
245 && initial_condition_override->
acceleration.size() == 0))
246 &&
"Static elasticity does not accept initial velocity or acceleration overrides");
257 if (initial_condition_override && initial_condition_override->
solution.size() != 0)
259 else if (sol.size() <= 0)
262 if (!
problem->is_time_dependent())
264 if (initial_condition_override && initial_condition_override->
solution.size() != 0)
265 assert(sol.cols() == 1 &&
"Static initial solution override must have exactly one column");
266 else if (sol.cols() != 1)
270 sol.conservativeResize(Eigen::NoChange, 1);
275 if (
problem->is_time_dependent())
#define POLYFEM_SCOPED_TIMER(...)
double assembling_stiffness_mat_time
time to assembly
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)
long long nn_zero
non zeros and sytem matrix size num dof is the total dof in the system
std::shared_ptr< solver::InertiaForm > inertia_form
std::shared_ptr< solver::BodyForm > body_form
std::shared_ptr< solver::ElasticForm > elastic_form
std::shared_ptr< time_integrator::ImplicitTimeIntegrator > time_integrator
static std::shared_ptr< ImplicitTimeIntegrator > construct_time_integrator(const json ¶ms, DynamicOrder dynamic_order=DynamicOrder::Second)
Factory method for constructing an implicit time integrator.
spdlog::logger & logger()
Retrieves the current logger.
void log_and_throw_error(const std::string &msg)
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix