PolyFEM
Loading...
Searching...
No Matches
VariableToSimulation.cpp
Go to the documentation of this file.
2#include <polyfem/State.hpp>
6
8
11
12namespace polyfem::solver
13{
14 std::unique_ptr<VariableToSimulation> VariableToSimulation::create(const std::string &type, const std::vector<std::shared_ptr<State>> &states, CompositeParametrization &&parametrization)
15 {
16 if (type == "shape")
17 return std::make_unique<ShapeVariableToSimulation>(states, parametrization);
18 else if (type == "elastic")
19 return std::make_unique<ElasticVariableToSimulation>(states, parametrization);
20 else if (type == "friction")
21 return std::make_unique<FrictionCoeffientVariableToSimulation>(states, parametrization);
22 else if (type == "damping")
23 return std::make_unique<DampingCoeffientVariableToSimulation>(states, parametrization);
24 else if (type == "initial")
25 return std::make_unique<InitialConditionVariableToSimulation>(states, parametrization);
26 else if (type == "dirichlet")
27 return std::make_unique<DirichletVariableToSimulation>(states, parametrization);
28 else if (type == "pressure")
29 return std::make_unique<PressureVariableToSimulation>(states, parametrization);
30 else if (type == "periodic-shape")
31 return std::make_unique<PeriodicShapeVariableToSimulation>(states, parametrization);
32
33 log_and_throw_adjoint_error("Invalid type of VariableToSimulation!");
34 return std::unique_ptr<VariableToSimulation>();
35 }
36
38 {
39 const std::string composite_map_type = args["composite_map_type"];
40 const State &state = *(states_[0]);
41 if (composite_map_type == "none")
42 {
43 output_indexing_.resize(0);
44 }
45 else if (composite_map_type == "indices")
46 {
47 if (args["composite_map_indices"].is_string())
48 {
49 Eigen::MatrixXi tmp_mat;
50 polyfem::io::read_matrix(state.resolve_input_path(args["composite_map_indices"].get<std::string>()), tmp_mat);
52 }
53 else if (args["composite_map_indices"].is_array())
54 output_indexing_ = args["composite_map_indices"];
55 else
56 log_and_throw_adjoint_error("Invalid composite map indices type!");
57 }
58 else
59 log_and_throw_adjoint_error("Unknown composite_map_type!");
60 }
61
62 Eigen::VectorXi VariableToSimulation::get_output_indexing(const Eigen::VectorXd &x) const
63 {
64 const int out_size = parametrization_.size(x.size());
65 if (output_indexing_.size() == out_size || out_size == 0)
66 return output_indexing_;
67 else if (output_indexing_.size() == 0)
68 {
69 Eigen::VectorXi ind;
70 ind.setLinSpaced(out_size, 0, out_size - 1);
71 return ind;
72 }
73 else
74 log_and_throw_adjoint_error(fmt::format("[{}] Indexing size and output size of the Parametrization do not match! {} vs {}", name(), output_indexing_.size(), out_size));
75 return Eigen::VectorXi();
76 }
77
78 Eigen::VectorXd VariableToSimulation::apply_parametrization_jacobian(const Eigen::VectorXd &term, const Eigen::VectorXd &x) const
79 {
81 }
82
84 {
85 log_and_throw_adjoint_error("[{}] inverse_eval not implemented!", name());
86 return Eigen::VectorXd();
87 }
88
89 void VariableToSimulation::update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices)
90 {
91 log_and_throw_adjoint_error("[{}] update_state not implemented!", name());
92 }
93
94 void VariableToSimulationGroup::init(const json &args, const std::vector<std::shared_ptr<State>> &states, const std::vector<int> &variable_sizes)
95 {
96 std::vector<ValueType>().swap(L);
97 for (const auto &arg : args)
98 L.push_back(AdjointOptUtils::create_variable_to_simulation(arg, states, variable_sizes));
99 }
100
101 Eigen::VectorXd VariableToSimulationGroup::compute_adjoint_term(const Eigen::VectorXd &x) const
102 {
103 Eigen::VectorXd adjoint_term = Eigen::VectorXd::Zero(x.size());
104 for (const auto &v2s : L)
105 adjoint_term += v2s->compute_adjoint_term(x);
106 return adjoint_term;
107 }
108
109 void VariableToSimulationGroup::compute_state_variable(const ParameterType type, const State *state_ptr, const Eigen::VectorXd &x, Eigen::VectorXd &state_variable) const
110 {
111 for (const auto &v2s : L)
112 {
113 if (v2s->get_parameter_type() != type)
114 continue;
115
116 const Eigen::VectorXd var = v2s->get_parametrization().eval(x);
117 for (const auto &state : v2s->get_states())
118 {
119 if (state.get() != state_ptr)
120 continue;
121
122 state_variable(v2s->get_output_indexing(x)) = var;
123 }
124 }
125 }
126
127 Eigen::VectorXd VariableToSimulationGroup::apply_parametrization_jacobian(const ParameterType type, const State *state_ptr, const Eigen::VectorXd &x, const std::function<Eigen::VectorXd()> &grad) const
128 {
129 Eigen::VectorXd gradv = Eigen::VectorXd::Zero(x.size());
130 for (const auto &v2s : L)
131 {
132 if (v2s->get_parameter_type() != type)
133 continue;
134
135 for (const auto &state : v2s->get_states())
136 {
137 if (state.get() != state_ptr)
138 continue;
139
140 gradv += v2s->apply_parametrization_jacobian(grad(), x);
141 }
142 }
143 return gradv;
144 }
145
146 void ShapeVariableToSimulation::update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices)
147 {
148 for (auto state : states_)
149 {
150 const int dim = state->mesh->dimension();
151
152 // If indices include one vertex entry, we assume it include all entries of this vertex.
153 for (int i = 0; i < indices.size(); i += dim)
154 for (int j = 0; j < dim; j++)
155 assert(indices(i + j) == indices(i) + j);
156
157 for (int i = 0; i < indices.size(); i += dim)
158 state->set_mesh_vertex(indices(i) / dim, state_variable(Eigen::seqN(i, dim)));
159 }
160 }
161 Eigen::VectorXd ShapeVariableToSimulation::compute_adjoint_term(const Eigen::VectorXd &x) const
162 {
163 Eigen::VectorXd term, cur_term;
164 for (auto state : states_)
165 {
166 if (state->problem->is_time_dependent())
167 AdjointTools::dJ_shape_transient_adjoint_term(*state, state->get_adjoint_mat(1), state->get_adjoint_mat(0), cur_term);
168 else
169 {
170 if (!state->is_homogenization())
171 AdjointTools::dJ_shape_static_adjoint_term(*state, state->diff_cached.u(0), state->get_adjoint_mat(0), cur_term);
172 else
173 AdjointTools::dJ_shape_homogenization_adjoint_term(*state, state->diff_cached.u(0), state->get_adjoint_mat(0), cur_term);
174 }
175
176 if (term.size() != cur_term.size())
177 term = cur_term;
178 else
179 term += cur_term;
180 }
181 return apply_parametrization_jacobian(term, x);
182 }
184 {
185 const int dim = states_[0]->mesh->dimension();
186 const int npts = states_[0]->mesh->n_vertices();
187
188 Eigen::VectorXd x;
189 Eigen::VectorXi indices = get_output_indexing(x);
190
191 if (indices.size() == 0)
192 indices.setLinSpaced(npts * dim, 0, npts * dim - 1);
193
194 Eigen::MatrixXd V;
195 states_[0]->get_vertices(V);
196 if (indices.maxCoeff() >= V.size())
197 log_and_throw_adjoint_error("Output indices larger than DoFs of vertices!");
198 x = utils::flatten(V)(indices);
199
201 }
203 {
204 const std::string composite_map_type = args["composite_map_type"];
205 const State &state = *(states_[0]);
206 if (composite_map_type == "interior")
207 {
208 VariableToInteriorNodes variable_to_node(state, args["volume_selection"]);
209 output_indexing_ = variable_to_node.get_output_indexing();
210 }
211 else if (composite_map_type == "boundary")
212 {
213 VariableToBoundaryNodes variable_to_node(state, args["surface_selection"]);
214 output_indexing_ = variable_to_node.get_output_indexing();
215 }
216 else if (composite_map_type == "boundary_excluding_surface")
217 {
218 const std::vector<int> excluded_surfaces = args["surface_selection"];
219 VariableToBoundaryNodesExclusive variable_to_node(state, excluded_surfaces);
220 output_indexing_ = variable_to_node.get_output_indexing();
221 }
222 else
224 }
225
226 void ElasticVariableToSimulation::update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices)
227 {
228 for (auto state : states_)
229 {
230 const int n_elem = state->bases.size();
231 assert(n_elem * 2 == state_variable.size());
232 state->assembler->update_lame_params(state_variable.segment(0, n_elem), state_variable.segment(n_elem, n_elem));
233 }
234 }
235 Eigen::VectorXd ElasticVariableToSimulation::compute_adjoint_term(const Eigen::VectorXd &x) const
236 {
237 Eigen::VectorXd term, cur_term;
238 for (auto state : states_)
239 {
240 if (state->problem->is_time_dependent())
241 AdjointTools::dJ_material_transient_adjoint_term(*state, state->get_adjoint_mat(1), state->get_adjoint_mat(0), cur_term);
242 else
243 AdjointTools::dJ_material_static_adjoint_term(*state, state->diff_cached.u(0), state->get_adjoint_mat(0), cur_term);
244
245 if (term.size() != cur_term.size())
246 term = cur_term;
247 else
248 term += cur_term;
249 }
250 return apply_parametrization_jacobian(term, x);
251 }
253 {
254 auto &state = *(states_[0]);
255 auto params_map = state.assembler->parameters();
256
257 auto search_lambda = params_map.find("lambda");
258 auto search_mu = params_map.find("mu");
259 if (search_lambda == params_map.end() || search_mu == params_map.end())
260 {
261 log_and_throw_adjoint_error("[{}] Failed to find Lame parameters!", name());
262 return Eigen::VectorXd();
263 }
264
265 Eigen::VectorXd lambdas(state.mesh->n_elements());
266 Eigen::VectorXd mus(state.mesh->n_elements());
267 for (int e = 0; e < state.mesh->n_elements(); e++)
268 {
269 RowVectorNd barycenter;
270 if (!state.mesh->is_volume())
271 {
272 const auto &mesh2d = *dynamic_cast<mesh::Mesh2D *>(state.mesh.get());
273 barycenter = mesh2d.face_barycenter(e);
274 }
275 else
276 {
277 const auto &mesh3d = *dynamic_cast<mesh::Mesh3D *>(state.mesh.get());
278 barycenter = mesh3d.cell_barycenter(e);
279 }
280 lambdas(e) = search_lambda->second(RowVectorNd::Zero(state.mesh->dimension()), barycenter, 0., e);
281 mus(e) = search_mu->second(RowVectorNd::Zero(state.mesh->dimension()), barycenter, 0., e);
282 }
283 state.assembler->update_lame_params(lambdas, mus);
284
285 Eigen::VectorXd params(lambdas.size() + mus.size());
286 params << lambdas, mus;
287
288 return parametrization_.inverse_eval(params);
289 }
290
291 void FrictionCoeffientVariableToSimulation::update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices)
292 {
293 assert(state_variable.size() == 1);
294 assert(state_variable(0) >= 0);
295 for (auto state : states_)
296 state->args["contact"]["friction_coefficient"] = state_variable(0);
297 }
298 Eigen::VectorXd FrictionCoeffientVariableToSimulation::compute_adjoint_term(const Eigen::VectorXd &x) const
299 {
300 Eigen::VectorXd term, cur_term;
301 for (auto state : states_)
302 {
303 if (state->problem->is_time_dependent())
304 AdjointTools::dJ_friction_transient_adjoint_term(*state, state->get_adjoint_mat(1), state->get_adjoint_mat(0), cur_term);
305 else
306 log_and_throw_adjoint_error("[{}] Gradient in static simulations not implemented!", name());
307
308 if (term.size() != cur_term.size())
309 term = cur_term;
310 else
311 term += cur_term;
312 }
313 return apply_parametrization_jacobian(term, x);
314 }
316 {
317 log_and_throw_adjoint_error("[{}] inverse_eval not implemented!", name());
318 return Eigen::VectorXd();
319 }
320
321 void DampingCoeffientVariableToSimulation::update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices)
322 {
323 assert(state_variable.size() == 2);
324 json damping_param = {
325 {"psi", state_variable(0)},
326 {"phi", state_variable(1)},
327 };
328 for (auto state : states_)
329 {
330 if (!state->args["materials"].is_array())
331 {
332 state->args["materials"]["psi"] = damping_param["psi"];
333 state->args["materials"]["phi"] = damping_param["phi"];
334 }
335 else
336 {
337 for (auto &arg : state->args["materials"])
338 {
339 arg["psi"] = damping_param["psi"];
340 arg["phi"] = damping_param["phi"];
341 }
342 }
343
344 if (state->damping_assembler)
345 state->damping_assembler->add_multimaterial(0, damping_param, state->units);
346 }
347 logger().info("[{}] Current params: {}, {}", name(), state_variable(0), state_variable(1));
348 }
349 Eigen::VectorXd DampingCoeffientVariableToSimulation::compute_adjoint_term(const Eigen::VectorXd &x) const
350 {
351 Eigen::VectorXd term, cur_term;
352 for (auto state : states_)
353 {
354 if (state->problem->is_time_dependent())
355 AdjointTools::dJ_damping_transient_adjoint_term(*state, state->get_adjoint_mat(1), state->get_adjoint_mat(0), cur_term);
356 else
357 log_and_throw_adjoint_error("[{}] Static simulation not supported!", name());
358
359 if (term.size() != cur_term.size())
360 term = cur_term;
361 else
362 term += cur_term;
363 }
364 return apply_parametrization_jacobian(term, x);
365 }
367 {
368 log_and_throw_adjoint_error("[{}] inverse_eval not implemented!", name());
369 return Eigen::VectorXd();
370 }
371
372 void InitialConditionVariableToSimulation::update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices)
373 {
374 for (auto state : states_)
375 {
376 if (state_variable.size() != state->ndof() * 2)
377 {
378 log_and_throw_adjoint_error("[{}] Inconsistent number of parameters {} and number of dofs in forward {}!", name(), state_variable.size(), state->ndof() * 2);
379 }
380 state->initial_sol_update = state_variable.head(state->ndof());
381 state->initial_vel_update = state_variable.tail(state->ndof());
382 }
383 }
384 Eigen::VectorXd InitialConditionVariableToSimulation::compute_adjoint_term(const Eigen::VectorXd &x) const
385 {
386 Eigen::VectorXd term, cur_term;
387 for (auto state : states_)
388 {
389 if (state->problem->is_time_dependent())
390 AdjointTools::dJ_initial_condition_adjoint_term(*state, state->get_adjoint_mat(1), state->get_adjoint_mat(0), cur_term);
391 else
392 log_and_throw_adjoint_error("[{}] Static simulation not supported!", name());
393
394 if (term.size() != cur_term.size())
395 term = cur_term;
396 else
397 term += cur_term;
398 }
399 return apply_parametrization_jacobian(term, x);
400 }
402 {
403 auto &state = *states_[0];
404 Eigen::MatrixXd sol, vel;
405 state.initial_solution(sol);
406 state.initial_velocity(vel);
407
408 Eigen::VectorXd x(sol.size() + vel.size());
409 x << sol, vel;
410 return x;
411 }
412
413 void DirichletVariableToSimulation::update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices)
414 {
415 auto tensor_problem = std::dynamic_pointer_cast<polyfem::assembler::GenericTensorProblem>(states_[0]->problem);
416 assert(dirichlet_boundaries_.size() > 0);
417 int dim = states_[0]->mesh->dimension();
418 int num_steps = indices.size() / dim;
419 for (int i = 0; i < num_steps; ++i)
420 for (const int &b : dirichlet_boundaries_)
421 tensor_problem->update_dirichlet_boundary(b, indices(i * dim) + 1, state_variable.segment(i * dim, dim));
422
423 logger().info("Current dirichlet boundary {} is {}.", dirichlet_boundaries_[0], state_variable.transpose());
424 }
425
426 Eigen::VectorXd DirichletVariableToSimulation::compute_adjoint_term(const Eigen::VectorXd &x) const
427 {
428 Eigen::VectorXd term, cur_term;
429 for (auto state : states_)
430 {
431 if (state->problem->is_time_dependent())
432 AdjointTools::dJ_dirichlet_transient_adjoint_term(*state, state->get_adjoint_mat(1), state->get_adjoint_mat(0), cur_term);
433 else
434 log_and_throw_adjoint_error("[{}] Static dirichlet boundary optimization not supported!", name());
435
436 if (term.size() != cur_term.size())
437 term = cur_term;
438 else
439 term += cur_term;
440 }
441 return apply_parametrization_jacobian(term, x);
442 }
443 std::string DirichletVariableToSimulation::variable_to_string(const Eigen::VectorXd &variable)
444 {
445 return "";
446 }
448 {
449 assert(dirichlet_boundaries_.size() > 0);
450 assert(states_.size() > 0);
451
452 int dim = states_[0]->mesh->dimension();
453 Eigen::VectorXd x;
454 for (const auto &b : states_[0]->args["boundary_conditions"]["dirichlet_boundary"])
455 if (b["id"].get<int>() == dirichlet_boundaries_[0])
456 {
457 auto value = b["value"];
458 if (value[0].is_array())
459 {
460 if (!states_[0]->problem->is_time_dependent())
461 log_and_throw_adjoint_error("Simulation must be time dependent for timestep wise dirichlet.");
462 Eigen::MatrixXd dirichlet = value;
463 x.setZero(dirichlet.rows() * (dirichlet.cols() - 1));
464 for (int j = 1; j < dirichlet.cols(); ++j)
465 x.segment((j - 1) * dim, dim) = dirichlet.col(j);
466 }
467 else if (value[0].is_number())
468 {
469 if (states_[0]->problem->is_time_dependent())
470 log_and_throw_adjoint_error("Simulation must be quasistatic for single value dirichlet.");
471 x.resize(dim);
472 x = value;
473 }
474 else if (value.is_string())
475 assert(false);
476 break;
477 }
478
480 }
482 {
483 const std::string composite_map_type = args["composite_map_type"];
484 const State &state = *(states_[0]);
485 if (composite_map_type == "time_step_indexing")
486 {
487 const int time_steps = state.args["time"]["time_steps"];
488 const int dim = state.mesh->dimension();
489
490 output_indexing_.setZero(time_steps * dim);
491 for (int i = 0; i < time_steps; ++i)
492 for (int k = 0; k < dim; ++k)
493 output_indexing_(i * dim + k) = i;
494 }
495 else
497
498 set_dirichlet_boundaries(args["surface_selection"]);
499 }
500
501 void PressureVariableToSimulation::update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices)
502 {
503 auto tensor_problem = std::dynamic_pointer_cast<polyfem::assembler::GenericTensorProblem>(states_[0]->problem);
504 assert(pressure_boundaries_.size() > 0);
505 for (int i = 0; i < indices.size(); ++i)
506 for (const int &b : pressure_boundaries_)
507 tensor_problem->update_pressure_boundary(b, indices(i) + 1, state_variable(i));
508
509 logger().info("Current pressure boundary {} is {}.", pressure_boundaries_[0], state_variable.transpose());
510 }
511
512 Eigen::VectorXd PressureVariableToSimulation::compute_adjoint_term(const Eigen::VectorXd &x) const
513 {
514 Eigen::VectorXd term, cur_term;
515 for (auto state : states_)
516 {
517 if (state->problem->is_time_dependent())
518 {
519 Eigen::MatrixXd adjoint_nu, adjoint_p;
520 adjoint_nu = state->get_adjoint_mat(1);
521 adjoint_p = state->get_adjoint_mat(0);
522 AdjointTools::dJ_pressure_transient_adjoint_term(*state, pressure_boundaries_, adjoint_nu, adjoint_p, cur_term);
523 }
524 else
525 {
526 AdjointTools::dJ_pressure_static_adjoint_term(*state, pressure_boundaries_, state->diff_cached.u(0), state->get_adjoint_mat(0), cur_term);
527 }
528 if (term.size() != cur_term.size())
529 term = cur_term;
530 else
531 term += cur_term;
532 }
533 return apply_parametrization_jacobian(term, x);
534 }
535
536 std::string PressureVariableToSimulation::variable_to_string(const Eigen::VectorXd &variable)
537 {
538 return "";
539 }
540
542 {
543 assert(pressure_boundaries_.size() > 0);
544 assert(states_.size() > 0);
545
546 Eigen::VectorXd x;
547 for (const auto &b : states_[0]->args["boundary_conditions"]["pressure_boundary"])
548 if (b["id"].get<int>() == pressure_boundaries_[0])
549 {
550 auto value = b["value"];
551 if (value.is_array())
552 {
553 if (!states_[0]->problem->is_time_dependent())
554 log_and_throw_adjoint_error("Simulation must be time dependent for timestep wise pressure.");
555 Eigen::VectorXd pressures = value;
556 x = pressures.segment(1, pressures.size() - 1);
557 }
558 else if (value.is_number())
559 {
560 if (states_[0]->problem->is_time_dependent())
561 log_and_throw_adjoint_error("Simulation must be quasistatic for single value pressure.");
562 x.resize(1);
563 x(0) = value;
564 }
565 else if (value.is_string())
566 assert(false);
567 break;
568 }
569
571 }
572
574 {
575 const std::string composite_map_type = args["composite_map_type"];
576 const State &state = *(states_[0]);
577 if (composite_map_type == "time_step_indexing")
578 {
579 const int time_steps = state.args["time"]["time_steps"];
580 output_indexing_.setZero(time_steps);
581 for (int i = 0; i < time_steps; ++i)
582 output_indexing_(i) = i;
583 }
584 else
586
587 set_pressure_boundaries(args["surface_selection"]);
588 }
589
590 Eigen::VectorXd PeriodicShapeVariableToSimulation::compute_adjoint_term(const Eigen::VectorXd &x) const
591 {
592 Eigen::VectorXd term, cur_term;
593 for (auto state : states_)
594 {
595 if (state->problem->is_time_dependent())
596 {
597 log_and_throw_error("Not implemented!");
598 }
599 else
600 {
601 AdjointTools::dJ_periodic_shape_adjoint_term(*state, *periodic_mesh_map, periodic_mesh_representation, state->diff_cached.u(0), state->get_adjoint_mat(0), cur_term);
602 }
603 if (term.size() != cur_term.size())
604 term = cur_term;
605 else
606 term += cur_term;
607 }
609 }
610 void PeriodicShapeVariableToSimulation::update(const Eigen::VectorXd &x)
611 {
612 const int dim = states_[0]->mesh->dimension();
614 const Eigen::MatrixXd V = utils::unflatten(periodic_mesh_map->eval(periodic_mesh_representation), dim);
615
616 for (auto state : states_)
617 {
618 const int n_verts = state->mesh->n_vertices();
619
620 for (int i = 0; i < n_verts; i++)
621 state->set_mesh_vertex(i, V.row(i));
622 }
623 }
625 {
626 const auto &state = *(states_[0]);
627
628 Eigen::MatrixXd V;
629 state.get_vertices(V);
630
631 if (!state.periodic_bc->all_direction_periodic())
632 log_and_throw_error("Cannot inverse evaluate periodic shape!");
633
634 periodic_mesh_map = std::make_unique<PeriodicMeshToMesh>(V);
636
638 }
639 Eigen::VectorXd PeriodicShapeVariableToSimulation::apply_parametrization_jacobian(const Eigen::VectorXd &term, const Eigen::VectorXd &x) const
640 {
641 const Eigen::VectorXd mid = periodic_mesh_map->apply_jacobian(term, periodic_mesh_representation);
642 return parametrization_.apply_jacobian(mid, x);
643 }
644} // namespace polyfem::solver
int V
StiffnessMatrix tmp_mat
int x
main class that contains the polyfem solver and all its state
Definition State.hpp:79
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
std::string resolve_input_path(const std::string &path, const bool only_if_exists=false) const
Resolve input path relative to root_path() if the path is not absolute.
RowVectorNd face_barycenter(const int index) const override
face barycenter
Definition Mesh2D.cpp:69
virtual RowVectorNd cell_barycenter(const int c) const =0
cell barycenter
int size(const int x_size) const override
Eigen::VectorXd apply_jacobian(const Eigen::VectorXd &grad_full, const Eigen::VectorXd &x) const override
Eigen::VectorXd inverse_eval(const Eigen::VectorXd &y) override
Eigen::VectorXd eval(const Eigen::VectorXd &x) const override
Eigen::VectorXd compute_adjoint_term(const Eigen::VectorXd &x) const override
void update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices) override
Eigen::VectorXd compute_adjoint_term(const Eigen::VectorXd &x) const override
std::string variable_to_string(const Eigen::VectorXd &variable)
void update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices) override
void set_dirichlet_boundaries(const std::vector< int > &dirichlet_boundaries)
Eigen::VectorXd compute_adjoint_term(const Eigen::VectorXd &x) const override
void update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices) override
Eigen::VectorXd compute_adjoint_term(const Eigen::VectorXd &x) const override
void update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices) override
Eigen::VectorXd compute_adjoint_term(const Eigen::VectorXd &x) const override
void update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices) override
Eigen::VectorXd compute_adjoint_term(const Eigen::VectorXd &x) const override
Eigen::VectorXd apply_parametrization_jacobian(const Eigen::VectorXd &term, const Eigen::VectorXd &x) const override
std::unique_ptr< PeriodicMeshToMesh > periodic_mesh_map
void set_pressure_boundaries(const std::vector< int > &pressure_boundaries)
std::string variable_to_string(const Eigen::VectorXd &variable)
void update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices) override
Eigen::VectorXd compute_adjoint_term(const Eigen::VectorXd &x) const override
virtual void update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices) override
void set_output_indexing(const json &args) override
Eigen::VectorXd compute_adjoint_term(const Eigen::VectorXd &x) const override
const Eigen::VectorXi & get_output_indexing() const
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 compute_adjoint_term(const Eigen::VectorXd &x) const
Computes the sum of adjoint terms for all VariableToSimulation.
virtual 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.
void init(const json &args, const std::vector< std::shared_ptr< State > > &states, const std::vector< int > &variable_sizes)
virtual Eigen::VectorXd apply_parametrization_jacobian(const Eigen::VectorXd &term, const Eigen::VectorXd &x) const
const std::vector< std::shared_ptr< State > > states_
virtual void update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices)
virtual void set_output_indexing(const json &args)
virtual std::string name() const =0
Eigen::VectorXi get_output_indexing(const Eigen::VectorXd &x) const
static std::unique_ptr< VariableToSimulation > create(const std::string &type, const std::vector< std::shared_ptr< State > > &states, CompositeParametrization &&parametrization)
bool read_matrix(const std::string &path, Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &mat)
Reads a matrix from a file. Determines the file format based on the path's extension.
Definition MatrixIO.cpp:18
void dJ_pressure_static_adjoint_term(const State &state, const std::vector< int > &boundary_ids, const Eigen::MatrixXd &sol, const Eigen::MatrixXd &adjoint, Eigen::VectorXd &one_form)
void dJ_periodic_shape_adjoint_term(const State &state, const PeriodicMeshToMesh &periodic_mesh_map, const Eigen::VectorXd &periodic_mesh_representation, const Eigen::MatrixXd &sol, const Eigen::MatrixXd &adjoint, Eigen::VectorXd &one_form)
void dJ_friction_transient_adjoint_term(const State &state, const Eigen::MatrixXd &adjoint_nu, const Eigen::MatrixXd &adjoint_p, Eigen::VectorXd &one_form)
void dJ_pressure_transient_adjoint_term(const State &state, const std::vector< int > &boundary_ids, const Eigen::MatrixXd &adjoint_nu, const Eigen::MatrixXd &adjoint_p, Eigen::VectorXd &one_form)
void dJ_initial_condition_adjoint_term(const State &state, const Eigen::MatrixXd &adjoint_nu, const Eigen::MatrixXd &adjoint_p, Eigen::VectorXd &one_form)
void dJ_material_transient_adjoint_term(const State &state, const Eigen::MatrixXd &adjoint_nu, const Eigen::MatrixXd &adjoint_p, Eigen::VectorXd &one_form)
void dJ_shape_homogenization_adjoint_term(const State &state, const Eigen::MatrixXd &sol, const Eigen::MatrixXd &adjoint, Eigen::VectorXd &one_form)
void dJ_shape_transient_adjoint_term(const State &state, const Eigen::MatrixXd &adjoint_nu, const Eigen::MatrixXd &adjoint_p, Eigen::VectorXd &one_form)
void dJ_material_static_adjoint_term(const State &state, const Eigen::MatrixXd &sol, const Eigen::MatrixXd &adjoint, Eigen::VectorXd &one_form)
void dJ_dirichlet_transient_adjoint_term(const State &state, const Eigen::MatrixXd &adjoint_nu, const Eigen::MatrixXd &adjoint_p, Eigen::VectorXd &one_form)
void dJ_shape_static_adjoint_term(const State &state, const Eigen::MatrixXd &sol, const Eigen::MatrixXd &adjoint, Eigen::VectorXd &one_form)
void dJ_damping_transient_adjoint_term(const State &state, const Eigen::MatrixXd &adjoint_nu, const Eigen::MatrixXd &adjoint_p, Eigen::VectorXd &one_form)
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.
spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:42
nlohmann::json json
Definition Common.hpp:9
void log_and_throw_adjoint_error(const std::string &msg)
Definition Logger.cpp:77
Eigen::Matrix< double, 1, Eigen::Dynamic, Eigen::RowMajor, 1, 3 > RowVectorNd
Definition Types.hpp:13
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:71
static std::unique_ptr< VariableToSimulation > create_variable_to_simulation(const json &args, const std::vector< std::shared_ptr< State > > &states, const std::vector< int > &variable_sizes)