41 const Eigen::VectorXi &in_node_to_node,
45 std::vector<basis::ElementBases> &bases,
46 const std::vector<basis::ElementBases> &geom_bases,
50 const double jacobian_threshold,
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 int n_boundary_samples,
59 const Eigen::MatrixXd &rhs,
60 const Eigen::MatrixXd &sol,
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,
69 const bool ignore_inertia,
71 const std::shared_ptr<assembler::ViscousDamping> damping_assembler,
74 const double lagged_regularization_weight,
75 const int lagged_regularization_iterations,
78 const size_t obstacle_ndof,
79 const std::vector<std::string> &hard_constraint_files,
80 const std::vector<json> &soft_constraint_files,
83 const bool contact_enabled,
84 const ipc::CollisionMesh &collision_mesh,
86 const double avg_mass,
87 const bool use_area_weighting,
88 const bool use_improved_max_operator,
89 const bool use_physical_barrier,
90 const json &barrier_stiffness,
91 const double initial_barrier_stiffness,
92 const ipc::BroadPhaseMethod broad_phase,
93 const double ccd_tolerance,
94 const long ccd_max_iterations,
95 const bool enable_shape_derivatives,
98 const bool use_gcp_formulation,
100 const double alpha_n,
101 const bool use_adaptive_dhat,
102 const double min_distance_ratio,
105 const bool adhesion_enabled,
111 const double tangential_adhesion_coefficient,
113 const int tangential_adhesion_iterations,
119 const bool periodic_contact,
120 const Eigen::VectorXi &tiled_to_single,
121 const std::shared_ptr<utils::PeriodicBoundary> &periodic_bc,
124 const double friction_coefficient,
126 const int friction_iterations,
129 const json &rayleigh_damping)
134 const int ndof = n_bases * dim;
137 const bool is_volume = dim == 3;
139 std::vector<std::shared_ptr<Form>> forms;
143 n_bases, bases, geom_bases, assembler, ass_vals_cache,
144 t, dt, is_volume, jacobian_threshold, check_inversion);
150 ndof, n_pressure_bases, boundary_nodes, local_boundary,
151 local_neumann_boundary, n_boundary_samples, rhs, *
rhs_assembler,
162 local_pressure_boundary,
163 local_pressure_cavity,
173 if (is_time_dependent)
182 if (damping_assembler !=
nullptr)
185 n_bases, bases, geom_bases, *damping_assembler, ass_vals_cache, t, dt, is_volume);
191 if (lagged_regularization_weight > 0)
193 forms.push_back(std::make_shared<LaggedRegForm>(lagged_regularization_iterations));
194 forms.back()->set_weight(lagged_regularization_weight);
206 if (!boundary_nodes.empty())
207 al_form.push_back(std::make_shared<BCLagrangianForm>(
208 ndof, boundary_nodes, local_boundary, local_neumann_boundary,
209 n_boundary_samples, mass_tmp, *
rhs_assembler, obstacle_ndof, is_time_dependent, t));
213 if (periodic_bc !=
nullptr)
215 al_form.push_back(std::make_shared<PeriodicLagrangianForm>(ndof, periodic_bc));
218 for (
const auto &path : hard_constraint_files)
220 logger().debug(
"Setting up hard constraints for {}", path);
221 h5pp::File file(path, h5pp::FileAccess::READONLY);
222 std::vector<int> local2global;
223 if (!file.findDatasets(
"local2global").empty())
224 local2global = file.readDataset<std::vector<int>>(
"local2global");
226 if (local2global.empty())
228 local2global.resize(in_node_to_node.size());
230 for (
int i = 0; i < local2global.size(); ++i)
231 local2global[i] = in_node_to_node[i];
235 for (
auto &v : local2global)
236 v = in_node_to_node[v];
239 Eigen::MatrixXd bin = file.readDataset<Eigen::MatrixXd>(
"b");
242 Eigen::MatrixXd b, b_proj;
244 if (!file.findDatasets(
"A").empty())
246 Eigen::MatrixXd Ain = file.readDataset<Eigen::MatrixXd>(
"A");
249 if (!file.findDatasets(
"A_proj").empty())
251 Eigen::MatrixXd A_proj_in = file.readDataset<Eigen::MatrixXd>(
"A_proj");
252 if (file.findDatasets(
"b_proj").empty())
255 Eigen::MatrixXd b_proj_in = file.readDataset<Eigen::MatrixXd>(
"b_proj");
261 std::vector<double> values = file.readDataset<std::vector<double>>(
"A_triplets/values");
262 std::vector<int> rows = file.readDataset<std::vector<int>>(
"A_triplets/rows");
263 std::vector<int> cols = file.readDataset<std::vector<int>>(
"A_triplets/cols");
264 std::vector<long> shape = file.readDataset<std::vector<long>>(
"A_triplets/shape");
267 if (!file.findGroups(
"A_proj_triplets").empty())
269 if (file.findDatasets(
"b_proj").empty())
271 if (file.findDatasets(
"rows",
"/A_proj_triplets").empty())
273 if (file.findDatasets(
"cols",
"/A_proj_triplets").empty())
275 if (file.findDatasets(
"values",
"/A_proj_triplets").empty())
278 std::vector<double> values_proj = file.readDataset<std::vector<double>>(
"A_proj_triplets/values");
279 std::vector<int> rows_proj = file.readDataset<std::vector<int>>(
"A_proj_triplets/rows");
280 std::vector<int> cols_proj = file.readDataset<std::vector<int>>(
"A_proj_triplets/cols");
281 Eigen::MatrixXd b_projin = file.readDataset<Eigen::MatrixXd>(
"b_proj");
282 std::vector<long> shape_proj = file.readDataset<std::vector<long>>(
"A_proj_triplets/shape");
284 utils::scatter_matrix_col(ndof, dim, shape_proj, rows_proj, cols_proj, values_proj, b_projin, local2global, A_proj, b_proj);
288 al_form.push_back(std::make_shared<MatrixLagrangianForm>(A, b, A_proj, b_proj));
292 for (
const auto &j : soft_constraint_files)
294 const std::string &path = j[
"data"];
295 double weight = j[
"weight"];
297 logger().debug(
"Setting up soft constraints for {}", path);
298 h5pp::File file(path, h5pp::FileAccess::READONLY);
299 std::vector<int> local2global;
300 if (!file.findDatasets(
"local2global").empty())
301 local2global = file.readDataset<std::vector<int>>(
"local2global");
303 if (local2global.empty())
305 local2global.resize(in_node_to_node.size());
307 for (
int i = 0; i < local2global.size(); ++i)
308 local2global[i] = in_node_to_node[i];
312 for (
auto &v : local2global)
313 v = in_node_to_node[v];
316 Eigen::MatrixXd bin = file.readDataset<Eigen::MatrixXd>(
"b");
321 if (!file.findDatasets(
"A").empty())
323 Eigen::MatrixXd Ain = file.readDataset<Eigen::MatrixXd>(
"A");
328 std::vector<double> values = file.readDataset<std::vector<double>>(
"A_triplets/values");
329 std::vector<int> rows = file.readDataset<std::vector<int>>(
"A_triplets/rows");
330 std::vector<int> cols = file.readDataset<std::vector<int>>(
"A_triplets/cols");
331 std::vector<long> shape = file.readDataset<std::vector<long>>(
"A_triplets/shape");
336 forms.push_back(std::make_shared<QuadraticPenaltyForm>(A, b, weight));
342 strain_al_lagr_form = std::make_shared<MacroStrainLagrangianForm>(macro_strain_constraint);
350 const bool use_adaptive_barrier_stiffness = !barrier_stiffness.is_number();
352 if (periodic_contact)
355 collision_mesh, tiled_to_single, dhat, avg_mass, use_area_weighting, use_improved_max_operator, use_physical_barrier,
356 use_adaptive_barrier_stiffness, is_time_dependent, enable_shape_derivatives, broad_phase, ccd_tolerance,
359 if (use_adaptive_barrier_stiffness)
366 assert(barrier_stiffness.is_number());
367 assert(barrier_stiffness.get<
double>() > 0);
376 if (use_gcp_formulation)
379 collision_mesh, dhat, avg_mass, alpha_t, alpha_n, use_adaptive_dhat, min_distance_ratio,
380 use_adaptive_barrier_stiffness, is_time_dependent, enable_shape_derivatives, broad_phase,
386 collision_mesh, dhat, avg_mass, use_area_weighting, use_improved_max_operator, use_physical_barrier,
387 use_adaptive_barrier_stiffness, is_time_dependent, enable_shape_derivatives, broad_phase, ccd_tolerance * units.
characteristic_length(),
391 if (use_adaptive_barrier_stiffness)
393 contact_form->set_barrier_stiffness(initial_barrier_stiffness);
398 assert(barrier_stiffness.is_number());
399 assert(barrier_stiffness.get<
double>() > 0);
407 if (friction_coefficient != 0)
416 if (adhesion_enabled)
419 collision_mesh, dhat_p, dhat_a, Y, is_time_dependent, enable_shape_derivatives,
424 if (tangential_adhesion_coefficient != 0)
427 collision_mesh,
time_integrator, epsa, tangential_adhesion_coefficient,
438 if (is_time_dependent)
441 const std::unordered_map<std::string, std::shared_ptr<Form>> possible_forms_to_damp = {
446 for (
const json ¶ms : rayleigh_damping_jsons)
449 params, possible_forms_to_damp,
453 else if (rayleigh_damping_jsons.size() > 0)
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 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 int 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 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 ¯o_strain_constraint, const bool periodic_contact, const Eigen::VectorXi &tiled_to_single, const std::shared_ptr< utils::PeriodicBoundary > &periodic_bc, const double friction_coefficient, const double epsv, const int friction_iterations, const json &rayleigh_damping)
Initialize the forms and return a vector of pointers to them.