Hello,
I would like to calculate traction/stress vectors for the deformed configuration. I have solved for a non-linear elasticity problem and am dealing with the Green-Lagrange strain tensor and the second Piola-Kirchoff stress tensor. I thought the simplest way to get the traction vectors would be to first calculate them in the material reference frame (by calculating the stress tensor and applying it to normal vectors in the material reference), and then using a pushforward operation (by applying the deformation gradient) to produce the stress vectors in the spatial reference frame (and also dividing by the determinant of the deformation vector to take care of the change in area).
However, the results do not appear as expected. To understand what was going on, I first decided to apply the pushforward operation to the normal vectors. I used the following code to carry this out.
template <int dim>
class SpatialNormalVectorPostprocess: public DataPostprocessorVector<dim> {
public:
SpatialNormalVectorPostprocess();
virtual void evaluate_vector_field(
const DataPostprocessorInputs::Vector<dim>& input_data,
std::vector<Vector<double>>& computed_quantities) const;
};
template <int dim>
SpatialNormalVectorPostprocess<dim>::SpatialNormalVectorPostprocess():
DataPostprocessorVector<dim>(
"spatial_normal",
update_gradients | update_normal_vectors) {}
template <int dim>
void SpatialNormalVectorPostprocess<dim>::evaluate_vector_field(
const DataPostprocessorInputs::Vector<dim>& input_data,
std::vector<Vector<double>>& computed_quantities) const {
for (unsigned int i {0}; i != input_data.normals.size(); i++) {
Tensor<2, dim, double> grad_u {};
Tensor<2, dim, double> identity_tensor {};
for (unsigned int d {0}; d != dim; d++) {
grad_u[d] = input_data.solution_gradients[i][d];
identity_tensor[d][d] = 1;
}
const Tensor<2, dim, double> deformation_grad {
grad_u + identity_tensor};
const Tensor<1, dim, double> material_normal_vector {
input_data.normals[i]};
const Tensor<1, dim, double> spatial_normal_vector_t {
deformation_grad * material_normal_vector};
Vector<double> spatial_normal_vector(dim);
for (unsigned int d {0}; d != dim; d++) {
spatial_normal_vector[d] = spatial_normal_vector_t[d];
}
computed_quantities[i] = spatial_normal_vector;
}
}
However, as seen below, the resulting vectors are not normal to the surfaces:
Contrast this with if I instead update the mesh and directly output the normal vectors:
Any input would be greatly appreciated.
Best wishes,
Alex