7 const int size =
F.rows();
9 Eigen::MatrixXd dEdt = 0.5 * (dFdt.transpose() *
F +
F.transpose() * dFdt);
18 const int size =
F.rows();
20 Eigen::MatrixXd dEdt = 0.5 * (dFdt.transpose() *
F +
F.transpose() * dFdt);
22 Eigen::MatrixXd dEdotdF, dEdotdFdot;
25 for (
size_t i = 0; i <
size; ++i)
27 for (
size_t j = 0; j <
size; ++j)
29 for (
size_t p = 0; p <
size; ++p)
31 dEdotdF(i *
size + j, p *
size + j) += dFdt(p, i) / 2.;
32 dEdotdFdot(i *
size + j, p *
size + j) +=
F(p, i) / 2.;
33 dEdotdF(i *
size + j, p *
size + i) += dFdt(p, j) / 2.;
34 dEdotdFdot(i *
size + j, p *
size + i) +=
F(p, j) / 2.;
42 for (
size_t i = 0; i <
size; ++i)
44 for (
size_t j = 0; j <
size; ++j)
46 const int idx = i *
size + j;
47 for (
size_t k = 0; k <
size; ++k)
66 if (params.contains(
"psi"))
68 if (params.contains(
"phi"))
76 if (data.
x_prev.size() != data.
x.size())
84 for (
size_t ii = 0; ii < bs.global.size(); ++ii)
86 local_disp.row(i) += bs.global[ii].val * data.
x.block(bs.global[ii].index *
size(), 0,
size(), 1).transpose();
87 local_prev_disp.row(i) += bs.global[ii].val * data.
x_prev.block(bs.global[ii].index *
size(), 0,
size(), 1).transpose();
91 Eigen::MatrixXd local_vel = (local_disp - local_prev_disp) / data.
dt;
96 const int n_pts = data.
da.size();
98 Eigen::MatrixXd def_grad, vel_def_grad;
99 Eigen::MatrixXd delF_delU;
100 Eigen::MatrixXd dRdF, dRdFdot;
101 for (
long p = 0; p < n_pts; ++p)
111 def_grad = local_disp.transpose() * delF_delU + Eigen::MatrixXd::Identity(
size(),
size());
112 vel_def_grad = local_vel.transpose() * delF_delU;
115 G -= delF_delU * dRdFdot * (data.
da(p) / data.
dt);
118 G.transposeInPlace();
120 Eigen::VectorXd temp(Eigen::Map<Eigen::VectorXd>(G.data(), G.size()));
129 if (data.
x_prev.size() != data.
x.size())
137 for (
size_t ii = 0; ii < bs.global.size(); ++ii)
139 local_disp.row(i) += bs.global[ii].val * data.
x.block(bs.global[ii].index *
size(), 0,
size(), 1).transpose();
140 local_prev_disp.row(i) += bs.global[ii].val * data.
x_prev.block(bs.global[ii].index *
size(), 0,
size(), 1).transpose();
144 Eigen::MatrixXd local_vel = (local_disp - local_prev_disp) / data.
dt;
149 const int n_pts = data.
da.size();
151 Eigen::MatrixXd def_grad, dFdt, dEdt;
152 for (
long p = 0; p < n_pts; ++p)
161 Eigen::MatrixXd delF_delU = grad * data.
vals.
jac_it[p];
163 def_grad = local_disp.transpose() * delF_delU + Eigen::MatrixXd::Identity(
size(),
size());
164 dFdt = local_vel.transpose() * delF_delU;
166 dEdt = dFdt.transpose() * def_grad;
167 dEdt = (dEdt + dEdt.transpose()).eval() / 2.;
170 G += delF_delU * ((dFdt + def_grad / data.
dt) * tmp).transpose() * data.
da(p);
173 G.transposeInPlace();
175 Eigen::VectorXd temp(Eigen::Map<Eigen::VectorXd>(G.data(), G.size()));
184 Eigen::MatrixXd hessian;
186 if (data.
x_prev.size() != data.
x.size())
194 for (
size_t ii = 0; ii < bs.global.size(); ++ii)
196 local_disp.row(i) += bs.global[ii].val * data.
x.block(bs.global[ii].index *
size(), 0,
size(), 1).transpose();
197 local_prev_disp.row(i) += bs.global[ii].val * data.
x_prev.block(bs.global[ii].index *
size(), 0,
size(), 1).transpose();
201 Eigen::MatrixXd local_vel = (local_disp - local_prev_disp) / data.
dt;
203 const int n_pts = data.
da.size();
205 Eigen::MatrixXd def_grad, dFdt;
206 Eigen::MatrixXd d2RdF2, d2RdFdFdot, d2RdFdot2;
207 Eigen::MatrixXd hessian_temp, delF_delU_tensor;
208 for (
long p = 0; p < n_pts; ++p)
217 Eigen::MatrixXd delF_delU = grad * data.
vals.
jac_it[p];
219 def_grad = local_disp.transpose() * delF_delU + Eigen::MatrixXd::Identity(
size(),
size());
220 dFdt = local_vel.transpose() * delF_delU;
223 hessian_temp = d2RdF2 + (1. / data.
dt) * (d2RdFdFdot + d2RdFdFdot.transpose()) + (1. / data.
dt / data.
dt) * d2RdFdot2;
225 delF_delU_tensor = Eigen::MatrixXd::Zero(
size() *
size(), grad.size());
226 for (
size_t i = 0; i < local_disp.rows(); ++i)
227 for (
size_t j = 0; j <
size(); ++j)
228 for (
size_t d = 0; d <
size(); d++)
229 delF_delU_tensor(
size() * j + d, i *
size() + j) = delF_delU(i, d);
231 hessian += delF_delU_tensor.transpose() * hessian_temp * delF_delU_tensor * data.
da(p);
241 Eigen::MatrixXd stress_grad_Ut;
243 if (data.
x_prev.size() != data.
x.size())
244 return stress_grad_Ut;
251 for (
size_t ii = 0; ii < bs.global.size(); ++ii)
253 local_disp.row(i) += bs.global[ii].val * data.
x.block(bs.global[ii].index *
size(), 0,
size(), 1).transpose();
254 local_prev_disp.row(i) += bs.global[ii].val * data.
x_prev.block(bs.global[ii].index *
size(), 0,
size(), 1).transpose();
258 Eigen::MatrixXd local_vel = (local_disp - local_prev_disp) / data.
dt;
260 const int n_pts = data.
da.size();
262 Eigen::MatrixXd def_grad, dFdt;
263 Eigen::MatrixXd d2RdF2, d2RdFdFdot, d2RdFdot2;
264 Eigen::MatrixXd stress_grad_Ut_temp, delF_delU_tensor;
265 for (
long p = 0; p < n_pts; ++p)
274 Eigen::MatrixXd delF_delU = grad * data.
vals.
jac_it[p];
276 def_grad = local_disp.transpose() * delF_delU + Eigen::MatrixXd::Identity(
size(),
size());
277 dFdt = local_vel.transpose() * delF_delU;
280 stress_grad_Ut_temp = -(1. / data.
dt) * d2RdFdFdot - (1. / data.
dt / data.
dt) * d2RdFdot2;
282 delF_delU_tensor = Eigen::MatrixXd::Zero(
size() *
size(), grad.size());
283 for (
size_t i = 0; i < local_disp.rows(); ++i)
284 for (
size_t j = 0; j <
size(); ++j)
285 for (
size_t d = 0; d <
size(); d++)
286 delF_delU_tensor(
size() * j + d, i *
size() + j) = delF_delU(i, d);
288 stress_grad_Ut += delF_delU_tensor.transpose() * stress_grad_Ut_temp * delF_delU_tensor * data.
da(p);
291 return stress_grad_Ut;
297 if (data.
x_prev.size() != data.
x.size())
305 for (
size_t ii = 0; ii < bs.global.size(); ++ii)
307 local_disp.row(i) += bs.global[ii].val * data.
x.block(bs.global[ii].index *
size(), 0,
size(), 1).transpose();
308 local_prev_disp.row(i) += bs.global[ii].val * data.
x_prev.block(bs.global[ii].index *
size(), 0,
size(), 1).transpose();
312 Eigen::MatrixXd local_vel = (local_disp - local_prev_disp) / data.
dt;
315 const int n_pts = data.
da.size();
317 Eigen::MatrixXd def_grad, dFdt, dEdt;
318 for (
long p = 0; p < n_pts; ++p)
327 const Eigen::MatrixXd delF_delU = grad * data.
vals.
jac_it[p];
328 def_grad = local_disp.transpose() * delF_delU + Eigen::MatrixXd::Identity(
size(),
size());
329 dFdt = local_vel.transpose() * delF_delU;
331 dEdt = dFdt.transpose() * def_grad;
332 dEdt = (dEdt + dEdt.transpose()).eval() / 2.;
335 energy +=
val * data.
da(p);
343 const Eigen::MatrixXd &prev_grad_u_i,
344 Eigen::MatrixXd &stress,
345 Eigen::MatrixXd &result)
const
347 const double dt = data.
dt;
348 const Eigen::MatrixXd &grad_u_i = data.
grad_u_i;
350 const Eigen::MatrixXd
F = Eigen::MatrixXd::Identity(
size(),
size()) + grad_u_i;
351 const Eigen::MatrixXd Fdot = (grad_u_i - prev_grad_u_i) / dt;
352 Eigen::MatrixXd d2RdF2, d2RdFdFdot, d2RdFdot2;
354 Eigen::MatrixXd dEdt = Fdot.transpose() *
F;
355 dEdt = (dEdt + dEdt.transpose()).eval() / 2.;
358 stress = (Fdot + (1. / dt) *
F) * tmp;
361 result = d2RdF2 + (1. / dt) * (d2RdFdFdot + d2RdFdFdot.transpose()) + (1. / dt / dt) * d2RdFdot2;
366 const Eigen::MatrixXd &prev_grad_u_i,
367 Eigen::MatrixXd &result)
const
369 const double dt = data.
dt;
370 const Eigen::MatrixXd &grad_u_i = data.
grad_u_i;
372 const Eigen::MatrixXd def_grad = Eigen::MatrixXd::Identity(grad_u_i.rows(), grad_u_i.cols()) + grad_u_i;
373 const Eigen::MatrixXd def_grad_fd = (grad_u_i - prev_grad_u_i) / dt;
374 Eigen::MatrixXd d2RdF2, d2RdFdFdot, d2RdFdot2;
377 result = -(1. / dt) * d2RdFdFdot - (1. / dt / dt) * d2RdFdot2;
382 const Eigen::MatrixXd &prev_grad_u_i,
383 Eigen::MatrixXd &dstress_dpsi,
384 Eigen::MatrixXd &dstress_dphi)
386 const double dt = data.
dt;
387 const Eigen::MatrixXd &grad_u_i = data.
grad_u_i;
389 const Eigen::MatrixXd
F = Eigen::MatrixXd::Identity(grad_u_i.rows(), grad_u_i.cols()) + grad_u_i;
390 const Eigen::MatrixXd dFdt = (grad_u_i - prev_grad_u_i) / dt;
391 const Eigen::MatrixXd dEdt = 0.5 * (dFdt.transpose() *
F +
F.transpose() * dFdt);
393 dstress_dpsi = 2 * (dFdt +
F / dt) * dEdt;
394 dstress_dphi = dEdt.trace() * (dFdt +
F / dt);
std::vector< AssemblyValues > basis_values
std::vector< Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3 > > jac_it
const Eigen::MatrixXd & x_prev
const ElementAssemblyValues & vals
const Eigen::MatrixXd & x
const QuadratureVector & da
const Eigen::MatrixXd & grad_u_i
virtual Eigen::VectorXd assemble_gradient(const NonLinearAssemblerData &data) const override
void compute_stress_aux(const Eigen::MatrixXd &F, const Eigen::MatrixXd &dFdt, Eigen::MatrixXd &dRdF, Eigen::MatrixXd &dRdFdot) const
double compute_energy(const NonLinearAssemblerData &data) const override
static void compute_dstress_dpsi_dphi(const OptAssemblerData &data, const Eigen::MatrixXd &prev_grad_u_i, Eigen::MatrixXd &dstress_dpsi, Eigen::MatrixXd &dstress_dphi)
void compute_stress_grad_aux(const Eigen::MatrixXd &F, const Eigen::MatrixXd &dFdt, Eigen::MatrixXd &d2RdF2, Eigen::MatrixXd &d2RdFdFdot, Eigen::MatrixXd &d2RdFdot2) const
virtual Eigen::MatrixXd assemble_hessian(const NonLinearAssemblerData &data) const override
void add_multimaterial(const int index, const json ¶ms, const Units &units) override
void compute_stress_grad(const OptAssemblerData &data, const Eigen::MatrixXd &prev_grad_u_i, Eigen::MatrixXd &stress, Eigen::MatrixXd &result) const override
void compute_stress_prev_grad(const OptAssemblerData &data, const Eigen::MatrixXd &prev_grad_u_i, Eigen::MatrixXd &result) const override
DampingParameters damping_params_
Eigen::VectorXd assemble_gradient(const NonLinearAssemblerData &data) const override
Eigen::MatrixXd assemble_hessian(const NonLinearAssemblerData &data) const override