14 return std::make_unique<ShapeVariableToSimulation>(states, parametrization);
15 else if (type ==
"elastic")
16 return std::make_unique<ElasticVariableToSimulation>(states, parametrization);
17 else if (type ==
"friction")
18 return std::make_unique<FrictionCoeffientVariableToSimulation>(states, parametrization);
19 else if (type ==
"damping")
20 return std::make_unique<DampingCoeffientVariableToSimulation>(states, parametrization);
21 else if (type ==
"initial")
22 return std::make_unique<InitialConditionVariableToSimulation>(states, parametrization);
23 else if (type ==
"dirichlet")
24 return std::make_unique<DirichletVariableToSimulation>(states, parametrization);
27 return std::unique_ptr<VariableToSimulation>();
38 ind.setLinSpaced(out_size, 0, out_size - 1);
43 return Eigen::VectorXi();
54 return Eigen::VectorXd();
59 std::vector<ValueType>().swap(
L);
60 for (
const auto &arg : args)
66 Eigen::VectorXd adjoint_term = Eigen::VectorXd::Zero(
x.size());
67 for (
const auto &v2s :
L)
68 adjoint_term += v2s->compute_adjoint_term(
x);
74 for (
const auto &v2s :
L)
76 if (v2s->get_parameter_type() != type)
79 const Eigen::VectorXd var = v2s->get_parametrization().eval(
x);
80 for (
const auto &state : v2s->get_states())
82 if (state.get() != state_ptr)
85 state_variable(v2s->get_output_indexing(
x)) = var;
92 Eigen::VectorXd gradv = Eigen::VectorXd::Zero(
x.size());
93 Eigen::VectorXd raw_grad;
94 for (
const auto &v2s :
L)
96 if (v2s->get_parameter_type() != type)
99 for (
const auto &state : v2s->get_states())
101 if (state.get() != state_ptr)
104 if (raw_grad.size() == 0)
105 raw_grad = v2s->apply_parametrization_jacobian(grad(),
x);
117 const int dim = state->mesh->dimension();
120 for (
int i = 0; i < indices.size(); i += dim)
121 for (
int j = 0; j < dim; j++)
122 assert(indices(i + j) == indices(i) + j);
124 for (
int i = 0; i < indices.size(); i += dim)
125 state->set_mesh_vertex(indices(i) / dim, state_variable(Eigen::seqN(i, dim)));
130 Eigen::VectorXd term, cur_term;
133 if (state->problem->is_time_dependent())
138 if (term.size() != cur_term.size())
147 const int dim =
states_[0]->mesh->dimension();
148 const int npts =
states_[0]->mesh->n_vertices();
153 if (indices.size() == 0)
154 indices.setLinSpaced(npts * dim, 0, npts * dim - 1);
156 Eigen::MatrixXd
V, V_flat;
160 x.setZero(indices.size());
161 for (
int i = 0; i < indices.size(); i++)
162 x(i) = V_flat(indices(i));
171 const int n_elem = state->bases.size();
172 assert(n_elem * 2 == state_variable.size());
173 state->assembler->update_lame_params(state_variable.segment(0, n_elem), state_variable.segment(n_elem, n_elem));
178 Eigen::VectorXd term, cur_term;
181 if (state->problem->is_time_dependent())
186 if (term.size() != cur_term.size())
196 auto params_map = state.assembler->parameters();
198 auto search_lambda = params_map.find(
"lambda");
199 auto search_mu = params_map.find(
"mu");
200 if (search_lambda == params_map.end() || search_mu == params_map.end())
203 return Eigen::VectorXd();
206 Eigen::VectorXd lambdas(state.mesh->n_elements());
207 Eigen::VectorXd mus(state.mesh->n_elements());
208 for (
int e = 0; e < state.mesh->n_elements(); e++)
211 if (!state.mesh->is_volume())
213 const auto &mesh2d = *
dynamic_cast<mesh::Mesh2D *
>(state.mesh.get());
218 const auto &mesh3d = *
dynamic_cast<mesh::Mesh3D *
>(state.mesh.get());
221 lambdas(e) = search_lambda->second(RowVectorNd::Zero(state.mesh->dimension()), barycenter, 0., e);
222 mus(e) = search_mu->second(RowVectorNd::Zero(state.mesh->dimension()), barycenter, 0., e);
224 state.assembler->update_lame_params(lambdas, mus);
226 Eigen::VectorXd params(lambdas.size() + mus.size());
227 params << lambdas, mus;
234 assert(state_variable.size() == 1);
235 assert(state_variable(0) >= 0);
237 state->args[
"contact"][
"friction_coefficient"] = state_variable(0);
241 Eigen::VectorXd term, cur_term;
244 if (state->problem->is_time_dependent())
249 if (term.size() != cur_term.size())
259 return Eigen::VectorXd();
264 assert(state_variable.size() == 2);
265 json damping_param = {
266 {
"psi", state_variable(0)},
267 {
"phi", state_variable(1)},
271 if (!state->args[
"materials"].is_array())
273 state->args[
"materials"][
"psi"] = damping_param[
"psi"];
274 state->args[
"materials"][
"phi"] = damping_param[
"phi"];
278 for (
auto &arg : state->args[
"materials"])
280 arg[
"psi"] = damping_param[
"psi"];
281 arg[
"phi"] = damping_param[
"phi"];
285 if (state->damping_assembler)
286 state->damping_assembler->add_multimaterial(0, damping_param, state->units);
288 logger().info(
"[{}] Current params: {}, {}",
name(), state_variable(0), state_variable(1));
292 Eigen::VectorXd term, cur_term;
295 if (state->problem->is_time_dependent())
300 if (term.size() != cur_term.size())
310 return Eigen::VectorXd();
317 if (state_variable.size() != state->ndof() * 2)
319 log_and_throw_adjoint_error(
"[{}] Inconsistent number of parameters {} and number of dofs in forward {}!",
name(), state_variable.size(), state->ndof() * 2);
321 state->initial_sol_update = state_variable.head(state->ndof());
322 state->initial_vel_update = state_variable.tail(state->ndof());
327 Eigen::VectorXd term, cur_term;
330 if (state->problem->is_time_dependent())
335 if (term.size() != cur_term.size())
345 Eigen::MatrixXd sol, vel;
346 state.initial_solution(sol);
347 state.initial_velocity(vel);
349 Eigen::VectorXd
x(sol.size() + vel.size());
372 Eigen::VectorXd term, cur_term;
375 if (state->problem->is_time_dependent())
380 if (term.size() != cur_term.size())
394 return Eigen::VectorXd();
main class that contains the polyfem solver and all its state
RowVectorNd face_barycenter(const int index) const override
face barycenter
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 compute_adjoint_term(const Eigen::VectorXd &x) const override
virtual Eigen::VectorXd inverse_eval() override
void update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices) override
std::string name() const override
Eigen::VectorXd compute_adjoint_term(const Eigen::VectorXd &x) const override
std::string variable_to_string(const Eigen::VectorXd &variable)
std::string name() const override
void update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices) override
virtual Eigen::VectorXd inverse_eval() override
std::string name() 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
virtual Eigen::VectorXd inverse_eval() override
Eigen::VectorXd compute_adjoint_term(const Eigen::VectorXd &x) const override
std::string name() const override
virtual Eigen::VectorXd inverse_eval() override
void update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices) override
virtual Eigen::VectorXd inverse_eval() override
Eigen::VectorXd compute_adjoint_term(const Eigen::VectorXd &x) const override
std::string name() const override
void update_state(const Eigen::VectorXd &state_variable, const Eigen::VectorXi &indices) override
virtual 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 Eigen::VectorXd inverse_eval() override
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.
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)
std::vector< ValueType > L
virtual Eigen::VectorXd apply_parametrization_jacobian(const Eigen::VectorXd &term, const Eigen::VectorXd &x) const
CompositeParametrization parametrization_
virtual Eigen::VectorXd inverse_eval()
const std::vector< std::shared_ptr< State > > states_
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 &¶metrization)
Eigen::VectorXi output_indexing_
Eigen::VectorXd flatten(const Eigen::MatrixXd &X)
Flatten rowwises.
spdlog::logger & logger()
Retrieves the current logger.
void log_and_throw_adjoint_error(const std::string &msg)
Eigen::Matrix< double, 1, Eigen::Dynamic, Eigen::RowMajor, 1, 3 > RowVectorNd
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)