18#include <polysolve/linear/FEMSolver.hpp>
22 using namespace varform::internal;
48 logger().error(
"Load the mesh first!");
51 if (solution.size() <= 0)
53 logger().error(
"Solve the problem first!");
57 logger().info(
"Saving json...");
59 const Eigen::MatrixXd stats_solution =
60 solution.rows() >= primary_size
61 ? solution.topRows(primary_size).eval()
69 args[
"output"][
"advanced"][
"sol_at_node"], j);
70 out << j.dump(4) << std::endl;
75 if (!
args[
"output"][
"advanced"][
"compute_error"])
79 if (!
args[
"time"].is_null())
80 tend =
args[
"time"][
"tend"];
82 Eigen::MatrixXd displacement, pressure;
109 json rhs_solver_params =
args[
"solver"][
"linear"];
110 if (!rhs_solver_params.contains(
"Pardiso"))
111 rhs_solver_params[
"Pardiso"] = {};
112 rhs_solver_params[
"Pardiso"][
"mtype"] = -2;
119 args[
"space"][
"advanced"][
"bc_method"],
134 const bool use_corner_quadrature =
args[
"space"][
"advanced"][
"use_corner_quadrature"];
135 const int quadrature_order =
args[
"space"][
"advanced"][
"quadrature_order"].get<
int>();
136 const int mass_quadrature_order =
args[
"space"][
"advanced"][
"mass_quadrature_order"].get<
int>();
137 const int order =
args[
"space"][
"pressure_discr_order"];
138 Eigen::VectorXi pressure_disc_orders(mesh.
n_elements());
139 pressure_disc_orders.setConstant(order);
141 const std::string pressure_basis_type =
args[
"space"][
"basis_type"].get<std::string>() ==
"Bernstein" ?
"Bernstein" :
"Lagrange";
145 pressure_disc_orders,
147 args[
"space"][
"poly_basis_type"],
151 mass_quadrature_order,
152 use_corner_quadrature,
153 args[
"space"][
"advanced"][
"n_harmonic_samples"],
154 args[
"space"][
"advanced"][
"integral_constraints"],
168 for (
const auto &lb : all_boundary)
188 for (
int d = 0; d < mesh.
dimension(); ++d)
206 const int prev_size =
rhs_.rows();
213 if (!
problem->is_time_dependent())
223 logger().info(
"Assembling mass mat...");
226 for (
int k = 0; k <
mass_.outerSize(); ++k)
227 for (StiffnessMatrix::InnerIterator it(
mass_, k); it; ++it)
229 assert(it.col() == k);
233 if (
args[
"solver"][
"advanced"][
"lump_mass_matrix"])
248 sol.conservativeResize(Eigen::NoChange, 1);
255 const int cols = std::max(1,
int(stacked.cols()));
258 const int primary_rows = std::min(
primary_ndof(),
int(stacked.rows()));
259 if (primary_rows > 0)
260 primary.topRows(primary_rows) = stacked.topRows(primary_rows);
264 if (pressure_rows > 0)
265 pressure.topRows(pressure_rows) = stacked.middleRows(
primary_ndof(), pressure_rows);
273 logger().info(
"Assembling stiffness mat...");
275 StiffnessMatrix elastic_stiffness, mixed_stiffness, pressure_stiffness;
282 elastic_stiffness, mixed_stiffness, pressure_stiffness, stiffness);
289 stats.
mat_size = (
long long)stiffness.rows() * (
long long)stiffness.cols();
294 const std::unique_ptr<polysolve::linear::Solver> &solver,
297 const bool compute_spectrum,
298 Eigen::MatrixXd &sol)
308 args[
"output"][
"data"][
"stiffness_mat"],
318 auto solver = polysolve::linear::Solver::create(
args[
"solver"][
"linear"],
logger());
319 logger().info(
"{}...", solver->name());
323 Eigen::VectorXd b =
rhs_;
329 auto solver = polysolve::linear::Solver::create(
args[
"solver"][
"linear"],
logger());
330 logger().info(
"{}...", solver->name());
332 Eigen::MatrixXd displacement, pressure;
337 Eigen::MatrixXd::Zero(displacement.rows(), displacement.cols()),
338 Eigen::MatrixXd::Zero(displacement.rows(), displacement.cols()),
344 Eigen::MatrixXd current_rhs =
rhs_;
351 const double time =
t0 + t *
dt;
360 const int old_rows = current_rhs.rows();
361 current_rhs.conservativeResize(
stacked_ndof(), current_rhs.cols());
363 current_rhs.bottomRows(
stacked_ndof() - old_rows).setZero();
368 Eigen::VectorXd b = Eigen::VectorXd::Zero(
stacked_ndof());
376 bdf->update_quantities(displacement.col(0));
392 if (
problem->is_time_dependent())
406 const Eigen::MatrixXd &solution,
409 Eigen::MatrixXd displacement, pressure;
411 const std::vector<std::pair<std::string, std::shared_ptr<solver::Form>>> named_forms;
413 sample, displacement, options,
nullptr,
time_integrator.get(), named_forms,
nullptr);
414 const bool export_pressure_gradient =
418 Eigen::MatrixXd values, gradients;
421 export_pressure_gradient ? &gradients :
nullptr))
425 if (export_pressure_gradient)
static std::shared_ptr< MixedAssembler > make_mixed_assembler(const std::string &formulation)
static std::string other_assembler_name(const std::string &formulation)
static void merge_mixed_matrices(const int n_bases, const int n_pressure_bases, const int problem_dim, const bool add_average, const StiffnessMatrix &velocity_stiffness, const StiffnessMatrix &mixed_stiffness, const StiffnessMatrix &pressure_stiffness, StiffnessMatrix &stiffness)
utility to merge 3 blocks of mixed matrices, A=velocity_stiffness, B=mixed_stiffness,...
static std::shared_ptr< Assembler > make_assembler(const std::string &formulation)
void init(const bool is_volume, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const bool is_mass=false)
computes the basis evaluation and geometric mapping for each of the given ElementBases in bases initi...
void init_empty(const bool is_mass=false)
initialize an empty cache.
double assembling_stiffness_mat_time
time to assembly
double assembling_mass_mat_time
time to assembly mass
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)
void compute_errors(const int n_bases, const std::vector< polyfem::basis::ElementBases > &bases, const std::vector< polyfem::basis::ElementBases > &gbases, const polyfem::mesh::Mesh &mesh, const assembler::Problem &problem, const double tend, const Eigen::MatrixXd &sol)
compute errors
long long nn_zero
non zeros and sytem matrix size num dof is the total dof in the system
void save_json(const nlohmann::json &args, const int n_bases, const int n_pressure_bases, const Eigen::MatrixXd &sol, const mesh::Mesh &mesh, const Eigen::VectorXi &disc_orders, const Eigen::VectorXi &disc_ordersq, const assembler::Problem &problem, const OutRuntimeData &runtime, const std::string &formulation, const bool isoparametric, const int sol_at_node_id, nlohmann::json &j) const
saves the output statistic to a json object
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
virtual bool is_volume() const =0
checks if mesh is volume
int dimension() const
utily for dimension
Eigen::SparseMatrix< double > lump_matrix(const Eigen::SparseMatrix< double > &M)
Lump each row of a matrix into the diagonal.
spdlog::logger & logger()
Retrieves the current logger.
void log_and_throw_error(const std::string &msg)
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix
bool export_field(const std::string &field) const
std::vector< std::string > fields