42 reduced_mat.resize(mat.rows(), mat.cols());
44 std::vector<bool> mask(mat.rows(),
false);
48 std::vector<Eigen::Triplet<double>> coeffs;
49 for (
int k = 0; k < mat.outerSize(); ++k)
51 for (StiffnessMatrix::InnerIterator it(mat, k); it; ++it)
55 if (it.row() == it.col())
56 coeffs.emplace_back(it.row(), it.col(), 1.0);
59 coeffs.emplace_back(it.row(), it.col(), it.value());
62 reduced_mat.setFromTriplets(coeffs.begin(), coeffs.end());
65 void compute_force_jacobian(State &state,
const Eigen::MatrixXd &sol,
const Eigen::MatrixXd &disp_grad,
StiffnessMatrix &hessian)
69 if (s.problem->is_time_dependent())
72 s.solve_data.nl_problem->set_project_to_psd(
false);
73 s.solve_data.nl_problem->FullNLProblem::solution_changed(sol);
74 s.solve_data.nl_problem->FullNLProblem::hessian(sol, tmp_hess);
76 replace_rows_by_identity(hessian, tmp_hess, s.boundary_nodes);
80 if (s.assembler->is_linear() && !s.is_contact_enabled() && !s.is_homogenization())
84 s.build_stiffness_mat(stiffness);
85 replace_rows_by_identity(hessian, stiffness, s.boundary_nodes);
89 s.solve_data.nl_problem->set_project_to_psd(
false);
90 if (s.is_homogenization())
92 Eigen::VectorXd reduced;
93 std::shared_ptr<solver::NLHomoProblem> homo_problem = std::dynamic_pointer_cast<solver::NLHomoProblem>(s.solve_data.nl_problem);
94 reduced = homo_problem->full_to_reduced(sol, disp_grad);
95 s.solve_data.nl_problem->solution_changed(reduced);
96 s.solve_data.nl_problem->hessian(reduced, hessian);
101 s.solve_data.nl_problem->FullNLProblem::solution_changed(sol);
102 s.solve_data.nl_problem->FullNLProblem::hessian(sol, tmp_hess);
104 replace_rows_by_identity(hessian, tmp_hess, s.boundary_nodes);
110 StiffnessMatrix compute_basis_nodes_to_gbasis_nodes(
const State &state)
112 auto &gbases = state.geom_bases();
113 auto &bases = state.bases;
115 std::map<std::array<int, 2>,
double> pairs;
116 for (
int e = 0;
e < gbases.size();
e++)
118 auto &gbs = gbases[
e].bases;
119 auto &bs = bases[
e].bases;
122 Eigen::MatrixXd local_pts;
123 int order = bs.front().order();
124 if (state.mesh->is_volume())
126 if (state.mesh->is_simplex(e))
137 if (state.mesh->is_simplex(e))
147 assembler::ElementAssemblyValues
vals;
148 vals.
compute(e, state.mesh->is_volume(), local_pts, gbases[e], gbases[e]);
150 for (
int i = 0; i < bs.size(); i++)
152 for (
int j = 0; j < gbs.size(); j++)
156 std::array<int, 2> index = {{gbs[j].global()[0].index, bs[i].global()[0].index}};
163 int dim = state.mesh->dimension();
164 std::vector<Eigen::Triplet<double>> coeffs;
165 coeffs.reserve(pairs.size() * dim);
166 for (
const auto &iter : pairs)
168 for (
int d = 0; d <
dim; d++)
170 coeffs.emplace_back(iter.first[0] * dim + d, iter.first[1] * dim + d, iter.second);
175 mapping.resize(state.n_geom_bases * dim, state.n_bases * dim);
176 mapping.setFromTriplets(coeffs.begin(), coeffs.end());
186 u_.setZero(ndof, n_time_steps + 1);
187 disp_grad_.assign(n_time_steps + 1, Eigen::MatrixXd::Zero(dimension, dimension));
191 v_.setZero(ndof, n_time_steps + 1);
192 acc_.setZero(ndof, n_time_steps + 1);
204 const Eigen::MatrixXd &u,
206 const ipc::NormalCollisions &collision_set,
207 const ipc::SmoothCollisions &smooth_collision_set,
208 const ipc::TangentialCollisions &friction_constraint_set,
209 const ipc::NormalCollisions &normal_adhesion_set,
210 const ipc::TangentialCollisions &tangential_adhesion_set,
211 const Eigen::MatrixXd &disp_grad)
228 const int cur_bdf_order,
229 const Eigen::MatrixXd &u,
230 const Eigen::MatrixXd &v,
231 const Eigen::MatrixXd &acc,
234 const ipc::NormalCollisions &collision_set,
235 const ipc::SmoothCollisions &smooth_collision_set,
236 const ipc::TangentialCollisions &friction_collision_set)
240 u_.col(cur_step) =
u;
241 v_.col(cur_step) =
v;
256 const Eigen::MatrixXd &u,
258 const ipc::NormalCollisions &collision_set,
259 const ipc::SmoothCollisions &smooth_collision_set,
260 const ipc::NormalCollisions &normal_adhesion_set,
261 const Eigen::MatrixXd &disp_grad)
263 u_.col(cur_step) =
u;
278 &&
"basis_nodes_to_gbasis_nodes is empty. Expect cache_transient(step==0) to build it first.");
286 const Eigen::MatrixXd &sol,
287 const Eigen::MatrixXd *disp_grad,
288 const Eigen::MatrixXd *pressure)
301 Eigen::MatrixXd disp_grad_final;
308 int mesh_dim = s.mesh->dimension();
309 disp_grad_final = Eigen::MatrixXd::Zero(mesh_dim, mesh_dim);
315 init(s.mesh->dimension(), s.ndof(), s.problem->is_time_dependent() ? s.args[
"time"][
"time_steps"].get<
int>() : 0);
318 ipc::NormalCollisions cur_collision_set;
319 ipc::SmoothCollisions cur_smooth_collision_set;
320 ipc::TangentialCollisions cur_friction_set;
321 ipc::NormalCollisions cur_normal_adhesion_set;
322 ipc::TangentialCollisions cur_tangential_adhesion_set;
324 if (!s.problem->is_time_dependent() || step > 0)
325 compute_force_jacobian(s, sol, disp_grad_final,
gradu_h);
327 if (s.solve_data.contact_form)
330 cur_collision_set = barrier_contact->collision_set();
332 cur_smooth_collision_set = smooth_contact->collision_set();
334 cur_friction_set = s.solve_data.friction_form ? s.solve_data.friction_form->friction_collision_set() : ipc::TangentialCollisions();
335 cur_normal_adhesion_set = s.solve_data.normal_adhesion_form ? s.solve_data.normal_adhesion_form->collision_set() : ipc::NormalCollisions();
336 cur_tangential_adhesion_set = s.solve_data.tangential_adhesion_form ? s.solve_data.tangential_adhesion_form->tangential_collision_set() : ipc::TangentialCollisions();
338 if (s.problem->is_time_dependent())
340 if (s.args[
"time"][
"quasistatic"].get<
bool>())
346 Eigen::MatrixXd vel,
acc;
351 const auto bdf_integrator =
dynamic_cast<time_integrator::BDF *
>(s.solve_data.time_integrator.get());
357 vel = euler_integrator->
v_prev();
362 acc.setZero(s.ndof(), 1);
366 vel = s.solve_data.time_integrator->compute_velocity(sol);
367 acc = s.solve_data.time_integrator->compute_acceleration(vel);
375 cache_quantities_static(sol,
gradu_h, cur_collision_set, cur_smooth_collision_set, cur_friction_set, cur_normal_adhesion_set, cur_tangential_adhesion_set, disp_grad_final);
ElementAssemblyValues vals
void cache_transient(int step, State &state, const Eigen::MatrixXd &sol, const Eigen::MatrixXd *disp_grad, const Eigen::MatrixXd *pressure)
Cache time-dependent adjoint optimization data.
std::vector< StiffnessMatrix > gradu_h_
std::vector< ipc::NormalCollisions > normal_adhesion_collision_set_
std::vector< ipc::TangentialCollisions > friction_collision_set_
const ipc::NormalCollisions & collision_set(int step) const
Eigen::MatrixXd disp_grad(int step=0) const
Eigen::MatrixXd adjoint_mat_
Eigen::VectorXd v(int step) const
StiffnessMatrix basis_nodes_to_gbasis_nodes_
std::vector< Eigen::MatrixXd > disp_grad_
const ipc::TangentialCollisions & friction_collision_set(int step) const
const Eigen::MatrixXd & adjoint_mat() const
void cache_quantities_static(const Eigen::MatrixXd &u, const StiffnessMatrix &gradu_h, const ipc::NormalCollisions &collision_set, const ipc::SmoothCollisions &smooth_collision_set, const ipc::TangentialCollisions &friction_constraint_set, const ipc::NormalCollisions &normal_adhesion_set, const ipc::TangentialCollisions &tangential_adhesion_set, const Eigen::MatrixXd &disp_grad)
Eigen::VectorXd acc(int step) const
std::vector< ipc::SmoothCollisions > smooth_collision_set_
std::vector< ipc::TangentialCollisions > tangential_adhesion_collision_set_
const StiffnessMatrix & basis_nodes_to_gbasis_nodes() const
Eigen::VectorXi bdf_order_
void cache_quantities_quasistatic(const int cur_step, const Eigen::MatrixXd &u, const StiffnessMatrix &gradu_h, const ipc::NormalCollisions &collision_set, const ipc::SmoothCollisions &smooth_collision_set, const ipc::NormalCollisions &normal_adhesion_set, const Eigen::MatrixXd &disp_grad)
std::vector< ipc::NormalCollisions > collision_set_
const ipc::SmoothCollisions & smooth_collision_set(int step) const
Eigen::VectorXd u(int step) const
void cache_adjoints(const Eigen::MatrixXd &adjoint_mat)
const StiffnessMatrix & gradu_h(int step) const
void init(const int dimension, const int ndof, const int n_time_steps=0)
void cache_quantities_transient(const int cur_step, const int cur_bdf_order, const Eigen::MatrixXd &u, const Eigen::MatrixXd &v, const Eigen::MatrixXd &acc, const StiffnessMatrix &gradu_h, const ipc::NormalCollisions &collision_set, const ipc::SmoothCollisions &smooth_collision_set, const ipc::TangentialCollisions &friction_collision_set)
main class that contains the polyfem solver and all its state
std::vector< AssemblyValues > basis_values
void compute(const int el_index, const bool is_volume, const Eigen::MatrixXd &pts, const basis::ElementBases &basis, const basis::ElementBases &gbasis)
computes the per element values at the local (ref el) points (pts) sets basis_values,...
Backward Differential Formulas.
Eigen::VectorXd weighted_sum_v_prevs() const
Compute the weighted sum of the previous velocities.
Implicit Euler time integrator of a second order ODE (equivently a system of coupled first order ODEs...
const Eigen::VectorXd & v_prev() const
Get the most recent previous velocity value.
void q_nodes_2d(const int q, Eigen::MatrixXd &val)
void p_nodes_2d(const int p, Eigen::MatrixXd &val)
void p_nodes_3d(const int p, Eigen::MatrixXd &val)
void q_nodes_3d(const int q, Eigen::MatrixXd &val)
void log_and_throw_adjoint_error(const std::string &msg)
void log_and_throw_error(const std::string &msg)
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix