19 class LocalThreadScalarStorage
25 LocalThreadScalarStorage()
40 int e_ref = params.elem;
42 e_ref = search->second;
44 Eigen::MatrixXd pts_ref;
45 target_state_->geom_bases()[e_ref].eval_geom_mapping(local_pts, pts_ref);
47 Eigen::MatrixXd u_ref, grad_u_ref;
51 val = (u_ref + pts_ref - u - pts).rowwise().squaredNorm();
55 int e_ref = params.elem;
57 e_ref = search->second;
59 Eigen::MatrixXd pts_ref;
60 target_state_->geom_bases()[e_ref].eval_geom_mapping(local_pts, pts_ref);
62 Eigen::MatrixXd u_ref, grad_u_ref;
66 val = 2 * (u + pts - u_ref - pts_ref);
76 val.setZero(u.rows(), 1);
78 const Eigen::MatrixXd X = u + pts;
79 for (
int q = 0; q < u.rows(); q++)
80 val(q) =
target_func(X(q, 0), X(q, 1), X.cols() == 2 ? 0 : X(q, 2), 0, params.elem);
84 val.setZero(u.rows(), u.cols());
86 const Eigen::MatrixXd X = u + pts;
87 for (
int q = 0; q < u.rows(); q++)
88 for (
int d = 0; d <
val.cols(); d++)
89 val(q, d) =
target_func_grad[d](X(q, 0), X(q, 1), X.cols() == 2 ? 0 : X(q, 2), 0, params.elem);
101 val.setZero(u.rows(), 1);
103 for (
int q = 0; q < u.rows(); q++)
105 Eigen::VectorXd err = u.row(q) - this->
target_disp.transpose();
109 val(q) = err.squaredNorm();
113 val.setZero(u.rows(), u.cols());
115 for (
int q = 0; q < u.rows(); q++)
117 Eigen::VectorXd err = u.row(q) - this->
target_disp.transpose();
121 val.row(q) = 2 * err;
139 std::map<int, std::vector<int>> ref_interested_body_id_to_e;
144 if (reference_cached_body_ids.size() > 0 && reference_cached_body_ids.count(body_id) == 0)
146 if (ref_interested_body_id_to_e.find(body_id) != ref_interested_body_id_to_e.end())
147 ref_interested_body_id_to_e[body_id].push_back(e);
149 ref_interested_body_id_to_e[body_id] = {e};
153 std::map<int, std::vector<int>> interested_body_id_to_e;
158 if (reference_cached_body_ids.size() > 0 && reference_cached_body_ids.count(body_id) == 0)
160 if (interested_body_id_to_e.find(body_id) != interested_body_id_to_e.end())
161 interested_body_id_to_e[body_id].push_back(e);
163 interested_body_id_to_e[body_id] = {e};
167 if (count != ref_count)
168 adjoint_logger().error(
"[{}] Number of interested elements in the reference and optimization examples do not match! {} {}",
name(), count, ref_count);
172 for (
const auto &kv : interested_body_id_to_e)
174 for (
int i = 0; i < kv.second.size(); ++i)
176 e_to_ref_e_[kv.second[i]] = ref_interested_body_id_to_e[kv.first][i];
184 for (
size_t k = 0; k < grad_func.size(); k++)
191 std::string target_data_path = args[
"target_data_path"];
192 if (!std::filesystem::is_regular_file(target_data_path))
194 throw std::runtime_error(
"Marker path invalid!");
200 Eigen::VectorXi nodes = tmp.col(0).cast<
int>();
203 for (
int s = 0; s < nodes.size(); s++)
253 gradv.setZero(
x.size());
256 return Eigen::VectorXd::Zero(0).eval();
262 dim = state1->mesh->dimension();
263 json tmp_args = args;
264 for (
int d = 0; d <
dim; d++)
267 center1.push_back(std::make_unique<PositionForm>(variable_to_simulations, *state1, tmp_args));
268 center2.push_back(std::make_unique<PositionForm>(variable_to_simulations, *state2, tmp_args));
274 Eigen::VectorXd term;
275 term.setZero(state.
ndof());
276 for (
int d = 0; d <
dim; d++)
278 double value =
center1[d]->value_unweighted_step(time_step,
x) -
center2[d]->value_unweighted_step(time_step,
x);
285 gradv.setZero(
x.size());
286 Eigen::VectorXd tmp1, tmp2;
287 for (
int d = 0; d <
dim; d++)
289 double value =
center1[d]->value_unweighted_step(time_step,
x) -
center2[d]->value_unweighted_step(time_step,
x);
290 center1[d]->compute_partial_gradient_step(time_step,
x, tmp1);
291 center2[d]->compute_partial_gradient_step(time_step,
x, tmp2);
292 gradv += (2 *
value) * (tmp1 - tmp2);
299 for (
int d = 0; d <
dim; d++)
ElementAssemblyValues vals
void set_dj_du(const functionalType &dj_du)
void set_j(const functionalType &j)
void set_dj_dx(const functionalType &dj_dx)
main class that contains the polyfem solver and all its state
Eigen::VectorXi in_node_to_node
Inpute nodes (including high-order) to polyfem nodes, only for isoparametric.
std::unique_ptr< mesh::Mesh > mesh
current mesh, it can be a Mesh2D or Mesh3D
std::shared_ptr< polyfem::mesh::MeshNodes > mesh_nodes
Mapping from input nodes to FE nodes.
solver::DiffCache diff_cached
std::vector< basis::ElementBases > bases
FE bases, the size is #elements.
stores per element basis values at given quadrature points and geometric mapping
static void interpolate_at_local_vals(const mesh::Mesh &mesh, const bool is_problem_scalar, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const int el_index, const Eigen::MatrixXd &local_pts, const Eigen::MatrixXd &fun, Eigen::MatrixXd &result, Eigen::MatrixXd &result_grad)
interpolate solution and gradient at element (calls interpolate_at_local_vals with sol)
Eigen::VectorXd u(int step) const
A collection of 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 &vals)
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.
spdlog::logger & adjoint_logger()
Retrieves the current logger for adjoint.
void log_and_throw_adjoint_error(const std::string &msg)
Eigen::Matrix< double, 1, Eigen::Dynamic, Eigen::RowMajor, 1, 3 > RowVectorNd
Parameters for the functional evaluation.