Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify creating and unrolling symmetric tensors #5640

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions include/aspect/utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,47 @@ namespace aspect
*/
namespace Tensors
{
/**
* Convert a series of doubles to a SymmetricTensor of the same size.
* The input is expected to be ordered according to the
* SymmetricTensor::unrolled_to_component_indices() function.
*/
template <int dim, class Iterator>
inline
SymmetricTensor<2,dim>
to_symmetric_tensor(const Iterator begin,
const Iterator end)
{
AssertDimension(std::distance(begin, end), (SymmetricTensor<2,dim>::n_independent_components));
(void) end;

SymmetricTensor<2,dim> output;

Iterator next = begin;
for (unsigned int i=0; i < SymmetricTensor<2,dim>::n_independent_components; ++i, ++next)
output[SymmetricTensor<2,dim>::unrolled_to_component_indices(i)] = *next;

return output;
}

/**
* Unroll a SymmetricTensor into a series of doubles. The output is ordered
* according to the SymmetricTensor::unrolled_to_component_indices() function.
*/
template <int dim, class Iterator>
inline
void
unroll_symmetric_tensor_into_array(const SymmetricTensor<2,dim> &tensor,
const Iterator begin,
const Iterator end)
{
AssertDimension(std::distance(begin, end), (SymmetricTensor<2,dim>::n_independent_components));
(void) end;

Iterator next = begin;
for (unsigned int i=0; i < SymmetricTensor<2,dim>::n_independent_components; ++i, ++next)
*next = tensor[SymmetricTensor<2,dim>::unrolled_to_component_indices(i)];
}

/**
* Rotate a 3D 4th order tensor representing the full stiffnexx matrix using a 3D 2nd order rotation tensor
Expand Down
19 changes: 9 additions & 10 deletions source/material_model/rheology/elasticity.cc
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,8 @@ namespace aspect
for (unsigned int i=0; i < in.n_evaluation_points(); ++i)
{
// Get old stresses from compositional fields
SymmetricTensor<2,dim> stress_old;
for (unsigned int j=0; j < SymmetricTensor<2,dim>::n_independent_components; ++j)
stress_old[SymmetricTensor<2,dim>::unrolled_to_component_indices(j)] = in.composition[i][j];
const SymmetricTensor<2,dim> stress_old (Utilities::Tensors::to_symmetric_tensor<dim>(&in.composition[i][0],
&in.composition[i][0]+SymmetricTensor<2,dim>::n_independent_components));

elastic_out->elastic_force[i] = -effective_creep_viscosities[i] / calculate_elastic_viscosity(average_elastic_shear_moduli[i]) * stress_old;
// The viscoelastic strain rate is needed only when the Newton method is selected.
Expand Down Expand Up @@ -393,9 +392,8 @@ namespace aspect
for (unsigned int i=0; i < in.n_evaluation_points(); ++i)
{
// Get old stresses from compositional fields
SymmetricTensor<2,dim> stress_old;
for (unsigned int j=0; j < SymmetricTensor<2,dim>::n_independent_components; ++j)
stress_old[SymmetricTensor<2,dim>::unrolled_to_component_indices(j)] = in.composition[i][j];
const SymmetricTensor<2,dim> stress_old(Utilities::Tensors::to_symmetric_tensor<dim>(&in.composition[i][0],
&in.composition[i][0]+SymmetricTensor<2,dim>::n_independent_components));

// Calculate the rotated stresses
// Rotation (vorticity) tensor (equation 25 in Moresi et al., 2003, J. Comp. Phys.)
Expand Down Expand Up @@ -426,11 +424,12 @@ namespace aspect
// timestep, then no averaging occurs as dt/dte = 1.
stress_new = ( ( 1. - ( dt / dte ) ) * stress_old ) + ( ( dt / dte ) * stress_new ) ;

// Fill reaction terms
for (unsigned int j = 0; j < SymmetricTensor<2,dim>::n_independent_components ; ++j)
out.reaction_terms[i][j] = -stress_old[SymmetricTensor<2,dim>::unrolled_to_component_indices(j)]
+ stress_new[SymmetricTensor<2,dim>::unrolled_to_component_indices(j)];
const SymmetricTensor<2,dim> stress_update = stress_new - stress_old;

// Fill reaction terms
Utilities::Tensors::unroll_symmetric_tensor_into_array(stress_update,
&out.reaction_terms[i][0],
&out.reaction_terms[i][0]+SymmetricTensor<2,dim>::n_independent_components);
}
}
}
Expand Down
11 changes: 5 additions & 6 deletions source/particle/property/cpo_elastic_tensor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,8 @@ namespace aspect
CpoElasticTensor<dim>::get_elastic_tensor(unsigned int cpo_data_position,
const ArrayView<double> &data)
{
SymmetricTensor<2,6> elastic_tensor;
for (unsigned int i = 0; i < SymmetricTensor<2,6>::n_independent_components ; ++i)
elastic_tensor[SymmetricTensor<2,6>::unrolled_to_component_indices(i)] = data[cpo_data_position + i];
return elastic_tensor;
return Utilities::Tensors::to_symmetric_tensor<6>(&data[cpo_data_position],
&data[cpo_data_position]+SymmetricTensor<2,6>::n_independent_components);
}


Expand All @@ -188,8 +186,9 @@ namespace aspect
const ArrayView<double> &data,
const SymmetricTensor<2,6> &elastic_tensor)
{
for (unsigned int i = 0; i < SymmetricTensor<2,6>::n_independent_components ; ++i)
data[cpo_data_position + i] = elastic_tensor[SymmetricTensor<2,6>::unrolled_to_component_indices(i)];
Utilities::Tensors::unroll_symmetric_tensor_into_array(elastic_tensor,
&data[cpo_data_position],
&data[cpo_data_position]+SymmetricTensor<2,6>::n_independent_components);
}


Expand Down
Loading