From 87c29c488e0d1ceb82c1d31630d5bd5c3e809051 Mon Sep 17 00:00:00 2001 From: bangerth Date: Thu, 11 Dec 2008 20:30:08 +0000 Subject: [PATCH] Cache even more data to make the case of primitive elements more efficient. git-svn-id: https://svn.dealii.org/trunk@17914 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/deal.II/include/fe/fe_values.h | 180 +++++++++++++++++-------- deal.II/deal.II/source/fe/fe_values.cc | 27 +++- 2 files changed, 150 insertions(+), 57 deletions(-) diff --git a/deal.II/deal.II/include/fe/fe_values.h b/deal.II/deal.II/include/fe/fe_values.h index 28d39c7b53..4df1dd4db8 100644 --- a/deal.II/deal.II/include/fe/fe_values.h +++ b/deal.II/deal.II/include/fe/fe_values.h @@ -503,6 +503,23 @@ namespace FEValuesViews * information. */ Table<2,unsigned int> row_index; + + /** + * For each shape function say the + * following: if only a single entry in + * is_nonzero_shape_function_component + * for this shape function is nonzero, + * then store the corresponding value + * of row_index and + * single_nonzero_component_index + * represents the index between 0 and + * dim for which it is attained. If + * multiple components are nonzero, + * then store -1. If no components are + * nonzero then store -2. + */ + Table<1,int> single_nonzero_component; + Table<1,unsigned int> single_nonzero_component_index; }; } @@ -3482,19 +3499,26 @@ namespace FEValuesViews // same as for the scalar case except // that we have one more index - // - // for primitive elements we could - // probably do even better than the loop - // below because we then know that only - // for one value of 'd' the - // 'if'-condition is true - value_type return_value; - for (unsigned int d=0; d::gradient (const unsigned int shape_function, const unsigned int q_point) const { - // this function works like in - // the case above - typedef FEValuesBase FVB; Assert (shape_function < fe_values.fe->dofs_per_cell, ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell)); @@ -3516,19 +3537,26 @@ namespace FEValuesViews // same as for the scalar case except // that we have one more index - // - // for primitive elements we could - // probably do even better than the loop - // below because we then know that only - // for one value of 'd' the - // 'if'-condition is true - gradient_type return_value; - for (unsigned int d=0; d FVB; Assert (shape_function < fe_values.fe->dofs_per_cell, ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell)); @@ -3550,19 +3577,26 @@ namespace FEValuesViews // same as for the scalar case except // that we have one more index - // - // for primitive elements we could - // probably do even better than the loop - // below because we then know that only - // for one value of 'd' the - // 'if'-condition is true - divergence_type return_value = 0; - for (unsigned int d=0; d::symmetric_gradient (const unsigned int shape_function, const unsigned int q_point) const { - return symmetrize (gradient(shape_function, q_point)); + typedef FEValuesBase FVB; + Assert (shape_function < fe_values.fe->dofs_per_cell, + ExcIndexRange (shape_function, 0, fe_values.fe->dofs_per_cell)); + Assert (fe_values.update_flags & update_gradients, + typename FVB::ExcAccessToUninitializedField()); + + // same as for the scalar case except + // that we have one more index + const int snc = single_nonzero_component(shape_function); + if (snc == -2) + return symmetric_gradient_type(); + else if (snc != -1) + { + gradient_type return_value; + return_value[single_nonzero_component_index[shape_function]] + = fe_values.shape_gradients[snc][q_point]; + return symmetrize(return_value); + } + else + { + gradient_type return_value; + for (unsigned int d=0; ddofs_per_cell, dim), row_index (fe_values.fe->dofs_per_cell, - dim) + dim), + single_nonzero_component (fe_values.fe->dofs_per_cell), + single_nonzero_component_index (fe_values.fe->dofs_per_cell) { Assert (first_vector_component+dim-1 < fe_values.fe->n_components(), ExcIndexRange(first_vector_component+dim-1, 0, @@ -174,6 +176,29 @@ namespace FEValuesViews row_index[i][d] = numbers::invalid_unsigned_int; } } + + for (unsigned int i=0; idofs_per_cell; ++i) + { + unsigned int n_nonzero_components = 0; + for (unsigned int d=0; d 1) + single_nonzero_component(i) = -1; + else + { + for (unsigned int d=0; d