38 const Eigen::MatrixXd &
x,
39 const Eigen::MatrixXd &x_prev,
40 const Eigen::MatrixXd &adjoint,
41 Eigen::VectorXd &term)
43 const int dim = form.is_volume_ ? 3 : 2;
45 const int n_elements = int(form.bases_.size());
47 if (form.assembler_.name() ==
"ViscousDamping")
56 for (
int e = start; e < end; ++e)
59 form.ass_vals_cache_.compute(e, form.is_volume_, form.bases_[e], form.geom_bases_[e],
vals);
64 Eigen::MatrixXd u, grad_u, prev_u, prev_grad_u, p, grad_p;
69 for (
int q = 0; q < local_storage.da.size(); ++q)
71 Eigen::MatrixXd grad_p_i, grad_u_i, prev_grad_u_i;
76 Eigen::MatrixXd f_prime_dpsi, f_prime_dphi;
79 prev_grad_u_i, f_prime_dpsi, f_prime_dphi);
82 local_storage.vec(0) += -utils::matrix_inner_product<double>(f_prime_dpsi, grad_p_i) * local_storage.da(q);
83 local_storage.vec(1) += -utils::matrix_inner_product<double>(f_prime_dphi, grad_p_i) * local_storage.da(q);
88 for (
const LocalThreadVecStorage &local_storage : storage)
89 term += local_storage.vec;
93 term.setZero(n_elements * 2, 1);
100 for (
int e = start; e < end; ++e)
103 form.ass_vals_cache_.compute(e, form.is_volume_, form.bases_[e], form.geom_bases_[e],
vals);
108 Eigen::MatrixXd u, grad_u, p, grad_p;
112 for (
int q = 0; q < local_storage.da.size(); ++q)
114 Eigen::MatrixXd grad_p_i, grad_u_i;
118 Eigen::MatrixXd f_prime_dmu, f_prime_dlambda;
119 form.assembler_.compute_dstress_dmu_dlambda(
121 f_prime_dmu, f_prime_dlambda);
124 local_storage.vec(e + n_elements) += -utils::matrix_inner_product<double>(f_prime_dmu, grad_p_i) * local_storage.da(q);
125 local_storage.vec(e) += -utils::matrix_inner_product<double>(f_prime_dlambda, grad_p_i) * local_storage.da(q);
130 for (
const LocalThreadVecStorage &local_storage : storage)
131 term += local_storage.vec;
139 const Eigen::MatrixXd &
x,
140 const Eigen::MatrixXd &x_prev,
141 const Eigen::MatrixXd &adjoint,
142 Eigen::VectorXd &term)
144 const int dim = form.is_volume_ ? 3 : 2;
145 const int actual_dim = ((form.assembler_.name() ==
"Laplacian") || (form.assembler_.name() ==
"Electrostatics")) ? 1 : dim;
147 const int n_elements = int(form.bases_.size());
148 term.setZero(n_verts * dim, 1);
152 if (form.assembler_.name() ==
"ViscousDamping")
157 for (
int e = start; e < end; ++e)
160 form.ass_vals_cache_.compute(e, form.is_volume_, form.bases_[e], form.geom_bases_[e],
vals);
167 Eigen::MatrixXd u, grad_u, prev_u, prev_grad_u, p, grad_p;
172 Eigen::MatrixXd grad_u_i, prev_grad_u_i;
173 Eigen::MatrixXd grad_v_i;
174 Eigen::MatrixXd stress_tensor;
175 Eigen::VectorXd f_prime_gradu_gradv, f_prev_prime_prev_gradu_gradv;
177 for (
int q = 0; q < local_storage.da.size(); ++q)
182 for (
auto &v :
gvals.basis_values)
184 Eigen::MatrixXd stress_grad, stress_prev_grad;
185 form.assembler_.compute_stress_grad(
187 prev_grad_u_i, stress_tensor, stress_grad);
188 form.assembler_.compute_stress_prev_grad(
190 prev_grad_u_i, stress_prev_grad);
191 for (
int d = 0; d < dim; d++)
193 grad_v_i.setZero(dim, dim);
194 grad_v_i.row(d) = v.grad_t_m.row(q);
196 f_prime_gradu_gradv = stress_grad *
utils::flatten(grad_u_i * grad_v_i);
197 f_prev_prime_prev_gradu_gradv = stress_prev_grad *
utils::flatten(prev_grad_u_i * grad_v_i);
199 Eigen::MatrixXd tmp = grad_v_i - grad_v_i.trace() * Eigen::MatrixXd::Identity(dim, dim);
200 local_storage.vec(v.global[0].index * dim + d) -= grad_p.row(q).dot(f_prime_gradu_gradv + f_prev_prime_prev_gradu_gradv +
utils::flatten(stress_tensor * tmp.transpose())) * local_storage.da(q);
212 for (
int e = start; e < end; ++e)
215 form.ass_vals_cache_.compute(e, form.is_volume_, form.bases_[e], form.geom_bases_[e],
vals);
222 Eigen::MatrixXd u, grad_u, p, grad_p;
226 for (
int q = 0; q < local_storage.da.size(); ++q)
228 Eigen::MatrixXd grad_u_i, grad_p_i, stiffness_i;
231 grad_u_i = grad_u.row(q);
232 grad_p_i = grad_p.row(q);
240 for (
auto &v :
gvals.basis_values)
242 for (
int d = 0; d < dim; d++)
244 Eigen::MatrixXd grad_v_i;
245 grad_v_i.setZero(dim, dim);
246 grad_v_i.row(d) = v.grad_t_m.row(q);
248 Eigen::MatrixXd stress_tensor, f_prime_gradu_gradv;
249 form.assembler_.compute_stress_grad_multiply_mat(
251 grad_u_i * grad_v_i, stress_tensor, f_prime_gradu_gradv);
253 const Eigen::MatrixXd tmp = stress_tensor * grad_v_i.transpose() - grad_v_i.trace() * stress_tensor;
254 local_storage.vec(v.global[0].index * dim + d) -= utils::matrix_inner_product<double>(f_prime_gradu_gradv + tmp, grad_p_i) * local_storage.da(q);
262 for (
const LocalThreadVecStorage &local_storage : storage)
263 term += local_storage.vec;
assembler::ElementAssemblyValues gvals
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)