9 Eigen::Matrix<double, dim, dim>
hat(
const Eigen::Matrix<double, dim, 1> &
x)
26 Eigen::Matrix<double, dim, 1>
cross(
const Eigen::Matrix<double, dim, 1> &
x,
const Eigen::Matrix<double, dim, 1> &
y)
46 Eigen::Matrix<double, Eigen::Dynamic, 1> gradient;
55 compute_energy_aux_gradient_fast<3, 2>(data, gradient);
61 compute_energy_aux_gradient_fast<6, 2>(data, gradient);
67 compute_energy_aux_gradient_fast<10, 2>(data, gradient);
73 compute_energy_aux_gradient_fast<Eigen::Dynamic, 2>(data, gradient);
86 compute_energy_aux_gradient_fast<4, 3>(data, gradient);
92 compute_energy_aux_gradient_fast<10, 3>(data, gradient);
98 compute_energy_aux_gradient_fast<20, 3>(data, gradient);
104 compute_energy_aux_gradient_fast<Eigen::Dynamic, 3>(data, gradient);
117 typedef Eigen::Matrix<T, Eigen::Dynamic, 1>
AutoDiffVect;
118 typedef Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3>
AutoDiffGradMat;
127 Eigen::MatrixXd standard(
size(),
size());
130 0.5, std::sqrt(3) / 2;
133 0.5, std::sqrt(3) / 2., 0,
134 0.5, 0.5 / std::sqrt(3), std::sqrt(3) / 2.;
135 standard = standard.inverse().transpose().eval();
137 const int n_pts = data.
da.size();
138 for (
long p = 0; p < n_pts; ++p)
140 for (
int i = 0; i <
size(); ++i)
141 for (
int j = 0; j <
size(); ++j)
142 def_grad(i, j) = T(0);
148 for (
long k = 0; k < jac_it.size(); ++k)
150 def_grad += jac_it.inverse();
151 def_grad = def_grad * standard;
154 const T
val = (def_grad.transpose() * def_grad).trace() / powJ;
156 energy +=
val * data.
da(p);
164 assert(data.
x.cols() == 1);
166 const int n_pts = data.
da.size();
169 local_disp.setZero();
173 for (
size_t ii = 0; ii < bs.global.size(); ++ii)
175 for (
int d = 0; d <
size(); ++d)
177 local_disp(i, d) += bs.global[ii].val * data.
x(bs.global[ii].index *
size() + d);
182 Eigen::Matrix<double, dim, dim> def_grad(
size(),
size());
187 Eigen::MatrixXd standard(
size(),
size());
190 0.5, std::sqrt(3) / 2;
193 0.5, std::sqrt(3) / 2., 0,
194 0.5, 0.5 / std::sqrt(3), std::sqrt(3) / 2.;
195 standard = standard.inverse().transpose().eval();
197 for (
long p = 0; p < n_pts; ++p)
206 Eigen::Matrix<double, dim, dim> jac_it = data.
vals.
jac_it[p];
209 def_grad = (local_disp.transpose() * grad + jac_it.inverse()) * standard;
211 double J = def_grad.determinant();
215 Eigen::Matrix<double, dim, dim> delJ_delF(
size(),
size());
221 delJ_delF(0, 0) = def_grad(1, 1);
222 delJ_delF(0, 1) = -def_grad(1, 0);
223 delJ_delF(1, 0) = -def_grad(0, 1);
224 delJ_delF(1, 1) = def_grad(0, 0);
229 Eigen::Matrix<double, dim, 1> u(def_grad.rows());
230 Eigen::Matrix<double, dim, 1> v(def_grad.rows());
231 Eigen::Matrix<double, dim, 1> w(def_grad.rows());
237 delJ_delF.col(0) = cross<dim>(v, w);
238 delJ_delF.col(1) = cross<dim>(w, u);
239 delJ_delF.col(2) = cross<dim>(u, v);
242 const double m = (dim == 2) ? 2. : 5. / 3.;
243 const double powJ = pow(J, m);
244 Eigen::Matrix<double, dim, dim> gradient_temp = (2 * def_grad - (def_grad.squaredNorm() * m) / J * delJ_delF) / powJ;
245 Eigen::Matrix<double, n_basis, dim> gradient = grad * standard * gradient_temp.transpose();
247 G.noalias() += gradient * data.
da(p);
250 Eigen::Matrix<double, dim, n_basis> G_T = G.transpose();
252 constexpr int N = (n_basis == Eigen::Dynamic) ? Eigen::Dynamic : n_basis * dim;
253 Eigen::Matrix<double, N, 1> temp(Eigen::Map<Eigen::Matrix<double, N, 1>>(G_T.data(), G_T.size()));
259 Eigen::MatrixXd hessian;
267 hessian.resize(6, 6);
269 compute_energy_hessian_aux_fast<3, 2>(data, hessian);
274 hessian.resize(12, 12);
276 compute_energy_hessian_aux_fast<6, 2>(data, hessian);
281 hessian.resize(20, 20);
283 compute_energy_hessian_aux_fast<10, 2>(data, hessian);
290 compute_energy_hessian_aux_fast<Eigen::Dynamic, 2>(data, hessian);
302 hessian.resize(12, 12);
304 compute_energy_hessian_aux_fast<4, 3>(data, hessian);
309 hessian.resize(30, 30);
311 compute_energy_hessian_aux_fast<10, 3>(data, hessian);
316 hessian.resize(60, 60);
318 compute_energy_hessian_aux_fast<20, 3>(data, hessian);
325 compute_energy_hessian_aux_fast<Eigen::Dynamic, 3>(data, hessian);
337 assert(data.
x.cols() == 1);
339 constexpr int N = (n_basis == Eigen::Dynamic) ? Eigen::Dynamic : n_basis * dim;
340 const int n_pts = data.
da.size();
343 local_disp.setZero();
347 for (
size_t ii = 0; ii < bs.global.size(); ++ii)
349 for (
int d = 0; d <
size(); ++d)
351 local_disp(i, d) += bs.global[ii].val * data.
x(bs.global[ii].index *
size() + d);
356 Eigen::Matrix<double, dim, dim> def_grad(
size(),
size());
358 Eigen::MatrixXd standard(
size(),
size());
361 0.5, std::sqrt(3) / 2;
364 0.5, std::sqrt(3) / 2., 0,
365 0.5, 0.5 / std::sqrt(3), std::sqrt(3) / 2.;
366 standard = standard.inverse().transpose().eval();
368 for (
long p = 0; p < n_pts; ++p)
377 Eigen::Matrix<double, dim, dim> jac_it = data.
vals.
jac_it[p];
380 def_grad = (local_disp.transpose() * grad + jac_it.inverse()) * standard;
382 Eigen::Matrix<double, dim * dim, dim * dim> hessian_temp;
387 Eigen::Matrix<Diff, dim, dim> def_grad_ad(dim, dim);
388 for (
int i = 0; i < def_grad.size(); i++)
389 def_grad_ad(i) =
Diff(i, def_grad(i));
393 hessian_temp =
val.getHessian();
448 Eigen::Matrix<double, dim * dim, N> delF_delU_tensor(jac_it.size(), grad.size());
450 for (
size_t i = 0; i < local_disp.rows(); ++i)
452 for (
size_t j = 0; j < local_disp.cols(); ++j)
454 Eigen::Matrix<double, dim, dim> temp(
size(),
size());
456 temp.row(j) = grad.row(i);
457 temp = temp * standard;
458 Eigen::Matrix<double, dim * dim, 1> temp_flattened(Eigen::Map<Eigen::Matrix<double, dim * dim, 1>>(temp.data(), temp.size()));
459 delF_delU_tensor.col(i *
size() + j) = temp_flattened;
463 Eigen::Matrix<double, N, N> hessian = delF_delU_tensor.transpose() * hessian_temp * delF_delU_tensor;
465 H += hessian * data.
da(p);