1) I have a field of symmetric tensors that I have found. I need to use the divergence of this field in a second computation. Were it a vector field I would use get_function_gradients and then take the trace of this for the divergence. How should I go about doing this for the SymmetricTensor<2,dim> field?
2) I am building an equation where I am solving for a field of
symmetric tensors. At assembly I would like to use the gradient
associated with the shape functions of the elements describing them. For
a vector valued problem there is a "view" type which allows me to
extract the symmetric tensor itself (const Tensor<2,dim> phi_j_T
= fe_values[Ts].value (j, q);) but there doesn't seem to be an
equivalent (const Tensor<3,dim> phi_j_T_grad =
fe_values[Ts].gradient (j, q);) How should I tackle this?
Thanks in advance,
ErnestoYou received this message because you are subscribed to a topic in the Google Groups "deal.II User Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/dealii/79newCZGhhM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to dealii+un...@googlegroups.com.
--
The deal.II project is located at http://www.dealii.org/
For mailing list/forum options, see https://groups.google.com/d/forum/dealii?hl=en
for (unsigned int shape_function=0;
shape_function<dofs_per_cell; ++shape_function)
{
for (unsigned int d=0; d<spacedim; ++d)
if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
{
const dealii::Tensor<1,spacedim> *shape_gradient_ptr =
&shape_gradients[shape_function_data[shape_function].
row_index[d]][0];
for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
divergences[q_point] += value * (*shape_gradient_ptr++)[d];
}
}
To me, it's not clear how the "value and shape_gradient_ptr" is used or in general how the (e.g.) u_x+v_y+w_z is done..
For the SymmetricTensor, the code differs as;
const unsigned int ii = dealii::SymmetricTensor<2,spacedim>::
unrolled_to_component_indices(comp)[0];
const unsigned int jj = dealii::SymmetricTensor<2,spacedim>::
unrolled_to_component_indices(comp)[1];
for (unsigned int q_point = 0; q_point < n_quadrature_points;
++q_point, ++shape_gradient_ptr)
{
divergences[q_point][ii] += value * (*shape_gradient_ptr)[jj];
if (ii != jj)
divergences[q_point][jj] += value * (*shape_gradient_ptr)[ii];
}
I again cannot follow it. and what should I understand, that the loop over spacedim (or SymmetricTensor<2,spacedim>::n_independent_components) not implemented or not needed? please see, Assert (false, ExcNotImplemented());
Also, as a general question, how/where does the "Tensor<2, dim, spacedim>::divergence" function operate?
[...]
For the vectors, the implementation (for the else case) is as following;for (unsigned int shape_function=0;
shape_function<dofs_per_cell; ++shape_function)
{
for (unsigned int d=0; d<spacedim; ++d)
if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
{
const dealii::Tensor<1,spacedim> *shape_gradient_ptr =
&shape_gradients[shape_function_data[shape_function].
row_index[d]][0];
for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
divergences[q_point] += value * (*shape_gradient_ptr++)[d];
}
}
To me, it's not clear how the "value and shape_gradient_ptr" is used or in general how the (e.g.) u_x+v_y+w_z is done..
if (snc != -1)
{
const unsigned int comp =
shape_function_data[shape_function].single_nonzero_component_index;
const dealii::Tensor < 1, spacedim> *shape_gradient_ptr =
&shape_gradients[snc][0];
const TableIndices<2> indices = dealii::Tensor<2,spacedim>::unrolled_to_component_indices(comp);
const unsigned int ii = indices[0];
const unsigned int jj = indices[1];
for (unsigned int q_point = 0; q_point < n_quadrature_points;
++q_point, ++shape_gradient_ptr)
{
divergences[q_point][jj] += value * (*shape_gradient_ptr)[ii];
}
}
else
{
for (unsigned int d = 0;
d < dim*dim; ++d)
if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
{
Assert (false, ExcNotImplemented());
}
}
There is only the "snc != 1" case, and it seems that the component now means the tensor components and not the directions in space. Is this function (for tensors) not yet implemented? or is it sth related to non-primitive shape functions (I would appreciate if you could comment on this as well)?
Thank you in advance.
Best,
Metin
I understand that the components are in space (x/y/z), and (*shape_gradient_ptr++)[d] would be derivative of phi in each direction; is that correct?
(compared to vectors) the implementation of divergence function for the tensors is as following;if (snc != -1)
{
const unsigned int comp =
shape_function_data[shape_function].single_nonzero_component_index;
const dealii::Tensor < 1, spacedim> *shape_gradient_ptr =
&shape_gradients[snc][0];
const TableIndices<2> indices = dealii::Tensor<2,spacedim>::unrolled_to_component_indices(comp);
const unsigned int ii = indices[0];
const unsigned int jj = indices[1];
for (unsigned int q_point = 0; q_point < n_quadrature_points;
++q_point, ++shape_gradient_ptr)
{
divergences[q_point][jj] += value * (*shape_gradient_ptr)[ii];
}
}
There is only the "snc != 1" case, and it seems that the component now means the tensor components and not the directions in space. Is this function (for tensors) not yet implemented? or is it sth related to non-primitive shape functions (I would appreciate if you could comment on this as well)?