Loading [MathJax]/extensions/tex2jax.js
PolyFEM
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
NLProblem.cpp
Go to the documentation of this file.
1#include "NLProblem.hpp"
2
6
7/*
8m \frac{\partial^2 u}{\partial t^2} = \psi = \text{div}(\sigma[u])\newline
9u^{t+1} = u(t+\Delta t)\approx u(t) + \Delta t \dot u + \frac{\Delta t^2} 2 \ddot u \newline
10= u(t) + \Delta t \dot u + \frac{\Delta t^2}{2} \psi\newline
11M 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
12%
13M (u^{t+1}_h - (u^t_h + \Delta t v^t_h)) - \frac{\Delta t^2} {2} A u^{t+1}_h
14*/
15// mü = ψ = div(σ[u])
16// uᵗ⁺¹ = u(t + Δt) ≈ u(t) + Δtu̇ + ½Δt²ü = u(t) + Δtu̇ + ½Δt²ψ
17// Muₕᵗ⁺¹ ≈ Muₕᵗ + ΔtMvₕᵗ ½Δt²Auₕᵗ⁺¹
18// Root-finding form:
19// M(uₕᵗ⁺¹ - (uₕᵗ + Δtvₕᵗ)) - ½Δt²Auₕᵗ⁺¹ = 0
20
21namespace polyfem::solver
22{
24 const int full_size,
25 const std::vector<std::shared_ptr<Form>> &forms,
26 const std::vector<std::shared_ptr<AugmentedLagrangianForm>> &penalty_forms)
27 : FullNLProblem(forms),
28 full_size_(full_size),
29 t_(0),
30 penalty_forms_(penalty_forms)
31 {
34
36 }
37
39 const int full_size,
40 const std::shared_ptr<utils::PeriodicBoundary> &periodic_bc,
41 const double t,
42 const std::vector<std::shared_ptr<Form>> &forms,
43 const std::vector<std::shared_ptr<AugmentedLagrangianForm>> &penalty_forms)
44 : FullNLProblem(forms),
45 full_size_(full_size),
46 periodic_bc_(periodic_bc),
47 t_(t),
48 penalty_forms_(penalty_forms)
49 {
51 reduced_size_ = (periodic_bc ? periodic_bc->n_periodic_dof() : full_size) - constraint_nodes_.size();
52
53 assert(std::is_sorted(constraint_nodes_.begin(), constraint_nodes_.end()));
54 assert(constraint_nodes_.size() == 0 || (constraint_nodes_.front() >= 0 && constraint_nodes_.back() < full_size_));
56 }
57
59 {
60 constraint_nodes_.clear();
61
62 for (const auto &f : penalty_forms_)
64 f->constraint_nodes().begin(),
65 f->constraint_nodes().end());
66 std::sort(constraint_nodes_.begin(), constraint_nodes_.end());
67 auto it = std::unique(constraint_nodes_.begin(), constraint_nodes_.end());
68 constraint_nodes_.resize(std::distance(constraint_nodes_.begin(), it));
69 }
70
75
76 void NLProblem::update_lagging(const TVector &x, const int iter_num)
77 {
79 }
80
81 void NLProblem::update_quantities(const double t, const TVector &x)
82 {
83 t_ = t;
84 const TVector full = reduced_to_full(x);
85 for (auto &f : forms_)
86 f->update_quantities(t, full);
87 }
88
89 void NLProblem::line_search_begin(const TVector &x0, const TVector &x1)
90 {
92 }
93
94 double NLProblem::max_step_size(const TVector &x0, const TVector &x1)
95 {
97 }
98
99 bool NLProblem::is_step_valid(const TVector &x0, const TVector &x1)
100 {
102 }
103
104 bool NLProblem::is_step_collision_free(const TVector &x0, const TVector &x1)
105 {
107 }
108
109 double NLProblem::value(const TVector &x)
110 {
111 // TODO: removed fearure const bool only_elastic
113 }
114
115 void NLProblem::gradient(const TVector &x, TVector &grad)
116 {
117 TVector full_grad;
119 grad = full_to_reduced_grad(full_grad);
120 }
121
122 void NLProblem::hessian(const TVector &x, THessian &hessian)
123 {
124 THessian full_hessian;
126
128 }
129
130 void NLProblem::solution_changed(const TVector &newX)
131 {
133 }
134
135 void NLProblem::post_step(const polysolve::nonlinear::PostStepData &data)
136 {
137 FullNLProblem::post_step(polysolve::nonlinear::PostStepData(data.iter_num, data.solver_info, reduced_to_full(data.x), reduced_to_full(data.grad)));
138
139 /*if (state_->args["output"]["advanced"]["save_nl_solve_sequence"])
140 {
141 const Eigen::MatrixXd displacements = utils::unflatten(reduced_to_full(data.x), state_->mesh->dimension());
142 io::OBJWriter::write(
143 state_->resolve_output_path(fmt::format("nonlinear_solve_iter{:03d}.obj", data.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:67
void line_search_begin(const TVector &x0, const TVector &x1) override
Definition NLProblem.cpp:89
virtual bool is_step_valid(const TVector &x0, const TVector &x1) override
Definition NLProblem.cpp:99
int reduced_size_
Size of the reduced problem.
Definition NLProblem.hpp:68
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:23
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:81
virtual void gradient(const TVector &x, TVector &gradv) override
void init_lagging(const TVector &x) override
Definition NLProblem.cpp:71
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:76
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:87
virtual double value(const TVector &x) override
virtual double max_step_size(const TVector &x0, const TVector &x1) override
Definition NLProblem.cpp:94
std::shared_ptr< utils::PeriodicBoundary > periodic_bc_
Definition NLProblem.hpp:70
virtual void hessian(const TVector &x, THessian &hessian) override
std::vector< int > constraint_nodes_
Definition NLProblem.hpp:65
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.