PolyFEM
Loading...
Searching...
No Matches
NLProblem.cpp
Go to the documentation of this file.
1#include "NLProblem.hpp"
2
5
6/*
7m \frac{\partial^2 u}{\partial t^2} = \psi = \text{div}(\sigma[u])\newline
8u^{t+1} = u(t+\Delta t)\approx u(t) + \Delta t \dot u + \frac{\Delta t^2} 2 \ddot u \newline
9= u(t) + \Delta t \dot u + \frac{\Delta t^2}{2} \psi\newline
10M u^{t+1}_h \approx M u^t_h + \Delta t M v^t_h + \frac{\Delta t^2} {2} A u^{t+1}_h \newline
11%
12M (u^{t+1}_h - (u^t_h + \Delta t v^t_h)) - \frac{\Delta t^2} {2} A u^{t+1}_h
13*/
14// mü = ψ = div(σ[u])
15// uᵗ⁺¹ = u(t + Δt) ≈ u(t) + Δtu̇ + ½Δt²ü = u(t) + Δtu̇ + ½Δt²ψ
16// Muₕᵗ⁺¹ ≈ Muₕᵗ + ΔtMvₕᵗ ½Δt²Auₕᵗ⁺¹
17// Root-finding form:
18// M(uₕᵗ⁺¹ - (uₕᵗ + Δtvₕᵗ)) - ½Δt²Auₕᵗ⁺¹ = 0
19
20namespace polyfem::solver
21{
23 const int full_size,
24 const std::vector<std::shared_ptr<Form>> &forms,
25 const std::vector<std::shared_ptr<AugmentedLagrangianForm>> &penalty_forms)
26 : FullNLProblem(forms),
27 full_size_(full_size),
28 t_(0),
29 penalty_forms_(penalty_forms)
30 {
33
35 }
36
38 const int full_size,
39 const std::shared_ptr<utils::PeriodicBoundary> &periodic_bc,
40 const double t,
41 const std::vector<std::shared_ptr<Form>> &forms,
42 const std::vector<std::shared_ptr<AugmentedLagrangianForm>> &penalty_forms)
43 : FullNLProblem(forms),
44 full_size_(full_size),
45 periodic_bc_(periodic_bc),
46 t_(t),
47 penalty_forms_(penalty_forms)
48 {
50 reduced_size_ = (periodic_bc ? periodic_bc->n_periodic_dof() : full_size) - constraint_nodes_.size();
51
52 assert(std::is_sorted(constraint_nodes_.begin(), constraint_nodes_.end()));
53 assert(constraint_nodes_.size() == 0 || (constraint_nodes_.front() >= 0 && constraint_nodes_.back() < full_size_));
55 }
56
58 {
59 constraint_nodes_.clear();
60
61 for (const auto &f : penalty_forms_)
63 f->constraint_nodes().begin(),
64 f->constraint_nodes().end());
65 std::sort(constraint_nodes_.begin(), constraint_nodes_.end());
66 auto it = std::unique(constraint_nodes_.begin(), constraint_nodes_.end());
67 constraint_nodes_.resize(std::distance(constraint_nodes_.begin(), it));
68 }
69
74
75 void NLProblem::update_lagging(const TVector &x, const int iter_num)
76 {
78 }
79
80 void NLProblem::update_quantities(const double t, const TVector &x)
81 {
82 t_ = t;
83 const TVector full = reduced_to_full(x);
84 for (auto &f : forms_)
85 f->update_quantities(t, full);
86 }
87
88 void NLProblem::line_search_begin(const TVector &x0, const TVector &x1)
89 {
91 }
92
93 double NLProblem::max_step_size(const TVector &x0, const TVector &x1)
94 {
96 }
97
98 bool NLProblem::is_step_valid(const TVector &x0, const TVector &x1)
99 {
101 }
102
103 bool NLProblem::is_step_collision_free(const TVector &x0, const TVector &x1)
104 {
106 }
107
108 double NLProblem::value(const TVector &x)
109 {
110 // TODO: removed fearure const bool only_elastic
112 }
113
114 void NLProblem::gradient(const TVector &x, TVector &grad)
115 {
116 TVector full_grad;
118 grad = full_to_reduced_grad(full_grad);
119 }
120
121 void NLProblem::hessian(const TVector &x, THessian &hessian)
122 {
123 THessian full_hessian;
125
127 }
128
129 void NLProblem::solution_changed(const TVector &newX)
130 {
132 }
133
134 void NLProblem::post_step(const polysolve::nonlinear::PostStepData &data)
135 {
136 FullNLProblem::post_step(polysolve::nonlinear::PostStepData(data.iter_num, data.solver_info, reduced_to_full(data.x), reduced_to_full(data.grad)));
137
138 // TODO: add me back
139 // if (state_.args["output"]["advanced"]["save_nl_solve_sequence"])
140 // {
141 // const Eigen::MatrixXd displacements = utils::unflatten(reduced_to_full(x), state_.mesh->dimension());
142 // io::OBJWriter::write(
143 // state_.resolve_output_path(fmt::format("nonlinear_solve_iter{:03d}.obj", iter_num)),
144 // state_.collision_mesh.displace_vertices(displacements),
145 // state_.collision_mesh.edges(), state_.collision_mesh.faces());
146 // }
147 }
148
149 NLProblem::TVector NLProblem::full_to_reduced(const TVector &full) const
150 {
151 TVector reduced;
153 return reduced;
154 }
155
156 NLProblem::TVector NLProblem::full_to_reduced_grad(const TVector &full) const
157 {
158 TVector reduced;
160 return reduced;
161 }
162
163 NLProblem::TVector NLProblem::reduced_to_full(const TVector &reduced) const
164 {
165 TVector full;
167 return full;
168 }
169
170 Eigen::MatrixXd NLProblem::constraint_values(const TVector &reduced) const
171 {
172 Eigen::MatrixXd result = Eigen::MatrixXd::Zero(full_size(), 1);
173
174 for (const auto &form : penalty_forms_)
175 {
176 const auto tmp = form->target(reduced);
177 if (tmp.size() > 0)
178 result += tmp;
179 }
180
181 return result;
182 }
183
184 template <class FullMat, class ReducedMat>
185 void NLProblem::full_to_reduced_aux(const std::vector<int> &constraint_nodes, const int full_size, const int reduced_size, const FullMat &full, ReducedMat &reduced) const
186 {
187 using namespace polyfem;
188
189 // Reduced is already at the full size
190 if (full_size == reduced_size || full.size() == reduced_size)
191 {
192 reduced = full;
193 return;
194 }
195
196 assert(full.size() == full_size);
197 assert(full.cols() == 1);
198 reduced.resize(reduced_size, 1);
199
200 Eigen::MatrixXd mid;
201 if (periodic_bc_)
202 mid = periodic_bc_->full_to_periodic(full, false);
203 else
204 mid = full;
205
206 assert(std::is_sorted(constraint_nodes.begin(), constraint_nodes.end()));
207
208 long j = 0;
209 size_t k = 0;
210 for (int i = 0; i < mid.size(); ++i)
211 {
212 if (k < constraint_nodes.size() && constraint_nodes[k] == i)
213 {
214 ++k;
215 continue;
216 }
217
218 assert(j < reduced.size());
219 reduced(j++) = mid(i);
220 }
221 }
222
223 template <class ReducedMat, class FullMat>
224 void NLProblem::reduced_to_full_aux(const std::vector<int> &constraint_nodes, const int full_size, const int reduced_size, const ReducedMat &reduced, const Eigen::MatrixXd &rhs, FullMat &full) const
225 {
226 using namespace polyfem;
227
228 // Full is already at the reduced size
229 if (full_size == reduced_size || full_size == reduced.size())
230 {
231 full = reduced;
232 return;
233 }
234
235 assert(reduced.size() == reduced_size);
236 assert(reduced.cols() == 1);
237 full.resize(full_size, 1);
238
239 assert(std::is_sorted(constraint_nodes.begin(), constraint_nodes.end()));
240
241 long j = 0;
242 size_t k = 0;
243 Eigen::MatrixXd mid(reduced_size + constraint_nodes.size(), 1);
244 for (int i = 0; i < mid.size(); ++i)
245 {
246 if (k < constraint_nodes.size() && constraint_nodes[k] == i)
247 {
248 ++k;
249 mid(i) = rhs(i);
250 continue;
251 }
252
253 mid(i) = reduced(j++);
254 }
255
256 full = periodic_bc_ ? periodic_bc_->periodic_to_full(full_size, mid) : mid;
257 }
258
259 template <class FullMat, class ReducedMat>
260 void NLProblem::full_to_reduced_aux_grad(const std::vector<int> &constraint_nodes, const int full_size, const int reduced_size, const FullMat &full, ReducedMat &reduced) const
261 {
262 using namespace polyfem;
263
264 // Reduced is already at the full size
265 if (full_size == reduced_size || full.size() == reduced_size)
266 {
267 reduced = full;
268 return;
269 }
270
271 assert(full.size() == full_size);
272 assert(full.cols() == 1);
273 reduced.resize(reduced_size, 1);
274
275 Eigen::MatrixXd mid;
276 if (periodic_bc_)
277 mid = periodic_bc_->full_to_periodic(full, true);
278 else
279 mid = full;
280
281 long j = 0;
282 size_t k = 0;
283 for (int i = 0; i < mid.size(); ++i)
284 {
285 if (k < constraint_nodes.size() && constraint_nodes[k] == i)
286 {
287 ++k;
288 continue;
289 }
290
291 reduced(j++) = mid(i);
292 }
293 }
294
295 void NLProblem::full_hessian_to_reduced_hessian(const THessian &full, THessian &reduced) const
296 {
297 // POLYFEM_SCOPED_TIMER("\tfull hessian to reduced hessian");
298 THessian mid = full;
299
300 if (periodic_bc_)
301 periodic_bc_->full_to_periodic(mid);
302
303 if (current_size() < full_size())
304 utils::full_to_reduced_matrix(mid.rows(), mid.rows() - constraint_nodes_.size(), constraint_nodes_, mid, reduced);
305 else
306 reduced = mid;
307 }
308} // namespace polyfem::solver
int x
virtual double max_step_size(const TVector &x0, const TVector &x1) override
virtual void init_lagging(const TVector &x)
virtual void hessian(const TVector &x, THessian &hessian) override
virtual bool is_step_collision_free(const TVector &x0, const TVector &x1)
std::vector< std::shared_ptr< Form > > forms_
virtual void post_step(const polysolve::nonlinear::PostStepData &data) override
virtual void update_lagging(const TVector &x, const int iter_num)
virtual bool is_step_valid(const TVector &x0, const TVector &x1) override
virtual double value(const TVector &x) override
virtual void solution_changed(const TVector &new_x) override
virtual void gradient(const TVector &x, TVector &gradv) override
virtual void line_search_begin(const TVector &x0, const TVector &x1) override
const int full_size_
Size of the full problem.
Definition NLProblem.hpp:65
void line_search_begin(const TVector &x0, const TVector &x1) override
Definition NLProblem.cpp:88
virtual bool is_step_valid(const TVector &x0, const TVector &x1) override
Definition NLProblem.cpp:98
int reduced_size_
Size of the reduced problem.
Definition NLProblem.hpp:66
virtual void post_step(const polysolve::nonlinear::PostStepData &data) override
virtual TVector full_to_reduced_grad(const TVector &full) const
NLProblem(const int full_size, const std::vector< std::shared_ptr< Form > > &forms, const std::vector< std::shared_ptr< AugmentedLagrangianForm > > &penalty_forms)
Definition NLProblem.cpp:22
virtual Eigen::MatrixXd constraint_values(const TVector &reduced) const
virtual TVector full_to_reduced(const TVector &full) const
virtual void update_quantities(const double t, const TVector &x)
Definition NLProblem.cpp:80
virtual void gradient(const TVector &x, TVector &gradv) override
void init_lagging(const TVector &x) override
Definition NLProblem.cpp:70
virtual bool is_step_collision_free(const TVector &x0, const TVector &x1) override
virtual TVector reduced_to_full(const TVector &reduced) const
void update_lagging(const TVector &x, const int iter_num) override
Definition NLProblem.cpp:75
virtual void full_hessian_to_reduced_hessian(const THessian &full, THessian &reduced) const
void full_to_reduced_aux(const std::vector< int > &constraint_nodes, const int full_size, const int reduced_size, const FullMat &full, ReducedMat &reduced) const
std::vector< std::shared_ptr< AugmentedLagrangianForm > > penalty_forms_
Definition NLProblem.hpp:84
virtual double value(const TVector &x) override
virtual double max_step_size(const TVector &x0, const TVector &x1) override
Definition NLProblem.cpp:93
std::shared_ptr< utils::PeriodicBoundary > periodic_bc_
Definition NLProblem.hpp:68
virtual void hessian(const TVector &x, THessian &hessian) override
std::vector< int > constraint_nodes_
Definition NLProblem.hpp:63
void solution_changed(const TVector &new_x) override
void reduced_to_full_aux(const std::vector< int > &constraint_nodes, const int full_size, const int reduced_size, const ReducedMat &reduced, const Eigen::MatrixXd &rhs, FullMat &full) const
void full_to_reduced_aux_grad(const std::vector< int > &constraint_nodes, const int full_size, const int reduced_size, const FullMat &full, ReducedMat &reduced) const
void full_to_reduced_matrix(const int full_size, const int reduced_size, const std::vector< int > &removed_vars, const StiffnessMatrix &full, StiffnessMatrix &reduced)
Map a full size matrix to a reduced one by dropping rows and columns.