PolyFEM
Loading...
Searching...
No Matches
SolveData.cpp
Go to the documentation of this file.
1#include "SolveData.hpp"
2
28
29#include <h5pp/h5pp.h>
30
31namespace polyfem::solver
32{
33 using namespace polyfem::time_integrator;
34
35 std::vector<std::shared_ptr<Form>> SolveData::init_forms(
36 // General
37 const Units &units,
38 const int dim,
39 const double t,
40 const Eigen::VectorXi &in_node_to_node,
41
42 // Elastic form
43 const int n_bases,
44 std::vector<basis::ElementBases> &bases,
45 const std::vector<basis::ElementBases> &geom_bases,
46 const assembler::Assembler &assembler,
47 assembler::AssemblyValsCache &ass_vals_cache,
48 const assembler::AssemblyValsCache &mass_ass_vals_cache,
49 const double jacobian_threshold,
50 const ElementInversionCheck check_inversion,
51 const unsigned conservative_max_iter,
52
53 // Body form
54 const int n_pressure_bases,
55 const std::vector<int> &boundary_nodes,
56 const std::vector<mesh::LocalBoundary> &local_boundary,
57 const std::vector<mesh::LocalBoundary> &local_neumann_boundary,
58 const QuadratureOrders &n_boundary_samples,
59 const Eigen::MatrixXd &rhs,
60 const Eigen::MatrixXd &sol,
61 const assembler::Density &density,
62
63 // Pressure form
64 const std::vector<mesh::LocalBoundary> &local_pressure_boundary,
65 const std::unordered_map<int, std::vector<mesh::LocalBoundary>> &local_pressure_cavity,
66 const std::shared_ptr<assembler::PressureAssembler> pressure_assembler,
67
68 // Inertia form
69 const bool ignore_inertia,
70 const StiffnessMatrix &mass,
71 const std::shared_ptr<assembler::ViscousDamping> damping_assembler,
72
73 // Lagged regularization form
74 const double lagged_regularization_weight,
75 const int lagged_regularization_iterations,
76
77 // Augemented lagrangian form
78 const size_t obstacle_ndof,
79 const std::vector<std::string> &hard_constraint_files,
80 const std::vector<json> &soft_constraint_files,
81 const json &zero_mean,
82
83 // Contact form
84 const bool contact_enabled,
85 const ipc::CollisionMesh &collision_mesh,
86 const double dhat,
87 const double avg_mass,
88 const bool use_area_weighting,
89 const bool use_improved_max_operator,
90 const bool use_physical_barrier,
91 const json &barrier_stiffness,
92 const double initial_barrier_stiffness,
93 const ipc::BroadPhaseMethod broad_phase,
94 const double ccd_tolerance,
95 const long ccd_max_iterations,
96 const bool enable_shape_derivatives,
97
98 // Smooth Contact Form
99 const bool use_gcp_formulation,
100 const double alpha_t,
101 const double alpha_n,
102 const bool use_adaptive_dhat,
103 const double min_distance_ratio,
104
105 // Normal Adhesion Form
106 const bool adhesion_enabled,
107 const double dhat_p,
108 const double dhat_a,
109 const double Y,
110
111 // Tangential Adhesion Form
112 const double tangential_adhesion_coefficient,
113 const double epsa,
114 const int tangential_adhesion_iterations,
115
116 // Homogenization
117 const assembler::MacroStrainValue &macro_strain_constraint,
118
119 // Periodic contact
120 const bool periodic_contact,
121 const Eigen::VectorXi &tiled_to_single,
122
123 // Friction form
124 const double friction_coefficient,
125 const double epsv,
126 const int friction_iterations,
127
128 // Rayleigh damping form
129 const json &rayleigh_damping,
130
131 // BC augmented-Lagrangian mass-metric lumping
132 const BCLumpingMode al_lumping,
133
134 // Boundary-ID periodic constraints
135 const mesh::Mesh *periodic_mesh,
136 const std::vector<mesh::LocalBoundary> *periodic_local_boundary,
137 const json &periodic_conditions,
138 const int fe_space_id)
139 {
140 const bool is_time_dependent = time_integrator != nullptr;
141 assert(!is_time_dependent || time_integrator != nullptr);
142 const double dt = is_time_dependent ? time_integrator->dt() : 0.0;
143 const int ndof = n_bases * dim;
144 // if (is_formulation_mixed) // mixed not supported
145 // ndof_ += n_pressure_bases; // pressure is a scalar
146 const bool is_volume = dim == 3;
147
148 std::vector<std::shared_ptr<Form>> forms;
149 al_form.clear();
150
151 elastic_form = std::make_shared<ElasticForm>(
152 n_bases, bases, geom_bases, assembler, ass_vals_cache,
153 t, dt, is_volume, jacobian_threshold, check_inversion, conservative_max_iter);
154 forms.push_back(elastic_form);
155
156 if (rhs_assembler != nullptr)
157 {
158 body_form = std::make_shared<BodyForm>(
159 ndof, n_pressure_bases, boundary_nodes, local_boundary,
160 local_neumann_boundary, n_boundary_samples, rhs, *rhs_assembler,
161 density, /*is_formulation_mixed=*/false,
162 is_time_dependent);
163 body_form->update_quantities(t, sol);
164 forms.push_back(body_form);
165 }
166
167 if (pressure_assembler != nullptr)
168 {
169 pressure_form = std::make_shared<PressureForm>(
170 ndof,
171 local_pressure_boundary,
172 local_pressure_cavity,
173 boundary_nodes,
174 n_boundary_samples, *pressure_assembler,
175 is_time_dependent);
176 pressure_form->update_quantities(t, sol);
177 forms.push_back(pressure_form);
178 }
179
180 inertia_form = nullptr;
181 damping_form = nullptr;
182 if (is_time_dependent)
183 {
184 if (!ignore_inertia)
185 {
186 assert(time_integrator != nullptr);
187 inertia_form = std::make_shared<InertiaForm>(mass, *time_integrator);
188 forms.push_back(inertia_form);
189 }
190
191 if (damping_assembler != nullptr)
192 {
193 damping_form = std::make_shared<ElasticForm>(
194 n_bases, bases, geom_bases, *damping_assembler, ass_vals_cache, t, dt, is_volume,
195 0., ElementInversionCheck::Discrete, conservative_max_iter);
196 forms.push_back(damping_form);
197 }
198 }
199 else
200 {
201 if (lagged_regularization_weight > 0)
202 {
203 forms.push_back(std::make_shared<LaggedRegForm>(lagged_regularization_iterations));
204 forms.back()->set_weight(lagged_regularization_weight);
205 }
206 }
207
208 if (rhs_assembler != nullptr)
209 {
210 // assembler::Mass mass_mat_assembler;
211 // mass_mat_assembler.set_size(dim);
212 StiffnessMatrix mass_tmp = mass;
213 // mass_mat_assembler.assemble(dim == 3, n_bases, bases, geom_bases, mass_ass_vals_cache, mass_tmp, true);
214 // assert(mass_tmp.rows() == mass.rows() && mass_tmp.cols() == mass.cols());
215
216 if (!boundary_nodes.empty())
217 al_form.push_back(std::make_shared<BCLagrangianForm>(
218 ndof, boundary_nodes, local_boundary, local_neumann_boundary,
219 n_boundary_samples, mass_tmp, *rhs_assembler, obstacle_ndof, is_time_dependent, t,
220 al_lumping));
221 // forms.push_back(al_form.back());
222 }
223
224 if (!periodic_conditions.empty())
225 {
226 if (periodic_mesh == nullptr || periodic_local_boundary == nullptr)
227 log_and_throw_error("Periodic boundary constraints require mesh boundary data");
228
229 for (const json &condition : periodic_conditions)
230 {
231 const int condition_fe_space = condition.value("fe_space", -1);
232 // -1 means all/unspecified FE spaces. If both IDs are explicit,
233 // instantiate the condition only for the matching space.
234 if (condition_fe_space >= 0 && fe_space_id >= 0 && condition_fe_space != fe_space_id)
235 continue;
236
237 if (!condition.contains("boundary_ids") || !condition["boundary_ids"].is_array() || condition["boundary_ids"].size() != 2)
238 log_and_throw_error("A periodic boundary condition must contain exactly two boundary_ids");
239
240 const std::array<int, 2> boundary_ids = {{condition["boundary_ids"][0].get<int>(),
241 condition["boundary_ids"][1].get<int>()}};
242 al_form.push_back(std::make_shared<PeriodicBoundaryLagrangianForm>(
243 ndof, dim, *periodic_mesh, bases, *periodic_local_boundary,
244 boundary_ids, condition.value("tolerance", 1e-5)));
245 }
246 }
247
248 bool add_zero_mean = false;
249 if (zero_mean.is_boolean())
250 {
251 add_zero_mean = zero_mean.get<bool>();
252 }
253 else if (zero_mean.is_array())
254 {
255 const int current_fe_space = fe_space_id < 0 ? 0 : fe_space_id;
256 add_zero_mean = std::find(zero_mean.begin(), zero_mean.end(), current_fe_space) != zero_mean.end();
257 }
258 else
259 {
260 log_and_throw_error("constraints.zero_mean must be a boolean or a list of FE-space IDs");
261 }
262
263 if (add_zero_mean)
264 {
265 StiffnessMatrix zero_mean_mass = mass;
266 if (zero_mean_mass.rows() != ndof || zero_mean_mass.cols() != ndof)
267 {
268 assembler::Mass mass_assembler;
269 mass_assembler.set_size(dim);
270 mass_assembler.assemble(
271 dim == 3, n_bases, bases, geom_bases,
272 mass_ass_vals_cache, 0, zero_mean_mass, true);
273 }
274 if (zero_mean_mass.rows() != ndof || zero_mean_mass.cols() != ndof)
275 log_and_throw_error("Unable to assemble zero-mean constraints for {} DoFs", ndof);
276
277 const Eigen::VectorXd weights = zero_mean_mass * Eigen::VectorXd::Ones(ndof);
278 std::vector<Eigen::Triplet<double>> entries;
279 for (int d = 0; d < dim; ++d)
280 {
281 double weight_sum = 0;
282 for (int dof = d; dof < ndof; dof += dim)
283 weight_sum += std::abs(weights(dof));
284 if (weight_sum <= 0)
285 log_and_throw_error("Unable to assemble a zero-mean constraint for component {}", d);
286 for (int dof = d; dof < ndof; dof += dim)
287 if (weights(dof) != 0)
288 entries.emplace_back(d, dof, weights(dof) / weight_sum);
289 }
290
291 StiffnessMatrix A(dim, ndof);
292 A.setFromTriplets(entries.begin(), entries.end());
293 Eigen::MatrixXd b = Eigen::MatrixXd::Zero(dim, 1);
294 al_form.push_back(std::make_shared<MatrixLagrangianForm>(A, b));
295 }
296
297 for (const auto &path : hard_constraint_files)
298 {
299 logger().debug("Setting up hard constraints for {}", path);
300 h5pp::File file(path, h5pp::FileAccess::READONLY);
301 std::vector<int> local2global;
302 if (!file.findDatasets("local2global").empty())
303 local2global = file.readDataset<std::vector<int>>("local2global");
304
305 if (local2global.empty())
306 {
307 local2global.resize(in_node_to_node.size());
308
309 for (int i = 0; i < local2global.size(); ++i)
310 local2global[i] = in_node_to_node[i];
311 }
312 else
313 {
314 for (auto &v : local2global)
315 v = in_node_to_node[v];
316 }
317
318 Eigen::MatrixXd bin = file.readDataset<Eigen::MatrixXd>("b");
319
320 StiffnessMatrix A, A_proj;
321 Eigen::MatrixXd b, b_proj;
322
323 if (!file.findDatasets("A").empty())
324 {
325 Eigen::MatrixXd Ain = file.readDataset<Eigen::MatrixXd>("A");
326 utils::scatter_matrix(ndof, dim, Ain, bin, local2global, A, b);
327
328 if (!file.findDatasets("A_proj").empty())
329 {
330 Eigen::MatrixXd A_proj_in = file.readDataset<Eigen::MatrixXd>("A_proj");
331 if (file.findDatasets("b_proj").empty())
332 log_and_throw_error("Missing b_proj in hard constraint file");
333
334 Eigen::MatrixXd b_proj_in = file.readDataset<Eigen::MatrixXd>("b_proj");
335 utils::scatter_matrix_col(ndof, dim, A_proj_in, b_proj_in, local2global, A_proj, b_proj);
336 }
337 }
338 else
339 {
340 std::vector<double> values = file.readDataset<std::vector<double>>("A_triplets/values");
341 std::vector<int> rows = file.readDataset<std::vector<int>>("A_triplets/rows");
342 std::vector<int> cols = file.readDataset<std::vector<int>>("A_triplets/cols");
343 std::vector<long> shape = file.readDataset<std::vector<long>>("A_triplets/shape");
344 utils::scatter_matrix(ndof, dim, shape, rows, cols, values, bin, local2global, A, b);
345
346 if (!file.findGroups("A_proj_triplets").empty())
347 {
348 if (file.findDatasets("b_proj").empty())
349 log_and_throw_error("Missing b_proj in hard constraint file");
350 if (file.findDatasets("rows", "/A_proj_triplets").empty())
351 log_and_throw_error("Missing A_proj_triplets/rows in hard constraint file");
352 if (file.findDatasets("cols", "/A_proj_triplets").empty())
353 log_and_throw_error("Missing A_proj_triplets/cols in hard constraint file");
354 if (file.findDatasets("values", "/A_proj_triplets").empty())
355 log_and_throw_error("Missing A_proj_triplets/values in hard constraint file");
356
357 std::vector<double> values_proj = file.readDataset<std::vector<double>>("A_proj_triplets/values");
358 std::vector<int> rows_proj = file.readDataset<std::vector<int>>("A_proj_triplets/rows");
359 std::vector<int> cols_proj = file.readDataset<std::vector<int>>("A_proj_triplets/cols");
360 Eigen::MatrixXd b_projin = file.readDataset<Eigen::MatrixXd>("b_proj");
361 std::vector<long> shape_proj = file.readDataset<std::vector<long>>("A_proj_triplets/shape");
362
363 utils::scatter_matrix_col(ndof, dim, shape_proj, rows_proj, cols_proj, values_proj, b_projin, local2global, A_proj, b_proj);
364 }
365 }
366
367 al_form.push_back(std::make_shared<MatrixLagrangianForm>(A, b, A_proj, b_proj));
368 // forms.push_back(al_form.back());
369 }
370
371 for (const auto &j : soft_constraint_files)
372 {
373 const std::string &path = j["data"];
374 double weight = j["weight"];
375
376 logger().debug("Setting up soft constraints for {}", path);
377 h5pp::File file(path, h5pp::FileAccess::READONLY);
378 std::vector<int> local2global;
379 if (!file.findDatasets("local2global").empty())
380 local2global = file.readDataset<std::vector<int>>("local2global");
381
382 if (local2global.empty())
383 {
384 local2global.resize(in_node_to_node.size());
385
386 for (int i = 0; i < local2global.size(); ++i)
387 local2global[i] = in_node_to_node[i];
388 }
389 else
390 {
391 for (auto &v : local2global)
392 v = in_node_to_node[v];
393 }
394
395 Eigen::MatrixXd bin = file.readDataset<Eigen::MatrixXd>("b");
396
398 Eigen::MatrixXd b;
399
400 if (!file.findDatasets("A").empty())
401 {
402 Eigen::MatrixXd Ain = file.readDataset<Eigen::MatrixXd>("A");
403 utils::scatter_matrix(ndof, dim, Ain, bin, local2global, A, b);
404 }
405 else
406 {
407 std::vector<double> values = file.readDataset<std::vector<double>>("A_triplets/values");
408 std::vector<int> rows = file.readDataset<std::vector<int>>("A_triplets/rows");
409 std::vector<int> cols = file.readDataset<std::vector<int>>("A_triplets/cols");
410 std::vector<long> shape = file.readDataset<std::vector<long>>("A_triplets/shape");
411
412 utils::scatter_matrix(ndof, dim, shape, rows, cols, values, bin, local2global, A, b);
413 }
414
415 forms.push_back(std::make_shared<QuadraticPenaltyForm>(A, b, weight));
416 }
417
418 if (macro_strain_constraint.is_active())
419 {
420 // don't push these two into forms because they take a different input x
421 strain_al_lagr_form = std::make_shared<MacroStrainLagrangianForm>(macro_strain_constraint);
422 }
423
424 contact_form = nullptr;
425 periodic_contact_form = nullptr;
426 friction_form = nullptr;
427 if (contact_enabled)
428 {
429 const bool use_adaptive_barrier_stiffness = !barrier_stiffness.is_number();
430
431 if (periodic_contact)
432 {
433 periodic_contact_form = std::make_shared<PeriodicContactForm>(
434 collision_mesh, tiled_to_single, dhat, avg_mass, use_area_weighting, use_improved_max_operator, use_physical_barrier,
435 use_adaptive_barrier_stiffness, is_time_dependent, enable_shape_derivatives, broad_phase, ccd_tolerance,
436 ccd_max_iterations);
437
438 if (use_adaptive_barrier_stiffness)
439 {
440 periodic_contact_form->set_barrier_stiffness(1);
441 // logger().debug("Using adaptive barrier stiffness");
442 }
443 else
444 {
445 assert(barrier_stiffness.is_number());
446 assert(barrier_stiffness.get<double>() > 0);
447 periodic_contact_form->set_barrier_stiffness(barrier_stiffness);
448 // logger().debug("Using fixed barrier stiffness of {}", contact_form->barrier_stiffness());
449 }
450
451 // periodic_contact_form is not pushed into forms since it takes different input vectors.
452 }
453 else
454 {
455 if (use_gcp_formulation)
456 {
457 contact_form = std::make_shared<SmoothContactForm>(
458 collision_mesh, dhat, avg_mass, alpha_t, alpha_n, use_adaptive_dhat, min_distance_ratio,
459 use_adaptive_barrier_stiffness, is_time_dependent, enable_shape_derivatives, broad_phase,
460 ccd_tolerance * units.characteristic_length(), ccd_max_iterations);
461 }
462 else
463 {
464 contact_form = std::make_shared<BarrierContactForm>(
465 collision_mesh, dhat, avg_mass, use_area_weighting, use_improved_max_operator, use_physical_barrier,
466 use_adaptive_barrier_stiffness, is_time_dependent, enable_shape_derivatives, broad_phase, ccd_tolerance * units.characteristic_length(),
467 ccd_max_iterations);
468 }
469
470 if (use_adaptive_barrier_stiffness)
471 {
472 contact_form->set_barrier_stiffness(initial_barrier_stiffness);
473 // logger().debug("Using adaptive barrier stiffness");
474 }
475 else
476 {
477 assert(barrier_stiffness.is_number());
478 assert(barrier_stiffness.get<double>() > 0);
479 contact_form->set_barrier_stiffness(barrier_stiffness);
480 // logger().debug("Using fixed barrier stiffness of {}", contact_form->barrier_stiffness());
481 }
482
483 forms.push_back(contact_form);
484 }
485
486 if (friction_coefficient != 0)
487 {
488 friction_form = std::make_shared<FrictionForm>(
489 collision_mesh, time_integrator, epsv, friction_coefficient,
490 broad_phase, *contact_form, friction_iterations);
491 friction_form->init_lagging(sol);
492 forms.push_back(friction_form);
493 }
494
495 if (adhesion_enabled)
496 {
497 normal_adhesion_form = std::make_shared<NormalAdhesionForm>(
498 collision_mesh, dhat_p, dhat_a, Y, is_time_dependent, enable_shape_derivatives,
499 broad_phase, ccd_tolerance * units.characteristic_length(), ccd_max_iterations);
500 forms.push_back(normal_adhesion_form);
501
502 if (tangential_adhesion_coefficient != 0)
503 {
504 tangential_adhesion_form = std::make_shared<TangentialAdhesionForm>(
505 collision_mesh, time_integrator, epsa, tangential_adhesion_coefficient,
506 broad_phase, *normal_adhesion_form, tangential_adhesion_iterations);
507 forms.push_back(tangential_adhesion_form);
508 }
509 }
510 }
511
512 const std::vector<json> rayleigh_damping_jsons = utils::json_as_array(rayleigh_damping);
513 if (is_time_dependent)
514 {
515 // Map from form name to form so RayleighDampingForm::create can get the correct form to damp
516 const std::unordered_map<std::string, std::shared_ptr<Form>> possible_forms_to_damp = {
517 {"elasticity", elastic_form},
518 {"contact", contact_form},
519 };
520
521 for (const json &params : rayleigh_damping_jsons)
522 {
523 forms.push_back(RayleighDampingForm::create(
524 params, possible_forms_to_damp,
526 }
527 }
528 else if (rayleigh_damping_jsons.size() > 0)
529 {
530 log_and_throw_adjoint_error("Rayleigh damping is only supported for time-dependent problems");
531 }
532
533 update_dt();
534
535 return forms;
536 }
537
538 void SolveData::update_barrier_stiffness(const Eigen::VectorXd &x)
539 {
540 if (contact_form == nullptr || !contact_form->use_adaptive_barrier_stiffness())
541 return;
542
543 Eigen::VectorXd grad_energy = Eigen::VectorXd::Zero(x.size());
544 const std::array<std::shared_ptr<Form>, 4> energy_forms{
546 for (const std::shared_ptr<Form> &form : energy_forms)
547 {
548 if (form == nullptr || !form->enabled())
549 continue;
550
551 Eigen::VectorXd grad_form;
552 form->first_derivative(x, grad_form);
553 grad_energy += grad_form;
554 }
555
556 contact_form->update_barrier_stiffness(x, grad_energy);
557 }
558
560 {
561 if (time_integrator == nullptr) // if is not time dependent
562 return;
563
564 const std::array<std::shared_ptr<Form>, 6> energy_forms{
566 for (const std::shared_ptr<Form> &form : energy_forms)
567 {
568 if (form == nullptr)
569 continue;
570 form->set_weight(time_integrator->acceleration_scaling());
571 }
572 }
573
574 std::vector<std::pair<std::string, std::shared_ptr<solver::Form>>> SolveData::named_forms() const
575 {
576 std::vector<std::pair<std::string, std::shared_ptr<solver::Form>>> res{
577 {"elastic", elastic_form},
578 {"inertia", inertia_form},
579 {"body", body_form},
580 {"contact", contact_form},
581 {"friction", friction_form},
582 {"damping", damping_form},
583 {"pressure", pressure_form},
584 {"strain_augmented_lagrangian_lagr", strain_al_lagr_form},
585 {"periodic_contact", periodic_contact_form},
586 };
587
588 for (const auto &form : al_form)
589 res.push_back({"augmented_lagrangian", form});
590
591 return res;
592 }
593} // namespace polyfem::solver
std::vector< Eigen::Triplet< double > > entries
std::vector< std::pair< int, double > > weights
int x
double characteristic_length() const
Definition Units.hpp:22
virtual void set_size(const int size)
Definition Assembler.hpp:66
Caches basis evaluation and geometric mapping at every element.
Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 9, 1 > assemble(const LinearAssemblerData &data) const override
computes and returns local stiffness matrix (1x1) for bases i,j (where i,j is passed in through data)...
Definition Mass.cpp:18
Abstract mesh class to capture 2d/3d conforming and non-conforming meshes.
Definition Mesh.hpp:49
static std::shared_ptr< RayleighDampingForm > create(const json &params, const std::unordered_map< std::string, std::shared_ptr< Form > > &forms, const time_integrator::ImplicitTimeIntegrator &time_integrator)
std::shared_ptr< solver::FrictionForm > friction_form
std::vector< std::shared_ptr< Form > > init_forms(const Units &units, 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 json &barrier_stiffness, const double initial_barrier_stiffness, 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 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 &macro_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.
Definition SolveData.cpp:35
std::shared_ptr< solver::InertiaForm > inertia_form
std::shared_ptr< solver::PeriodicContactForm > periodic_contact_form
void update_dt()
updates the dt inside the different forms
std::shared_ptr< solver::PressureForm > pressure_form
std::shared_ptr< solver::BodyForm > body_form
std::shared_ptr< solver::MacroStrainLagrangianForm > strain_al_lagr_form
std::shared_ptr< solver::NormalAdhesionForm > normal_adhesion_form
std::shared_ptr< solver::ContactForm > contact_form
std::vector< std::pair< std::string, std::shared_ptr< solver::Form > > > named_forms() const
std::shared_ptr< solver::ElasticForm > damping_form
std::shared_ptr< solver::ElasticForm > elastic_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::shared_ptr< solver::TangentialAdhesionForm > tangential_adhesion_form
std::shared_ptr< assembler::PressureAssembler > pressure_assembler
std::shared_ptr< assembler::RhsAssembler > rhs_assembler
BCLumpingMode
Lumping mode for the mass metric of the BC penalty.
void scatter_matrix(const int n_dofs, const int dim, const Eigen::MatrixXd &A, const Eigen::MatrixXd &b, const std::vector< int > &local_to_global, StiffnessMatrix &Aout, Eigen::MatrixXd &bout)
std::vector< T > json_as_array(const json &j)
Return the value of a json object as an array.
Definition JSONUtils.hpp:38
void scatter_matrix_col(const int n_dofs, const int dim, const Eigen::MatrixXd &A, const Eigen::MatrixXd &b, const std::vector< int > &local_to_global, StiffnessMatrix &Aout, Eigen::MatrixXd &bout)
spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:44
std::array< int, 2 > QuadratureOrders
Definition Types.hpp:19
nlohmann::json json
Definition Common.hpp:9
void log_and_throw_adjoint_error(const std::string &msg)
Definition Logger.cpp:79
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:73
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix
Definition Types.hpp:24