PolyFEM
Loading...
Searching...
No Matches
DampingVariableToSimulation.cpp
Go to the documentation of this file.
2
3#include <polyfem/Common.hpp>
8
9#include <Eigen/Core>
10
11#include <cassert>
12#include <string>
13
14namespace polyfem::solver
15{
16
18 DiffCachePtrs diff_caches,
19 CompositeParametrization parametrizations)
20 : states_(std::move(states)),
21 diff_caches_(std::move(diff_caches)),
22 parametrization_(std::move(parametrizations))
23 {
24 assert(!states_.empty());
25 assert(states_.size() == diff_caches_.size());
26
27 for (auto &s : states_)
28 {
29 if (!s->problem->is_time_dependent())
30 {
31 log_and_throw_adjoint_error("Fail to construct damping variable to simulation. Reason: Can't optimize damping for static problem.");
32 }
33 }
34 }
35
37 {
38 return "damping";
39 }
40
45
47 {
48 for (const auto &s : states_)
49 {
50 if (s.get() == &target)
51 {
52 return true;
53 }
54 }
55 return false;
56 }
57
58 void DampingVariableToSimulation::update(const Eigen::VectorXd &x)
59 {
60 Eigen::VectorXd y = parametrization_.eval(x);
61 assert(y.size() == para_out_dof());
62
63 double psi = y(0);
64 double phi = y(1);
65
66 for (auto &s : states_)
67 {
68 if (!s->args["materials"].is_array())
69 {
70 s->args["materials"]["psi"] = psi;
71 s->args["materials"]["phi"] = phi;
72 }
73 else
74 {
75 for (auto &arg : s->args["materials"])
76 {
77 arg["psi"] = psi;
78 arg["phi"] = phi;
79 }
80 }
81
82 if (s->damping_assembler)
83 {
84 json damping_param = {
85 {"psi", psi},
86 {"phi", phi},
87 };
88 s->damping_assembler->add_multimaterial(0, damping_param, s->units, s->root_path());
89 }
90 }
91 }
92
93 void DampingVariableToSimulation::update_state_variables(const Eigen::VectorXd &x, Eigen::VectorXd &state_variables) const
94 {
95 assert(state_variables.size() == para_out_dof());
96 state_variables = parametrization_.eval(x);
97 }
98
99 Eigen::VectorXd DampingVariableToSimulation::compute_adjoint_term(const Eigen::VectorXd &x) const
100 {
101 Eigen::VectorXd term, cur_term;
102 for (int i = 0; i < int(states_.size()); ++i)
103 {
104 auto &state = states_[i];
105 auto &diff_cache = diff_caches_[i];
106
107 assert(state->problem->is_time_dependent());
108 Eigen::MatrixXd adjoint_p = get_adjoint_mat(*state, *diff_cache, 0);
109 Eigen::MatrixXd adjoint_nu = get_adjoint_mat(*state, *diff_cache, 1);
110 AdjointTools::dJ_damping_transient_adjoint_term(*state, *diff_cache, adjoint_nu, adjoint_p, cur_term);
111
112 if (term.size() != cur_term.size())
113 {
114 term = cur_term;
115 }
116 else
117 {
118 term += cur_term;
119 }
120 }
121
122 assert(term.size() == para_out_dof());
123 return parametrization_.apply_jacobian(term, x);
124 }
125
130
132 {
133 Eigen::VectorXd y(para_out_dof());
134 json material = states_[0]->args["materials"];
135 if (material.is_array())
136 {
137 material = material[0];
138 }
139
140 y(0) = material["psi"].get<double>();
141 y(1) = material["phi"].get<double>();
143 }
144
145 Eigen::VectorXd DampingVariableToSimulation::apply_parametrization_jacobian(const Eigen::VectorXd &, const Eigen::VectorXd &) const
146 {
147 // Not implemented because there's no user
148 log_and_throw_adjoint_error("apply_parametrization_jacobian is not implemented in {} variable to simulation.", name());
149 }
150
152 {
153 return 2;
154 }
155
156} // namespace polyfem::solver
int y
int x
main class that contains the polyfem solver and all its state
Definition State.hpp:114
Eigen::VectorXd apply_jacobian(const Eigen::VectorXd &grad_full, const Eigen::VectorXd &x) const override
Apply jacobian for chain rule.
Eigen::VectorXd inverse_eval(const Eigen::VectorXd &y) const override
Eval x = f^-1 (y).
int inverse_size(int y_size) const override
Compute DOF of x given DOF of y.
Eigen::VectorXd eval(const Eigen::VectorXd &x) const override
Eval y = f(x).
bool affect_state(const legacy::State &target) const override
Return true if current var2sim maps to target state.
Eigen::VectorXd inverse_eval() const override
Compute optimization variables from forward simulation legacy::State.
int inverse_dof() const override
Compute optimization variables dof.
Eigen::VectorXd apply_parametrization_jacobian(const Eigen::VectorXd &term, const Eigen::VectorXd &x) const override
Apply parametrization jacobian to compute the gradient w.r.t.
void update(const Eigen::VectorXd &x) override
Update forward simulation states from optimization variables.
void update_state_variables(const Eigen::VectorXd &x, Eigen::VectorXd &state_variables) const override
Update state variables from optimization variables.
DampingVariableToSimulation(StatePtrs states, DiffCachePtrs diff_caches, CompositeParametrization parametrizations)
Construct DampingVariableToSimulation.
std::vector< std::shared_ptr< DiffCache > > DiffCachePtrs
Eigen::VectorXd compute_adjoint_term(const Eigen::VectorXd &x) const override
Compute adjoint contribution of objective gradient.
std::vector< std::shared_ptr< legacy::State > > StatePtrs
void dJ_damping_transient_adjoint_term(const legacy::State &state, const DiffCache &diff_cache, const Eigen::MatrixXd &adjoint_nu, const Eigen::MatrixXd &adjoint_p, Eigen::VectorXd &one_form)
nlohmann::json json
Definition Common.hpp:9
void log_and_throw_adjoint_error(const std::string &msg)
Definition Logger.cpp:79
Eigen::MatrixXd get_adjoint_mat(const legacy::State &state, const DiffCache &diff_cache, int type)
Get adjoint parameter nu or p.