PolyFEM
Loading...
Searching...
No Matches
BarrierForms.cpp
Go to the documentation of this file.
1#include "BarrierForms.hpp"
2#include <polyfem/State.hpp>
3
4namespace polyfem::solver
5{
6 CollisionBarrierForm::CollisionBarrierForm(const VariableToSimulationGroup& variable_to_simulation, const State &state, const double dhat)
7 : AdjointForm(variable_to_simulation), state_(state), dhat_(dhat), barrier_potential_(dhat)
8 {
12 [this](const std::string &p) { return this->state_.resolve_input_path(p); },
14
15 Eigen::MatrixXd V;
18
19 broad_phase_method_ = ipc::BroadPhaseMethod::HASH_GRID;
20 }
21
22 double CollisionBarrierForm::value_unweighted(const Eigen::VectorXd &x) const
23 {
24 const Eigen::MatrixXd displaced_surface = collision_mesh_.vertices(utils::unflatten(get_updated_mesh_nodes(x), state_.mesh->dimension()));
25 return barrier_potential_(collision_set, collision_mesh_, displaced_surface);
26 }
27
28 void CollisionBarrierForm::compute_partial_gradient(const Eigen::VectorXd &x, Eigen::VectorXd &gradv) const
29 {
30
32 const Eigen::MatrixXd displaced_surface = collision_mesh_.vertices(utils::unflatten(get_updated_mesh_nodes(x), state_.mesh->dimension()));
33 const Eigen::VectorXd grad = collision_mesh_.to_full_dof(barrier_potential_.gradient(collision_set, collision_mesh_, displaced_surface));
35 });
36 }
37
38 void CollisionBarrierForm::solution_changed(const Eigen::VectorXd &x)
39 {
41
42 const Eigen::MatrixXd displaced_surface = collision_mesh_.vertices(utils::unflatten(get_updated_mesh_nodes(x), state_.mesh->dimension()));
43 build_collision_set(displaced_surface);
44 }
45
46 bool CollisionBarrierForm::is_step_collision_free(const Eigen::VectorXd &x0, const Eigen::VectorXd &x1) const
47 {
48 const Eigen::MatrixXd V0 = utils::unflatten(get_updated_mesh_nodes(x0), state_.mesh->dimension());
49 const Eigen::MatrixXd V1 = utils::unflatten(get_updated_mesh_nodes(x1), state_.mesh->dimension());
50
51 // Skip CCD if the displacement is zero.
52 if ((V1 - V0).lpNorm<Eigen::Infinity>() == 0.0)
53 return true;
54
55 bool is_valid = ipc::is_step_collision_free(
57 collision_mesh_.vertices(V0),
58 collision_mesh_.vertices(V1),
60 1e-6, 1e6);
61
62 return is_valid;
63 }
64
65 double CollisionBarrierForm::max_step_size(const Eigen::VectorXd &x0, const Eigen::VectorXd &x1) const
66 {
67 const Eigen::MatrixXd V0 = utils::unflatten(get_updated_mesh_nodes(x0), state_.mesh->dimension());
68 const Eigen::MatrixXd V1 = utils::unflatten(get_updated_mesh_nodes(x1), state_.mesh->dimension());
69
70 double max_step = ipc::compute_collision_free_stepsize(
72 collision_mesh_.vertices(V0),
73 collision_mesh_.vertices(V1),
74 broad_phase_method_, 1e-6, 1e6);
75
76 return max_step;
77 }
78
79 void CollisionBarrierForm::build_collision_set(const Eigen::MatrixXd &displaced_surface)
80 {
81 static Eigen::MatrixXd cached_displaced_surface;
82 if (cached_displaced_surface.size() == displaced_surface.size() && cached_displaced_surface == displaced_surface)
83 return;
84
85 collision_set.build(collision_mesh_, displaced_surface, dhat_, 0, broad_phase_method_);
86
87 cached_displaced_surface = displaced_surface;
88 }
89
90 Eigen::VectorXd CollisionBarrierForm::get_updated_mesh_nodes(const Eigen::VectorXd &x) const
91 {
92 Eigen::VectorXd X = X_init;
95 }
96
97 DeformedCollisionBarrierForm::DeformedCollisionBarrierForm(const VariableToSimulationGroup& variable_to_simulation, const State &state, const double dhat)
98 : AdjointForm(variable_to_simulation), state_(state), dhat_(dhat), barrier_potential_(dhat)
99 {
101 log_and_throw_adjoint_error("[{}] Should use linear FE basis!", name());
102
106 [this](const std::string &p) { return this->state_.resolve_input_path(p); },
108
109 Eigen::MatrixXd V;
112
113 broad_phase_method_ = ipc::BroadPhaseMethod::HASH_GRID;
114 }
115
116 double DeformedCollisionBarrierForm::value_unweighted(const Eigen::VectorXd &x) const
117 {
118 const Eigen::MatrixXd displaced_surface = collision_mesh_.vertices(utils::unflatten(get_updated_mesh_nodes(x), state_.mesh->dimension()));
119
120 return barrier_potential_(collision_set, collision_mesh_, displaced_surface);
121 }
122
123 void DeformedCollisionBarrierForm::compute_partial_gradient(const Eigen::VectorXd &x, Eigen::VectorXd &gradv) const
124 {
126 const Eigen::MatrixXd displaced_surface = collision_mesh_.vertices(utils::unflatten(get_updated_mesh_nodes(x), state_.mesh->dimension()));
127 const Eigen::VectorXd grad = collision_mesh_.to_full_dof(barrier_potential_.gradient(collision_set, collision_mesh_, displaced_surface));
129 });
130 }
131
133 {
135
136 const Eigen::MatrixXd displaced_surface = collision_mesh_.vertices(utils::unflatten(get_updated_mesh_nodes(x), state_.mesh->dimension()));
137 build_collision_set(displaced_surface);
138 }
139
140 bool DeformedCollisionBarrierForm::is_step_collision_free(const Eigen::VectorXd &x0, const Eigen::VectorXd &x1) const
141 {
142 // const Eigen::MatrixXd V0 = utils::unflatten(get_updated_mesh_nodes(x0), state_.mesh->dimension());
143 // const Eigen::MatrixXd V1 = utils::unflatten(get_updated_mesh_nodes(x1), state_.mesh->dimension());
144
145 // // Skip CCD if the displacement is zero.
146 // if ((V1 - V0).lpNorm<Eigen::Infinity>() == 0.0)
147 // return true;
148
149 // bool is_valid = ipc::is_step_collision_free(
150 // collision_mesh_,
151 // collision_mesh_.vertices(V0),
152 // collision_mesh_.vertices(V1),
153 // broad_phase_method_,
154 // 1e-6, 1e6);
155
156 return true; // is_valid;
157 }
158
159 double DeformedCollisionBarrierForm::max_step_size(const Eigen::VectorXd &x0, const Eigen::VectorXd &x1) const
160 {
161 // const Eigen::MatrixXd V0 = utils::unflatten(get_updated_mesh_nodes(x0), state_.mesh->dimension());
162 // const Eigen::MatrixXd V1 = utils::unflatten(get_updated_mesh_nodes(x1), state_.mesh->dimension());
163
164 // double max_step = ipc::compute_collision_free_stepsize(
165 // collision_mesh_,
166 // collision_mesh_.vertices(V0),
167 // collision_mesh_.vertices(V1),
168 // broad_phase_method_, 1e-6, 1e6);
169
170 return 1; // max_step;
171 }
172
173 void DeformedCollisionBarrierForm::build_collision_set(const Eigen::MatrixXd &displaced_surface)
174 {
175 static Eigen::MatrixXd cached_displaced_surface;
176 if (cached_displaced_surface.size() == displaced_surface.size() && cached_displaced_surface == displaced_surface)
177 return;
178
179 collision_set.build(collision_mesh_, displaced_surface, dhat_, 0, broad_phase_method_);
180
181 cached_displaced_surface = displaced_surface;
182 }
183
190} // namespace polyfem::solver
int V
int x
main class that contains the polyfem solver and all its state
Definition State.hpp:79
void get_vertices(Eigen::MatrixXd &vertices) const
Definition StateDiff.cpp:69
int n_bases
number of bases
Definition State.hpp:178
const std::vector< basis::ElementBases > & geom_bases() const
Get a constant reference to the geometry mapping bases.
Definition State.hpp:223
Eigen::VectorXi in_node_to_node
Inpute nodes (including high-order) to polyfem nodes, only for isoparametric.
Definition State.hpp:450
mesh::Obstacle obstacle
Obstacles used in collisions.
Definition State.hpp:468
std::unique_ptr< mesh::Mesh > mesh
current mesh, it can be a Mesh2D or Mesh3D
Definition State.hpp:466
json args
main input arguments containing all defaults
Definition State.hpp:101
solver::DiffCache diff_cached
Definition State.hpp:669
int n_geom_bases
number of geometric bases
Definition State.hpp:182
std::vector< mesh::LocalBoundary > total_local_boundary
mapping from elements to nodes for all mesh
Definition State.hpp:431
void build_collision_mesh()
extracts the boundary mesh for collision, called in build_basis
Definition State.cpp:1407
virtual void solution_changed(const Eigen::VectorXd &new_x) override
Update cached fields upon a change in the solution.
const VariableToSimulationGroup variable_to_simulations_
void build_collision_set(const Eigen::MatrixXd &displaced_surface)
ipc::BroadPhaseMethod broad_phase_method_
bool is_step_collision_free(const Eigen::VectorXd &x0, const Eigen::VectorXd &x1) const override
Checks if the step is collision free.
double max_step_size(const Eigen::VectorXd &x0, const Eigen::VectorXd &x1) const override
Determine the maximum step size allowable between the current and next solution.
CollisionBarrierForm(const VariableToSimulationGroup &variable_to_simulation, const State &state, const double dhat)
void compute_partial_gradient(const Eigen::VectorXd &x, Eigen::VectorXd &gradv) const override
const ipc::BarrierPotential barrier_potential_
void solution_changed(const Eigen::VectorXd &x) override
Update cached fields upon a change in the solution.
double value_unweighted(const Eigen::VectorXd &x) const override
Compute the value of the form.
Eigen::VectorXd get_updated_mesh_nodes(const Eigen::VectorXd &x) const
bool is_step_collision_free(const Eigen::VectorXd &x0, const Eigen::VectorXd &x1) const override
Checks if the step is collision free.
void compute_partial_gradient(const Eigen::VectorXd &x, Eigen::VectorXd &gradv) const override
double max_step_size(const Eigen::VectorXd &x0, const Eigen::VectorXd &x1) const override
Determine the maximum step size allowable between the current and next solution.
DeformedCollisionBarrierForm(const VariableToSimulationGroup &variable_to_simulation, const State &state, const double dhat)
double value_unweighted(const Eigen::VectorXd &x) const override
Compute the value of the form.
const ipc::BarrierPotential barrier_potential_
void build_collision_set(const Eigen::MatrixXd &displaced_surface)
Eigen::VectorXd get_updated_mesh_nodes(const Eigen::VectorXd &x) const
void solution_changed(const Eigen::VectorXd &x) override
Update cached fields upon a change in the solution.
Eigen::VectorXd u(int step) const
virtual double weight() const
Get the form's multiplicative constant weight.
Definition Form.hpp:126
A collection of VariableToSimulation.
void compute_state_variable(const ParameterType type, const State *state_ptr, const Eigen::VectorXd &x, Eigen::VectorXd &state_variable) const
Evaluate the variable to simulations and overwrite the state_variable based on x.
Eigen::VectorXd apply_parametrization_jacobian(const ParameterType type, const State *state_ptr, const Eigen::VectorXd &x, const std::function< Eigen::VectorXd()> &grad) const
Maps the partial gradient wrt.
Eigen::VectorXd map_primitive_to_node_order(const State &state, const Eigen::VectorXd &primitives)
Eigen::VectorXd map_node_to_primitive_order(const State &state, const Eigen::VectorXd &nodes)
Eigen::MatrixXd unflatten(const Eigen::VectorXd &x, int dim)
Unflatten rowwises, so every dim elements in x become a row.
Eigen::VectorXd flatten(const Eigen::MatrixXd &X)
Flatten rowwises.
void log_and_throw_adjoint_error(const std::string &msg)
Definition Logger.cpp:77