From d48a39aceb54ab57a4ddf66c3de24f7a86307d6a Mon Sep 17 00:00:00 2001 From: kormann Date: Sat, 5 May 2012 18:36:25 +0000 Subject: [PATCH] Merge branch with matrix-free computations. Remaining parts. git-svn-id: https://svn.dealii.org/trunk@25493 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/examples/step-37/doc/intro.dox | 17 +- deal.II/include/deal.II/base/parallel.h | 11 + .../include/deal.II/base/symmetric_tensor.h | 36 +- deal.II/include/deal.II/base/utilities.h | 29 + deal.II/include/deal.II/fe/fe_poly.h | 16 + .../include/deal.II/fe/fe_poly.templates.h | 60 + .../include/deal.II/matrix_free/dof_info.h | 59 +- .../deal.II/matrix_free/dof_info.templates.h | 363 +++- .../deal.II/matrix_free/fe_evaluation.h | 1686 +++++++++-------- .../deal.II/matrix_free/helper_functions.h | 285 +-- .../deal.II/matrix_free/mapping_info.h | 118 +- .../matrix_free/mapping_info.templates.h | 212 ++- .../include/deal.II/matrix_free/matrix_free.h | 451 +++-- .../matrix_free/matrix_free.templates.h | 628 +++--- .../{fe_evaluation_data.h => shape_info.h} | 17 +- ...ata.templates.h => shape_info.templates.h} | 77 +- deal.II/source/lac/constraint_matrix.inst.pl | 3 +- tests/fe/injection_q/cmp/generic | 2 +- tests/matrix_free/copy.cc | 34 +- tests/matrix_free/create_mesh.h | 38 +- tests/matrix_free/get_functions_circle.cc | 2 +- tests/matrix_free/get_functions_common.h | 196 +- tests/matrix_free/get_functions_float.cc | 12 +- tests/matrix_free/get_functions_gl.cc | 90 +- tests/matrix_free/get_functions_mappingq.cc | 16 +- tests/matrix_free/get_functions_multife.cc | 224 +-- tests/matrix_free/get_functions_multife2.cc | 286 +-- .../get_functions_q_hierarchical.cc | 94 +- tests/matrix_free/get_functions_rect.cc | 32 +- tests/matrix_free/get_functions_variants.cc | 94 +- tests/matrix_free/get_values_plain.cc | 70 +- tests/matrix_free/integrate_functions.cc | 108 +- .../integrate_functions_multife.cc | 236 +-- .../integrate_functions_multife2.cc | 236 +-- tests/matrix_free/matrix_vector_02.cc | 2 +- tests/matrix_free/matrix_vector_03.cc | 6 +- tests/matrix_free/matrix_vector_05.cc | 4 +- tests/matrix_free/matrix_vector_06.cc | 6 +- tests/matrix_free/matrix_vector_07.cc | 16 +- tests/matrix_free/matrix_vector_08.cc | 6 +- tests/matrix_free/matrix_vector_09.cc | 6 +- tests/matrix_free/matrix_vector_common.h | 100 +- tests/matrix_free/matrix_vector_curl.cc | 136 +- tests/matrix_free/matrix_vector_float.cc | 4 +- tests/matrix_free/matrix_vector_hp.cc | 136 +- tests/matrix_free/matrix_vector_mg.cc | 122 +- tests/matrix_free/matrix_vector_stokes.cc | 172 +- .../matrix_vector_stokes_noflux.cc | 196 +- tests/matrix_free/quadrature_points.cc | 26 +- tests/matrix_free/thread_correctness.cc | 94 +- tests/matrix_free/thread_correctness_hp.cc | 90 +- tests/mpi/matrix_free_01.cc | 100 +- tests/mpi/matrix_free_02.cc | 96 +- tests/mpi/matrix_free_03.cc | 102 +- tests/mpi/parallel_partitioner_01.cc | 18 +- tests/mpi/parallel_partitioner_02.cc | 12 +- tests/mpi/parallel_partitioner_03.cc | 14 +- tests/mpi/parallel_partitioner_04.cc | 20 +- tests/mpi/parallel_vector_01.cc | 4 +- tests/mpi/parallel_vector_02.cc | 8 +- tests/mpi/parallel_vector_03.cc | 10 +- tests/mpi/parallel_vector_04.cc | 22 +- tests/mpi/parallel_vector_05.cc | 8 +- tests/mpi/parallel_vector_07.cc | 18 +- tests/mpi/parallel_vector_08.cc | 44 +- tests/mpi/parallel_vector_09.cc | 18 +- tests/mpi/parallel_vector_10.cc | 6 +- tests/mpi/parallel_vector_11.cc | 10 +- tests/mpi/parallel_vector_12.cc | 29 +- 69 files changed, 3893 insertions(+), 3606 deletions(-) rename deal.II/include/deal.II/matrix_free/{fe_evaluation_data.h => shape_info.h} (94%) rename deal.II/include/deal.II/matrix_free/{fe_evaluation_data.templates.h => shape_info.templates.h} (73%) diff --git a/deal.II/examples/step-37/doc/intro.dox b/deal.II/examples/step-37/doc/intro.dox index 54c3686564..6f18b1bf51 100644 --- a/deal.II/examples/step-37/doc/intro.dox +++ b/deal.II/examples/step-37/doc/intro.dox @@ -4,9 +4,13 @@ This program was contributed by Katharina Kormann and Martin Kronbichler. -The algorithm for the matrix-vector product is built upon the preprint "A generic interface for parallel cell-based finite element operator application" by Martin Kronbichler and Katharina Kormann, Uppsala -University, October 2011, and the paper "Parallel finite element operator application: Graph partitioning and coloring" by Katharina Kormann and Martin Kronbichler in: Proceedings of the 7th IEEE International Conference on e-Science, 2011. - +The algorithm for the matrix-vector product is built upon the article A generic interface +for parallel cell-based finite element operator application by Martin +Kronbichler and Katharina Kormann, Computers and Fluids, 2012, and the paper +"Parallel finite element operator application: Graph partitioning and +coloring" by Katharina Kormann and Martin Kronbichler in: Proceedings of +the 7th IEEE International Conference on e-Science, 2011. @@ -343,6 +347,13 @@ reduces the complexity for computing this product from $p^4$ to $2 p^3$, where p is the number of shape functions in each coordinate direction), or $p^{2d}$ to $d p^{d+1}$ in general. +Implementing a matrix-free and cell-based finite element operator requires a +somewhat different design compared to the usual matrix assembly codes shown in +previous tutorial programs. The data structures for doing this are the +MatrixFree class that collects all data and issues a (parallel) loop over all +cells and the FEEvaluation class that evaluates finite element basis functions +by making use of the tensor product structure. + The implementation of the matrix-free matrix-vector product shown in this tutorial is slower than a matrix-vector product using a sparse matrix for diff --git a/deal.II/include/deal.II/base/parallel.h b/deal.II/include/deal.II/base/parallel.h index 23d9bc7f92..9ca7284426 100644 --- a/deal.II/include/deal.II/base/parallel.h +++ b/deal.II/include/deal.II/base/parallel.h @@ -508,6 +508,12 @@ namespace parallel */ struct ParallelForInteger { + /** + * Destructor. Made virtual to ensure that derived classes also + * have virtual destructors. + */ + virtual ~ParallelForInteger (); + /** * This function runs the for loop over the * given range [lower,upper), @@ -834,6 +840,11 @@ namespace parallel #endif + inline + ParallelForInteger::~ParallelForInteger () + {} + + inline void ParallelForInteger::apply_parallel (const std::size_t begin, diff --git a/deal.II/include/deal.II/base/symmetric_tensor.h b/deal.II/include/deal.II/base/symmetric_tensor.h index 4bddb22908..90f6948cc8 100644 --- a/deal.II/include/deal.II/base/symmetric_tensor.h +++ b/deal.II/include/deal.II/base/symmetric_tensor.h @@ -898,27 +898,27 @@ class SymmetricTensor Number & operator [] (const TableIndices &indices); - /** - * Access to an element according - * to unrolled index. The - * function - * s.access_raw_entry(i) - * does the same as - * s[s.unrolled_to_component_indices(i)], - * but more efficiently. - */ + /** + * Access to an element according + * to unrolled index. The + * function + * s.access_raw_entry(i) + * does the same as + * s[s.unrolled_to_component_indices(i)], + * but more efficiently. + */ Number access_raw_entry (const unsigned int unrolled_index) const; - /** - * Access to an element according - * to unrolled index. The - * function - * s.access_raw_entry(i) - * does the same as - * s[s.unrolled_to_component_indices(i)], - * but more efficiently. - */ + /** + * Access to an element according + * to unrolled index. The + * function + * s.access_raw_entry(i) + * does the same as + * s[s.unrolled_to_component_indices(i)], + * but more efficiently. + */ Number & access_raw_entry (const unsigned int unrolled_index); diff --git a/deal.II/include/deal.II/base/utilities.h b/deal.II/include/deal.II/base/utilities.h index 8750535850..8bd5a226a9 100644 --- a/deal.II/include/deal.II/base/utilities.h +++ b/deal.II/include/deal.II/base/utilities.h @@ -188,6 +188,35 @@ namespace Utilities T fixed_power (const T t); + /** + * Calculate a fixed power of an integer + * number by a template expression where + * both the number a and the + * power N are compile-time + * constants. This gives compile-time + * knowledge of the result of the power + * operation. + * + * Use this function as in + * fixed_int_power@::value. + */ + template + struct fixed_int_power + { + static const int value = a * fixed_int_power::value; + }; + + /** + * Base case for the power operation with + * N=0, which gives the result + * 1. + */ + template + struct fixed_int_power + { + static const int value = 1; + }; + /** * Optimized replacement for * std::lower_bound for diff --git a/deal.II/include/deal.II/fe/fe_poly.h b/deal.II/include/deal.II/fe/fe_poly.h index 8f163f64ab..437dee900c 100644 --- a/deal.II/include/deal.II/fe/fe_poly.h +++ b/deal.II/include/deal.II/fe/fe_poly.h @@ -81,6 +81,22 @@ class FE_Poly : public FiniteElement */ unsigned int get_degree () const; + /** + * Return the numbering of the underlying + * polynomial space compared to + * lexicographic ordering of the basis + * functions. Returns + * POLY::get_numbering(). + */ + std::vector get_poly_space_numbering() const; + + /** + * Return the inverse numbering of the + * underlying polynomial space. Returns + * POLY::get_numbering_inverse(). + */ + std::vector get_poly_space_numbering_inverse() const; + /** * Return the value of the * ith shape function at diff --git a/deal.II/include/deal.II/fe/fe_poly.templates.h b/deal.II/include/deal.II/fe/fe_poly.templates.h index 8d1d549927..cc79e573ab 100644 --- a/deal.II/include/deal.II/fe/fe_poly.templates.h +++ b/deal.II/include/deal.II/fe/fe_poly.templates.h @@ -438,4 +438,64 @@ FE_Poly::fill_fe_subface_values (const Mapping this->compute_2nd (mapping, cell, offset, mapping_data, fe_data, data); } + + +namespace internal +{ + template + inline + std::vector + get_poly_space_numbering (const POLY&) + { + Assert (false, ExcNotImplemented()); + return std::vector(); + } + + template + inline + std::vector + get_poly_space_numbering_inverse (const POLY&) + { + Assert (false, ExcNotImplemented()); + return std::vector(); + } + + template + inline + std::vector + get_poly_space_numbering (const TensorProductPolynomials &poly) + { + return poly.get_numbering(); + } + + template + inline + std::vector + get_poly_space_numbering_inverse (const TensorProductPolynomials &poly) + { + return poly.get_numbering_inverse(); + } +} + + + +template +std::vector +FE_Poly::get_poly_space_numbering () const +{ + return internal::get_poly_space_numbering (poly_space); +} + + + + +template +std::vector +FE_Poly::get_poly_space_numbering_inverse () const +{ + return internal::get_poly_space_numbering_inverse (poly_space); +} + + + DEAL_II_NAMESPACE_CLOSE diff --git a/deal.II/include/deal.II/matrix_free/dof_info.h b/deal.II/include/deal.II/matrix_free/dof_info.h index b5d78e96cb..a86b2bcb66 100644 --- a/deal.II/include/deal.II/matrix_free/dof_info.h +++ b/deal.II/include/deal.II/matrix_free/dof_info.h @@ -159,7 +159,7 @@ namespace MatrixFreeFunctions const std::vector &lexicographic_inv, const ConstraintMatrix &constraints, const unsigned int cell_number, - internal::ConstraintValues&constraint_values, + ConstraintValues&constraint_values, bool &cell_at_boundary); /** @@ -174,18 +174,55 @@ namespace MatrixFreeFunctions */ void assign_ghosts(const std::vector &boundary_cells); + /** + * Reorganizes cells for serial + * (non-thread-parallelized) such that + * boundary cells are places in the + * middle. This way, computations and + * communication can be overlapped. Should + * only be called by one DoFInfo object when + * used on a system of several DoFHandlers. + */ + void compute_renumber_serial (const std::vector &boundary_cells, + const SizeInfo &size_info, + std::vector &renumbering); + + /** + * Reorganizes cells in the hp case without + * parallelism such that all cells with the + * same FE index are placed + * consecutively. Should only be called by one + * DoFInfo object when used on a system of + * several DoFHandlers. + */ + void compute_renumber_hp_serial (SizeInfo &size_info, + std::vector &renumbering, + std::vector &irregular_cells); + + /** + * Computes the initial renumbering of cells + * such that all cells with ghosts are put + * first. This is the first step before + * building the thread graph and used to + * overlap computations and communication. + */ + void compute_renumber_parallel (const std::vector &boundary_cells, + SizeInfo &size_info, + std::vector &renumbering); + /** * This method reorders the way cells are gone * through based on a given renumbering of the - * cells. It also takes @p n_vectors cells - * together and interprets them as one cell - * only, as is needed for vectorization. + * cells. It also takes @p + * vectorization_length cells together and + * interprets them as one cell only, as is + * needed for vectorization. */ void reorder_cells (const SizeInfo &size_info, const std::vector &renumbering, const std::vector &constraint_pool_row_index, const std::vector &irregular_cells, - const unsigned int n_vectors); + const unsigned int vectorization_length); /** * This helper function determines a block @@ -292,12 +329,14 @@ namespace MatrixFreeFunctions const SizeInfo &size_info) const; /** - * Returns the memory consumption in bytes of - * this class. + * Prints a representation of the + * indices in the class to the given + * output stream. */ template - void print (const CompressedMatrix &constraint_pool, - std::ostream &out) const; + void print (const std::vector &constraint_pool_data, + const std::vector &constraint_pool_row_index, + std::ostream &out) const; /** * Stores the rowstart indices of the @@ -344,7 +383,7 @@ namespace MatrixFreeFunctions * reading from or writing to a vector. The * second number stores the index of the * constraint weights, stored in the variable - * constraint_pool. + * constraint_pool_data. */ std::vector > constraint_indicator; diff --git a/deal.II/include/deal.II/matrix_free/dof_info.templates.h b/deal.II/include/deal.II/matrix_free/dof_info.templates.h index 478eb70928..bba6378016 100644 --- a/deal.II/include/deal.II/matrix_free/dof_info.templates.h +++ b/deal.II/include/deal.II/matrix_free/dof_info.templates.h @@ -23,8 +23,7 @@ namespace internal { namespace MatrixFreeFunctions { - namespace internal - { + /** * A struct that takes entries describing * a constraint and puts them into a @@ -53,7 +52,8 @@ namespace MatrixFreeFunctions unsigned short insert_entries (const std::vector > &entries); - CompressedMatrix constraint_pool; + std::vector constraint_pool_data; + std::vector constraint_pool_row_index; std::vector > pool_locations; std::vector > constraint_entries; std::vector constraint_indices; @@ -67,7 +67,7 @@ namespace MatrixFreeFunctions : hashes (1.) { - constraint_pool.row_index.push_back (0); + constraint_pool_row_index.push_back (0); } template @@ -112,7 +112,7 @@ namespace MatrixFreeFunctions // If constraint has to be added, which will // be its no. - test.second = constraint_pool.row_index.size()-1; + test.second = constraint_pool_row_index.size()-1; // Hash value larger than all the ones // before. We need to add it. @@ -127,7 +127,8 @@ namespace MatrixFreeFunctions while(is_same == true) { if(one_constraint.size()!= - (constraint_pool.row_length(pos->second))) + (constraint_pool_row_index[pos->second+1]- + constraint_pool_row_index[pos->second])) // The constraints have different length, and // hence different. is_same = false; @@ -135,8 +136,8 @@ namespace MatrixFreeFunctions for (unsigned int q=0; qsecond]+q]- + if (std::fabs(constraint_pool_data[constraint_pool_row_index + [pos->second]+q]- one_constraint[q])>hashes.scaling) { is_same = false; @@ -172,9 +173,10 @@ namespace MatrixFreeFunctions // Remember hash value and location of // constraint. - constraint_pool.data.insert_back(one_constraint.begin(), - one_constraint.end()); - constraint_pool.complete_last_row(); + constraint_pool_data.insert (constraint_pool_data.end(), + one_constraint.begin(), + one_constraint.end()); + constraint_pool_row_index.push_back (constraint_pool_data.size()); // Add the location of constraint in pool. insert_position = test.second; @@ -188,7 +190,6 @@ namespace MatrixFreeFunctions ExcInternalError()); return static_cast(insert_position); } - } // end of namespace internal @@ -240,7 +241,7 @@ namespace MatrixFreeFunctions const std::vector &lexicographic_inv, const ConstraintMatrix &constraints, const unsigned int cell_number, - internal::ConstraintValues &constraint_values, + ConstraintValues &constraint_values, bool &cell_at_boundary) { Assert (vector_partitioner.get() !=0, ExcInternalError()); @@ -397,7 +398,8 @@ namespace MatrixFreeFunctions for (unsigned int j=0; j new_ghosts; ghost_dofs.swap(new_ghosts); + // set the ghost indices now. need to cast // away constness here, but that is uncritical // since we reset the Partitioner in the same @@ -523,24 +526,163 @@ namespace MatrixFreeFunctions + void + DoFInfo::compute_renumber_serial (const std::vector &boundary_cells, + const SizeInfo &size_info, + std::vector &renumbering) + { + std::vector reverse_numbering (size_info.n_active_cells, + numbers::invalid_unsigned_int); + const unsigned int n_boundary_cells = boundary_cells.size(); + for (unsigned int j=0; j &renumbering, + std::vector &irregular_cells) + { + const unsigned int n_active_cells = size_info.n_active_cells; + const unsigned int vectorization_length = size_info.vectorization_length; + irregular_cells.resize (0); + irregular_cells.resize (size_info.n_macro_cells+3*max_fe_index); + std::vector > renumbering_fe_index; + renumbering_fe_index.resize(max_fe_index); + unsigned int counter,n_macro_cells_before = 0; + const unsigned int + start_bound = std::min (size_info.n_active_cells, + size_info.boundary_cells_start*vectorization_length), + end_bound = std::min (size_info.n_active_cells, + size_info.boundary_cells_end*vectorization_length); + for(counter=0; counter &boundary_cells, + SizeInfo &size_info, + std::vector &renumbering) + { + std::vector reverse_numbering (size_info.n_active_cells, + numbers::invalid_unsigned_int); + const unsigned int n_boundary_cells = boundary_cells.size(); + for (unsigned int j=0; j &renumbering, const std::vector &constraint_pool_row_index, const std::vector &irregular_cells, - const unsigned int n_vectors) + const unsigned int vectorization_length) { // first reorder the active fe index. if (cell_active_fe_index.size() > 0) { std::vector new_active_fe_index; new_active_fe_index.reserve (size_info.n_macro_cells); - std::vector fe_indices(n_vectors); + std::vector fe_indices(vectorization_length); unsigned int position_cell = 0; for (unsigned int cell=0; cell 0 ? - irregular_cells[cell] : n_vectors); + irregular_cells[cell] : vectorization_length); for (unsigned int j=0; j glob_indices (n_vectors); - std::vector plain_glob_indices (n_vectors); + std::vector glob_indices (vectorization_length); + std::vector plain_glob_indices (vectorization_length); std::vector*> - constr_ind(n_vectors), constr_end(n_vectors); - std::vector index(n_vectors); + constr_ind(vectorization_length), constr_end(vectorization_length); + std::vector index(vectorization_length); for (unsigned int i=0; i (new_dof_indices.size(), new_constraint_indicator.size(), irregular_cells[i]); const unsigned int n_comp = (irregular_cells[i]>0 ? - irregular_cells[i] : n_vectors); + irregular_cells[i] : vectorization_length); for (unsigned int j=0; j= n_comp) @@ -759,9 +901,10 @@ namespace MatrixFreeFunctions // if there are too few degrees of freedom per // cell, need to increase the block size + const unsigned int minimum_parallel_grain_size = 500; if (dofs_per_cell[0] * task_info.block_size < - internal::minimum_parallel_grain_size) - task_info.block_size = (internal::minimum_parallel_grain_size / + minimum_parallel_grain_size) + task_info.block_size = (minimum_parallel_grain_size / dofs_per_cell[0] + 1); } if (task_info.block_size > size_info.n_macro_cells) @@ -780,8 +923,8 @@ namespace MatrixFreeFunctions if (size_info.n_macro_cells == 0) return; - const std::size_t n_vectors = size_info.n_vectors; - Assert (n_vectors > 0, ExcInternalError()); + const std::size_t vectorization_length = size_info.vectorization_length; + Assert (vectorization_length > 0, ExcInternalError()); guess_block_size (size_info, task_info); @@ -816,7 +959,7 @@ namespace MatrixFreeFunctions std::vector > renumbering_fe_index; renumbering_fe_index.resize(max_fe_index); unsigned int counter,n_macro_cells_before = 0; - for(counter=0;counter color_finder; + // this performs a classical breath-first + // search in the connectivity graph of the + // cell chunks while(work) { // put all cells up to begin_inner_cells into @@ -972,11 +1118,11 @@ namespace MatrixFreeFunctions // Color the cells within each partition - task_info.partition_color_blocks.row_index.resize(partition+1); + task_info.partition_color_blocks_row_index.resize(partition+1); unsigned int color_counter = 0, index_counter = 0; for(unsigned int part=0; part0) - ?irregular_cells[mcell]:size_info.n_vectors; + ?irregular_cells[mcell]:size_info.vectorization_length; block_start[block+1] += n_comp; ++counter; } @@ -1101,7 +1247,7 @@ namespace MatrixFreeFunctions task_info.odds = (partition)>>1; task_info.n_blocked_workers = task_info.odds- (task_info.odds+task_info.evens+1)%2; - task_info.n_workers = task_info.partition_color_blocks.data.size()-1- + task_info.n_workers = task_info.partition_color_blocks_data.size()-1- task_info.n_blocked_workers; } @@ -1118,8 +1264,8 @@ namespace MatrixFreeFunctions if (size_info.n_macro_cells == 0) return; - const std::size_t n_vectors = size_info.n_vectors; - Assert (n_vectors > 0, ExcInternalError()); + const std::size_t vectorization_length = size_info.vectorization_length; + Assert (vectorization_length > 0, ExcInternalError()); guess_block_size (size_info, task_info); @@ -1130,7 +1276,7 @@ namespace MatrixFreeFunctions task_info.block_size_last = size_info.n_macro_cells- (task_info.block_size*(task_info.n_blocks-1)); task_info.position_short_block = task_info.n_blocks-1; - unsigned int cluster_size = task_info.block_size*n_vectors; + unsigned int cluster_size = task_info.block_size*vectorization_length; // create the connectivity graph without // internal blocking @@ -1138,37 +1284,43 @@ namespace MatrixFreeFunctions make_connectivity_graph (size_info, task_info, renumbering,irregular_cells, false, connectivity); - // Create cell-block partitioning. + // Create cell-block partitioning. - // For each block of cells, this variable - // saves to which partitions the block - // belongs. Initialize all to n_macro_cells to - // mark them as not yet assigned a partition. + // For each block of cells, this variable + // saves to which partitions the block + // belongs. Initialize all to n_macro_cells to + // mark them as not yet assigned a partition. std::vector cell_partition (size_info.n_active_cells, size_info.n_active_cells); std::vector neighbor_list; std::vector neighbor_neighbor_list; - // In element j of this variable, one puts the - // old number of the block that should be the - // jth block in the new numeration. + // In element j of this variable, one puts the + // old number of the block that should be the + // jth block in the new numeration. std::vector partition_list(size_info.n_active_cells,0); std::vector partition_partition_list(size_info.n_active_cells,0); - // This vector points to the start of each - // partition. + // This vector points to the start of each + // partition. std::vector partition_size(2,0); unsigned int partition = 0,start_up=0,counter=0; - unsigned int start_nonboundary = n_vectors * size_info.boundary_cells_end; + unsigned int start_nonboundary = vectorization_length * size_info.boundary_cells_end; if (start_nonboundary > size_info.n_active_cells) start_nonboundary = size_info.n_active_cells; bool work = true; unsigned int remainder = cluster_size; + + // this performs a classical breath-first + // search in the connectivity graph of the + // cells under the restriction that the size + // of the partitions should be a multiple of + // the given block size while (work) { - // put the cells with neighbors on remote MPI - // processes up front + // put the cells with neighbors on remote MPI + // processes up front if(start_nonboundary>0) { for(unsigned int cell=0; cell cell_partition_l2(size_info.n_active_cells, size_info.n_active_cells); - task_info.partition_color_blocks.row_index.resize(partition+1,0); - task_info.partition_color_blocks.data.resize(1,0); + task_info.partition_color_blocks_row_index.resize(partition+1,0); + task_info.partition_color_blocks_data.resize(1,0); start_up = 0; counter = 0; @@ -1428,19 +1580,19 @@ namespace MatrixFreeFunctions for (unsigned int j=0; j0) - size_info.boundary_cells_end = task_info.partition_color_blocks. - data[task_info.partition_color_blocks.row_index[1]]; + size_info.boundary_cells_end = task_info.partition_color_blocks_data + [task_info.partition_color_blocks_row_index[1]]; if (hp_bool == false) renumbering.swap(partition_partition_list); @@ -1596,11 +1748,11 @@ namespace MatrixFreeFunctions for(unsigned int part=0;part0) - ?irregular_cells[mcell]:size_info.n_vectors; + ?irregular_cells[mcell]:size_info.vectorization_length; for (unsigned int cell = cell_start; cell < cell_start+n_comp; ++cell) { @@ -1801,7 +1953,7 @@ namespace MatrixFreeFunctions ++mcell) { unsigned int n_comp = (irregular_cells[mcell]>0) - ?irregular_cells[mcell]:size_info.n_vectors; + ?irregular_cells[mcell]:size_info.vectorization_length; for (unsigned int cell = cell_start; cell < cell_start+n_comp; ++cell) { @@ -1949,26 +2101,31 @@ namespace MatrixFreeFunctions const SizeInfo &size_info) const { out << " Memory row starts indices: "; - size_info.print_mem (out, (row_starts.capacity()* - sizeof(std_cxx1x::tuple))); + size_info.print_memory_statistics + (out, (row_starts.capacity()*sizeof(std_cxx1x::tuple))); out << " Memory dof indices: "; - size_info.print_mem (out, MemoryConsumption::memory_consumption (dof_indices)); + size_info.print_memory_statistics + (out, MemoryConsumption::memory_consumption (dof_indices)); out << " Memory constraint indicators: "; - size_info.print_mem (out, MemoryConsumption::memory_consumption (constraint_indicator)); + size_info.print_memory_statistics + (out, MemoryConsumption::memory_consumption (constraint_indicator)); out << " Memory plain indices: "; - size_info.print_mem (out, MemoryConsumption::memory_consumption (row_starts_plain_indices)+ - MemoryConsumption::memory_consumption (plain_dof_indices)); + size_info.print_memory_statistics + (out, MemoryConsumption::memory_consumption (row_starts_plain_indices)+ + MemoryConsumption::memory_consumption (plain_dof_indices)); out << " Memory vector partitioner: "; - size_info.print_mem (out, MemoryConsumption::memory_consumption (*vector_partitioner)); + size_info.print_memory_statistics + (out, MemoryConsumption::memory_consumption (*vector_partitioner)); } template void - DoFInfo::print (const CompressedMatrix &constraint_pool, - std::ostream &out) const + DoFInfo::print (const std::vector &constraint_pool_data, + const std::vector &constraint_pool_row_index, + std::ostream &out) const { const unsigned int n_rows = row_starts.size() - 1; for (unsigned int row=0 ; rowsecond]; - ksecond+1]; + for(unsigned int k=constraint_pool_row_index[con_it->second]; + ksecond+1]; k++,index++) { Assert (glob_indices+index != end_row, ExcInternalError()); out << glob_indices[index] << "/" - << constraint_pool.data[k]; - if (ksecond+1]-1) + << constraint_pool_data[k]; + if (ksecond+1]-1) out << " "; } out << "] "; diff --git a/deal.II/include/deal.II/matrix_free/fe_evaluation.h b/deal.II/include/deal.II/matrix_free/fe_evaluation.h index c6e36a3a46..7e8a42ed09 100644 --- a/deal.II/include/deal.II/matrix_free/fe_evaluation.h +++ b/deal.II/include/deal.II/matrix_free/fe_evaluation.h @@ -45,9 +45,12 @@ namespace internal /** * This is the base class for the FEEvaluation classes. This class is a base * class and needs usually not be called in user code. Use one of the derived - * classes instead. It implements access functions to vectors for the @p - * read_dof_values, @p set_dof_values, and @p distributed_local_to_global - * functions, as well as the @p reinit method. + * classes FEEvaluationGeneral, FEEvaluation or FEEvaluationGL instead. It + * implements a reinit method that is used to set pointers so that operations + * on quadrature points can be performed quickly, access functions to vectors + * for the @p read_dof_values, @p set_dof_values, and @p + * distributed_local_to_global functions, as well as methods to access values + * and gradients of finite element functions. * * This class has five template arguments: * @@ -75,25 +78,16 @@ template vector_t; - static const std::size_t n_vectors = - VectorizedArray::n_array_elements; + typedef Tensor<1,n_components,VectorizedArray > value_type; + typedef Tensor<1,n_components,Tensor<1,dim,VectorizedArray > > gradient_type; + static const unsigned int dimension = dim; static const unsigned int dofs_per_cell = dofs_per_cell_; static const unsigned int n_q_points = n_q_points_; /** - * Constructor. Takes all data stored in - * MatrixFree. If applied to problems with - * more than one finite element or more than - * one quadrature formula selected during - * construction of @p matrix_free, @p - * fe_no and @p quad_no allow to select the - * appropriate components. + * @name 1: General operations */ - FEEvaluationBase (const MatrixFree &matrix_free, - const unsigned int fe_no = 0, - const unsigned int quad_no = 0); - + //@{ /** * Initializes the operation pointer to the * current cell. Unlike the FEValues::reinit @@ -112,7 +106,7 @@ public: * index which belongs to the current cell as * specified in @p reinit. Note that * MappingInfo has different fields for - * Cartesian cells, cells with linear mapping + * Cartesian cells, cells with affine mapping * and with general mappings, so in order to * access the correct data, this interface * must be used together with get_cell_type. @@ -120,136 +114,24 @@ public: unsigned int get_cell_data_number() const; /** - * Returns the type of the cell the @p reinit - * function has been called for. 0 means - * Cartesian cells (which allows for - * considerable data compression), 1 means - * cells with linear mappings, and 2 means - * general cells without any compressed - * storage applied. + * Returns the type of the cell the @p + * reinit function has been called + * for. Valid values are @p cartesian + * for Cartesian cells (which allows + * for considerable data compression), + * @p affine for cells with affine + * mappings, and @p general for + * general cells without any + * compressed storage applied. */ - unsigned int get_cell_type() const; + internal::MatrixFreeFunctions::CellType get_cell_type() const; - /** - * Returns a read-only pointer to the first - * field of function values on quadrature - * points. First come the function values on - * all quadrature points for the first - * component, then all values for the second - * component, and so on. This is related to - * the internal data structures used in this - * class. The raw data after a call to @p - * evaluate only contains unit cell - * operations, so possible transformations, - * quadrature weights etc. must be applied - * manually. In general, it is safer to use - * the get_value() function instead, which - * does all the transformation internally. - */ - const vector_t * begin_values () const; - - /** - * Returns a read and write pointer to the - * first field of function values on - * quadrature points. First come the function - * values on all quadrature points for the - * first component, then all values for the - * second component, and so on. This is - * related to the internal data structures - * used in this class. The raw data after a - * call to @p evaluate only contains unit - * cell operations, so possible - * transformations, quadrature weights - * etc. must be applied manually. In general, - * it is safer to use the get_value() function - * instead, which does all the transformation - * internally. - */ - vector_t * begin_values (); + //@} /** - * Returns a read-only pointer to the first - * field of function gradients on quadrature - * points. First comes the x-component of the - * gradient for the first component on all - * quadrature points, then the y-component, - * and so on. Next comes the x-component of - * the second component, and so on. This is - * related to the internal data structures - * used in this class. The raw data after a - * call to @p evaluate only contains unit - * cell operations, so possible - * transformations, quadrature weights - * etc. must be applied manually. In general, - * it is safer to use the get_gradient() function - * instead, which does all the transformation - * internally. + * @name 2: Reading from and writing to vectors */ - const vector_t * begin_gradients () const; - - /** - * Returns a read and write pointer to the - * first field of function gradients on - * quadrature points. First comes the - * x-component of the gradient for the first - * component on all quadrature points, then - * the y-component, and so on. Next comes the - * x-component of the second component, and so - * on. This is related to the internal data - * structures used in this class. The raw data - * after a call to @p evaluate only - * contains unit cell operations, so possible - * transformations, quadrature weights - * etc. must be applied manually. In general, - * it is safer to use the get_gradient() - * function instead, which does all the - * transformation internally. - */ - vector_t * begin_gradients (); - - /** - * Returns a read-only pointer to the first - * field of function hessians on quadrature - * points. First comes the xx-component of the - * hessian for the first component on all - * quadrature points, then the yy-component, - * zz-component in (3D), then the - * xy-component, and so on. Next comes the - * xx-component of the second component, and - * so on. This is related to the internal data - * structures used in this class. The raw data - * after a call to @p evaluate only - * contains unit cell operations, so possible - * transformations, quadrature weights - * etc. must be applied manually. In general, - * it is safer to use the get_laplacian() or - * get_hessian() functions instead, which does - * all the transformation internally. - */ - const vector_t * begin_hessians () const; - - /** - * Returns a read and write pointer to the - * first field of function hessians on - * quadrature points. First comes the - * xx-component of the hessian for the first - * component on all quadrature points, then - * the yy-component, zz-component in (3D), - * then the xy-component, and so on. Next - * comes the xx-component of the second - * component, and so on. This is related to - * the internal data structures used in this - * class. The raw data after a call to @p - * evaluate only contains unit cell - * operations, so possible transformations, - * quadrature weights etc. must be applied - * manually. In general, it is safer to use - * the get_laplacian() or get_hessian() - * functions instead, which does all the - * transformation internally. - */ - vector_t * begin_hessians (); - + //@{ /** * For the vector @p src, read out the values * on the degrees of freedom of the current @@ -498,6 +380,12 @@ public: template void set_dof_values (VectorType * dst_data[]) const; + //@} + + /** + * @name 3: Data access + */ + //@{ /** * Returns the value stored for the local * degree of freedom with index @p dof. If the @@ -511,18 +399,32 @@ public: * corresponds to the value of the integrated * function with the test function of the * given index. + * + * Note that the derived class + * FEEvaluationAccess overloads this operation + * with specializations for the scalar case + * (n_components == 1) and for the + * vector-valued case (n_components == dim). */ - Tensor<1,n_components,vector_t> - get_dof_value (unsigned int dof) const; + value_type get_dof_value (const unsigned int dof) const; /** * Write a value to the field containing the * degrees of freedom with component @p - * dof. Access to the same field as through @p - * get_dof_value. + * dof. Writes to the same field as is + * accessed through @p + * get_dof_value. Therefore, the original data + * that was read from a vector is overwritten + * as soon as a value is submitted. + * + * Note that the derived class + * FEEvaluationAccess overloads this operation + * with specializations for the scalar case + * (n_components == 1) and for the + * vector-valued case (n_components == dim). */ - void submit_dof_value (Tensor<1,n_components,vector_t> val_in, - unsigned int dof); + void submit_dof_value (const value_type val_in, + const unsigned int dof); /** * Returns the value of a finite @@ -537,9 +439,14 @@ public: * when vectorization is enabled, * values from several cells are * grouped together. + * + * Note that the derived class + * FEEvaluationAccess overloads this operation + * with specializations for the scalar case + * (n_components == 1) and for the + * vector-valued case (n_components == dim). */ - Tensor<1,n_components,vector_t> - get_value (unsigned int q_point) const; + value_type get_value (const unsigned int q_point) const; /** * Write a value to the field containing the @@ -550,9 +457,15 @@ public: * called, this specifies the value which is * tested by all basis function on the current * cell and integrated over. + * + * Note that the derived class + * FEEvaluationAccess overloads this operation + * with specializations for the scalar case + * (n_components == 1) and for the + * vector-valued case (n_components == dim). */ - void submit_value (Tensor<1,n_components,vector_t> val_in, - unsigned int q_point); + void submit_value (const value_type val_in, + const unsigned int q_point); /** * Returns the gradient of a finite element @@ -561,9 +474,14 @@ public: * evaluate(...,true,...), or the value * that has been stored there with a call to * @p submit_gradient. + * + * Note that the derived class + * FEEvaluationAccess overloads this operation + * with specializations for the scalar case + * (n_components == 1) and for the + * vector-valued case (n_components == dim). */ - Tensor<1,n_components,Tensor<1,dim,vector_t> > - get_gradient (unsigned int q_point) const; + gradient_type get_gradient (const unsigned int q_point) const; /** * Write a gradient to the field containing @@ -575,9 +493,15 @@ public: * this specifies the gradient which is tested * by all basis function gradients on the * current cell and integrated over. + * + * Note that the derived class + * FEEvaluationAccess overloads this operation + * with specializations for the scalar case + * (n_components == 1) and for the + * vector-valued case (n_components == dim). */ - void submit_gradient(Tensor<1,n_components,Tensor<1,dim,vector_t> >grad_in, - unsigned int q_point); + void submit_gradient(const gradient_type grad_in, + const unsigned int q_point); /** * Returns the Hessian of a finite element @@ -587,27 +511,46 @@ public: * diagonal or even the trace of the Hessian, * the Laplacian, is needed, use the other * functions below. + * + * Note that the derived class + * FEEvaluationAccess overloads this operation + * with specializations for the scalar case + * (n_components == 1) and for the + * vector-valued case (n_components == dim). */ - Tensor<1,n_components,Tensor<2,dim,vector_t> > - get_hessian (unsigned int q_point) const; + Tensor<1,n_components,Tensor<2,dim,VectorizedArray > > + get_hessian (const unsigned int q_point) const; /** * Returns the diagonal of the Hessian of a * finite element function at quadrature point * number @p q_point after a call to @p * evaluate(...,true). + * + * Note that the derived class + * FEEvaluationAccess overloads this operation + * with specializations for the scalar case + * (n_components == 1) and for the + * vector-valued case (n_components == dim). */ - Tensor<1,n_components,Tensor<1,dim,vector_t> > - get_hessian_diagonal (unsigned int q_point) const; + gradient_type get_hessian_diagonal (const unsigned int q_point) const; /** - * Returns the Laplacian of a finite element - * function at quadrature point number @p - * q_point after a call to @p - * evaluate(...,true). + * Returns the Laplacian (i.e., the trace of + * the Hessian) of a finite element function + * at quadrature point number @p q_point after + * a call to @p evaluate(...,true). Compared + * to the case when computing the full + * Hessian, some operations can be saved when + * only the Laplacian is requested. + * + * Note that the derived class + * FEEvaluationAccess overloads this operation + * with specializations for the scalar case + * (n_components == 1) and for the + * vector-valued case (n_components == dim). */ - Tensor<1,n_components,vector_t> - get_laplacian (unsigned int q_point) const; + value_type get_laplacian (const unsigned int q_point) const; /** * Takes values on quadrature points, @@ -622,40 +565,91 @@ public: * enabled, the integral values of several * cells are represented together. */ - Tensor<1,n_components,vector_t> - integrate_value (); + value_type integrate_value () const; + + //@} + +protected: /** - * Stores a reference to the underlying data. + * Constructor. Made protected to prevent + * users from directly using this class. Takes + * all data stored in MatrixFree. If applied + * to problems with more than one finite + * element or more than one quadrature formula + * selected during construction of @p + * matrix_free, @p fe_no and @p quad_no allow + * to select the appropriate components. */ - const MatrixFree &matrix_info; + FEEvaluationBase (const MatrixFree &matrix_free, + const unsigned int fe_no = 0, + const unsigned int quad_no = 0); /** - * Stores a reference to the underlying DoF - * indices and constraint description for the - * component specified at construction. Also - * contained in matrix_info, but it simplifies - * code if we store a reference to it. + * Internal data fields that store the + * values. Since all array lengths are known + * at compile time and since they are rarely + * more than a few kilobytes, allocate them on + * the stack. This makes it possible to + * cheaply set up a FEEvaluation object and + * write thread-safe programs by letting each + * thread own a private object of this type. + * + * This field stores the values for local + * degrees of freedom (e.g. after reading out + * from a vector but before applying unit cell + * transformations or before distributing them + * into a result vector). The methods + * get_dof_value() and submit_dof_value() + * read from or write to this field. */ - const internal::MatrixFreeFunctions::DoFInfo &dof_info; + VectorizedArray values_dofs[n_components][dofs_per_cell>0?dofs_per_cell:1]; /** - * Stores the constraints weights that - * supplement DoFInfo. Also contained in - * matrix_info, but it simplifies code if we - * store a reference to it. + * This field stores the values of the finite + * element function on quadrature points after + * applying unit cell transformations or + * before integrating. The methods get_value() + * and submit_value() access this field. */ - const internal::MatrixFreeFunctions::CompressedMatrix &constraint_pool; + VectorizedArray values_quad[n_components][n_q_points>0?n_q_points:1]; /** - * Stores a reference to the underlying - * transformation data from unit to real cells - * for the given quadrature formula specified - * at construction. Also contained in - * matrix_info, but it simplifies code if we - * store a reference to it. + * This field stores the gradients of the + * finite element function on quadrature + * points after applying unit cell + * transformations or before integrating. The + * methods get_gradient() and + * submit_gradient() (as well as some + * specializations like + * get_symmetric_gradient() or + * get_divergence()) access this field. */ - const internal::MatrixFreeFunctions::MappingInfo &mapping_info; + VectorizedArray gradients_quad[n_components][dim][n_q_points>0?n_q_points:1]; + + /** + * This field stores the Hessians of the + * finite element function on quadrature + * points after applying unit cell + * transformations. The methods get_hessian(), + * get_laplacian(), get_hessian_diagonal() + * access this field. + */ + VectorizedArray hessians_quad[n_components][(dim*(dim+1))/2][n_q_points>0?n_q_points:1]; + + /** + * Stores the number of the quadrature formula + * of the present cell. + */ + const unsigned int quad_no; + + /** + * Stores the number of components in the + * finite element as detected in the + * MatrixFree storage class for comparison + * with the template argument. + */ + const unsigned int n_fe_components; /** * Stores the active fe index for this class @@ -670,6 +664,30 @@ public: */ const unsigned int active_quad_index; + /** + * Stores a reference to the underlying data. + */ + const MatrixFree &matrix_info; + + /** + * Stores a reference to the underlying DoF + * indices and constraint description for the + * component specified at construction. Also + * contained in matrix_info, but it simplifies + * code if we store a reference to it. + */ + const internal::MatrixFreeFunctions::DoFInfo &dof_info; + + /** + * Stores a reference to the underlying + * transformation data from unit to real cells + * for the given quadrature formula specified + * at construction. Also contained in + * matrix_info, but it simplifies code if we + * store a reference to it. + */ + const internal::MatrixFreeFunctions::MappingInfo &mapping_info; + /** * Stores a reference to the unit cell data, * i.e., values, gradients and Hessians in 1D @@ -678,33 +696,52 @@ public: * matrix_info, but it simplifies code if we * store a reference to it. */ - const internal::MatrixFreeFunctions::FEEvaluationData &data; + const internal::MatrixFreeFunctions::ShapeInfo &data; -protected: /** - * Internal data fields that store the - * values. Since all array lengths are known - * at compile time and since they are rarely - * more than a few kilobytes, allocate them on - * the stack. This makes it possible to - * cheaply set up a FEEvaluation object and - * write thread-safe programs by letting each - * thread own a private object of this type. + * After a call to reinit(), stores the number + * of the cell we are currently working with. */ - vector_t values_dofs[n_components][dofs_per_cell>0?dofs_per_cell:1]; - vector_t values_quad[n_components][n_q_points>0?n_q_points:1]; - vector_t gradients_quad[n_components][dim][n_q_points>0?n_q_points:1]; - vector_t hessians_quad[n_components][(dim*(dim+1))/2][n_q_points>0?n_q_points:1]; + unsigned int cell; /** - * Stores the indices of the current cell. + * Stores the type of the cell we are + * currently working with after a call to + * reinit(). Valid values are @p cartesian, @p + * affine and @p general, which have different + * implications on how the Jacobian + * transformations are stored internally in + * MappingInfo. + */ + internal::MatrixFreeFunctions::CellType cell_type; + + /** + * The stride to access the correct data in + * MappingInfo. */ - const unsigned int quad_no; - const unsigned int n_fe_components; - unsigned int cell; - unsigned int cell_type; unsigned int cell_data_number; + + /** + * Stores whether the present cell chunk used + * in vectorization is not completely filled + * up with physical cells. E.g. if + * vectorization dictates that four cells + * should be worked with but only three + * physical cells are left, this flag will be + * set to true, otherwise to false. Mainly + * used for internal checking when reading + * from vectors or writing to vectors. + */ bool at_irregular_cell; + + /** + * If the present cell chunk for vectorization + * is not completely filled up with data, this + * field stores how many physical cells are + * underlying. Is between 1 and + * VectorizedArray::n_array_elements-1 + * (inclusive). + */ unsigned int n_irreg_components_filled; /** @@ -713,14 +750,14 @@ protected: * to a useful value if on a Cartesian cell, * otherwise zero. */ - const Tensor<1,dim,vector_t> * cartesian; + const Tensor<1,dim,VectorizedArray > * cartesian_data; /** * A pointer to the Jacobian information of * the present cell. Only set to a useful * value if on a non-Cartesian cell. */ - const Tensor<2,dim,vector_t> * jacobian; + const Tensor<2,dim,VectorizedArray > * jacobian; /** * A pointer to the Jacobian determinant of @@ -730,19 +767,19 @@ protected: * the Jacobian determinant times the * quadrature weight. */ - const vector_t * J_value; + const VectorizedArray * J_value; /** * A pointer to the quadrature weights of the * underlying quadrature formula. */ - const vector_t * quadrature_weights; + const VectorizedArray * quadrature_weights; /** * A pointer to the quadrature points on the * present cell. */ - const Point * quadrature_points; + const Point > * quadrature_points; /** * A pointer to the diagonal part of the @@ -750,7 +787,7 @@ protected: * cell. Only set to a useful value if on a * general cell with non-constant Jacobian. */ - const Tensor<2,dim,vector_t> * jacobian_grad; + const Tensor<2,dim,VectorizedArray > * jacobian_grad; /** * A pointer to the upper diagonal part of the @@ -758,17 +795,59 @@ protected: * set to a useful value if on a general cell * with non-constant Jacobian. */ - const Tensor<1,(dim>1?dim*(dim-1)/2:1),Tensor<1,dim,vector_t> > * jacobian_grad_upper; + const Tensor<1,(dim>1?dim*(dim-1)/2:1),Tensor<1,dim,VectorizedArray > > * jacobian_grad_upper; /** - * Debug information to track whether we - * uninitialized fields are accessed. + * Debug information to track whether dof + * values have been initialized before + * accessed. Used to control exceptions when + * uninitialized data is used. */ bool dof_values_initialized; + + /** + * Debug information to track whether values + * on quadrature points have been initialized + * before accessed. Used to control exceptions + * when uninitialized data is used. + */ bool values_quad_initialized; + + /** + * Debug information to track whether + * gradients on quadrature points have been + * initialized before accessed. Used to + * control exceptions when uninitialized data + * is used. + */ bool gradients_quad_initialized; + + /** + * Debug information to track whether + * Hessians on quadrature points have been + * initialized before accessed. Used to + * control exceptions when uninitialized data + * is used. + */ bool hessians_quad_initialized; + + /** + * Debug information to track whether values + * on quadrature points have been submitted + * for integration before the integration is + * actually stared. Used to control exceptions + * when uninitialized data is used. + */ bool values_quad_submitted; + + /** + * Debug information to track whether + * gradients on quadrature points have been + * submitted for integration before the + * integration is actually stared. Used to + * control exceptions when uninitialized data + * is used. + */ bool gradients_quad_submitted; }; @@ -787,28 +866,29 @@ template { - public: - typedef VectorizedArray vector_t; - typedef Tensor<1,n_components,vector_t> value_type; - typedef Tensor<1,n_components,Tensor<1,dim,vector_t> > gradient_type; - static const std::size_t n_vectors = VectorizedArray::n_array_elements; +public: + typedef Tensor<1,n_components,VectorizedArray > value_type; + typedef Tensor<1,n_components,Tensor<1,dim,VectorizedArray > > gradient_type; + static const unsigned int dimension = dim; static const unsigned int dofs_per_cell = dofs_per_cell_; static const unsigned int n_q_points = n_q_points_; typedef FEEvaluationBase BaseClass; +protected: /** - * Constructor. Takes all data stored in - * MatrixFree. If applied to problems with - * more than one finite element or more than - * one quadrature formula selected during - * construction of @p matrix_free, @p - * fe_no and @p quad_no allow to select the - * appropriate components. + * Constructor. Made protected to prevent + * initialization in user code. Takes all data + * stored in MatrixFree. If applied to + * problems with more than one finite element + * or more than one quadrature formula + * selected during construction of @p + * matrix_free, @p fe_no and @p quad_no allow + * to select the appropriate components. */ FEEvaluationAccess (const MatrixFree &matrix_free, - const unsigned int fe_no = 0, - const unsigned int quad_no = 0); + const unsigned int fe_no = 0, + const unsigned int quad_no = 0); }; @@ -827,29 +907,13 @@ class FEEvaluationAccess : public FEEvaluationBase { public: - typedef Number number_type; - typedef VectorizedArray vector_t; - typedef VectorizedArray value_type; - typedef Tensor<1,dim,vector_t> gradient_type; - static const unsigned int dimension = dim; - static const std::size_t n_vectors = VectorizedArray::n_array_elements; - static const unsigned int dofs_per_cell = dofs_per_cell_; - static const unsigned int n_q_points = n_q_points_; + typedef VectorizedArray value_type; + typedef Tensor<1,dim,VectorizedArray > gradient_type; + static const unsigned int dimension = dim; + static const unsigned int dofs_per_cell = dofs_per_cell_; + static const unsigned int n_q_points = n_q_points_; typedef FEEvaluationBase BaseClass; - /** - * Constructor. Takes all data stored in - * MatrixFree. If applied to problems with - * more than one finite element or more than - * one quadrature formula selected during - * construction of @p matrix_free, @p - * fe_no and @p quad_no allow to select the - * appropriate components. - */ - FEEvaluationAccess (const MatrixFree &matrix_free, - const unsigned int fe_no = 0, - const unsigned int quad_no = 0); - /** * Returns the value stored for the local * degree of freedom with index @p dof. If the @@ -864,8 +928,7 @@ class FEEvaluationAccess : * function with the test function of the * given index. */ - vector_t - get_dof_value (unsigned int dof) const; + value_type get_dof_value (const unsigned int dof) const; /** * Write a value to the field containing the @@ -873,8 +936,8 @@ class FEEvaluationAccess : * dof. Access to the same field as through @p * get_dof_value. */ - void submit_dof_value (vector_t val_in, - unsigned int dof); + void submit_dof_value (const value_type val_in, + const unsigned int dof); /** * Returns the value of a finite element @@ -888,8 +951,7 @@ class FEEvaluationAccess : * vectorization is enabled, values from * several cells are grouped together. */ - vector_t - get_value (unsigned int q_point) const; + value_type get_value (const unsigned int q_point) const; /** * Write a value to the field @@ -903,8 +965,8 @@ class FEEvaluationAccess : * by all basis function on the * current cell and integrated over. */ - void submit_value (vector_t val_in, - unsigned int q_point); + void submit_value (const value_type val_in, + const unsigned int q_point); /** * Returns the gradient of a finite @@ -915,8 +977,7 @@ class FEEvaluationAccess : * there with a call to @p * submit_gradient. */ - gradient_type - get_gradient (unsigned int q_point) const; + gradient_type get_gradient (const unsigned int q_point) const; /** * Write a gradient to the field @@ -931,8 +992,8 @@ class FEEvaluationAccess : * gradients on the current cell and * integrated over. */ - void submit_gradient(gradient_type grad_in, - unsigned int q_point); + void submit_gradient(const gradient_type grad_in, + const unsigned int q_point); /** * Returns the Hessian of a finite @@ -944,7 +1005,7 @@ class FEEvaluationAccess : * Laplacian, are needed, use the * respective functions below. */ - Tensor<2,dim,vector_t> + Tensor<2,dim,VectorizedArray > get_hessian (unsigned int q_point) const; /** @@ -954,8 +1015,7 @@ class FEEvaluationAccess : * after a call to @p * evaluate(...,true). */ - gradient_type - get_hessian_diagonal (unsigned int q_point) const; + gradient_type get_hessian_diagonal (const unsigned int q_point) const; /** * Returns the Laplacian of a finite @@ -963,8 +1023,7 @@ class FEEvaluationAccess : * point number @p q_point after a * call to @p evaluate(...,true). */ - value_type - get_laplacian (unsigned int q_point) const; + value_type get_laplacian (const unsigned int q_point) const; /** * Takes values on quadrature points, @@ -979,8 +1038,22 @@ class FEEvaluationAccess : * enabled, the integral values of several * cells are represented together. */ - value_type - integrate_value (); + value_type integrate_value () const; + +protected: + /** + * Constructor. Made protected to avoid + * initialization in user code. Takes all data + * stored in MatrixFree. If applied to + * problems with more than one finite element + * or more than one quadrature formula + * selected during construction of @p + * matrix_free, @p fe_no and @p quad_no allow + * to select the appropriate components. + */ + FEEvaluationAccess (const MatrixFree &matrix_free, + const unsigned int fe_no = 0, + const unsigned int quad_no = 0); }; @@ -999,38 +1072,20 @@ class FEEvaluationAccess : public FEEvaluationBase { public: - typedef VectorizedArray vector_t; - typedef Tensor<1,dim,vector_t> value_type; - typedef Tensor<2,dim,vector_t> gradient_type; - typedef SymmetricTensor<2,dim,vector_t> sym_gradient_type; - typedef Tensor<1,dim==2?1:dim,vector_t> curl_type; - - static const std::size_t n_vectors = VectorizedArray::n_array_elements; + typedef Tensor<1,dim,VectorizedArray > value_type; + typedef Tensor<2,dim,VectorizedArray > gradient_type; + static const unsigned int dimension = dim; static const unsigned int dofs_per_cell = dofs_per_cell_; static const unsigned int n_q_points = n_q_points_; typedef FEEvaluationBase BaseClass; - /** - * Constructor. Takes all data stored in - * MatrixFree. If applied to problems with - * more than one finite element or more than - * one quadrature formula selected during - * construction of @p matrix_free, @p - * fe_no and @p quad_no allow to select the - * appropriate components. - */ - FEEvaluationAccess (const MatrixFree &matrix_free, - const unsigned int fe_no = 0, - const unsigned int quad_no = 0); - /** * Returns the gradient of a finite element * function at quadrature point number @p * q_point after a call to @p * evaluate(...,true,...). */ - gradient_type - get_gradient (unsigned int q_point) const; + gradient_type get_gradient (const unsigned int q_point) const; /** * Returns the divergence of a vector-valued @@ -1038,8 +1093,7 @@ class FEEvaluationAccess : * @p q_point after a call to @p * evaluate(...,true,...). */ - vector_t - get_divergence (unsigned int q_point) const; + VectorizedArray get_divergence (const unsigned int q_point) const; /** * Returns the symmetric gradient of a @@ -1050,16 +1104,16 @@ class FEEvaluationAccess : * corresponds to 0.5 * (grad+gradT). */ - sym_gradient_type - get_symmetric_gradient (unsigned int q_point) const; + SymmetricTensor<2,dim,VectorizedArray > + get_symmetric_gradient (const unsigned int q_point) const; /** * Returns the curl of the vector field, * $nabla \times v$ after a call to @p * evaluate(...,true,...). */ - curl_type - get_curl (unsigned int q_point) const; + Tensor<1,dim==2?1:dim,VectorizedArray > + get_curl (const unsigned int q_point) const; /** * Returns the Hessian of a finite @@ -1071,8 +1125,8 @@ class FEEvaluationAccess : * needed, use the respective * functions. */ - Tensor<3,dim,vector_t> - get_hessian (unsigned int q_point) const; + Tensor<3,dim,VectorizedArray > + get_hessian (const unsigned int q_point) const; /** * Returns the diagonal of the Hessian @@ -1081,8 +1135,7 @@ class FEEvaluationAccess : * after a call to @p * evaluate(...,true). */ - gradient_type - get_hessian_diagonal (unsigned int q_point) const; + gradient_type get_hessian_diagonal (const unsigned int q_point) const; /** * Write a gradient to the field containing @@ -1095,8 +1148,8 @@ class FEEvaluationAccess : * by all basis function gradients on the * current cell and integrated over. */ - void submit_gradient(gradient_type grad_in, - unsigned int q_point); + void submit_gradient(const gradient_type grad_in, + const unsigned int q_point); /** * Write a gradient to the field containing @@ -1110,8 +1163,8 @@ class FEEvaluationAccess : * dimension-independent programming, this * function can be used instead. */ - void submit_gradient(Tensor<1,dim,Tensor<1,dim,vector_t> > grad_in, - unsigned int q_point); + void submit_gradient(const Tensor<1,dim,Tensor<1,dim,VectorizedArray > > grad_in, + const unsigned int q_point); /** * Write a gradient to the field containing @@ -1124,8 +1177,8 @@ class FEEvaluationAccess : * by all basis function gradients on the * current cell and integrated over. */ - void submit_symmetric_gradient(sym_gradient_type grad_in, - unsigned int q_point); + void submit_symmetric_gradient(const SymmetricTensor<2,dim,VectorizedArray > grad_in, + const unsigned int q_point); /** * Write the components of a curl containing @@ -1133,8 +1186,23 @@ class FEEvaluationAccess : * q_point. Access to the same data field as * through @p get_gradient. */ - void submit_curl (curl_type curl_in, - unsigned int q_point); + void submit_curl (const Tensor<1,dim==2?1:dim,VectorizedArray > curl_in, + const unsigned int q_point); + +protected: + /** + * Constructor. Made protected to avoid + * initialization in user code. Takes all data + * stored in MatrixFree. If applied to + * problems with more than one finite element + * or more than one quadrature formula + * selected during construction of @p + * matrix_free, @p fe_no and @p quad_no allow + * to select the appropriate components. + */ + FEEvaluationAccess (const MatrixFree &matrix_free, + const unsigned int fe_no = 0, + const unsigned int quad_no = 0); }; @@ -1162,11 +1230,11 @@ class FEEvaluationAccess : * * @param dim Dimension in which this class is to be used * - * @param n_dofs_1d Number of degrees of freedom of the FE in 1D, usually - * fe_degree+1, for elements based on a tensor product + * @param fe_degree Degree of the tensor product finite element with + * fe_degree+1 degrees of freedom per coordinate direction * * @param n_q_points_1d Number of points in the quadrature formula in 1D, - * usually chosen as fe_degree+1 + * usually chosen as fe_degree+1 * * @param n_components Number of vector components when solving a system of * PDEs. If the same operation is applied to several @@ -1178,21 +1246,21 @@ class FEEvaluationAccess : * * @author Katharina Kormann and Martin Kronbichler, 2010, 2011 */ -template class FEEvaluationGeneral : public FEEvaluationAccess1?n_dofs_1d:1)*(dim>2?n_dofs_1d:1)), - (n_q_points_1d*(dim>1?n_q_points_1d:1)*(dim>2?n_q_points_1d:1)), + Utilities::fixed_int_power::value, + Utilities::fixed_int_power::value, n_components,Number> { public: - typedef VectorizedArray vector_t; - static const std::size_t n_vectors = VectorizedArray::n_array_elements; - typedef FEEvaluationAccess1?n_dofs_1d:1)* - (dim>2?n_dofs_1d:1)), - (n_q_points_1d*(dim>1?n_q_points_1d:1)*(dim>2?n_q_points_1d:1)), - n_components, Number> BaseClass; + typedef FEEvaluationAccess::value, + Utilities::fixed_int_power::value, + n_components, Number> BaseClass; + typedef typename BaseClass::value_type value_type; + typedef typename BaseClass::gradient_type gradient_type; static const unsigned int dofs_per_cell = BaseClass::dofs_per_cell; static const unsigned int n_q_points = BaseClass::n_q_points; @@ -1206,8 +1274,8 @@ class FEEvaluationGeneral : * appropriate components. */ FEEvaluationGeneral (const MatrixFree &matrix_free, - const unsigned int fe_no = 0, - const unsigned int quad_no = 0); + const unsigned int fe_no = 0, + const unsigned int quad_no = 0); /** * Evaluates the function values, the @@ -1220,7 +1288,7 @@ class FEEvaluationGeneral : * @p get_gradient() or @p get_laplacian * return useful information. */ - void evaluate (bool evaluate_val, bool evaluate_grad, + void evaluate (bool evaluate_val, bool evaluate_grad, bool evaluate_hess=false); /** @@ -1239,7 +1307,8 @@ class FEEvaluationGeneral : * Returns the q-th quadrature point stored in * MappingInfo. */ - Point quadrature_point (const unsigned int q_point) const; + Point > + quadrature_point (const unsigned int q_point) const; protected: @@ -1256,9 +1325,9 @@ protected: * some previous results or not. */ template - void apply_tensor_prod (const vector_t * shape_data, - const vector_t in [], - vector_t out []); + void apply_tensor_prod (const VectorizedArray * shape_data, + const VectorizedArray in [], + VectorizedArray out []); }; @@ -1272,14 +1341,24 @@ protected: * * This class is a specialization of FEEvaluationGeneral designed for standard * FE_Q or FE_DGQ elements and quadrature points symmetric around 0.5 (like - * Gauss quadrature), and hence the most common situation. + * Gauss quadrature), and hence the most common situation. Note that many of + * the operations available through this class are inherited from the base + * class FEEvaluationBase, in particular reading from and writing to + * vectors. Also, the class inherits from FEEvaluationAccess that implements + * access to values, gradients and Hessians of the finite element function on + * quadrature points. + * + * This class assumes that shape functions of the FiniteElement under + * consideration do not depend on the actual shape of the cells in + * real space. Currently, other finite elements cannot be treated with the + * matrix-free concept. * * This class has five template arguments: * * @param dim Dimension in which this class is to be used * - * @param n_dofs_1d Number of degrees of freedom of the FE in 1D, usually - * fe_degree+1, for elements based on a tensor product + * @param fe_degree Degree of the tensor product finite element with + * fe_degree+1 degrees of freedom per coordinate direction * * @param n_q_points_1d Number of points in the quadrature formula in 1D, * usually chosen as fe_degree+1 @@ -1294,15 +1373,15 @@ protected: * * @author Katharina Kormann and Martin Kronbichler, 2010, 2011 */ -template class FEEvaluation : - public FEEvaluationGeneral + public FEEvaluationGeneral { public: - typedef VectorizedArray vector_t; - static const std::size_t n_vectors = VectorizedArray::n_array_elements; - typedef FEEvaluationGeneral BaseClass; + typedef FEEvaluationGeneral BaseClass; + typedef typename BaseClass::value_type value_type; + typedef typename BaseClass::gradient_type gradient_type; static const unsigned int dofs_per_cell = BaseClass::dofs_per_cell; static const unsigned int n_q_points = BaseClass::n_q_points; @@ -1316,8 +1395,8 @@ class FEEvaluation : * appropriate components. */ FEEvaluation (const MatrixFree &matrix_free, - const unsigned int fe_no = 0, - const unsigned int quad_no = 0); + const unsigned int fe_no = 0, + const unsigned int quad_no = 0); /** * Evaluates the function values, the @@ -1332,7 +1411,7 @@ class FEEvaluation : * (unless these values have been set * manually). */ - void evaluate (bool evaluate_val, bool evaluate_grad, + void evaluate (bool evaluate_val, bool evaluate_grad, bool evaluate_hess=false); /** @@ -1362,7 +1441,8 @@ protected: * not. */ template - void apply_values (const vector_t in [], vector_t out []); + void apply_values (const VectorizedArray in [], + VectorizedArray out []); /** * Internal function that applies the gradient @@ -1378,7 +1458,8 @@ protected: * not. */ template - void apply_gradients (const vector_t in [], vector_t out []); + void apply_gradients (const VectorizedArray in [], + VectorizedArray out []); /** * Internal function that applies the second @@ -1394,7 +1475,8 @@ protected: * content in the data fields or not. */ template - void apply_hessians (const vector_t in [], vector_t out []); + void apply_hessians (const VectorizedArray in [], + VectorizedArray out []); }; @@ -1416,15 +1498,15 @@ protected: * directions other than the gradient direction are again identity * operations). * - * This class has five template arguments: + * This class has four template arguments: * * @param dim Dimension in which this class is to be used * - * @param n_dofs_1d Number of degrees of freedom of the FE in 1D, usually - * fe_degree+1, for elements based on a tensor product - * - * @param n_q_points_1d Number of points in the quadrature formula in 1D, - * usually chosen as fe_degree+1 + * @param fe_degree Degree of the tensor product finite element with + * fe_degree+1 degrees of freedom per coordinate + * direction. The quadrature formula is tied to the choice of + * the element by setting n_q_points_1d = fe_degree+1, which + * gives a diagonal mass matrix * * @param n_components Number of vector components when solving a system of * PDEs. If the same operation is applied to several @@ -1436,14 +1518,14 @@ protected: * * @author Katharina Kormann and Martin Kronbichler, 2010, 2011 */ -template +template class FEEvaluationGL : - public FEEvaluation + public FEEvaluation { public: - typedef VectorizedArray vector_t; - static const std::size_t n_vectors = VectorizedArray::n_array_elements; - typedef FEEvaluation BaseClass; + typedef FEEvaluation BaseClass; + typedef typename BaseClass::value_type value_type; + typedef typename BaseClass::gradient_type gradient_type; static const unsigned int dofs_per_cell = BaseClass::dofs_per_cell; static const unsigned int n_q_points = BaseClass::n_q_points; @@ -1457,8 +1539,8 @@ class FEEvaluationGL : * appropriate components. */ FEEvaluationGL (const MatrixFree &matrix_free, - const unsigned int fe_no = 0, - const unsigned int quad_no = 0); + const unsigned int fe_no = 0, + const unsigned int quad_no = 0); /** * Evaluates the function values, the @@ -1473,7 +1555,7 @@ class FEEvaluationGL : * (unless these values have been set * manually). */ - void evaluate (bool evaluate_val, bool evaluate_grad, + void evaluate (bool evaluate_val, bool evaluate_grad, bool evaluate_lapl=false); /** @@ -1502,7 +1584,8 @@ protected: * some previous results or not. */ template - void apply_gradients (const vector_t in [], vector_t out []); + void apply_gradients (const VectorizedArray in [], + VectorizedArray out []); }; @@ -1523,23 +1606,25 @@ FEEvaluationBase (const MatrixFree &data_in, const unsigned int fe_no_in, const unsigned int quad_no_in) : + quad_no (quad_no_in), + n_fe_components (data_in.get_dof_info(fe_no_in).n_components), + active_fe_index (data_in.get_dof_info(fe_no_in).fe_index_from_dofs_per_cell + (dofs_per_cell_ * n_fe_components)), + active_quad_index (data_in.get_mapping_info(). + mapping_data_gen[quad_no_in]. + quad_index_from_n_q_points(n_q_points_)), matrix_info (data_in), dof_info (data_in.get_dof_info(fe_no_in)), - constraint_pool (data_in.get_constraint_pool()), mapping_info (data_in.get_mapping_info()), - active_fe_index (dof_info.fe_index_from_dofs_per_cell - (dofs_per_cell_ * dof_info.n_components)), - active_quad_index (mapping_info. - mapping_data_gen[quad_no_in]. - quad_index_from_n_q_points(n_q_points_)), - data (data_in.get_fe_evaluation + data (data_in.get_shape_info (fe_no_in, quad_no_in, active_fe_index, active_quad_index)), - quad_no (quad_no_in), - n_fe_components (dof_info.n_components), cell (numbers::invalid_unsigned_int), - cell_type (numbers::invalid_unsigned_int), - cartesian (0), + cell_type (internal::MatrixFreeFunctions::undefined), + cell_data_number (0), + at_irregular_cell (false), + n_irreg_components_filled (0), + cartesian_data (0), jacobian (0), J_value (0), quadrature_weights (mapping_info.mapping_data_gen[quad_no]. @@ -1552,7 +1637,8 @@ FEEvaluationBase (const MatrixFree &data_in, ExcNotInitialized()); Assert (matrix_info.mapping_initialized() == true, ExcNotInitialized()); - AssertDimension (matrix_info.get_size_info().n_vectors, n_vectors); + AssertDimension (matrix_info.get_size_info().vectorization_length, + VectorizedArray::n_array_elements); Assert (n_fe_components == 1 || n_components == n_fe_components, ExcMessage ("The underlying FE is vector-valued. In this case, the " @@ -1594,15 +1680,15 @@ reinit (const unsigned int cell_in) &mapping_info.mapping_data_gen[quad_no].quadrature_points[index]; } - if (cell_type == 0) + if (cell_type == internal::MatrixFreeFunctions::cartesian) { - cartesian = &mapping_info.cartesian[cell_data_number].first; - J_value = &mapping_info.cartesian[cell_data_number].second; + cartesian_data = &mapping_info.cartesian_data[cell_data_number].first; + J_value = &mapping_info.cartesian_data[cell_data_number].second; } - else if (cell_type == 1) + else if (cell_type == internal::MatrixFreeFunctions::affine) { - jacobian = &mapping_info.linear[cell_data_number].first; - J_value = &mapping_info.linear[cell_data_number].second; + jacobian = &mapping_info.affine_data[cell_data_number].first; + J_value = &mapping_info.affine_data[cell_data_number].second; } else { @@ -1661,7 +1747,7 @@ get_cell_data_number () const template inline -unsigned int +internal::MatrixFreeFunctions::CellType FEEvaluationBase:: get_cell_type () const { @@ -1671,89 +1757,6 @@ get_cell_type () const -template -inline -const VectorizedArray * -FEEvaluationBase:: -begin_values () const -{ - Assert (values_quad_initialized || values_quad_submitted, - ExcNotInitialized()); - return &values_quad[0][0]; -} - - - -template -inline -VectorizedArray * -FEEvaluationBase:: -begin_values () -{ -#ifdef DEBUG - values_quad_submitted = true; -#endif - return &values_quad[0][0]; -} - - - -template -inline -const VectorizedArray * -FEEvaluationBase:: -begin_gradients () const -{ - Assert (gradients_quad_initialized || gradients_quad_submitted, - ExcNotInitialized()); - return &gradients_quad[0][0][0]; -} - - - -template -inline -VectorizedArray * -FEEvaluationBase:: -begin_gradients () -{ -#ifdef DEBUG - gradients_quad_submitted = true; -#endif - return &gradients_quad[0][0][0]; -} - - - -template -inline -const VectorizedArray * -FEEvaluationBase:: -begin_hessians () const -{ - Assert (hessians_quad_initialized, ExcNotInitialized()); - return &hessians_quad[0][0][0]; -} - - - -template -inline -VectorizedArray * -FEEvaluationBase:: -begin_hessians () -{ - return &hessians_quad[0][0][0]; -} - - - namespace internal { // write access to generic vectors that have @@ -1931,6 +1934,8 @@ read_dof_values (const VectorType * src[]) // a different vector each) if (n_fe_components == 1) { + const unsigned int n_local_dofs = + VectorizedArray::n_array_elements * dofs_per_cell; for (unsigned int comp=0; compsecond); - const unsigned int row_length = - constraint_pool.row_length(indicators->second); - for (unsigned int k=0; ksecond); + const Number * end_pool = + matrix_info.constraint_pool_end(indicators->second); + for ( ; data_val != end_pool; ++data_val, ++dof_indices) for (unsigned int comp=0; comp(n_local_dofs)); + for (unsigned int j=0; j= n_irreg_components_filled) + while (ind_local % VectorizedArray::n_array_elements + >= n_irreg_components_filled) { for (unsigned int comp=0; compsecond); - const unsigned int row_length = - constraint_pool.row_length(indicators->second); - for (unsigned int k=0; ksecond); + const Number * end_pool = + matrix_info.constraint_pool_end(indicators->second); + for ( ; data_val != end_pool; ++data_val, ++dof_indices) for (unsigned int comp=0; comp= n_irreg_components_filled) + while (ind_local % VectorizedArray::n_array_elements + >= n_irreg_components_filled) { for (unsigned int comp=0; comp= n_irreg_components_filled) + while (ind_local % VectorizedArray::n_array_elements + >= n_irreg_components_filled) { for (unsigned int comp=0; comp::n_array_elements * n_components; Number * local_src_number = reinterpret_cast(values_dofs[0]); if (at_irregular_cell == false) { @@ -2109,14 +2115,13 @@ read_dof_values (const VectorType * src[]) // according to constraints Number value = 0; const Number * data_val = - constraint_pool.begin(indicators->second); - const unsigned int row_length = - constraint_pool.row_length(indicators->second); - for (unsigned int k=0; ksecond); + const Number * end_pool = + matrix_info.constraint_pool_end(indicators->second); + for ( ; data_val != end_pool; ++data_val, ++dof_indices) value += - (internal::vector_access (*src[0], dof_indices[k]) * - data_val[k]); - dof_indices += row_length; + (internal::vector_access (*src[0], *dof_indices) * + (*data_val)); local_src_number[ind_local] = value; ind_local++; @@ -2124,7 +2129,7 @@ read_dof_values (const VectorType * src[]) // get the dof values past the last // constraint - for(; ind_local(total_dofs_per_cell)); - for (unsigned int j=0; j(n_local_dofs)); + for (unsigned int j=0; j= n_irreg_components_filled) + while (ind_local % VectorizedArray::n_array_elements + >= n_irreg_components_filled) { local_src_number[ind_local] = 0.; ++ind_local; @@ -2175,22 +2181,22 @@ read_dof_values (const VectorType * src[]) // according to constraint Number value = 0; const Number * data_val = - constraint_pool.begin(indicators->second); - const unsigned int row_length = - constraint_pool.row_length(indicators->second); - for (unsigned int k=0; ksecond); + const Number * end_pool = + matrix_info.constraint_pool_end(indicators->second); + for ( ; data_val != end_pool; ++data_val, ++dof_indices) value += - internal::vector_access (*src[0], dof_indices[k]) * data_val[k]; - dof_indices += row_length; + internal::vector_access (*src[0], *dof_indices) * (*data_val); local_src_number[ind_local] = value; ind_local++; - while (ind_local % n_vectors >= n_irreg_components_filled) + while (ind_local % VectorizedArray::n_array_elements + >= n_irreg_components_filled) { local_src_number[ind_local] = 0.; ++ind_local; } } - for(; ind_local= n_irreg_components_filled) + while (ind_local % VectorizedArray::n_array_elements + >= n_irreg_components_filled) { local_src_number[ind_local] = 0.; ++ind_local; @@ -2307,6 +2314,8 @@ read_dof_values_plain (const VectorType * src[]) // a different vector each) if (n_fe_components == 1) { + const unsigned int n_local_dofs = + VectorizedArray::n_array_elements * dofs_per_cell; for (unsigned int comp=0; comp 0, ExcInternalError()); - for(unsigned int ind_local=0; ind_local= n_irreg_components_filled) + while (ind_local % VectorizedArray::n_array_elements >= n_irreg_components_filled) { for (unsigned int comp=0; comp::n_array_elements * n_components; Number * local_src_number = reinterpret_cast(values_dofs[0]); if (at_irregular_cell == false) { - for (unsigned int j=0; j 0, ExcInternalError()); - for(unsigned int ind_local=0; ind_local= n_irreg_components_filled) + while (ind_local % VectorizedArray::n_array_elements >= n_irreg_components_filled) { local_src_number[ind_local] = 0.; ++ind_local; @@ -2496,6 +2505,8 @@ distribute_local_to_global (VectorType * dst[]) const // a different vector each) if (n_fe_components == 1) { + const unsigned int n_local_dofs = + VectorizedArray::n_array_elements * dofs_per_cell; for (unsigned int comp=0; compsecond); - const unsigned int row_length = - constraint_pool.row_length(indicators->second); - for (unsigned int k=0; ksecond); + const Number * end_pool = + matrix_info.constraint_pool_end(indicators->second); + for ( ; data_val != end_pool; ++data_val, ++dof_indices) for (unsigned int comp=0; comp(n_local_dofs)); + for (unsigned int j=0; j::n_array_elements == n_irreg_components_filled) + ind_local += VectorizedArray::n_array_elements-n_irreg_components_filled; } dof_indices += indicators->first; // constrained case: distribute according to // the constraint const Number * data_val = - constraint_pool.begin(indicators->second); - const unsigned int row_length = - constraint_pool.row_length(indicators->second); - for (unsigned int k=0; ksecond); + const Number * end_pool = + matrix_info.constraint_pool_end(indicators->second); + for ( ; data_val != end_pool; ++data_val, ++dof_indices) { for (unsigned int comp=0; comp::n_array_elements == + n_irreg_components_filled) + ind_local += VectorizedArray::n_array_elements- + n_irreg_components_filled; } - for(; ind_local::n_array_elements == + n_irreg_components_filled) + ind_local += VectorizedArray::n_array_elements-n_irreg_components_filled; } } else @@ -2614,8 +2626,8 @@ distribute_local_to_global (VectorType * dst[]) const { internal::check_vector_compatibility (*dst[0], dof_info); Assert (n_fe_components == n_components, ExcNotImplemented()); - const unsigned int total_dofs_per_cell = - dofs_per_cell * n_vectors * n_components; + const unsigned int n_local_dofs = + dofs_per_cell * VectorizedArray::n_array_elements * n_components; const Number * local_dst_number = reinterpret_cast(values_dofs[0]); if (at_irregular_cell == false) @@ -2638,18 +2650,17 @@ distribute_local_to_global (VectorType * dst[]) const // a linear combination of the global value // according to constraint const Number * data_val = - constraint_pool.begin(indicators->second); - const unsigned int row_length = - constraint_pool.row_length(indicators->second); - for (unsigned int k=0; ksecond); + const Number * end_pool = + matrix_info.constraint_pool_end(indicators->second); + for ( ; data_val != end_pool; ++data_val, ++dof_indices) + internal::vector_access (*dst[0], *dof_indices) + += local_dst_number[ind_local] * (*data_val); ++ind_local; } // distribute values after the last constraint // (values not constrained) - for(; ind_local(total_dofs_per_cell)); - for (unsigned int j=0; j(n_local_dofs)); + for (unsigned int j=0; j::n_array_elements == n_irreg_components_filled) + ind_local += VectorizedArray::n_array_elements-n_irreg_components_filled; } dof_indices += indicators->first; // constrained case: distribute according to // the constraint const Number * data_val = - constraint_pool.begin(indicators->second); - const unsigned int row_length = - constraint_pool.row_length(indicators->second); - for (unsigned int k=0; ksecond); + const Number * end_pool = + matrix_info.constraint_pool_end(indicators->second); + for ( ; data_val != end_pool; ++data_val, ++dof_indices) { - internal::vector_access (*dst[0], dof_indices[k]) - += local_dst_number[ind_local] * data_val[k]; + internal::vector_access (*dst[0], *dof_indices) + += local_dst_number[ind_local] * (*data_val); } - dof_indices += row_length; ++ind_local; - if (ind_local % n_vectors == n_irreg_components_filled) - ind_local += n_vectors-n_irreg_components_filled; + if (ind_local % VectorizedArray::n_array_elements == n_irreg_components_filled) + ind_local += VectorizedArray::n_array_elements-n_irreg_components_filled; } - for(; ind_local::n_array_elements == n_irreg_components_filled) + ind_local += VectorizedArray::n_array_elements-n_irreg_components_filled; } Assert (dof_indices == dof_info.end_indices(cell), ExcInternalError()); @@ -2809,6 +2819,8 @@ set_dof_values (VectorType * dst[]) const if (n_fe_components == 1) { + const unsigned int n_local_dofs = + VectorizedArray::n_array_elements * dofs_per_cell; for (unsigned int comp=0; compsize(), dof_info.vector_partitioner->size()); @@ -2836,13 +2848,14 @@ set_dof_values (VectorType * dst[]) const // jump over constraints const unsigned int row_length = - constraint_pool.row_length(indicators->second); + matrix_info.constraint_pool_end(indicators->second)- + matrix_info.constraint_pool_begin(indicators->second); dof_indices += row_length; ++ind_local; } // distribute values after the last constraint // (values not constrained) - for(; ind_local::n_array_elements == n_irreg_components_filled) + ind_local += VectorizedArray::n_array_elements-n_irreg_components_filled; } dof_indices += indicators->first; // jump over constraint const unsigned int row_length = - constraint_pool.row_length(indicators->second); + matrix_info.constraint_pool_end(indicators->second)- + matrix_info.constraint_pool_begin(indicators->second); dof_indices += row_length; ++ind_local; - if (ind_local % n_vectors == n_irreg_components_filled) - ind_local += n_vectors-n_irreg_components_filled; + if (ind_local % VectorizedArray::n_array_elements == + n_irreg_components_filled) + ind_local += VectorizedArray::n_array_elements - + n_irreg_components_filled; } - for(; ind_local::n_array_elements == n_irreg_components_filled) + ind_local += VectorizedArray::n_array_elements-n_irreg_components_filled; } } else @@ -2910,8 +2926,8 @@ set_dof_values (VectorType * dst[]) const AssertDimension (dst[0]->size(), dof_info.vector_partitioner->size()); Assert (n_fe_components == n_components, ExcNotImplemented()); - const unsigned int total_dofs_per_cell = - dofs_per_cell * n_vectors * n_components; + const unsigned int n_local_dofs = + dofs_per_cell * VectorizedArray::n_array_elements * n_components; const Number * local_dst_number = reinterpret_cast(values_dofs[0]); @@ -2933,13 +2949,14 @@ set_dof_values (VectorType * dst[]) const // jump over constraints const unsigned int row_length = - constraint_pool.row_length(indicators->second); + matrix_info.constraint_pool_end(indicators->second) - + matrix_info.constraint_pool_begin(indicators->second); dof_indices += row_length; ++ind_local; } // distribute values after the last constraint // (values not constrained) - for(; ind_local::n_array_elements == n_irreg_components_filled) + ind_local += VectorizedArray::n_array_elements-n_irreg_components_filled; } dof_indices += indicators->first; // jump over constraint const unsigned int row_length = - constraint_pool.row_length(indicators->second); + matrix_info.constraint_pool_end(indicators->second)- + matrix_info.constraint_pool_begin(indicators->second); dof_indices += row_length; ++ind_local; - if (ind_local % n_vectors == n_irreg_components_filled) - ind_local += n_vectors-n_irreg_components_filled; + if (ind_local % VectorizedArray::n_array_elements == n_irreg_components_filled) + ind_local += VectorizedArray::n_array_elements-n_irreg_components_filled; } - for(; ind_local::n_array_elements == n_irreg_components_filled) + ind_local += VectorizedArray::n_array_elements-n_irreg_components_filled; } Assert (dof_indices == dof_info.end_indices (cell), ExcInternalError()); @@ -3004,10 +3022,10 @@ template > FEEvaluationBase:: -get_dof_value (unsigned int dof) const +get_dof_value (const unsigned int dof) const { AssertIndexRange (dof, dofs_per_cell); - Tensor<1,n_components,vector_t> return_value (false); + Tensor<1,n_components,VectorizedArray > return_value (false); for(unsigned int comp=0;compvalues_dofs[comp][dof]; return return_value; @@ -3020,12 +3038,12 @@ template > FEEvaluationBase:: -get_value (unsigned int q_point) const +get_value (const unsigned int q_point) const { Assert (this->values_quad_initialized==true, internal::ExcAccessToUninitializedField()); AssertIndexRange (q_point, n_q_points); - Tensor<1,n_components,vector_t> return_value (false); + Tensor<1,n_components,VectorizedArray > return_value (false); for(unsigned int comp=0;compvalues_quad[comp][q_point]; return return_value; @@ -3038,24 +3056,24 @@ template > > FEEvaluationBase:: -get_gradient (unsigned int q_point) const +get_gradient (const unsigned int q_point) const { Assert (this->gradients_quad_initialized==true, internal::ExcAccessToUninitializedField()); AssertIndexRange (q_point, n_q_points); - Tensor<1,n_components,Tensor<1,dim,vector_t> > grad_out (false); + Tensor<1,n_components,Tensor<1,dim,VectorizedArray > > grad_out (false); // Cartesian cell - if (this->cell_type == 0) + if (this->cell_type == internal::MatrixFreeFunctions::cartesian) { for (unsigned int comp=0;compgradients_quad[comp][d][q_point] * - cartesian[0][d]); + cartesian_data[0][d]); } // cell with general Jacobian - else if (this->cell_type == 2) + else if (this->cell_type == internal::MatrixFreeFunctions::general) { for(unsigned int comp=0;compcell_type == 1) + else // if (this->cell_type == internal::MatrixFreeFunctions::affine) { for(unsigned int comp=0;comp > > FEEvaluationBase:: -get_hessian (unsigned int q_point) const +get_hessian (const unsigned int q_point) const { Assert (this->hessians_quad_initialized==true, internal::ExcAccessToUninitializedField()); AssertIndexRange (q_point, n_q_points); - Tensor<2,dim,vector_t> hessian_out [n_components]; + Tensor<2,dim,VectorizedArray > hessian_out [n_components]; // Cartesian cell - if (this->cell_type == 0) + if (this->cell_type == internal::MatrixFreeFunctions::cartesian) { - const Tensor<1,dim,vector_t> &jac = cartesian[0]; + const Tensor<1,dim,VectorizedArray > &jac = cartesian_data[0]; for (unsigned int comp=0;compcell_type == 2) + else if (this->cell_type == internal::MatrixFreeFunctions::general) { Assert (this->mapping_info.second_derivatives_initialized == true, ExcNotInitialized()); - const Tensor<2,dim,vector_t> & jac = jacobian[q_point]; - const Tensor<2,dim,vector_t> & jac_grad = jacobian_grad[q_point]; - const typename internal::MatrixFreeFunctions::MappingInfo::tensorUT + const Tensor<2,dim,VectorizedArray > & jac = jacobian[q_point]; + const Tensor<2,dim,VectorizedArray > & jac_grad = jacobian_grad[q_point]; + const Tensor<1,(dim>1?dim*(dim-1)/2:1), + Tensor<1,dim,VectorizedArray > > & jac_grad_UT = jacobian_grad_upper[q_point]; for(unsigned int comp=0;comp tmp[dim][dim]; // compute tmp = hess_unit(u) * J^T. do this // manually because we do not store the lower @@ -3210,15 +3229,15 @@ get_hessian (unsigned int q_point) const } // cell with general Jacobian, but constant // within the cell - else // if (this->cell_type == 1) + else // if (this->cell_type == internal::MatrixFreeFunctions::affine) { - const Tensor<2,dim,vector_t> &jac = jacobian[0]; + const Tensor<2,dim,VectorizedArray > &jac = jacobian[0]; for(unsigned int comp=0;comp tmp[dim][dim]; // compute tmp = hess_unit(u) * J^T. do this // manually because we do not store the lower @@ -3270,7 +3289,7 @@ get_hessian (unsigned int q_point) const hessian_out[comp][e][d] = hessian_out[comp][d][e]; } } - return Tensor<1,n_components,Tensor<2,dim,vector_t> >(hessian_out); + return Tensor<1,n_components,Tensor<2,dim,VectorizedArray > >(hessian_out); } @@ -3280,36 +3299,36 @@ template > > FEEvaluationBase:: -get_hessian_diagonal (unsigned int q_point) const +get_hessian_diagonal (const unsigned int q_point) const { Assert (this->hessians_quad_initialized==true, internal::ExcAccessToUninitializedField()); AssertIndexRange (q_point, n_q_points); - Tensor<1,n_components,Tensor<1,dim,vector_t> > hessian_out (false); + Tensor<1,n_components,Tensor<1,dim,VectorizedArray > > hessian_out (false); // Cartesian cell - if (this->cell_type == 0) + if (this->cell_type == internal::MatrixFreeFunctions::cartesian) { - const Tensor<1,dim,vector_t> &jac = cartesian[0]; + const Tensor<1,dim,VectorizedArray > &jac = cartesian_data[0]; for (unsigned int comp=0;comphessians_quad[comp][d][q_point] * jac[d] * jac[d]); } // cell with general Jacobian - else if (this->cell_type == 2) + else if (this->cell_type == internal::MatrixFreeFunctions::general) { Assert (this->mapping_info.second_derivatives_initialized == true, ExcNotInitialized()); - const Tensor<2,dim,vector_t> &jac = jacobian[q_point]; - const Tensor<2,dim,vector_t> &jac_grad = jacobian_grad[q_point]; + const Tensor<2,dim,VectorizedArray > &jac = jacobian[q_point]; + const Tensor<2,dim,VectorizedArray > &jac_grad = jacobian_grad[q_point]; for(unsigned int comp=0;comp tmp[dim][dim]; // compute tmp = hess_unit(u) * J^T. do this // manually because we do not store the lower @@ -3358,15 +3377,15 @@ get_hessian_diagonal (unsigned int q_point) const } // cell with general Jacobian, but constant // within the cell - else // if (this->cell_type == 1) + else // if (this->cell_type == internal::MatrixFreeFunctions::affine) { - const Tensor<2,dim,vector_t> & jac = jacobian[0]; + const Tensor<2,dim,VectorizedArray > & jac = jacobian[0]; for(unsigned int comp=0;comp tmp[dim][dim]; // compute tmp = hess_unit(u) * J^T. do this // manually because we do not store the lower @@ -3418,13 +3437,13 @@ template > FEEvaluationBase:: -get_laplacian (unsigned int q_point) const +get_laplacian (const unsigned int q_point) const { Assert (this->hessians_quad_initialized==true, internal::ExcAccessToUninitializedField()); AssertIndexRange (q_point, n_q_points); - Tensor<1,n_components,vector_t> laplacian_out (false); - const Tensor<1,n_components,Tensor<1,dim,vector_t> > hess_diag + Tensor<1,n_components,VectorizedArray > laplacian_out (false); + const Tensor<1,n_components,Tensor<1,dim,VectorizedArray > > hess_diag = get_hessian_diagonal(q_point); for (unsigned int comp=0; comp:: -submit_dof_value (Tensor<1,n_components,VectorizedArray > val_in, - unsigned int dof) +submit_dof_value (const Tensor<1,n_components,VectorizedArray > val_in, + const unsigned int dof) { #ifdef DEBUG this->dof_values_initialized = true; @@ -3460,23 +3479,23 @@ template :: -submit_value (Tensor<1,n_components,VectorizedArray > val_in, - unsigned int q_point) +submit_value (const Tensor<1,n_components,VectorizedArray > val_in, + const unsigned int q_point) { #ifdef DEBUG Assert (this->cell != numbers::invalid_unsigned_int, ExcNotInitialized()); AssertIndexRange (q_point, n_q_points); this->values_quad_submitted = true; #endif - if (this->cell_type == 2) + if (this->cell_type == internal::MatrixFreeFunctions::general) { - const vector_t JxW = J_value[q_point]; + const VectorizedArray JxW = J_value[q_point]; for (unsigned int comp=0; compvalues_quad[comp][q_point] = val_in[comp] * JxW; } - else //if (this->cell_type < 2) + else //if (this->cell_type < internal::MatrixFreeFunctions::general) { - const vector_t JxW = J_value[0] * quadrature_weights[q_point]; + const VectorizedArray JxW = J_value[0] * quadrature_weights[q_point]; for (unsigned int comp=0; compvalues_quad[comp][q_point] = val_in[comp] * JxW; } @@ -3489,41 +3508,41 @@ template :: -submit_gradient (Tensor<1,n_components, - Tensor<1,dim,VectorizedArray > > grad_in, - unsigned int q_point) +submit_gradient (const Tensor<1,n_components, + Tensor<1,dim,VectorizedArray > > grad_in, + const unsigned int q_point) { #ifdef DEBUG Assert (this->cell != numbers::invalid_unsigned_int, ExcNotInitialized()); AssertIndexRange (q_point, n_q_points); this->gradients_quad_submitted = true; #endif - if (this->cell_type == 0) + if (this->cell_type == internal::MatrixFreeFunctions::cartesian) { - const vector_t JxW = J_value[0] * quadrature_weights[q_point]; + const VectorizedArray JxW = J_value[0] * quadrature_weights[q_point]; for (unsigned int comp=0;compgradients_quad[comp][d][q_point] = (grad_in[comp][d] * - cartesian[0][d] * JxW); + cartesian_data[0][d] * JxW); } - else if (this->cell_type == 2) + else if (this->cell_type == internal::MatrixFreeFunctions::general) { for (unsigned int comp=0; comp new_val = jacobian[q_point][0][d] * grad_in[comp][0]; for (unsigned e=1; egradients_quad[comp][d][q_point] = new_val * J_value[q_point]; } } - else //if (this->cell_type == 1) + else //if (this->cell_type == internal::MatrixFreeFunctions::affine) { - const vector_t JxW = J_value[0] * quadrature_weights[q_point]; + const VectorizedArray JxW = J_value[0] * quadrature_weights[q_point]; for (unsigned int comp=0; comp new_val = jacobian[0][0][d] * grad_in[comp][0]; for (unsigned e=1; egradients_quad[comp][d][q_point] = new_val * JxW; @@ -3538,14 +3557,14 @@ template > FEEvaluationBase:: -integrate_value () +integrate_value () const { #ifdef DEBUG Assert (this->cell != numbers::invalid_unsigned_int, ExcNotInitialized()); Assert (this->values_quad_submitted == true, internal::ExcAccessToUninitializedField()); #endif - Tensor<1,n_components,vector_t> return_value (false); + Tensor<1,n_components,VectorizedArray > return_value (false); for (unsigned int comp=0; compvalues_quad[comp][0]; for (unsigned int q=0; q inline VectorizedArray FEEvaluationAccess:: -get_dof_value (unsigned int dof) const +get_dof_value (const unsigned int dof) const { AssertIndexRange (dof, dofs_per_cell); return this->values_dofs[0][dof]; @@ -3606,7 +3625,7 @@ template inline VectorizedArray FEEvaluationAccess:: -get_value (unsigned int q_point) const +get_value (const unsigned int q_point) const { Assert (this->values_quad_initialized==true, internal::ExcAccessToUninitializedField()); @@ -3620,7 +3639,7 @@ template inline Tensor<1,dim,VectorizedArray > FEEvaluationAccess:: -get_gradient (unsigned int q_point) const +get_gradient (const unsigned int q_point) const { // could use the base class gradient, but that // involves too many inefficient @@ -3630,17 +3649,17 @@ get_gradient (unsigned int q_point) const internal::ExcAccessToUninitializedField()); AssertIndexRange (q_point, n_q_points); - Tensor<1,dim,vector_t> grad_out (false); + Tensor<1,dim,VectorizedArray > grad_out (false); // Cartesian cell - if (this->cell_type == 0) + if (this->cell_type == internal::MatrixFreeFunctions::cartesian) { for (unsigned int d=0; dgradients_quad[0][d][q_point] * - this->cartesian[0][d]); + this->cartesian_data[0][d]); } // cell with general Jacobian - else if (this->cell_type == 2) + else if (this->cell_type == internal::MatrixFreeFunctions::general) { for (unsigned int d=0; dcell_type == 1) + else // if (this->cell_type == internal::MatrixFreeFunctions::affine) { for (unsigned int d=0; d inline Tensor<2,dim,VectorizedArray > FEEvaluationAccess:: -get_hessian (unsigned int q_point) const +get_hessian (const unsigned int q_point) const { return BaseClass::get_hessian(q_point)[0]; } @@ -3684,7 +3703,7 @@ template inline Tensor<1,dim,VectorizedArray > FEEvaluationAccess:: -get_hessian_diagonal (unsigned int q_point) const +get_hessian_diagonal (const unsigned int q_point) const { return BaseClass::get_hessian_diagonal(q_point)[0]; } @@ -3695,7 +3714,7 @@ template inline VectorizedArray FEEvaluationAccess:: -get_laplacian (unsigned int q_point) const +get_laplacian (const unsigned int q_point) const { return BaseClass::get_laplacian(q_point)[0]; } @@ -3706,8 +3725,8 @@ template inline void FEEvaluationAccess:: -submit_dof_value (VectorizedArray val_in, - unsigned int dof) +submit_dof_value (const VectorizedArray val_in, + const unsigned int dof) { #ifdef DEBUG this->dof_values_initialized = true; @@ -3722,22 +3741,22 @@ template inline void FEEvaluationAccess:: -submit_value (VectorizedArray val_in, - unsigned int q_point) +submit_value (const VectorizedArray val_in, + const unsigned int q_point) { #ifdef DEBUG Assert (this->cell != numbers::invalid_unsigned_int, ExcNotInitialized()); AssertIndexRange (q_point, n_q_points); this->values_quad_submitted = true; #endif - if (this->cell_type == 2) + if (this->cell_type == internal::MatrixFreeFunctions::general) { - const vector_t JxW = this->J_value[q_point]; + const VectorizedArray JxW = this->J_value[q_point]; this->values_quad[0][q_point] = val_in * JxW; } - else //if (this->cell_type < 2) + else //if (this->cell_type < internal::MatrixFreeFunctions::general) { - const vector_t JxW = this->J_value[0] * this->quadrature_weights[q_point]; + const VectorizedArray JxW = this->J_value[0] * this->quadrature_weights[q_point]; this->values_quad[0][q_point] = val_in * JxW; } } @@ -3748,37 +3767,38 @@ template inline void FEEvaluationAccess:: -submit_gradient (Tensor<1,dim,VectorizedArray > grad_in, - unsigned int q_point) +submit_gradient (const Tensor<1,dim,VectorizedArray > grad_in, + const unsigned int q_point) { #ifdef DEBUG Assert (this->cell != numbers::invalid_unsigned_int, ExcNotInitialized()); AssertIndexRange (q_point, n_q_points); this->gradients_quad_submitted = true; #endif - if (this->cell_type == 0) + if (this->cell_type == internal::MatrixFreeFunctions::cartesian) { - const vector_t JxW = this->J_value[0] * this->quadrature_weights[q_point]; + const VectorizedArray JxW = this->J_value[0] * this->quadrature_weights[q_point]; for (unsigned int d=0; dgradients_quad[0][d][q_point] = (grad_in[d] * - this->cartesian[0][d] * JxW); + this->cartesian_data[0][d] * + JxW); } - else if (this->cell_type == 2) + else if (this->cell_type == internal::MatrixFreeFunctions::general) { for (unsigned int d=0; djacobian[q_point][0][d] * grad_in[0]; + VectorizedArray new_val = this->jacobian[q_point][0][d] * grad_in[0]; for (unsigned e=1; ejacobian[q_point][e][d] * grad_in[e]; this->gradients_quad[0][d][q_point] = new_val * this->J_value[q_point]; } } - else //if (this->cell_type == 1) + else //if (this->cell_type == internal::MatrixFreeFunctions::affine) { - const vector_t JxW = this->J_value[0] * this->quadrature_weights[q_point]; + const VectorizedArray JxW = this->J_value[0] * this->quadrature_weights[q_point]; for (unsigned int d=0; djacobian[0][0][d] * grad_in[0]; + VectorizedArray new_val = this->jacobian[0][0][d] * grad_in[0]; for (unsigned e=1; ejacobian[0][e][d] * grad_in[e]; this->gradients_quad[0][d][q_point] = new_val * JxW; @@ -3792,7 +3812,7 @@ template inline VectorizedArray FEEvaluationAccess:: -integrate_value () +integrate_value () const { return BaseClass::integrate_value()[0]; } @@ -3820,7 +3840,7 @@ template inline Tensor<2,dim,VectorizedArray > FEEvaluationAccess:: -get_gradient (unsigned int q_point) const +get_gradient (const unsigned int q_point) const { return BaseClass::get_gradient (q_point); } @@ -3831,25 +3851,25 @@ template inline VectorizedArray FEEvaluationAccess:: -get_divergence (unsigned int q_point) const +get_divergence (const unsigned int q_point) const { Assert (this->gradients_quad_initialized==true, internal::ExcAccessToUninitializedField()); AssertIndexRange (q_point, n_q_points); - vector_t divergence; + VectorizedArray divergence; // Cartesian cell - if (this->cell_type == 0) + if (this->cell_type == internal::MatrixFreeFunctions::cartesian) { divergence = (this->gradients_quad[0][0][q_point] * - this->cartesian[0][0]); + this->cartesian_data[0][0]); for (unsigned int d=1; dgradients_quad[d][d][q_point] * - this->cartesian[0][d]); + this->cartesian_data[0][d]); } // cell with general Jacobian - else if (this->cell_type == 2) + else if (this->cell_type == internal::MatrixFreeFunctions::general) { divergence = (this->jacobian[q_point][0][0] * this->gradients_quad[0][0][q_point]); @@ -3863,7 +3883,7 @@ get_divergence (unsigned int q_point) const } // cell with general Jacobian, but constant // within the cell - else // if (this->cell_type == 1) + else // if (this->cell_type == internal::MatrixFreeFunctions::affine) { divergence = (this->jacobian[0][0][0] * this->gradients_quad[0][0][q_point]); @@ -3884,13 +3904,13 @@ template inline SymmetricTensor<2,dim,VectorizedArray > FEEvaluationAccess:: -get_symmetric_gradient (unsigned int q_point) const +get_symmetric_gradient (const unsigned int q_point) const { // copy from generic function into // dim-specialization function - const Tensor<2,dim,vector_t> grad = get_gradient(q_point); - vector_t symmetrized [(dim*dim+dim)/2]; - vector_t half = make_vectorized_array (0.5); + const Tensor<2,dim,VectorizedArray > grad = get_gradient(q_point); + VectorizedArray symmetrized [(dim*dim+dim)/2]; + VectorizedArray half = make_vectorized_array (0.5); for (unsigned int d=0; d (symmetrized); + return SymmetricTensor<2,dim,VectorizedArray > (symmetrized); } template inline -typename FEEvaluationAccess::curl_type +Tensor<1,dim==2?1:dim,VectorizedArray > FEEvaluationAccess:: -get_curl (unsigned int q_point) const +get_curl (const unsigned int q_point) const { // copy from generic function into // dim-specialization function - const Tensor<2,dim,vector_t> grad = get_gradient(q_point); - curl_type curl; + const Tensor<2,dim,VectorizedArray > grad = get_gradient(q_point); + Tensor<1,dim==2?1:dim,VectorizedArray > curl (false); switch (dim) { case 1: @@ -3953,7 +3973,7 @@ template inline Tensor<2,dim,VectorizedArray > FEEvaluationAccess:: -get_hessian_diagonal (unsigned int q_point) const +get_hessian_diagonal (const unsigned int q_point) const { Assert (this->hessians_quad_initialized==true, internal::ExcAccessToUninitializedField()); @@ -3968,7 +3988,7 @@ template inline Tensor<3,dim,VectorizedArray > FEEvaluationAccess:: -get_hessian (unsigned int q_point) const +get_hessian (const unsigned int q_point) const { Assert (this->hessians_quad_initialized==true, internal::ExcAccessToUninitializedField()); @@ -3982,8 +4002,8 @@ template inline void FEEvaluationAccess:: -submit_gradient (Tensor<2,dim,VectorizedArray > grad_in, - unsigned int q_point) +submit_gradient (const Tensor<2,dim,VectorizedArray > grad_in, + const unsigned int q_point) { BaseClass::submit_gradient (grad_in, q_point); } @@ -3994,8 +4014,8 @@ template inline void FEEvaluationAccess:: -submit_gradient (Tensor<1,dim,Tensor<1,dim,VectorizedArray > > grad_in, - unsigned int q_point) +submit_gradient (const Tensor<1,dim,Tensor<1,dim,VectorizedArray > > grad_in, + const unsigned int q_point) { BaseClass::submit_gradient(grad_in, q_point); } @@ -4006,9 +4026,9 @@ template inline void FEEvaluationAccess:: -submit_symmetric_gradient (SymmetricTensor<2,dim,VectorizedArray > - sym_grad, - unsigned int q_point) +submit_symmetric_gradient (const SymmetricTensor<2,dim,VectorizedArray > + sym_grad, + const unsigned int q_point) { // could have used base class operator, but // that involves some overhead which is @@ -4020,34 +4040,34 @@ submit_symmetric_gradient (SymmetricTensor<2,dim,VectorizedArray > AssertIndexRange (q_point, n_q_points); this->gradients_quad_submitted = true; #endif - if (this->cell_type == 0) + if (this->cell_type == internal::MatrixFreeFunctions::cartesian) { - const vector_t JxW = this->J_value[0] * this->quadrature_weights[q_point]; + const VectorizedArray JxW = this->J_value[0] * this->quadrature_weights[q_point]; for (unsigned int d=0; dgradients_quad[d][d][q_point] = (sym_grad.access_raw_entry(d) * JxW * - this->cartesian[0][d]); + this->cartesian_data[0][d]); for (unsigned int e=0, counter=dim; e value = sym_grad.access_raw_entry(counter) * JxW; this->gradients_quad[e][d][q_point] = (value * - this->cartesian[0][d]); + this->cartesian_data[0][d]); this->gradients_quad[d][e][q_point] = (value * - this->cartesian[0][e]); + this->cartesian_data[0][e]); } } - else if (this->cell_type == 2) + else if (this->cell_type == internal::MatrixFreeFunctions::general) { - vector_t weighted [dim][dim]; + VectorizedArray weighted [dim][dim]; { - const vector_t JxW = this->J_value[q_point]; + const VectorizedArray JxW = this->J_value[q_point]; for (unsigned int i=0; i value = sym_grad.access_raw_entry(counter) * JxW; weighted[i][j] = value; weighted[j][i] = value; } @@ -4055,24 +4075,24 @@ submit_symmetric_gradient (SymmetricTensor<2,dim,VectorizedArray > for (unsigned int comp=0; compjacobian[q_point][0][d] * weighted[comp][0]; + VectorizedArray new_val = this->jacobian[q_point][0][d] * weighted[comp][0]; for (unsigned e=1; ejacobian[q_point][e][d] * weighted[comp][e]; this->gradients_quad[comp][d][q_point] = new_val; } } - else //if (this->cell_type == 1) + else //if (this->cell_type == internal::MatrixFreeFunctions::affine) { - vector_t weighted [dim][dim]; + VectorizedArray weighted [dim][dim]; { - const vector_t JxW = (this->J_value[0] * + const VectorizedArray JxW = (this->J_value[0] * this->quadrature_weights[q_point]); for (unsigned int i=0; i value = sym_grad.access_raw_entry(counter) * JxW; weighted[i][j] = value; weighted[j][i] = value; } @@ -4080,7 +4100,7 @@ submit_symmetric_gradient (SymmetricTensor<2,dim,VectorizedArray > for (unsigned int comp=0; compjacobian[q_point][0][d] * weighted[comp][0]; + VectorizedArray new_val = this->jacobian[q_point][0][d] * weighted[comp][0]; for (unsigned e=1; ejacobian[q_point][e][d] * weighted[comp][e]; this->gradients_quad[comp][d][q_point] = new_val; @@ -4094,10 +4114,10 @@ template inline void FEEvaluationAccess:: -submit_curl (curl_type curl, - unsigned int q_point) +submit_curl (const Tensor<1,dim==2?1:dim,VectorizedArray > curl, + const unsigned int q_point) { - Tensor<2,dim,vector_t> grad; + Tensor<2,dim,VectorizedArray > grad; switch (dim) { case 1: @@ -4126,10 +4146,10 @@ submit_curl (curl_type curl, /*----------------------- FEEvaluationGeneral -------------------------------*/ -template inline -FEEvaluationGeneral:: +FEEvaluationGeneral:: FEEvaluationGeneral (const MatrixFree &data_in, const unsigned int fe_no, const unsigned int quad_no_in) @@ -4146,7 +4166,7 @@ FEEvaluationGeneral (const MatrixFree &data_in, "-------------------------------------------------------\n"; message += "Illegal arguments in constructor/wrong template arguments!\n"; message += " Called --> FEEvaluation(data, "; message += Utilities::int_to_string(fe_no) + ", "; message += Utilities::int_to_string(quad_no_in) + ")\n"; @@ -4173,7 +4193,7 @@ FEEvaluationGeneral (const MatrixFree &data_in, { message += "Wrong vector component selection:\n"; message += " Did you mean FEEvaluation(data, "; message += Utilities::int_to_string(proposed_dof_comp) + ", "; message += Utilities::int_to_string(proposed_quad_comp) + ")?\n"; @@ -4191,17 +4211,17 @@ FEEvaluationGeneral (const MatrixFree &data_in, // ok, did not find the numbers specified by // the template arguments in the given // list. Suggest correct template arguments - const unsigned int proposed_n_dofs_1d = static_cast(std::pow(1.001*this->data.dofs_per_cell,1./dim)); + const unsigned int proposed_fe_degree = static_cast(std::pow(1.001*this->data.dofs_per_cell,1./dim))-1; const unsigned int proposed_n_q_points_1d = static_cast(std::pow(1.001*this->data.n_q_points,1./dim)); message += "Wrong template arguments:\n"; message += " Did you mean FEEvaluation &data_in, -template inline void -FEEvaluationGeneral:: +FEEvaluationGeneral:: evaluate (bool evaluate_val, bool evaluate_grad, bool evaluate_lapl) { Assert (this->cell != numbers::invalid_unsigned_int, ExcNotInitialized()); Assert (this->dof_values_initialized == true, internal::ExcAccessToUninitializedField()); - const vector_t * val = this->data.shape_values.begin(); - const vector_t * grad = this->data.shape_gradients.begin(); - const vector_t * hess = this->data.shape_hessians.begin(); + const VectorizedArray * val = this->data.shape_values.begin(); + const VectorizedArray * grad = this->data.shape_gradients.begin(); + const VectorizedArray * hess = this->data.shape_hessians.begin(); for(unsigned int comp=0;comp n_q_points_1d ? dofs_per_cell : n_q_points]; - vector_t temp2[n_dofs_1d > n_q_points_1d ? dofs_per_cell : n_q_points]; + VectorizedArray temp1[fe_degree >= n_q_points_1d ? dofs_per_cell : n_q_points]; + VectorizedArray temp2[fe_degree >= n_q_points_1d ? dofs_per_cell : n_q_points]; if (dim == 3) { @@ -4367,11 +4387,11 @@ evaluate (bool evaluate_val, bool evaluate_grad, bool evaluate_lapl) -template inline void -FEEvaluationGeneral:: +FEEvaluationGeneral:: integrate (bool integrate_val,bool integrate_grad) { #ifdef DEBUG @@ -4384,13 +4404,13 @@ integrate (bool integrate_val,bool integrate_grad) internal::ExcAccessToUninitializedField()); #endif - const vector_t * val = this->data.shape_values.begin(); - const vector_t * grad = this->data.shape_gradients.begin(); + const VectorizedArray * val = this->data.shape_values.begin(); + const VectorizedArray * grad = this->data.shape_gradients.begin(); for(unsigned int comp=0;comp n_q_points_1d ? dofs_per_cell : n_q_points]; - vector_t temp2[n_dofs_1d > n_q_points_1d ? dofs_per_cell : n_q_points]; + VectorizedArray temp1[fe_degree >= n_q_points_1d ? dofs_per_cell : n_q_points]; + VectorizedArray temp2[fe_degree >= n_q_points_1d ? dofs_per_cell : n_q_points]; if (dim == 3) { @@ -4403,10 +4423,10 @@ integrate (bool integrate_val,bool integrate_grad) { // grad x: can sum to temporary value in temp1 if (integrate_val == true) - apply_tensor_prod<0,false,true> + apply_tensor_prod<0,false,true> (grad, this->gradients_quad[comp][0],temp1); else - apply_tensor_prod<0,false,false> + apply_tensor_prod<0,false,false> (grad, this->gradients_quad[comp][0],temp1); } apply_tensor_prod<1,false,false> (val, temp1, temp2); @@ -4434,10 +4454,10 @@ integrate (bool integrate_val,bool integrate_grad) { //grad x if (integrate_val == true) - apply_tensor_prod<0,false,true> + apply_tensor_prod<0,false,true> (grad, this->gradients_quad[comp][0],temp1); else - apply_tensor_prod<0,false,false> + apply_tensor_prod<0,false,false> (grad, this->gradients_quad[comp][0],temp1); } apply_tensor_prod<1,false,false> (val, temp1, this->values_dofs[comp]); @@ -4472,11 +4492,11 @@ integrate (bool integrate_val,bool integrate_grad) -template inline Point > -FEEvaluationGeneral:: +FEEvaluationGeneral:: quadrature_point (const unsigned int q) const { Assert (this->mapping_info.quadrature_points_initialized == true, @@ -4487,9 +4507,9 @@ quadrature_point (const unsigned int q) const // are stored, only the diagonal. Hence, need // to find the tensor product index and // retrieve the value from that - if (this->cell_type == 0) + if (this->cell_type == internal::MatrixFreeFunctions::cartesian) { - Point point (false); + Point > point (false); switch (dim) { case 1: @@ -4519,39 +4539,39 @@ quadrature_point (const unsigned int q) const // to three spatial dimensions. Does not // assume any symmetry in the shape values // field -template template inline void -FEEvaluationGeneral:: +FEEvaluationGeneral:: apply_tensor_prod (const VectorizedArray*shape_data, const VectorizedArray input [], VectorizedArray output []) { AssertIndexRange (direction, dim); - const int mm = dof_to_quad ? n_dofs_1d : n_q_points_1d, - nn = dof_to_quad ? n_q_points_1d : n_dofs_1d; + const int mm = dof_to_quad ? (fe_degree+1) : n_q_points_1d, + nn = dof_to_quad ? n_q_points_1d : (fe_degree+1); const int n_blocks1 = (dim > 1 ? (direction > 0 ? nn : mm) : 1); const int n_blocks2 = (dim > 2 ? (direction > 1 ? nn : mm) : 1); const int stride = ((direction > 0 ? nn : 1 ) * (direction > 1 ? nn : 1)); - const vector_t * in = &input[0]; - vector_t * out = &output[0]; + const VectorizedArray * in = &input[0]; + VectorizedArray * out = &output[0]; for (int i2=0; i2 val0; if (dof_to_quad == true) val0 = shape_data[col]; else val0 = shape_data[col*n_q_points_1d]; - vector_t res0 = val0 * in[0]; + VectorizedArray res0 = val0 * in[0]; for (int ind=1; ind*shape_data, /*----------------------- FEEvaluation -------------------------------*/ -template inline -FEEvaluation:: +FEEvaluation:: FEEvaluation (const MatrixFree &data_in, const unsigned int fe_no, const unsigned int quad_no) @@ -4617,6 +4637,7 @@ FEEvaluation (const MatrixFree &data_in, error_message += "Try FEEvaluationGeneral<...> instead!"; // symmetry for values + const unsigned int n_dofs_1d = fe_degree + 1; for (unsigned int i=0; i<(n_dofs_1d+1)/2; ++i) for (unsigned int j=0; jdata.shape_values[i*n_q_points_1d+j][0] - @@ -4664,11 +4685,11 @@ FEEvaluation (const MatrixFree &data_in, -template inline void -FEEvaluation:: +FEEvaluation:: evaluate (bool evaluate_val, bool evaluate_grad, bool evaluate_lapl) { Assert (this->cell != numbers::invalid_unsigned_int, @@ -4678,8 +4699,8 @@ evaluate (bool evaluate_val, bool evaluate_grad, bool evaluate_lapl) for(unsigned int comp=0;comp n_q_points_1d ? dofs_per_cell : n_q_points]; - vector_t temp2[n_dofs_1d > n_q_points_1d ? dofs_per_cell : n_q_points]; + VectorizedArray temp1[fe_degree >= n_q_points_1d ? dofs_per_cell : n_q_points]; + VectorizedArray temp2[fe_degree >= n_q_points_1d ? dofs_per_cell : n_q_points]; if (dim == 3) { @@ -4803,11 +4824,11 @@ evaluate (bool evaluate_val, bool evaluate_grad, bool evaluate_lapl) -template inline void -FEEvaluation:: +FEEvaluation:: integrate (bool integrate_val,bool integrate_grad) { #ifdef DEBUG @@ -4823,8 +4844,8 @@ integrate (bool integrate_val,bool integrate_grad) for(unsigned int comp=0;comp n_q_points_1d ? dofs_per_cell : n_q_points]; - vector_t temp2[n_dofs_1d > n_q_points_1d ? dofs_per_cell : n_q_points]; + VectorizedArray temp1[fe_degree >= n_q_points_1d ? dofs_per_cell : n_q_points]; + VectorizedArray temp2[fe_degree >= n_q_points_1d ? dofs_per_cell : n_q_points]; if (dim == 3) { @@ -4907,18 +4928,18 @@ integrate (bool integrate_val,bool integrate_grad) // ----------------- optimized implementation tensor product symmetric case -template template inline void -FEEvaluation:: +FEEvaluation:: apply_values (const VectorizedArray input [], VectorizedArray output []) { AssertIndexRange (direction, dim); - const int mm = dof_to_quad ? n_dofs_1d : n_q_points_1d, - nn = dof_to_quad ? n_q_points_1d : n_dofs_1d; + const int mm = dof_to_quad ? (fe_degree+1) : n_q_points_1d, + nn = dof_to_quad ? n_q_points_1d : (fe_degree+1); const int n_cols = nn / 2; const int mid = mm / 2; @@ -4927,15 +4948,15 @@ apply_values (const VectorizedArray input [], const int stride = ((direction > 0 ? nn : 1 ) * (direction > 1 ? nn : 1)); - const vector_t * in = &input[0]; - vector_t * out = &output[0]; + const VectorizedArray * in = &input[0]; + VectorizedArray * out = &output[0]; for (int i2=0; i2 val0, val1, res0, res1; if (dof_to_quad == true) { val0 = this->data.shape_values[col]; @@ -4971,7 +4992,7 @@ apply_values (const VectorizedArray input [], } } else - res0 = res1 = vector_t(); + res0 = res1 = VectorizedArray(); if (dof_to_quad == true) { if (mm % 2 == 1) @@ -5012,8 +5033,8 @@ apply_values (const VectorizedArray input [], } else if (dof_to_quad == true && nn%2==1) { - vector_t res0; - vector_t val0 = this->data.shape_values[n_cols]; + VectorizedArray res0; + VectorizedArray val0 = this->data.shape_values[n_cols]; if (mid > 0) { res0 = in[0] + in[stride*(mm-1)]; @@ -5021,13 +5042,13 @@ apply_values (const VectorizedArray input [], for (int ind=1; inddata.shape_values[ind*n_q_points_1d+n_cols]; - vector_t val1 = in[stride*ind] + in[stride*(mm-1-ind)]; + VectorizedArray val1 = in[stride*ind] + in[stride*(mm-1-ind)]; val1 *= val0; res0 += val1; } } else - res0 = vector_t(); + res0 = VectorizedArray(); if (mm % 2 == 1) { val0 = this->data.shape_values[mid*n_q_points_1d+n_cols]; @@ -5040,16 +5061,16 @@ apply_values (const VectorizedArray input [], } else if (dof_to_quad == false && nn%2 == 1) { - vector_t res0; + VectorizedArray res0; if (mid > 0) { - vector_t val0 = this->data.shape_values[n_cols*n_q_points_1d]; + VectorizedArray val0 = this->data.shape_values[n_cols*n_q_points_1d]; res0 = in[0] + in[stride*(mm-1)]; res0 *= val0; for (int ind=1; inddata.shape_values[n_cols*n_q_points_1d+ind]; - vector_t val1 = in[stride*ind] + in[stride*(mm-1-ind)]; + VectorizedArray val1 = in[stride*ind] + in[stride*(mm-1-ind)]; val1 *= val0; res0 += val1; } @@ -5093,18 +5114,18 @@ apply_values (const VectorizedArray input [], -template template inline void -FEEvaluation:: +FEEvaluation:: apply_gradients (const VectorizedArray input [], VectorizedArray output []) { AssertIndexRange (direction, dim); - const int mm = dof_to_quad ? n_dofs_1d : n_q_points_1d, - nn = dof_to_quad ? n_q_points_1d : n_dofs_1d; + const int mm = dof_to_quad ? (fe_degree+1) : n_q_points_1d, + nn = dof_to_quad ? n_q_points_1d : (fe_degree+1); const int n_cols = nn / 2; const int mid = mm / 2; @@ -5113,15 +5134,15 @@ apply_gradients (const VectorizedArray input [], const int stride = ((direction > 0 ? nn : 1 ) * (direction > 1 ? nn : 1)); - const vector_t * in = &input[0]; - vector_t * out = &output[0]; + const VectorizedArray * in = &input[0]; + VectorizedArray * out = &output[0]; for (int i2=0; i2 val0, val1, res0, res1; if (dof_to_quad == true) { val0 = this->data.shape_gradients[col]; @@ -5157,7 +5178,7 @@ apply_gradients (const VectorizedArray input [], } } else - res0 = res1 = vector_t(); + res0 = res1 = VectorizedArray(); if (mm % 2 == 1) { if (dof_to_quad == true) @@ -5181,7 +5202,7 @@ apply_gradients (const VectorizedArray input [], } if ( nn%2 == 1 ) { - vector_t val0, res0; + VectorizedArray val0, res0; if (dof_to_quad == true) val0 = this->data.shape_gradients[n_cols]; else @@ -5194,7 +5215,7 @@ apply_gradients (const VectorizedArray input [], val0 = this->data.shape_gradients[ind*n_q_points_1d+n_cols]; else val0 = this->data.shape_gradients[n_cols*n_q_points_1d+ind]; - vector_t val1 = in[stride*ind] - in[stride*(mm-1-ind)]; + VectorizedArray val1 = in[stride*ind] - in[stride*(mm-1-ind)]; val1 *= val0; res0 += val1; } @@ -5240,18 +5261,18 @@ apply_gradients (const VectorizedArray input [], // same symmetry relations hold. However, it // is not possible to omit some values that // are zero for the values -template template inline void -FEEvaluation:: +FEEvaluation:: apply_hessians (const VectorizedArray input [], VectorizedArray output []) { AssertIndexRange (direction, dim); - const int mm = dof_to_quad ? n_dofs_1d : n_q_points_1d, - nn = dof_to_quad ? n_q_points_1d : n_dofs_1d; + const int mm = dof_to_quad ? (fe_degree+1) : n_q_points_1d, + nn = dof_to_quad ? n_q_points_1d : (fe_degree+1); const int n_cols = nn / 2; const int mid = mm / 2; @@ -5260,15 +5281,15 @@ apply_hessians (const VectorizedArray input [], const int stride = ((direction > 0 ? nn : 1 ) * (direction > 1 ? nn : 1)); - const vector_t * in = &input[0]; - vector_t * out = &output[0]; + const VectorizedArray * in = &input[0]; + VectorizedArray * out = &output[0]; for (int i2=0; i2 val0, val1, res0, res1; if (dof_to_quad == true) { val0 = this->data.shape_hessians[col]; @@ -5304,7 +5325,7 @@ apply_hessians (const VectorizedArray input [], } } else - res0 = res1 = vector_t(); + res0 = res1 = VectorizedArray(); if (mm % 2 == 1) { if (dof_to_quad == true) @@ -5328,7 +5349,7 @@ apply_hessians (const VectorizedArray input [], } if ( nn%2 == 1 ) { - vector_t val0, res0; + VectorizedArray val0, res0; if (dof_to_quad == true) val0 = this->data.shape_hessians[n_cols]; else @@ -5343,13 +5364,13 @@ apply_hessians (const VectorizedArray input [], val0 = this->data.shape_hessians[ind*n_q_points_1d+n_cols]; else val0 = this->data.shape_hessians[n_cols*n_q_points_1d+ind]; - vector_t val1 = in[stride*ind] + in[stride*(mm-1-ind)]; + VectorizedArray val1 = in[stride*ind] + in[stride*(mm-1-ind)]; val1 *= val0; res0 += val1; } } else - res0 = vector_t(); + res0 = VectorizedArray(); if (mm % 2 == 1) { if (dof_to_quad == true) @@ -5395,9 +5416,9 @@ apply_hessians (const VectorizedArray input [], /*----------------------- FEEvaluationGL -------------------------------*/ -template +template inline -FEEvaluationGL:: +FEEvaluationGL:: FEEvaluationGL (const MatrixFree &data_in, const unsigned int fe_no, const unsigned int quad_no) @@ -5413,6 +5434,7 @@ FEEvaluationGL (const MatrixFree &data_in, const double zero_tol = types_are_equal::value==true?1e-9:1e-7; + const unsigned int n_points_1d = fe_degree+1; for (unsigned int i=0; i &data_in, -template +template inline void -FEEvaluationGL:: +FEEvaluationGL:: evaluate (bool evaluate_val,bool evaluate_grad,bool evaluate_lapl) { Assert (this->cell != numbers::invalid_unsigned_int, @@ -5503,7 +5525,7 @@ evaluate (bool evaluate_val,bool evaluate_grad,bool evaluate_lapl) this->template apply_hessians<2,true,false> (this->values_dofs[comp], this->hessians_quad[comp][2]); - vector_t temp1[n_q_points]; + VectorizedArray temp1[n_q_points]; // grad xy apply_gradients<0,true,false> (this->values_dofs[comp], temp1); apply_gradients<1,true,false> (temp1, this->hessians_quad[comp][3]); @@ -5521,7 +5543,7 @@ evaluate (bool evaluate_val,bool evaluate_grad,bool evaluate_lapl) // grad y this->template apply_hessians<1,true,false> (this->values_dofs[comp], this->hessians_quad[comp][1]); - vector_t temp1[n_q_points]; + VectorizedArray temp1[n_q_points]; // grad xy apply_gradients<0,true,false> (this->values_dofs[comp], temp1); apply_gradients<1,true,false> (temp1, this->hessians_quad[comp][2]); @@ -5538,10 +5560,10 @@ evaluate (bool evaluate_val,bool evaluate_grad,bool evaluate_lapl) -template +template inline void -FEEvaluationGL:: +FEEvaluationGL:: integrate (bool integrate_val, bool integrate_grad) { Assert (this->cell != numbers::invalid_unsigned_int, @@ -5612,17 +5634,17 @@ integrate (bool integrate_val, bool integrate_grad) -template +template template inline void -FEEvaluationGL:: +FEEvaluationGL:: apply_gradients (const VectorizedArray input [], VectorizedArray output []) { AssertIndexRange (direction, dim); - const int mm = n_points_1d; - const int nn = n_points_1d; + const int mm = fe_degree+1; + const int nn = fe_degree+1; const int n_cols = nn / 2; const int mid = mm / 2; @@ -5631,15 +5653,15 @@ apply_gradients (const VectorizedArray input [], const int stride = ((direction > 0 ? nn : 1 ) * (direction > 1 ? nn : 1)); - const vector_t * in = &input[0]; - vector_t * out = &output[0]; + const VectorizedArray * in = &input[0]; + VectorizedArray * out = &output[0]; for (int i2=0; i2 val0, val1, res0, res1; if (dof_to_quad == true) { val0 = this->data.shape_gradients[col]; @@ -5647,8 +5669,8 @@ apply_gradients (const VectorizedArray input [], } else { - val0 = this->data.shape_gradients[col*n_points_1d]; - val1 = this->data.shape_gradients[(nn-col-1)*n_points_1d]; + val0 = this->data.shape_gradients[col*mm]; + val1 = this->data.shape_gradients[(nn-col-1)*mm]; } if (mid > 0) { @@ -5660,13 +5682,13 @@ apply_gradients (const VectorizedArray input [], { if (dof_to_quad == true) { - val0 = this->data.shape_gradients[ind*n_points_1d+col]; - val1 = this->data.shape_gradients[ind*n_points_1d+nn-1-col]; + val0 = this->data.shape_gradients[ind*mm+col]; + val1 = this->data.shape_gradients[ind*mm+nn-1-col]; } else { - val0 = this->data.shape_gradients[col*n_points_1d+ind]; - val1 = this->data.shape_gradients[(nn-col-1)*n_points_1d+ind]; + val0 = this->data.shape_gradients[col*mm+ind]; + val1 = this->data.shape_gradients[(nn-col-1)*mm+ind]; } // at inner points, the gradient is zero for @@ -5686,13 +5708,13 @@ apply_gradients (const VectorizedArray input [], } } else - res0 = res1 = vector_t(); + res0 = res1 = VectorizedArray(); if (mm % 2 == 1) { if (dof_to_quad == true) - val0 = this->data.shape_gradients[mid*n_points_1d+col]; + val0 = this->data.shape_gradients[mid*mm+col]; else - val0 = this->data.shape_gradients[col*n_points_1d+mid]; + val0 = this->data.shape_gradients[col*mm+mid]; val1 = val0 * in[stride*mid]; res0 += val1; res1 -= val1; @@ -5710,11 +5732,11 @@ apply_gradients (const VectorizedArray input [], } if ( nn%2 == 1 ) { - vector_t val0, res0; + VectorizedArray val0, res0; if (dof_to_quad == true) val0 = this->data.shape_gradients[n_cols]; else - val0 = this->data.shape_gradients[n_cols*n_points_1d]; + val0 = this->data.shape_gradients[n_cols*mm]; if (mid > 0) { res0 = in[0] - in[stride*(mm-1)]; @@ -5722,16 +5744,16 @@ apply_gradients (const VectorizedArray input [], for (int ind=1; inddata.shape_gradients[ind*n_points_1d+n_cols]; + val0 = this->data.shape_gradients[ind*mm+n_cols]; else - val0 = this->data.shape_gradients[n_cols*n_points_1d+ind]; - vector_t val1 = in[stride*ind] - in[stride*(mm-1-ind)]; + val0 = this->data.shape_gradients[n_cols*mm+ind]; + VectorizedArray val1 = in[stride*ind] - in[stride*(mm-1-ind)]; val1 *= val0; res0 += val1; } } else - res0 = vector_t(); + res0 = VectorizedArray(); if (add == false) out[stride*n_cols] = res0; else diff --git a/deal.II/include/deal.II/matrix_free/helper_functions.h b/deal.II/include/deal.II/matrix_free/helper_functions.h index 71cc7263f5..5fccb9d8b6 100644 --- a/deal.II/include/deal.II/matrix_free/helper_functions.h +++ b/deal.II/include/deal.II/matrix_free/helper_functions.h @@ -33,85 +33,7 @@ namespace internal namespace MatrixFreeFunctions { // forward declaration of internal data structure - namespace internal - { - template struct ConstraintValues; - } - - - // set minimum grain size for parallel - // computations - namespace internal - { - const unsigned int minimum_parallel_grain_size = 500; - } - - - /* - * Compressed data type to store a two - * dimensional array. The data is stored in - * a single standard vector. In a second - * vector, the first element belonging to - * each row is stored. - */ - template - struct CompressedMatrix - { - AlignedVector data; - std::vector row_index; - T* operator[] (const unsigned int row) { - return begin(row); - }; - const T* operator[] (const unsigned int row) const { - return begin(row); - }; - const T* begin(const unsigned int row) const { - AssertIndexRange (row, row_index.size()-1); - return data.begin() + row_index[row]; - }; - const T* end(const unsigned int row) const { - AssertIndexRange (row, row_index.size()-1); - return data.begin() + row_index[row+1]; - }; - unsigned int row_length (const unsigned int row) const { - AssertIndexRange (row, row_index.size()-1); - return row_index[row+1] - row_index[row]; - }; - T* begin(const unsigned int row) { - AssertIndexRange (row, row_index.size()-1); - return data.begin() + row_index[row]; - }; - T* end(const unsigned int row) { - AssertIndexRange (row, row_index.size()-1); - return data.begin() + row_index[row+1]; - }; - void complete_last_row() { - row_index.push_back (data.size()); - } - void swap (CompressedMatrix &other) { - data.swap (other.data); - row_index.swap (other.row_index); - } - void print (std::ostream &out) const - { - for (unsigned int row=0; row struct ConstraintValues; /** * A struct that collects all information @@ -124,43 +46,19 @@ namespace MatrixFreeFunctions /** * Constructor. */ - TaskInfo () - { - clear(); - } + TaskInfo (); /** * Clears all the data fields and resets them * to zero. */ - void clear () - { - block_size = 0; - n_blocks = 0; - block_size_last = 0; - position_short_block = 0; - use_multithreading = false; - use_partition_partition = false; - use_coloring_only = false; - partition_color_blocks.clear(); - evens = 0; - odds = 0; - n_blocked_workers = 0; - n_workers = 0; - partition_evens.clear(); - partition_odds.clear(); - partition_n_blocked_workers.clear(); - partition_n_workers.clear(); - } + void clear (); - std::size_t memory_consumption () const - { - return (MemoryConsumption::memory_consumption (partition_color_blocks) + - MemoryConsumption::memory_consumption (partition_evens) + - MemoryConsumption::memory_consumption (partition_odds) + - MemoryConsumption::memory_consumption (partition_n_blocked_workers) + - MemoryConsumption::memory_consumption (partition_n_workers)); - } + /** + * Returns the memory consumption of + * the class. + */ + std::size_t memory_consumption () const; unsigned int block_size; unsigned int n_blocks; @@ -170,7 +68,8 @@ namespace MatrixFreeFunctions bool use_partition_partition; bool use_coloring_only; - CompressedMatrix partition_color_blocks; + std::vector partition_color_blocks_row_index; + std::vector partition_color_blocks_data; unsigned int evens; unsigned int odds; unsigned int n_blocked_workers; @@ -194,91 +93,38 @@ namespace MatrixFreeFunctions /** * Constructor. */ - SizeInfo () - { - clear(); - } + SizeInfo (); /** * Clears all data fields and resets the sizes * to zero. */ - void clear() - { - n_active_cells = 0; - n_macro_cells = 0; - boundary_cells_start = 0; - boundary_cells_end = 0; - n_vectors = 0; - locally_owned_cells = IndexSet(); - ghost_cells = IndexSet(); - communicator = MPI_COMM_SELF; - my_pid = 0; - n_procs = 0; - } - + void clear(); + + /** + * Prints minimum, average, and + * maximal memory consumption over the + * MPI processes. + */ template - void print_mem (STREAM &out, - std::size_t data_length) const - { - Utilities::MPI::MinMaxAvg memory_c; - if (Utilities::System::job_supports_mpi() == true) - { - memory_c = Utilities::MPI::min_max_avg (1e-6*data_length, - communicator); - } - else - { - memory_c.sum = 1e-6*data_length; - memory_c.min = memory_c.sum; - memory_c.max = memory_c.sum; - memory_c.avg = memory_c.sum; - memory_c.min_index = 0; - memory_c.max_index = 0; - } - if (n_procs < 2) - out << memory_c.min; - else - out << memory_c.min << "/" << memory_c.avg << "/" << memory_c.max; - out << " MB" << std::endl; - } + void print_memory_statistics (STREAM &out, + std::size_t data_length) const; + /** + * Determines the position of cells + * with ghosts for distributed-memory + * calculations. + */ void make_layout (const unsigned int n_active_cells_in, - const unsigned int n_boundary_cells, - const unsigned int n_vectors_in, - std::vector &irregular_cells) - { - n_vectors = n_vectors_in; - n_active_cells = n_active_cells_in; - - // check that number of boundary cells is - // divisible by n_vectors or that it contains - // all cells - Assert (n_boundary_cells % n_vectors == 0 || - n_boundary_cells == n_active_cells, ExcInternalError()); - n_macro_cells = (n_active_cells+n_vectors-1)/n_vectors; - irregular_cells.resize (n_macro_cells); - if (n_macro_cells*n_vectors > n_active_cells) - { - irregular_cells[n_macro_cells-1] = - n_vectors - (n_macro_cells*n_vectors - n_active_cells); - } - if (n_procs > 1) - { - const unsigned int n_macro_boundary_cells = - (n_boundary_cells+n_vectors-1)/n_vectors; - boundary_cells_start = (n_macro_cells-n_macro_boundary_cells)/2; - boundary_cells_end = boundary_cells_start + n_macro_boundary_cells; - } - else - boundary_cells_start = boundary_cells_end = n_macro_cells; - } + const unsigned int vectorization_length_in, + std::vector &boundary_cells, + std::vector &irregular_cells); unsigned int n_active_cells; unsigned int n_macro_cells; unsigned int boundary_cells_start; unsigned int boundary_cells_end; - unsigned int n_vectors; + unsigned int vectorization_length; /** * index sets to describe the layout of cells: @@ -296,11 +142,12 @@ namespace MatrixFreeFunctions unsigned int n_procs; }; + /** + * Data type to identify cell type. + */ + enum CellType {cartesian=0, affine=1, general=2, undefined=3}; - - namespace internal - { - // ----------------- hash structure -------------------------------- + // ----------------- hash structure -------------------------------- /** * A class that is @@ -318,17 +165,13 @@ namespace MatrixFreeFunctions * easily detected (unless roundoff spoils the * hash function) */ - struct HashValue - { + struct HashValue + { // Constructor: sets the size of Number values // with the typical magnitude that is to be // expected. - HashValue (const double element_size = 1.) - : - scaling (element_size * std::numeric_limits::epsilon() * - 1024.) - {}; - + HashValue (const double element_size = 1.); + // get hash value for a vector of floating // point numbers (which are assumed to be of // order of magnitude one). Do this by first @@ -336,54 +179,22 @@ namespace MatrixFreeFunctions // the scaling (in order to eliminate noise // from roundoff errors) and then calling the // boost hash function - unsigned int operator ()(const std::vector &vec) - { - std::vector mod_vec(vec); - for (unsigned int i=0; i(boost::hash_range (mod_vec.begin(), mod_vec.end())); - }; + unsigned int operator ()(const std::vector &vec); // get hash value for a tensor of rank // two where the magnitude of the // entries is given by the parameter // weight - template - unsigned int operator ()(const Tensor<2,dim,VectorizedArray > &input, - const bool is_diagonal) - { - const unsigned int n_vectors = VectorizedArray::n_array_elements; - - if (is_diagonal) - { - number mod_tensor [dim][n_vectors]; - for (unsigned int i=0; i(boost::hash_range - (&mod_tensor[0][0], - &mod_tensor[0][0]+dim*n_vectors)); - } - else - { - number mod_tensor [dim][dim][n_vectors]; - for (unsigned int i=0; i(boost::hash_range - (&mod_tensor[0][0][0], - &mod_tensor[0][0][0]+ - dim*dim*n_vectors)); - } - }; - - const double scaling; - }; + template + unsigned int operator ()(const Tensor<2,dim,VectorizedArray > + &input, + const bool is_diagonal); + + + const double scaling; + }; - } // end of namespace internal + // Note: Implementation in matrix_free.templates.h } // end of namespace MatrixFreeFunctions } // end of namespace internal diff --git a/deal.II/include/deal.II/matrix_free/mapping_info.h b/deal.II/include/deal.II/matrix_free/mapping_info.h index 3dc07eca94..1848193b73 100644 --- a/deal.II/include/deal.II/matrix_free/mapping_info.h +++ b/deal.II/include/deal.II/matrix_free/mapping_info.h @@ -41,15 +41,6 @@ namespace MatrixFreeFunctions template struct MappingInfo { - typedef VectorizedArray vector_t; - typedef Point point; - typedef Tensor<1,dim,vector_t> tensor1; - typedef Tensor<2,dim,vector_t> tensor2; - typedef Tensor<3,dim,vector_t> tensor3; - typedef Tensor<1,(dim>1?dim*(dim-1)/2:1),Tensor<1,dim,vector_t> > tensorUT; - static const std::size_t n_vectors - = VectorizedArray::n_array_elements; - /** * Determines how many bits of an unsigned int * are used to distinguish the cell types @@ -103,21 +94,13 @@ namespace MatrixFreeFunctions * Returns the type of a given cell as * detected during initialization. */ - unsigned int get_cell_type (const unsigned int cell_chunk_no) const - { - AssertIndexRange (cell_chunk_no, cell_type.size()); - return cell_type[cell_chunk_no] % n_cell_types; - }; + CellType get_cell_type (const unsigned int cell_chunk_no) const; /** * Returns the type of a given cell as * detected during initialization. */ - unsigned int get_cell_data_index (const unsigned int cell_chunk_no) const - { - AssertIndexRange (cell_chunk_no, cell_type.size()); - return cell_type[cell_chunk_no] >> n_cell_type_bits; - }; + unsigned int get_cell_data_index (const unsigned int cell_chunk_no) const; /** * Clears all data fields in this class. @@ -170,7 +153,8 @@ namespace MatrixFreeFunctions * quadrature point, whereas the determinant * is the same on each quadrature point). */ - AlignedVector > cartesian; + AlignedVector >, + VectorizedArray > > cartesian_data; /** * The first field stores the Jacobian for @@ -190,7 +174,8 @@ namespace MatrixFreeFunctions * the determinant is the same on each * quadrature point). */ - AlignedVector > linear; + AlignedVector >, + VectorizedArray > > affine_data; /** * Definition of a structure that stores data @@ -216,14 +201,14 @@ namespace MatrixFreeFunctions * FEValues::inverse_jacobian) for general * cells. */ - AlignedVector jacobians; + AlignedVector > > jacobians; /** * This field stores the Jacobian * determinant times the quadrature weights * (JxW in deal.II speak) for general cells. */ - AlignedVector JxW_values; + AlignedVector > JxW_values; /** * Stores the diagonal part of the gradient of @@ -237,7 +222,7 @@ namespace MatrixFreeFunctions * x_i \partial x_j, i\neq j$ because that is * only needed for computing a full Hessian. */ - AlignedVector jacobians_grad_diag; + AlignedVector > > jacobians_grad_diag; /** * Stores the off-diagonal part of the @@ -251,7 +236,8 @@ namespace MatrixFreeFunctions * so on. The second index is the spatial * coordinate. Not filled currently. */ - AlignedVector jacobians_grad_upper; + AlignedVector1?dim*(dim-1)/2:1), + Tensor<1,dim,VectorizedArray > > > jacobians_grad_upper; /** * Stores the row start for quadrature points @@ -268,7 +254,7 @@ namespace MatrixFreeFunctions * coordinates for Cartesian cells (does not * need to store the full data on all points) */ - AlignedVector quadrature_points; + AlignedVector > > quadrature_points; /** * The dim-dimensional quadrature formula @@ -304,7 +290,7 @@ namespace MatrixFreeFunctions * The quadrature weights (vectorized data * format) on the unit cell. */ - std::vector > quadrature_weights; + std::vector > > quadrature_weights; /** * This variable stores the number of @@ -323,13 +309,7 @@ namespace MatrixFreeFunctions * given degree is actually present. */ unsigned int - quad_index_from_n_q_points (const unsigned int n_q_points) const - { - for (unsigned int i=0; i quadrature_points; - AlignedVector general_jac; - AlignedVector general_jac_grad; - tensor2 const_jac; - const double jac_size; + CellData (const double jac_size); + void resize (const unsigned int size); + + AlignedVector > > quadrature_points; + AlignedVector > > general_jac; + AlignedVector > > general_jac_grad; + Tensor<2,dim,VectorizedArray > const_jac; + const double jac_size; }; /** @@ -406,12 +376,52 @@ namespace MatrixFreeFunctions const std::pair *cells, const unsigned int cell, const unsigned int my_q, - unsigned int (&cell_t_prev)[n_vectors], - unsigned int (&cell_t)[n_vectors], + CellType (&cell_t_prev)[VectorizedArray::n_array_elements], + CellType (&cell_t)[VectorizedArray::n_array_elements], FEValues &fe_values, CellData &cell_data) const; }; + + + /* ------------------- inline functions ----------------------------- */ + + template + inline + unsigned int + MappingInfo::MappingInfoDependent:: + quad_index_from_n_q_points (const unsigned int n_q_points) const + { + for (unsigned int i=0; i + inline + CellType + MappingInfo::get_cell_type (const unsigned int cell_no) const + { + AssertIndexRange (cell_no, cell_type.size()); + CellType enum_cell_type = (CellType)(cell_type[cell_no] % n_cell_types); + Assert(enum_cell_type != undefined, ExcInternalError()); + return enum_cell_type; + } + + + + template + inline + unsigned int + MappingInfo::get_cell_data_index (const unsigned int cell_no) const + { + AssertIndexRange (cell_no, cell_type.size()); + return cell_type[cell_no] >> n_cell_type_bits; + } + } // end of namespace MatrixFreeFunctions } // end of namespace internal diff --git a/deal.II/include/deal.II/matrix_free/mapping_info.templates.h b/deal.II/include/deal.II/matrix_free/mapping_info.templates.h index 2e3e1f6154..c607df65e6 100644 --- a/deal.II/include/deal.II/matrix_free/mapping_info.templates.h +++ b/deal.II/include/deal.II/matrix_free/mapping_info.templates.h @@ -48,8 +48,8 @@ namespace MatrixFreeFunctions second_derivatives_initialized = false; mapping_data_gen.clear(); cell_type.clear(); - cartesian.clear(); - linear.clear(); + cartesian_data.clear(); + affine_data.clear(); } @@ -140,8 +140,10 @@ namespace MatrixFreeFunctions clear(); const unsigned int n_quads = quad.size(); const unsigned int n_cells = cells.size(); - Assert (n_cells%n_vectors == 0, ExcInternalError()); - const unsigned int n_macro_cells = n_cells/n_vectors; + const unsigned int vectorization_length = + VectorizedArray::n_array_elements; + Assert (n_cells%vectorization_length == 0, ExcInternalError()); + const unsigned int n_macro_cells = n_cells/vectorization_length; mapping_data_gen.resize (n_quads); cell_type.resize (n_macro_cells); @@ -175,8 +177,8 @@ namespace MatrixFreeFunctions const double jacobian_size = internal::get_jacobian_size(tria); // objects that hold the data for up to - // n_vectors cells while we fill them up. Only - // after all n_vectors cells have been + // vectorization_length cells while we fill them up. Only + // after all vectorization_length cells have been // processed, we can insert the data into the // data structures of this class CellData data (jacobian_size); @@ -235,17 +237,18 @@ namespace MatrixFreeFunctions if (cells.size() == 0) continue; - tensor3 jac_grad, grad_jac_inv; - tensor1 tmp; + Tensor<3,dim,VectorizedArray > jac_grad, grad_jac_inv; + Tensor<1,dim,VectorizedArray > tmp; // encodes the cell types of the current // cell. Since several cells must be // considered together, this variable holds // the individual info of the last chunk of // cells - unsigned int cell_t [n_vectors], cell_t_prev [n_vectors]; - for (unsigned int j=0; j > hash_collection; - internal::HashValue hash_value (jacobian_size); + HashValue hash_value (jacobian_size); // loop over all cells for (unsigned int cell=0; cell 0 && active_fe_index.size() > 0 && active_fe_index[cell] != active_fe_index[cell-1]) - cell_t_prev[n_vectors-1] = numbers::invalid_unsigned_int; - evaluate_on_cell (tria, &cells[cell*n_vectors], + cell_t_prev[vectorization_length-1] = undefined; + evaluate_on_cell (tria, &cells[cell*vectorization_length], cell, my_q, cell_t_prev, cell_t, fe_val, data); // now reorder the data into vectorized // types. if we are here for the first time, // we need to find out whether the Jacobian // allows for some simplification (Cartesian, - // linear) taking n_vectors cell together and + // affine) taking vectorization_length cell together and // we have to insert that data into the // respective fields. Also, we have to // compress different cell indicators into one @@ -333,8 +336,8 @@ namespace MatrixFreeFunctions { // find the most general cell type (most // general type is 2 (general cell)) - unsigned int most_general_type = 0; - for (unsigned int j=0; j most_general_type) most_general_type = cell_t[j]; AssertIndexRange (most_general_type, 3); @@ -344,12 +347,13 @@ namespace MatrixFreeFunctions // Jacobian determinant unsigned int insert_position = numbers::invalid_unsigned_int; typedef std::vector >::iterator iter; - if (most_general_type == 0) + if (most_general_type == cartesian) { - std::pair new_entry; + std::pair >, + VectorizedArray > new_entry; for (unsigned int d=0; dfirst == hash) { for (unsigned int d=0; dsecond].first[d][j])> + cartesian_data[-pos->second].first[d][j])> hash_value.scaling) duplicate = false; } @@ -385,7 +389,7 @@ namespace MatrixFreeFunctions if (duplicate == false) { hash_collection.insert (pos, insertion); - cartesian.push_back (new_entry); + cartesian_data.push_back (new_entry); } // else, remember the position else @@ -394,9 +398,9 @@ namespace MatrixFreeFunctions // Constant Jacobian case. same strategy as // before, but with other data fields - else if (most_general_type == 1) + else if (most_general_type == affine) { - insert_position = linear.size(); + insert_position = affine_data.size(); // check whether everything is the same as on // the previous cell @@ -415,9 +419,10 @@ namespace MatrixFreeFunctions { for (unsigned int d=0; dsecond].first[d][e][j])> + affine_data[-pos->second].first[d] + [e][j])> hash_value.scaling) duplicate = false; } @@ -427,8 +432,11 @@ namespace MatrixFreeFunctions if (duplicate == false) { hash_collection.insert (pos, insertion); - linear.push_back (std::pair(data.const_jac, - make_vectorized_array (Number(0.)))); + affine_data.push_back + (std::pair >, + VectorizedArray >(data.const_jac, + make_vectorized_array + (Number(0.)))); } else insert_position = -pos->second; @@ -443,7 +451,7 @@ namespace MatrixFreeFunctions // here involves at most one reallocation. else { - Assert (most_general_type == 2, ExcInternalError()); + Assert (most_general_type == general, ExcInternalError()); insert_position = current_data.rowstart_jacobians.size(); if (current_data.rowstart_jacobians.size() == 0) { @@ -462,7 +470,7 @@ namespace MatrixFreeFunctions } cell_type[cell] = ((insert_position << n_cell_type_bits) + - most_general_type); + (unsigned int)most_general_type); } // end if (my_q == 0) @@ -470,7 +478,7 @@ namespace MatrixFreeFunctions // quadrature points and collect the // data. done for all different quadrature // formulas, so do it outside the above loop. - if (get_cell_type(cell) == 2) + if (get_cell_type(cell) == general) { const unsigned int previous_size = current_data.jacobians.size(); @@ -489,10 +497,10 @@ namespace MatrixFreeFunctions } for (unsigned int q=0; q > &jac = data.general_jac[q]; + Tensor<3,dim,VectorizedArray > &jacobian_grad = data.general_jac_grad[q]; + for (unsigned int j=0; j det = determinant (jac); current_data.jacobians.push_back (transpose(invert(jac))); - const tensor2 &inv_jac = current_data.jacobians.back(); + const Tensor<2,dim,VectorizedArray > &inv_jac = current_data.jacobians.back(); // TODO: deal.II does not use abs on // determinants. Is there an assumption @@ -553,7 +561,7 @@ namespace MatrixFreeFunctions { for (unsigned int f=0; f(); for (unsigned int g=0; g grad_diag[dim][dim]; for (unsigned int d=0; d(grad_diag)); + (Tensor<2,dim,VectorizedArray >(grad_diag)); } // sets upper-diagonal part of Jacobian - tensorUT grad_upper; + Tensor<1,(dim>1?dim*(dim-1)/2:1),Tensor<1,dim,VectorizedArray > > grad_upper; for (unsigned int d=0, count=0; d > quad_point; - if (get_cell_type(cell) == 0) + if (get_cell_type(cell) == cartesian) { current_data.quadrature_points.resize (old_size+ n_q_points_1d[fe_index]); @@ -633,25 +641,26 @@ namespace MatrixFreeFunctions current_data.rowstart_q_points[n_macro_cells] = current_data.quadrature_points.size(); - // finally, need to invert and transpose the - // Jacobians in the cartesian and linear + // finally, need to invert and + // transpose the Jacobians in the + // cartesian_data and affine_data // fields and compute the JxW value. if (my_q == 0) { - for (unsigned int i=0; i det = cartesian_data[i].first[0]; for (unsigned int d=1; d det = determinant(affine_data[i].first); + affine_data[i].first = transpose(invert(affine_data[i].first)); + affine_data[i].second = std::abs(det); } } } @@ -665,11 +674,13 @@ namespace MatrixFreeFunctions const std::pair *cells, const unsigned int cell, const unsigned int my_q, - unsigned int (&cell_t_prev)[n_vectors], - unsigned int (&cell_t)[n_vectors], + CellType (&cell_t_prev)[VectorizedArray::n_array_elements], + CellType (&cell_t)[VectorizedArray::n_array_elements], FEValues &fe_val, CellData &data) const { + const unsigned int vectorization_length = + VectorizedArray::n_array_elements; const unsigned int n_q_points = fe_val.n_quadrature_points; const UpdateFlags update_flags = fe_val.get_update_flags(); @@ -678,12 +689,12 @@ namespace MatrixFreeFunctions // not have that field here) const double zero_tolerance_double = data.jac_size * std::numeric_limits::epsilon() * 1024.; - for (unsigned int j=0; j::cell_iterator cell_it (&tria, cells[j].first, cells[j].second); fe_val.reinit(cell_it); - cell_t[j] = numbers::invalid_unsigned_int; + cell_t[j] = undefined; // extract quadrature points and store them // temporarily. if we have Cartesian cells, we @@ -700,7 +711,8 @@ namespace MatrixFreeFunctions // and we already have determined that this // cell is either Cartesian or with constant // Jacobian, we have nothing more to do. - if (my_q > 0 && get_cell_type(cell) < 2) + if (my_q > 0 && (get_cell_type(cell) == cartesian + || get_cell_type(cell) == affine) ) continue; // first round: if the transformation is @@ -713,7 +725,7 @@ namespace MatrixFreeFunctions if (j==0) { Assert (cell>0, ExcInternalError()); - cell_t[j] = cell_t_prev[n_vectors-1]; + cell_t[j] = cell_t_prev[vectorization_length-1]; } else cell_t[j] = cell_t[j-1]; @@ -726,7 +738,7 @@ namespace MatrixFreeFunctions // check whether the Jacobian is constant on // this cell the first time we come around // here - if (cell_t[j] == numbers::invalid_unsigned_int) + if (cell_t[j] == undefined) { bool jacobian_constant = true; for (unsigned int q=1; q + MappingInfo::CellData::CellData (const double jac_size_in) + : + jac_size (jac_size_in) + {} + + + + template + void + MappingInfo::CellData::resize (const unsigned int size) + { + if (general_jac.size() != size) + { + quadrature_points.resize(size); + general_jac.resize(size); + general_jac_grad.resize(size); + } + } + template @@ -896,8 +928,8 @@ namespace MatrixFreeFunctions { std::size_t memory= MemoryConsumption::memory_consumption (mapping_data_gen); - memory += MemoryConsumption::memory_consumption (linear); - memory += MemoryConsumption::memory_consumption (cartesian); + memory += MemoryConsumption::memory_consumption (affine_data); + memory += MemoryConsumption::memory_consumption (cartesian_data); memory += MemoryConsumption::memory_consumption (cell_type); memory += sizeof (this); return memory; @@ -911,8 +943,9 @@ namespace MatrixFreeFunctions (STREAM &out, const SizeInfo &size_info) const { - // print_mem involves global communication, so - // we can disable the check here only if no + // print_memory_statistics involves + // global communication, so we can + // disable the check here only if no // processor has any such data #if DEAL_II_COMPILER_SUPPORTS_MPI unsigned int general_size_glob = 0, general_size_loc = jacobians.size(); @@ -924,15 +957,13 @@ namespace MatrixFreeFunctions if (general_size_glob > 0) { out << " Memory Jacobian data: "; - size_info.print_mem (out, - MemoryConsumption::memory_consumption (jacobians) - + - MemoryConsumption::memory_consumption (JxW_values)); + size_info.print_memory_statistics + (out, MemoryConsumption::memory_consumption (jacobians) + + MemoryConsumption::memory_consumption (JxW_values)); out << " Memory second derivative data: "; - size_info.print_mem (out, - MemoryConsumption::memory_consumption (jacobians_grad_diag) - + - MemoryConsumption::memory_consumption (jacobians_grad_upper)); + size_info.print_memory_statistics + (out,MemoryConsumption::memory_consumption (jacobians_grad_diag) + + MemoryConsumption::memory_consumption (jacobians_grad_upper)); } #if DEAL_II_COMPILER_SUPPORTS_MPI @@ -945,10 +976,9 @@ namespace MatrixFreeFunctions if (quad_size_glob > 0) { out << " Memory quadrature points: "; - size_info.print_mem (out, - MemoryConsumption::memory_consumption (rowstart_q_points) - + - MemoryConsumption::memory_consumption (quadrature_points)); + size_info.print_memory_statistics + (out, MemoryConsumption::memory_consumption (rowstart_q_points) + + MemoryConsumption::memory_consumption (quadrature_points)); } } @@ -960,10 +990,12 @@ namespace MatrixFreeFunctions const SizeInfo &size_info) const { out << " Cell types: "; - size_info.print_mem (out, MemoryConsumption::memory_consumption (cell_type)); + size_info.print_memory_statistics + (out, MemoryConsumption::memory_consumption (cell_type)); out << " Memory transformations compr: "; - size_info.print_mem (out, MemoryConsumption::memory_consumption (linear) + - MemoryConsumption::memory_consumption (cartesian)); + size_info.print_memory_statistics + (out, MemoryConsumption::memory_consumption (affine_data) + + MemoryConsumption::memory_consumption (cartesian_data)); for (unsigned int j=0; j #include #include -#include +#include #include #include @@ -56,6 +56,11 @@ DEAL_II_NAMESPACE_OPEN * matrix-vector products or residual computations on the same * mesh. The class is used in step-37 and step-48. * + * This class does not implement any operations involving finite element basis + * functions, i.e., regarding the operation performed on the cells. For these + * operations, the class FEEvaluation is designed to use the data collected in + * this class. + * * The stored data can be subdivided into three main components: * * - DoFInfo: It stores how local degrees of freedom relate to global degrees @@ -66,7 +71,7 @@ DEAL_II_NAMESPACE_OPEN * are necessary in order to build derivatives of finite element functions * and find location of quadrature weights in physical space. * - * - FEEvaluationData: It contains the shape functions of the finite element, + * - ShapeInfo: It contains the shape functions of the finite element, * evaluated on the unit cell. * * Besides the initialization routines, this class implements only a @@ -307,6 +312,10 @@ public: bool initialize_mapping; }; + /** + * @name 1: Construction and initialization + */ + //@{ /** * Default empty constructor. Does * nothing. @@ -506,6 +515,12 @@ public: */ void clear(); + //@} + + /** + * @name 2: Loop over cells + */ + //@{ /** * This method runs the loop over all * cells (in parallel) and performs @@ -579,33 +594,46 @@ public: const InVector &src) const; /** - * Returns an approximation of the memory - * consumption of this class in bytes. + * In the hp adaptive case, a subrange of + * cells as computed during the cell loop + * might contain elements of different + * degrees. Use this function to compute what + * the subrange for an individual finite + * element degree is. The finite element + * degree is associated to the vector + * component given in the function call. */ - std::size_t memory_consumption() const; + std::pair + create_cell_subrange_hp (const std::pair &range, + const unsigned int fe_degree, + const unsigned int vector_component = 0) const; /** - * Prints a detailed summary of memory - * consumption in the different structures of - * this class to the given output stream. + * In the hp adaptive case, a subrange of + * cells as computed during the cell loop + * might contain elements of different + * degrees. Use this function to compute what + * the subrange for a given index the hp + * finite element, as opposed to the finite + * element degree in the other function. */ - template - void print_memory_consumption(STREAM &out) const; + std::pair + create_cell_subrange_hp_by_index (const std::pair &range, + const unsigned int fe_index, + const unsigned int vector_component = 0) const; + + //@} /** - * Prints a summary of this class to the given - * output stream. It is focused on the - * indices, and does not print all the data - * stored. + * @name 3: Initialization of vectors */ - void print (std::ostream &out) const; - + //@{ /** * Initialize function for a general * vector. The length of the vector is equal * to the total number of degrees in the * DoFHandler. If the vector is of class - * parallel::distributed::Vector, the ghost + * parallel::distributed::Vector@, the ghost * entries are set accordingly. For * vector-valued problems with several * DoFHandlers underlying this class, the @@ -621,7 +649,7 @@ public: * vector. The length of the vector is equal * to the total number of degrees in the * DoFHandler. If the vector is of class - * parallel::distributed::Vector, the ghost + * parallel::distributed::Vector@, the ghost * entries are set accordingly. For * vector-valued problems with several * DoFHandlers underlying this class, the @@ -636,11 +664,35 @@ public: * Returns the partitioner that represents the * locally owned data and the ghost indices * where access is needed to for the cell - * loop. + * loop. The partitioner is constructed from + * the locally owned dofs and ghost dofs given + * by the respective fields. If you want to + * have specific information about these + * objects, you can query them with the + * respective access functions. If you just + * want to initialize a (parallel) vector, you + * should usually prefer this data structure + * as the data exchange information can be + * reused from one vector to another. */ const std_cxx1x::shared_ptr& get_vector_partitioner (const unsigned int vector_component=0) const; + /** + * Returns the set of cells that are + * oned by the processor. + */ + const IndexSet & + get_locally_owned_set (const unsigned int fe_component = 0) const; + + /** + * Returns the set of ghost cells + * needed but not owned by the + * processor. + */ + const IndexSet & + get_ghost_set (const unsigned int fe_component = 0) const; + /** * Returns a list of all degrees of freedom * that are constrained. The list is returned @@ -653,34 +705,6 @@ public: const std::vector & get_constrained_dofs (const unsigned int fe_component = 0) const; - /** - * In the hp adaptive case, a subrange of - * cells as computed during the cell loop - * might contain elements of different - * degrees. Use this function to compute what - * the subrange for an individual finite - * element degree is. The finite element - * degree is associated to the vector - * component given in the function call. - */ - std::pair - create_cell_subrange_hp (const std::pair &range, - const unsigned int fe_degree, - const unsigned int vector_component = 0) const; - - /** - * In the hp adaptive case, a subrange of - * cells as computed during the cell loop - * might contain elements of different - * degrees. Use this function to compute what - * the subrange for a given index the hp - * finite element, as opposed to the finite - * element degree in the other function. - */ - std::pair - create_cell_subrange_hp_by_index (const std::pair &range, - const unsigned int fe_index, - const unsigned int vector_component = 0) const; /** * Calls renumber_dofs function in dof * info which renumbers the the @@ -690,19 +714,17 @@ public: void renumber_dofs (std::vector &renumbering, const unsigned int vector_component = 0); - unsigned int n_components () const; + //@} /** - * Returns information on task graph. + * @name 4: General information */ - const internal::MatrixFreeFunctions::TaskInfo & - get_task_info () const; - + //@{ /** - * Returns information on system size. + * Returns the number of different DoFHandlers + * specified at initialization. */ - const internal::MatrixFreeFunctions::SizeInfo & - get_size_info () const; + unsigned int n_components () const; /** * Returns the number of cells this structure @@ -718,46 +740,26 @@ public: unsigned int n_physical_cells () const; /** - * Returns the number of macro cells that this - * structure works on, i.e., the number of - * cell chunks that are worked on after the - * application of vectorization which in - * general works on several cells at once. The - * cell range in @p cell_loop runs from zero - * to n_macro_cells() (exclusive), so this is - * the appropriate size if you want to store - * arrays of data for all cells to be worked - * on. This number is approximately - * n_physical_cells()/VectorizedArray::n_array_elements - * (depending on how many cells are not filled - * up completely). + * Returns the number of macro cells + * that this structure works on, i.e., + * the number of cell chunks that are + * worked on after the application of + * vectorization which in general + * works on several cells at once. The + * cell range in @p cell_loop runs + * from zero to n_macro_cells() + * (exclusive), so this is the + * appropriate size if you want to + * store arrays of data for all cells + * to be worked on. This number is + * approximately + * n_physical_cells()/VectorizedArray@::n_array_elements + * (depending on how many cell chunks + * that do not get filled up + * completely). */ unsigned int n_macro_cells () const; - /* - * Returns geometry-dependent - * information on the cells. - */ - - const internal::MatrixFreeFunctions::MappingInfo & - get_mapping_info () const; - - /** - * Returns information on indexation - * degrees of freedom. - */ - - const internal::MatrixFreeFunctions::DoFInfo & - get_dof_info (const unsigned int fe_component = 0) const; - - /* - * Returns the constraint pool holding - * all the constraints in the mesh. - */ - - const internal::MatrixFreeFunctions::CompressedMatrix & - get_constraint_pool () const; - /** * In case this structure was built based on a * DoFHandler, this returns the @@ -864,7 +866,7 @@ public: * mixed with deal.II access to cells, * care needs to be taken. This * function returns @p true if not all - * @p n_vectors cells for the given @p + * @p vectorization_length cells for the given @p * macro_cell are real cells. To find * out how many cells are actually * used, use the function @p @@ -879,7 +881,7 @@ public: * vectorization data types correspond * to real cells in the mesh. For most * given @p macro_cells, this is just - * @p n_vectors many, but there might + * @p vectorization_length many, but there might * be one or a few meshes (where the * numbers do not add up) where there * are less such components filled, @@ -925,31 +927,6 @@ public: get_n_q_points_face (const unsigned int quad_index = 0, const unsigned int hp_active_fe_index = 0) const; - /** - * Returns the set of cells that are - * oned by the processor. - */ - const IndexSet & - get_locally_owned_set (const unsigned int fe_component = 0) const; - - /** - * Returns the set of ghost cells - * needed but not owned by the - * processor. - */ - const IndexSet & - get_ghost_set (const unsigned int fe_component = 0) const; - - /** - * Returns the unit cell information - * for given hp index. - */ - const internal::MatrixFreeFunctions::FEEvaluationData & - get_fe_evaluation (const unsigned int fe_component = 0, - const unsigned int quad_index = 0, - const unsigned int hp_active_fe_index = 0, - const unsigned int hp_active_quad_index = 0) const; - /** * Returns the quadrature rule for * given hp index. @@ -972,13 +949,99 @@ public: bool mapping_initialized () const; + /** + * Returns an approximation of the memory + * consumption of this class in bytes. + */ + std::size_t memory_consumption() const; + + /** + * Prints a detailed summary of memory + * consumption in the different structures of + * this class to the given output stream. + */ + template + void print_memory_consumption(STREAM &out) const; + + /** + * Prints a summary of this class to the given + * output stream. It is focused on the + * indices, and does not print all the data + * stored. + */ + void print (std::ostream &out) const; + + //@} + + /** + * @name 5: Access of internal data structure (expert mode) + */ + //@{ + /** + * Returns information on task graph. + */ + const internal::MatrixFreeFunctions::TaskInfo & + get_task_info () const; + + /** + * Returns information on system size. + */ + const internal::MatrixFreeFunctions::SizeInfo & + get_size_info () const; + + /* + * Returns geometry-dependent + * information on the cells. + */ + const internal::MatrixFreeFunctions::MappingInfo & + get_mapping_info () const; + + /** + * Returns information on indexation + * degrees of freedom. + */ + const internal::MatrixFreeFunctions::DoFInfo & + get_dof_info (const unsigned int fe_component = 0) const; + + /** + * Returns a pointer to the first + * number in the constraint pool data + * with index @p pool_index (to + * be used together with @p + * constraint_pool_end()). + */ + const Number* + constraint_pool_begin (const unsigned int pool_index) const; + + /** + * Returns a pointer to one past the + * last number in the constraint pool + * data with index @p pool_index (to + * be used together with @p + * constraint_pool_begin()). + */ + const Number* + constraint_pool_end (const unsigned int pool_index) const; + + /** + * Returns the unit cell information + * for given hp index. + */ + const internal::MatrixFreeFunctions::ShapeInfo & + get_shape_info (const unsigned int fe_component = 0, + const unsigned int quad_index = 0, + const unsigned int hp_active_fe_index = 0, + const unsigned int hp_active_quad_index = 0) const; + + //@} + private: - /** - * This is the actual reinit function - * that sets up the indices for the - * DoFHandler and MGDoFHandler case. - */ + /** + * This is the actual reinit function + * that sets up the indices for the + * DoFHandler and MGDoFHandler case. + */ template void internal_reinit (const Mapping &mapping, const std::vector &dof_handler, @@ -987,10 +1050,10 @@ private: const std::vector > &quad, const AdditionalData additional_data); - /** - * Same as before but for hp::DoFHandler - * instead of generic DoFHandler type. - */ + /** + * Same as before but for hp::DoFHandler + * instead of generic DoFHandler type. + */ void internal_reinit (const Mapping &mapping, const std::vector*> &dof_handler, const std::vector &constraint, @@ -999,8 +1062,14 @@ private: const AdditionalData additional_data); /** - * Initializes the fields in DoFInfo together - * with @p constraint_pool. + * Initializes the fields in DoFInfo + * together with the constraint pool + * that holds all different weights in + * the constraints (not part of + * DoFInfo because several DoFInfo + * classes can have the same weights + * which consequently only need to be + * stored once). */ void initialize_indices (const std::vector &constraint, @@ -1066,7 +1135,14 @@ private: * arguments on DoFInfo and keeps it a plain * field of indices only. */ - internal::MatrixFreeFunctions::CompressedMatrix constraint_pool; + std::vector constraint_pool_data; + + /** + * Contains an indicator to the start + * of the ith index in the constraint + * pool data. + */ + std::vector constraint_pool_row_index; /** * Holds information on transformation of @@ -1079,7 +1155,7 @@ private: * Contains shape value information on the * unit cell. */ - Table<4,internal::MatrixFreeFunctions::FEEvaluationData > fe_evaluation_data; + Table<4,internal::MatrixFreeFunctions::ShapeInfo > shape_info; /** * Describes how the cells are gone @@ -1248,10 +1324,22 @@ MatrixFree::get_dof_info (unsigned int dof_index) const template inline -const internal::MatrixFreeFunctions::CompressedMatrix & -MatrixFree::get_constraint_pool () const +const Number* +MatrixFree::constraint_pool_begin (const unsigned int row) const +{ + AssertIndexRange (row, constraint_pool_row_index.size()-1); + return &constraint_pool_data[0] + constraint_pool_row_index[row]; +} + + + +template +inline +const Number* +MatrixFree::constraint_pool_end (const unsigned int row) const { - return constraint_pool; + AssertIndexRange (row, constraint_pool_row_index.size()-1); + return &constraint_pool_data[0] + constraint_pool_row_index[row+1]; } @@ -1383,11 +1471,11 @@ MatrixFree::get_cell_iterator(const unsigned int macro_cell_number, const unsigned int vector_number, const unsigned int dof_index) const { - const unsigned int n_vectors=VectorizedArray::n_array_elements; + const unsigned int vectorization_length=VectorizedArray::n_array_elements; #ifdef DEBUG AssertIndexRange (dof_index, dof_handlers.n_dof_handlers); AssertIndexRange (macro_cell_number, size_info.n_macro_cells); - AssertIndexRange (vector_number, n_vectors); + AssertIndexRange (vector_number, vectorization_length); const unsigned int irreg_filled = std_cxx1x::get<2>(dof_info[dof_index].row_starts[macro_cell_number]); if (irreg_filled > 0) @@ -1417,7 +1505,7 @@ MatrixFree::get_cell_iterator(const unsigned int macro_cell_number, } std::pair index = - cell_level_index[macro_cell_number*n_vectors+vector_number]; + cell_level_index[macro_cell_number*vectorization_length+vector_number]; return typename DoFHandler::active_cell_iterator (&dofh->get_tria(), index.first, index.second, dofh); } @@ -1431,11 +1519,11 @@ MatrixFree::get_mg_cell_iterator(const unsigned int macro_cell_numbe const unsigned int vector_number, const unsigned int dof_index) const { - const unsigned int n_vectors=VectorizedArray::n_array_elements; + const unsigned int vectorization_length=VectorizedArray::n_array_elements; #ifdef DEBUG AssertIndexRange (dof_index, dof_handlers.n_dof_handlers); AssertIndexRange (macro_cell_number, size_info.n_macro_cells); - AssertIndexRange (vector_number, n_vectors); + AssertIndexRange (vector_number, vectorization_length); const unsigned int irreg_filled = std_cxx1x::get<2>(dof_info[dof_index].row_starts[macro_cell_number]); if (irreg_filled > 0) @@ -1447,7 +1535,7 @@ MatrixFree::get_mg_cell_iterator(const unsigned int macro_cell_numbe const MGDoFHandler * dofh = dof_handlers.mg_dof_handler[dof_index]; std::pair index = - cell_level_index[macro_cell_number*n_vectors+vector_number]; + cell_level_index[macro_cell_number*vectorization_length+vector_number]; return typename MGDoFHandler::cell_iterator (&dofh->get_tria(), index.first, index.second, dofh); } @@ -1461,11 +1549,11 @@ MatrixFree::get_hp_cell_iterator(const unsigned int macro_cell_numbe const unsigned int vector_number, const unsigned int dof_index) const { - const unsigned int n_vectors=VectorizedArray::n_array_elements; + const unsigned int vectorization_length=VectorizedArray::n_array_elements; #ifdef DEBUG AssertIndexRange (dof_index, dof_handlers.n_dof_handlers); AssertIndexRange (macro_cell_number, size_info.n_macro_cells); - AssertIndexRange (vector_number, n_vectors); + AssertIndexRange (vector_number, vectorization_length); const unsigned int irreg_filled = std_cxx1x::get<2>(dof_info[dof_index].row_starts[macro_cell_number]); if (irreg_filled > 0) @@ -1476,7 +1564,7 @@ MatrixFree::get_hp_cell_iterator(const unsigned int macro_cell_numbe ExcNotImplemented()); const hp::DoFHandler * dofh = dof_handlers.hp_dof_handler[dof_index]; std::pair index = - cell_level_index[macro_cell_number*n_vectors+vector_number]; + cell_level_index[macro_cell_number*vectorization_length+vector_number]; return typename hp::DoFHandler::cell_iterator (&dofh->get_tria(), index.first, index.second, dofh); } @@ -1584,18 +1672,18 @@ MatrixFree::get_ghost_set(const unsigned int dof_index) const template inline -const internal::MatrixFreeFunctions::FEEvaluationData & -MatrixFree::get_fe_evaluation(const unsigned int index_fe, - const unsigned int index_quad, - const unsigned int active_fe_index, - const unsigned int active_quad_index) const +const internal::MatrixFreeFunctions::ShapeInfo & +MatrixFree::get_shape_info (const unsigned int index_fe, + const unsigned int index_quad, + const unsigned int active_fe_index, + const unsigned int active_quad_index) const { - AssertIndexRange (index_fe, fe_evaluation_data.size(0)); - AssertIndexRange (index_quad, fe_evaluation_data.size(1)); - AssertIndexRange (active_fe_index, fe_evaluation_data.size(2)); - AssertIndexRange (active_quad_index, fe_evaluation_data.size(3)); - return fe_evaluation_data(index_fe, index_quad, - active_fe_index, active_quad_index); + AssertIndexRange (index_fe, shape_info.size(0)); + AssertIndexRange (index_quad, shape_info.size(1)); + AssertIndexRange (active_fe_index, shape_info.size(2)); + AssertIndexRange (active_quad_index, shape_info.size(3)); + return shape_info(index_fe, index_quad, + active_fe_index, active_quad_index); } @@ -2008,8 +2096,8 @@ namespace internal tbb::task* execute () { std::pair cell_range - (task_info.partition_color_blocks.data[partition], - task_info.partition_color_blocks.data[partition+1]); + (task_info.partition_color_blocks_data[partition], + task_info.partition_color_blocks_data[partition+1]); worker(cell_range); if(blocked==true) dummy->spawn (*dummy); @@ -2043,10 +2131,10 @@ namespace internal if(false) { std::pair cell_range - (task_info.partition_color_blocks.data - [task_info.partition_color_blocks.row_index[partition]], - task_info.partition_color_blocks.data - [task_info.partition_color_blocks.row_index[partition+1]]); + (task_info.partition_color_blocks_data + [task_info.partition_color_blocks_row_index[partition]], + task_info.partition_color_blocks_data + [task_info.partition_color_blocks_row_index[partition+1]]); function(cell_range); } else @@ -2066,9 +2154,8 @@ namespace internal { worker[j] = new(root->allocate_child()) CellWork(function,task_info. - partition_color_blocks. - row_index[partition]+ - 2*j,task_info); + partition_color_blocks_row_index + [partition] + 2*j, task_info); if(j>0) { worker[j]->set_ref_count(2); @@ -2082,9 +2169,8 @@ namespace internal { blocked_worker[j] = new(worker[j]->allocate_child()) CellWork(function,task_info. - partition_color_blocks. - row_index[partition]+ - 2*j+1,task_info); + partition_color_blocks_row_index + [partition] + 2*j+1, task_info); } else { @@ -2093,9 +2179,8 @@ namespace internal worker[evens] = new(worker[j]->allocate_child()) CellWork(function, task_info. - partition_color_blocks. - row_index[partition]+ - 2*j+1,task_info); + partition_color_blocks_row_index + [partition]+2*j+1,task_info); worker[j]->spawn(*worker[evens]); } else @@ -2180,8 +2265,8 @@ namespace internal {}; tbb::task* execute () { - unsigned int lower = task_info.partition_color_blocks.data[partition], - upper = task_info.partition_color_blocks.data[partition+1]; + unsigned int lower = task_info.partition_color_blocks_data[partition], + upper = task_info.partition_color_blocks_data[partition+1]; parallel_for(tbb::blocked_range(lower,upper,1), CellWork (worker,task_info)); if(blocked==true) @@ -2368,7 +2453,7 @@ MatrixFree::cell_loop tbb::empty_task* root = new( tbb::task::allocate_root() ) tbb::empty_task; root->set_ref_count(evens+1); unsigned int n_blocked_workers = odds-(odds+evens+1)%2; - unsigned int n_workers = task_info.partition_color_blocks.data.size()-1- + unsigned int n_workers = task_info.partition_color_blocks_data.size()-1- n_blocked_workers; std::vector*> worker(n_workers); std::vector*> blocked_worker(n_blocked_workers); @@ -2379,7 +2464,7 @@ MatrixFree::cell_loop internal::MPIComCompress(dst); worker_compr->set_ref_count(1); for (unsigned int part=0; - part::cell_loop worker[worker_index] = new(root->allocate_child()) internal::color::PartitionWork(func,slice_index,task_info); slice_index++; - for(;slice_indexset_ref_count(1); @@ -2419,15 +2504,15 @@ MatrixFree::cell_loop worker_index++; } part += 1; - if(partallocate_child()) internal::color::PartitionWork(func,slice_index,task_info); slice_index++; if(slice_index< - task_info.partition_color_blocks.row_index[part+1]) + task_info.partition_color_blocks_row_index[part+1]) { blocked_worker[part/2]->set_ref_count(1); worker[worker_index] = new(blocked_worker[part/2]->allocate_child()) @@ -2440,11 +2525,11 @@ MatrixFree::cell_loop continue; } } - for(;slice_index - task_info.partition_color_blocks.row_index[part]) + task_info.partition_color_blocks_row_index[part]) { worker[worker_index]->set_ref_count(1); worker_index++; @@ -2477,11 +2562,11 @@ MatrixFree::cell_loop internal::update_ghost_values_finish(src); for (unsigned int color=0; - color < task_info.partition_color_blocks.row_index[1]; + color < task_info.partition_color_blocks_row_index[1]; ++color) { - unsigned int lower = task_info.partition_color_blocks.data[color], - upper = task_info.partition_color_blocks.data[color+1]; + unsigned int lower = task_info.partition_color_blocks_data[color], + upper = task_info.partition_color_blocks_data[color+1]; parallel_for(tbb::blocked_range(lower,upper,1), internal::color::CellWork (func,task_info)); diff --git a/deal.II/include/deal.II/matrix_free/matrix_free.templates.h b/deal.II/include/deal.II/matrix_free/matrix_free.templates.h index aaddd916d1..675f5679ae 100644 --- a/deal.II/include/deal.II/matrix_free/matrix_free.templates.h +++ b/deal.II/include/deal.II/matrix_free/matrix_free.templates.h @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include @@ -54,9 +54,10 @@ copy_from (const MatrixFree &v) clear (); dof_handlers = v.dof_handlers; dof_info = v.dof_info; - constraint_pool = v.constraint_pool; + constraint_pool_data = v.constraint_pool_data; + constraint_pool_row_index = v.constraint_pool_row_index; mapping_info = v.mapping_info; - fe_evaluation_data = v.fe_evaluation_data; + shape_info = v.shape_info; cell_level_index = v.cell_level_index; task_info = v.task_info; size_info = v.size_info; @@ -156,7 +157,7 @@ internal_reinit(const Mapping &mapping, // set dof_indices together with // constraint_indicator and - // constraint_pool. It also reorders the way + // constraint_pool_data. It also reorders the way // cells are gone through (to separate cells // with overlap to other processors from // others without). @@ -168,14 +169,14 @@ internal_reinit(const Mapping &mapping, // Hessians for quadrature points. const unsigned int n_fe = dof_handler.size(); const unsigned int n_quad = quad.size(); - fe_evaluation_data.reinit (TableIndices<4>(n_fe, n_quad, 1, 1)); + shape_info.reinit (TableIndices<4>(n_fe, n_quad, 1, 1)); for (unsigned int no=0; no &fe = dof_handler[no]->get_fe(); for(unsigned int nq =0;nq &mapping, // set dof_indices together with // constraint_indicator and - // constraint_pool. It also reorders the way + // constraint_pool_data. It also reorders the way // cells are gone through (to separate cells // with overlap to other processors from // others without). @@ -273,17 +274,17 @@ internal_reinit(const Mapping &mapping, unsigned int n_quad_in_collection = 0; for (unsigned int q=0; q(n_components, n_quad, - n_fe_in_collection, - n_quad_in_collection)); + shape_info.reinit (TableIndices<4>(n_components, n_quad, + n_fe_in_collection, + n_quad_in_collection)); for (unsigned int no=0; noget_fe().size(); ++fe_no) { const FiniteElement &fe = dof_handler[no]->get_fe()[fe_no]; for(unsigned int nq =0; nq::initialize_indices std::vector > ghost_dofs(n_fe); std::vector > > lexicographic_inv(n_fe); - internal::MatrixFreeFunctions::internal::ConstraintValues constraint_values; + internal::MatrixFreeFunctions::ConstraintValues constraint_values; std::vector constraint_indices; for(unsigned int no=0; no::initialize_indices ExcMessage ("MatrixFree only works for DoFHandler with one base element")); const unsigned int n_fe_components = fe.element_multiplicity (0); - // cache number of finite elements and - // dofs_per_cell + // cache number of finite elements and + // dofs_per_cell dof_info[no].dofs_per_cell.push_back (fe.dofs_per_cell); dof_info[no].dofs_per_face.push_back (fe.dofs_per_face); dof_info[no].n_components = n_fe_components; - // get permutation that gives lexicographic - // renumbering of the cell dofs - // renumber (this is necessary for FE_Q, for - // example, since there the vertex DoFs come - // first, which is incompatible with the - // lexicographic ordering necessary to apply - // tensor products efficiently) - const FE_Poly,dim,dim> *cast_fe = + // get permutation that gives lexicographic + // renumbering of the cell dofs + // renumber (this is necessary for FE_Q, for + // example, since there the vertex DoFs come + // first, which is incompatible with the + // lexicographic ordering necessary to apply + // tensor products efficiently) + const FE_Poly,dim,dim> *fe_poly = dynamic_cast,dim,dim>*> (&fe.base_element(0)); - // This class currently only works for - // elements derived from - // FE_Poly,dim,dim>. - // For any other element, the dynamic cast - // above will fail and give cast_fe == 0. - Assert (cast_fe != 0, ExcNotImplemented()); - - // create a derived finite element that gives - // us access to the inverse numbering (which - // we need in order to get a lexicographic - // ordering of local degrees of freedom) - const internal::MatrixFreeFunctions::internal::FE_PolyAccess&fe_acc = - static_cast &>(*cast_fe); + + // This class currently only works for + // elements derived from + // FE_Poly,dim,dim>. + // For any other element, the dynamic cast + // above will fail and give fe_poly == 0. + Assert (fe_poly != 0, ExcNotImplemented()); if (n_fe_components == 1) { - lexicographic_inv[no][fe_index] = fe_acc.get_numbering_inverse(); + lexicographic_inv[no][fe_index] = + fe_poly->get_poly_space_numbering_inverse(); AssertDimension (lexicographic_inv[no][fe_index].size(), dof_info[no].dofs_per_cell[fe_index]); } else { - // ok, we have more than one component + // ok, we have more than one component Assert (n_fe_components > 1, ExcInternalError()); - std::vector scalar_lex=fe_acc.get_numbering(); + std::vector scalar_lex = + fe_poly->get_poly_space_numbering(); AssertDimension (scalar_lex.size() * n_fe_components, dof_info[no].dofs_per_cell[fe_index]); - lexicographic_inv[no][fe_index].resize (dof_info[no].dofs_per_cell[fe_index]); std::vector lexicographic (dof_info[no].dofs_per_cell[fe_index]); for (unsigned int comp=0; comp::initialize_indices boundary_cells.push_back(counter); } - // try to make the number of boundary cells - // divisible by the number of vectors in - // vectorization - const unsigned int n_vectors = VectorizedArray::n_array_elements; - { - unsigned int n_max_boundary_cells = boundary_cells.size(); - unsigned int n_boundary_cells = n_max_boundary_cells; - - /* - // try to balance the number of cells before - // and after the boundary part on each - // processor. probably not worth it! -#if DEAL_II_COMPILER_SUPPORTS_MPI - MPI_Allreduce (&n_boundary_cells, &n_max_boundary_cells, 1, MPI_UNSIGNED, - MPI_MAX, size_info.communicator); -#endif - if (n_max_boundary_cells > n_active_cells) - n_max_boundary_cells = n_active_cells; - */ - - unsigned int fillup_needed = - (n_vectors - n_boundary_cells%n_vectors)%n_vectors; - /* - if (task_info.use_multithreading == true) - fillup_needed = - (n_vectors - n_boundary_cells%n_vectors)%n_vectors; - else - fillup_needed = (n_max_boundary_cells + - (n_vectors - n_max_boundary_cells%n_vectors)%n_vectors - - n_boundary_cells); - */ - if (fillup_needed > 0 && n_boundary_cells < n_active_cells) - { - // fill additional cells into the list of - // boundary cells to get a balanced number. Go - // through the indices successively until we - // found enough indices - std::vector new_boundary_cells; - new_boundary_cells.reserve (n_max_boundary_cells); - - unsigned int next_free_slot = 0, bound_index = 0; - while (fillup_needed > 0 && bound_index < boundary_cells.size()) - { - if (next_free_slot < boundary_cells[bound_index]) - { - // check if there are enough cells to fill - // with in the current slot - if (next_free_slot + fillup_needed <= boundary_cells[bound_index]) - { - for (unsigned int j=boundary_cells[bound_index]-fillup_needed; - j < boundary_cells[bound_index]; ++j) - new_boundary_cells.push_back(j); - fillup_needed = 0; - } - // ok, not enough indices, so just take them - // all up to the next boundary cell - else - { - for (unsigned int j=next_free_slot; - j 0 && (new_boundary_cells.size()==0 || - new_boundary_cells.back()::n_array_elements; std::vector irregular_cells; - size_info.make_layout (n_active_cells, n_boundary_cells, n_vectors, + size_info.make_layout (n_active_cells, vectorization_length, boundary_cells, irregular_cells); for (unsigned int no=0; no renumbering (n_active_cells, - numbers::invalid_unsigned_int); - { - std::vector reverse_numbering (n_active_cells, - numbers::invalid_unsigned_int); - unsigned int counter; - if (task_info.use_multithreading == true) - { - for (unsigned int j=0; j renumbering; if (task_info.use_multithreading == true) { + dof_info[0].compute_renumber_parallel (boundary_cells, size_info, + renumbering); if(task_info.use_partition_partition == true) dof_info[0].make_thread_graph_partition_partition (size_info, task_info, renumbering, irregular_cells, @@ -853,82 +710,13 @@ void MatrixFree::initialize_indices // In case, we have an hp-dofhandler, we have // to reorder the cell according to the // polynomial degree on the cell. + dof_info[0].compute_renumber_serial (boundary_cells, size_info, + renumbering); if (dof_handlers.active_dof_handler == DoFHandlers::hp) - { - const unsigned int max_fe_index = - dof_info[0].max_fe_index; - irregular_cells.resize (0); - irregular_cells.resize (size_info.n_macro_cells+3*max_fe_index); - const std::vector &cell_active_fe_index = - dof_info[0].cell_active_fe_index; - std::vector > renumbering_fe_index; - renumbering_fe_index.resize(max_fe_index); - unsigned int counter,n_macro_cells_before = 0; - const unsigned int - start_bound = std::min (size_info.n_active_cells, - size_info.boundary_cells_start*n_vectors), - end_bound = std::min (size_info.n_active_cells, - size_info.boundary_cells_end*n_vectors); - for(counter=0; counter::initialize_indices std::vector > cell_level_index_old; cell_level_index.swap (cell_level_index_old); - cell_level_index.reserve(size_info.n_macro_cells*n_vectors); + cell_level_index.reserve(size_info.n_macro_cells*vectorization_length); unsigned int position_cell=0; for (unsigned int i=0; i0)? - irregular_cells[i] : n_vectors; + irregular_cells[i] : vectorization_length; for (unsigned int j=0; j::memory_consumption () const { std::size_t memory = MemoryConsumption::memory_consumption (dof_info); memory += MemoryConsumption::memory_consumption (cell_level_index); - memory += MemoryConsumption::memory_consumption (fe_evaluation_data); - memory += MemoryConsumption::memory_consumption (constraint_pool); + memory += MemoryConsumption::memory_consumption (shape_info); + memory += MemoryConsumption::memory_consumption (constraint_pool_data); + memory += MemoryConsumption::memory_consumption (constraint_pool_row_index); memory += MemoryConsumption::memory_consumption (task_info); memory += sizeof(this); memory += mapping_info.memory_consumption(); @@ -1024,9 +813,10 @@ template void MatrixFree::print_memory_consumption (STREAM &out) const { out << " Memory cell FE operator total: --> "; - size_info.print_mem (out, memory_consumption()); + size_info.print_memory_statistics (out, memory_consumption()); out << " Memory cell index: "; - size_info.print_mem (out, MemoryConsumption::memory_consumption (cell_level_index)); + size_info.print_memory_statistics + (out, MemoryConsumption::memory_consumption (cell_level_index)); for (unsigned int j=0; j::print_memory_consumption (STREAM &out) const mapping_info.print_memory_consumption(out, size_info); out << " Memory unit cell shape data: "; - size_info.print_mem (out, MemoryConsumption::memory_consumption (fe_evaluation_data)); + size_info.print_memory_statistics + (out, MemoryConsumption::memory_consumption (shape_info)); if (task_info.use_multithreading == true) { out << " Memory task partitioning info: "; - size_info.print_mem (out, MemoryConsumption::memory_consumption (task_info)); + size_info.print_memory_statistics + (out, MemoryConsumption::memory_consumption (task_info)); } } @@ -1054,10 +846,272 @@ void MatrixFree::print (std::ostream &out) const for (unsigned int no=0; no + void SizeInfo::print_memory_statistics (STREAM &out, + std::size_t data_length) const + { + Utilities::MPI::MinMaxAvg memory_c; + if (Utilities::System::job_supports_mpi() == true) + { + memory_c = Utilities::MPI::min_max_avg (1e-6*data_length, + communicator); + } + else + { + memory_c.sum = 1e-6*data_length; + memory_c.min = memory_c.sum; + memory_c.max = memory_c.sum; + memory_c.avg = memory_c.sum; + memory_c.min_index = 0; + memory_c.max_index = 0; + } + if (n_procs < 2) + out << memory_c.min; + else + out << memory_c.min << "/" << memory_c.avg << "/" << memory_c.max; + out << " MB" << std::endl; + } + + + + inline + void SizeInfo::make_layout (const unsigned int n_active_cells_in, + const unsigned int vectorization_length_in, + std::vector &boundary_cells, + std::vector &irregular_cells) + { + vectorization_length = vectorization_length_in; + n_active_cells = n_active_cells_in; + + unsigned int n_max_boundary_cells = boundary_cells.size(); + unsigned int n_boundary_cells = n_max_boundary_cells; + + // try to make the number of boundary cells + // divisible by the number of vectors in + // vectorization + /* + // try to balance the number of cells before + // and after the boundary part on each + // processor. probably not worth it! +#if DEAL_II_COMPILER_SUPPORTS_MPI + MPI_Allreduce (&n_boundary_cells, &n_max_boundary_cells, 1, MPI_UNSIGNED, + MPI_MAX, size_info.communicator); +#endif + if (n_max_boundary_cells > n_active_cells) + n_max_boundary_cells = n_active_cells; + */ + + unsigned int fillup_needed = + (vectorization_length - n_boundary_cells%vectorization_length)%vectorization_length; + if (fillup_needed > 0 && n_boundary_cells < n_active_cells) + { + // fill additional cells into the list of + // boundary cells to get a balanced number. Go + // through the indices successively until we + // found enough indices + std::vector new_boundary_cells; + new_boundary_cells.reserve (n_max_boundary_cells); + + unsigned int next_free_slot = 0, bound_index = 0; + while (fillup_needed > 0 && bound_index < boundary_cells.size()) + { + if (next_free_slot < boundary_cells[bound_index]) + { + // check if there are enough cells to fill + // with in the current slot + if (next_free_slot + fillup_needed <= boundary_cells[bound_index]) + { + for (unsigned int j=boundary_cells[bound_index]-fillup_needed; + j < boundary_cells[bound_index]; ++j) + new_boundary_cells.push_back(j); + fillup_needed = 0; + } + // ok, not enough indices, so just take them + // all up to the next boundary cell + else + { + for (unsigned int j=next_free_slot; + j 0 && (new_boundary_cells.size()==0 || + new_boundary_cells.back() n_active_cells) + { + irregular_cells[n_macro_cells-1] = + vectorization_length - (n_macro_cells*vectorization_length - n_active_cells); + } + if (n_procs > 1) + { + const unsigned int n_macro_boundary_cells = + (n_boundary_cells+vectorization_length-1)/vectorization_length; + boundary_cells_start = (n_macro_cells-n_macro_boundary_cells)/2; + boundary_cells_end = boundary_cells_start + n_macro_boundary_cells; + } + else + boundary_cells_start = boundary_cells_end = n_macro_cells; + } + + + + HashValue::HashValue (const double element_size) + : + scaling (element_size * std::numeric_limits::epsilon() * + 1024.) + {} + + + + unsigned int HashValue::operator ()(const std::vector &vec) + { + std::vector mod_vec(vec); + for (unsigned int i=0; i(boost::hash_range (mod_vec.begin(), mod_vec.end())); + } + + + template + unsigned int HashValue::operator () + (const Tensor<2,dim,VectorizedArray > &input, + const bool is_diagonal) + { + const unsigned int vectorization_length = + VectorizedArray::n_array_elements; + + if (is_diagonal) + { + number mod_tensor [dim][vectorization_length]; + for (unsigned int i=0; i + (boost::hash_range(&mod_tensor[0][0], + &mod_tensor[0][0]+dim*vectorization_length)); + } + else + { + number mod_tensor [dim][dim][vectorization_length]; + for (unsigned int i=0; i(boost::hash_range + (&mod_tensor[0][0][0], + &mod_tensor[0][0][0]+ + dim*dim*vectorization_length)); + } + } + + } +} + + DEAL_II_NAMESPACE_CLOSE diff --git a/deal.II/include/deal.II/matrix_free/fe_evaluation_data.h b/deal.II/include/deal.II/matrix_free/shape_info.h similarity index 94% rename from deal.II/include/deal.II/matrix_free/fe_evaluation_data.h rename to deal.II/include/deal.II/matrix_free/shape_info.h index 8fce46b7a3..3011e56b03 100644 --- a/deal.II/include/deal.II/matrix_free/fe_evaluation_data.h +++ b/deal.II/include/deal.II/matrix_free/shape_info.h @@ -11,8 +11,8 @@ // //--------------------------------------------------------------------------- -#ifndef __deal2__matrix_free_fe_evaluation_data_h -#define __deal2__matrix_free_fe_evaluation_data_h +#ifndef __deal2__matrix_free_shape_info_h +#define __deal2__matrix_free_shape_info_h #include @@ -38,15 +38,12 @@ namespace MatrixFreeFunctions * @author Katharina Kormann and Martin Kronbichler, 2010, 2011 */ template - struct FEEvaluationData + struct ShapeInfo { - typedef VectorizedArray vector_t; - static const std::size_t n_vectors = VectorizedArray::n_array_elements; - /** * Empty constructor. Does nothing. */ - FEEvaluationData (); + ShapeInfo (); /** * Initializes the data fields. Takes a @@ -90,7 +87,7 @@ namespace MatrixFreeFunctions * quadrature points are the index running * fastest. */ - AlignedVector shape_values; + AlignedVector > shape_values; /** * Stores the shape gradients of the 1D finite @@ -103,7 +100,7 @@ namespace MatrixFreeFunctions * quadrature points are the index running * fastest. */ - AlignedVector shape_gradients; + AlignedVector > shape_gradients; /** * Stores the shape Hessians of the 1D finite @@ -116,7 +113,7 @@ namespace MatrixFreeFunctions * quadrature points are the index running * fastest. */ - AlignedVector shape_hessians; + AlignedVector > shape_hessians; /** * Stores the indices from cell DoFs to face diff --git a/deal.II/include/deal.II/matrix_free/fe_evaluation_data.templates.h b/deal.II/include/deal.II/matrix_free/shape_info.templates.h similarity index 73% rename from deal.II/include/deal.II/matrix_free/fe_evaluation_data.templates.h rename to deal.II/include/deal.II/matrix_free/shape_info.templates.h index 4401cc644e..2dbc45bc0f 100644 --- a/deal.II/include/deal.II/matrix_free/fe_evaluation_data.templates.h +++ b/deal.II/include/deal.II/matrix_free/shape_info.templates.h @@ -18,7 +18,7 @@ #include #include -#include +#include DEAL_II_NAMESPACE_OPEN @@ -28,59 +28,11 @@ namespace internal { namespace MatrixFreeFunctions { - namespace internal - { - - // ----------------- FE_PolyAccess ----------------------------------- - - // in order to read out the 1D info from a - // finite element and use the tensor product - // structure easily, we need to be able to - // access the numbering in the polynomial - // space of the finite element. that - // information is not public, but we can get - // access to that information by creating a - // new dummy class that is based on - // FE_Poly,dim,spacedim> - template - class FE_PolyAccess : public FE_Poly, dim, spacedim> - { - public: - FE_PolyAccess (const FE_Poly,dim,spacedim> &fe) - : - FE_Poly,dim,spacedim>(fe) - {} - - virtual std::string get_name() const - { - Assert (false, ExcNotImplemented()); - return 0; - } - virtual FiniteElement * clone() const - { - Assert (false, ExcNotImplemented()); - return 0; - } - - const std::vector get_numbering () const - { - return this->poly_space.get_numbering(); - } - - const std::vector get_numbering_inverse () const - { - return this->poly_space.get_numbering_inverse(); - } - }; - - } // end of namespace internal - - - // ----------------- actual FEEvaluationData functions -------------------- + // ----------------- actual ShapeInfo functions -------------------- template - FEEvaluationData::FEEvaluationData () + ShapeInfo::ShapeInfo () : n_q_points (0), dofs_per_cell (0) @@ -91,7 +43,7 @@ namespace MatrixFreeFunctions template template void - FEEvaluationData::reinit (const Quadrature<1> &quad, + ShapeInfo::reinit (const Quadrature<1> &quad, const FiniteElement &fe_dim) { Assert (fe_dim.n_components() == 1, @@ -115,7 +67,7 @@ namespace MatrixFreeFunctions template void - FEEvaluationData::do_initialize (const Quadrature<1> &quad, + ShapeInfo::do_initialize (const Quadrature<1> &quad, const FiniteElement<1> &fe, const unsigned int dim) { @@ -129,12 +81,10 @@ namespace MatrixFreeFunctions // lexicographic ordering necessary to apply // tensor products efficiently) { - const FE_Poly,1,1> *cast_fe = + const FE_Poly,1,1> *fe_poly = dynamic_cast,1,1>*>(&fe); - Assert (cast_fe != 0, ExcNotImplemented()); - const internal::FE_PolyAccess<1,1> & fe_acc = - static_cast< const internal::FE_PolyAccess<1,1> &>(*cast_fe); - lexicographic = fe_acc.get_numbering(); + Assert (fe_poly != 0, ExcNotImplemented()); + lexicographic = fe_poly->get_poly_space_numbering(); } n_q_points = 1; @@ -171,9 +121,10 @@ namespace MatrixFreeFunctions const unsigned int my_i = lexicographic[i]; for (unsigned int q=0; q::n_array_elements + // copies for the shape information and + // non-vectorized fields const Point<1> q_point = quad.get_points()[q]; shape_values_number[my_i*n_q_points_1d+q] = fe.shape_value(i,q_point); shape_gradient_number[my_i*n_q_points_1d+q] = fe.shape_grad (i,q_point)[0]; @@ -239,7 +190,7 @@ namespace MatrixFreeFunctions template std::size_t - FEEvaluationData::memory_consumption () const + ShapeInfo::memory_consumption () const { std::size_t memory = sizeof(*this); memory += MemoryConsumption::memory_consumption(shape_values); @@ -256,7 +207,7 @@ namespace MatrixFreeFunctions return memory; } - // end of functions for FEEvaluationData + // end of functions for ShapeInfo } // end of namespace MatrixFreeFunctions } // end of namespace internal diff --git a/deal.II/source/lac/constraint_matrix.inst.pl b/deal.II/source/lac/constraint_matrix.inst.pl index af0f37d0c0..7e47773f01 100644 --- a/deal.II/source/lac/constraint_matrix.inst.pl +++ b/deal.II/source/lac/constraint_matrix.inst.pl @@ -26,7 +26,7 @@ template void ConstraintMatrix::distribute(V1 &) const; EOT ; -my $vector_functions_also_parallel = <(V1&) const; @@ -56,6 +56,7 @@ EOT ###################################################################### multisubst($vector_functions, ['V1'], \@sequential_vectors); +multisubst($vector_functions, ['V1'], \@deal_parallel_vectors); multisubst($vector_functions_also_parallel, ['V1'], \@sequential_vectors); multisubst($vector_functions_also_parallel, ['V1'], \@parallel_vectors); multisubst($scalar_functions, ['S1'], \@real_scalars); diff --git a/tests/fe/injection_q/cmp/generic b/tests/fe/injection_q/cmp/generic index 1c1250a3f6..18b255ef78 100644 --- a/tests/fe/injection_q/cmp/generic +++ b/tests/fe/injection_q/cmp/generic @@ -20604,7 +20604,7 @@ DEAL::27 22 -0.0521 DEAL::27 23 0.156 DEAL::27 24 0.312 DEAL::27 25 -0.0625 -DEAL::27 26 0.312 +DEAL::27 26 0.313 DEAL::28 0 0 DEAL::28 1 0 DEAL::28 2 0 diff --git a/tests/matrix_free/copy.cc b/tests/matrix_free/copy.cc index 3ed0b82bc7..859459b839 100644 --- a/tests/matrix_free/copy.cc +++ b/tests/matrix_free/copy.cc @@ -45,21 +45,21 @@ void sub_test() DoFHandler dof (tria); deallog << "Testing " << fe.get_name() << std::endl; - // run test for several different meshes + // run test for several different meshes for (unsigned int i=0; i<8-2*dim; ++i) { cell = tria.begin_active (); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (9-i) == 0) - cell->set_refine_flag(); + if (counter % (9-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); dof.distribute_dofs(fe); ConstraintMatrix constraints; DoFTools::make_hanging_node_constraints(dof, constraints); VectorTools::interpolate_boundary_values (dof, 0, ZeroFunction(), - constraints); + constraints); constraints.close(); //std::cout << "Number of cells: " << dof.get_tria().n_active_cells() << std::endl; @@ -68,26 +68,26 @@ void sub_test() MatrixFree mf_data; { - const QGauss<1> quad (fe_degree+1); - mf_data.reinit (dof, constraints, quad, - typename MatrixFree::AdditionalData(MPI_COMM_SELF,MatrixFree::AdditionalData::none)); + const QGauss<1> quad (fe_degree+1); + mf_data.reinit (dof, constraints, quad, + typename MatrixFree::AdditionalData(MPI_COMM_SELF,MatrixFree::AdditionalData::none)); } - MatrixFreeTest mf_ref (mf_data); + MatrixFreeTest mf_ref (mf_data); Vector in_dist (dof.n_dofs()); Vector out_ref (in_dist), out_copy (in_dist); - MatrixFree mf_copy; + MatrixFree mf_copy; mf_copy.copy_from (mf_data); - MatrixFreeTest copied (mf_copy); + MatrixFreeTest copied (mf_copy); for (unsigned int i=0; i &tria, - const double scale_grid = 1.) + const double scale_grid = 1.) { const unsigned int dim = 2; std::vector > points (12); - // build the mesh layer by layer from points + // build the mesh layer by layer from points - // 1. cube cell + // 1. cube cell points[0] = Point (0, 0); points[1] = Point (0, 1); points[2] = Point (1 ,0); points[3] = Point (1 ,1); - // 2. rectangular cell + // 2. rectangular cell points[4] = Point (3., 0); points[5] = Point (3., 1); - // 3. parallelogram cell + // 3. parallelogram cell points[6] = Point (5., 1.); points[7] = Point (5., 2.); - // almost square cell (but trapezoidal by - // 1e-8) + // almost square cell (but trapezoidal by + // 1e-8) points[8] = Point (6., 1.); points[9] = Point (6., 2.+1e-8); - // apparently trapezoidal cell + // apparently trapezoidal cell points[10] = Point (7., 1.4); points[11] = Point (7.5, numbers::PI); if (scale_grid != 1.) for (unsigned int i=0; i > cells(5); for (unsigned int i=0; i<5; ++i) { @@ -70,14 +70,14 @@ void create_mesh (Triangulation<2> &tria, void create_mesh (Triangulation<3> &tria, - const double scale_grid = 1.) + const double scale_grid = 1.) { const unsigned int dim = 3; std::vector > points (24); - // build the mesh layer by layer from points + // build the mesh layer by layer from points - // 1. cube cell + // 1. cube cell points[0] = Point (0,0,0); points[1] = Point (0,1.,0); points[2] = Point (0,0,1); @@ -87,26 +87,26 @@ void create_mesh (Triangulation<3> &tria, points[6] = Point (1.,0,1); points[7] = Point (1.,1.,1); - // 2. rectangular cell + // 2. rectangular cell points[8] = Point (3., 0, 0); points[9] = Point (3., 1, 0); points[10] = Point (3., 0,1); points[11] = Point (3., 1,1); - // 3. parallelogram cell + // 3. parallelogram cell points[12] = Point (5., 1., 1.); points[13] = Point (5., 2., 1.); points[14] = Point (5., 1., 2.); points[15] = Point (5., 2., 2.); - // almost square cell (but trapezoidal by - // 1e-8 in y-direction) + // almost square cell (but trapezoidal by + // 1e-8 in y-direction) points[16] = Point (6., 1., 1.); points[17] = Point (6., 2.+1e-8, 1.); points[18] = Point (6., 1., 2.); points[19] = Point (6., 2., 2.); - // apparently trapezoidal cell + // apparently trapezoidal cell points[20] = Point (7., 1.4, 1.2231); points[21] = Point (7.5, numbers::PI, 1.334); points[22] = Point (7., 1.5, 7.1); @@ -116,7 +116,7 @@ void create_mesh (Triangulation<3> &tria, for (unsigned int i=0; i > cells(5); for (unsigned int i=0; i<5; ++i) { diff --git a/tests/matrix_free/get_functions_circle.cc b/tests/matrix_free/get_functions_circle.cc index 28de48739a..0f54e17133 100644 --- a/tests/matrix_free/get_functions_circle.cc +++ b/tests/matrix_free/get_functions_circle.cc @@ -25,7 +25,7 @@ void test () GridGenerator::hyper_ball (tria); static const HyperBallBoundary boundary; tria.set_boundary (0, boundary); - // refine first and last cell + // refine first and last cell tria.begin(tria.n_levels()-1)->set_refine_flag(); tria.last()->set_refine_flag(); tria.execute_coarsening_and_refinement(); diff --git a/tests/matrix_free/get_functions_common.h b/tests/matrix_free/get_functions_common.h index 77e9157727..122db07661 100644 --- a/tests/matrix_free/get_functions_common.h +++ b/tests/matrix_free/get_functions_common.h @@ -38,7 +38,7 @@ void test (); -template +template class MatrixFreeTest { public: @@ -47,31 +47,31 @@ class MatrixFreeTest MatrixFreeTest(const MatrixFree &data_in): data (data_in), fe_val (data.get_dof_handler().get_fe(), - Quadrature(data.get_quad(0)), - update_values | update_gradients | update_hessians) + Quadrature(data.get_quad(0)), + update_values | update_gradients | update_hessians) {}; MatrixFreeTest(const MatrixFree &data_in, - const Mapping &mapping): + const Mapping &mapping): data (data_in), fe_val (mapping, data.get_dof_handler().get_fe(), - Quadrature(data.get_quad(0)), - update_values | update_gradients | update_hessians) + Quadrature(data.get_quad(0)), + update_values | update_gradients | update_hessians) {}; virtual ~MatrixFreeTest () {} - // make function virtual to allow derived - // classes to define a different function + // make function virtual to allow derived + // classes to define a different function virtual void operator () (const MatrixFree &data, - Vector &, - const Vector &src, - const std::pair &cell_range) const + Vector &, + const Vector &src, + const std::pair &cell_range) const { typedef VectorizedArray vector_t; - FEEvaluation fe_eval (data); + FEEvaluation fe_eval (data); std::vector reference_values (fe_eval.n_q_points); std::vector > reference_grads (fe_eval.n_q_points); @@ -79,53 +79,53 @@ class MatrixFreeTest for(unsigned int cell=cell_range.first;cell dst_dummy; data.cell_loop (&MatrixFreeTest::operator(), this, dst_dummy, src); - // for doubles, use a stricter condition than - // for floats for the relative error size + // for doubles, use a stricter condition than + // for floats for the relative error size if (types_are_equal::value == true) { - deallog.threshold_double (5e-14); - deallog << "Error function values: " - << errors[0]/total[0] << std::endl; - deallog << "Error function gradients: " - << errors[1]/total[1] << std::endl; - - // need to set quite a loose tolerance because - // FEValues approximates Hessians with finite - // differences, which are not so - // accurate. moreover, Hessians are quite - // large since we chose random numbers. for - // some elements, it might also be zero - // (linear elements on quadrilaterals), so - // need to check for division by 0, too. - deallog.threshold_double (5e-7); - const double output2 = total[2] == 0 ? 0. : errors[2] / total[2]; - deallog << "Error function Laplacians: " << output2 << std::endl; + deallog.threshold_double (5e-14); + deallog << "Error function values: " + << errors[0]/total[0] << std::endl; + deallog << "Error function gradients: " + << errors[1]/total[1] << std::endl; + + // need to set quite a loose tolerance because + // FEValues approximates Hessians with finite + // differences, which are not so + // accurate. moreover, Hessians are quite + // large since we chose random numbers. for + // some elements, it might also be zero + // (linear elements on quadrilaterals), so + // need to check for division by 0, too. + deallog.threshold_double (5e-7); + const double output2 = total[2] == 0 ? 0. : errors[2] / total[2]; + deallog << "Error function Laplacians: " << output2 << std::endl; const double output3 = total[3] == 0 ? 0. : errors[3] / total[3]; - deallog << "Error function diagonal of Hessian: " << output3 << std::endl; + deallog << "Error function diagonal of Hessian: " << output3 << std::endl; const double output4 = total[4] == 0 ? 0. : errors[4] / total[4]; - deallog << "Error function Hessians: " << output4 << std::endl; + deallog << "Error function Hessians: " << output4 << std::endl; } else if (types_are_equal::value == true) { - deallog.threshold_double (1e-6); - deallog << "Error function values: " - << errors[0]/total[0] << std::endl; - deallog << "Error function gradients: " - << errors[1]/total[1] << std::endl; - const double output2 = total[2] == 0 ? 0. : errors[2] / total[2]; - deallog.threshold_double (1e-5); - deallog << "Error function Laplacians: " << output2 << std::endl; + deallog.threshold_double (1e-6); + deallog << "Error function values: " + << errors[0]/total[0] << std::endl; + deallog << "Error function gradients: " + << errors[1]/total[1] << std::endl; + const double output2 = total[2] == 0 ? 0. : errors[2] / total[2]; + deallog.threshold_double (1e-5); + deallog << "Error function Laplacians: " << output2 << std::endl; const double output3 = total[3] == 0 ? 0. : errors[3] / total[3]; - deallog << "Error function diagonal of Hessian: " << output3 << std::endl; + deallog << "Error function diagonal of Hessian: " << output3 << std::endl; const double output4 = total[4] == 0 ? 0. : errors[4] / total[4]; - deallog << "Error function Hessians: " << output4 << std::endl; + deallog << "Error function Hessians: " << output4 << std::endl; } deallog << std::endl; }; @@ -194,8 +194,8 @@ protected: // dummy with empty quadrature formula -template -class MatrixFreeTest +template +class MatrixFreeTest { public: typedef VectorizedArray vector_t; @@ -205,12 +205,12 @@ class MatrixFreeTest {}; MatrixFreeTest(const MatrixFree &, - const Mapping &) + const Mapping &) {}; void cell_integration (Vector &, - const Vector &, - const std::pair) const {} + const Vector &, + const std::pair) const {} void test_functions (const Vector &) const {} @@ -221,22 +221,22 @@ class MatrixFreeTest template void do_test (const DoFHandler &dof, - const ConstraintMatrix&constraints) + const ConstraintMatrix&constraints) { deallog << "Testing " << dof.get_fe().get_name() << std::endl; // use this for info on problem //std::cout << "Number of cells: " << dof.get_tria().n_active_cells() - // << std::endl; + // << std::endl; //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl; Vector solution (dof.n_dofs()); - // create vector with random entries + // create vector with random entries for (unsigned int i=0; i &dof, mf_data.reinit (dof, constraints, quad, data); } - MatrixFreeTest mf (mf_data); + MatrixFreeTest mf (mf_data); mf.test_functions(solution); } diff --git a/tests/matrix_free/get_functions_float.cc b/tests/matrix_free/get_functions_float.cc index f5d2a336ba..73a70fbb60 100644 --- a/tests/matrix_free/get_functions_float.cc +++ b/tests/matrix_free/get_functions_float.cc @@ -26,16 +26,16 @@ void test () create_mesh (tria); tria.refine_global(4-dim); - // refine a few cells + // refine a few cells for (unsigned int i=0; i<10-3*dim; ++i) { typename Triangulation::active_cell_iterator - cell = tria.begin_active (), - endc = tria.end(); + cell = tria.begin_active (), + endc = tria.end(); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -46,7 +46,7 @@ void test () ConstraintMatrix constraints; DoFTools::make_hanging_node_constraints (dof, constraints); VectorTools::interpolate_boundary_values (dof, 1, ZeroFunction(), - constraints); + constraints); constraints.close(); do_test (dof, constraints); diff --git a/tests/matrix_free/get_functions_gl.cc b/tests/matrix_free/get_functions_gl.cc index 42d5b0a649..3d80aa9182 100644 --- a/tests/matrix_free/get_functions_gl.cc +++ b/tests/matrix_free/get_functions_gl.cc @@ -19,57 +19,57 @@ std::ofstream logfile("get_functions_gl/output"); #include "get_functions_common.h" -template -class MatrixFreeTestGL : public MatrixFreeTest +template +class MatrixFreeTestGL : public MatrixFreeTest { public: typedef VectorizedArray vector_t; static const std::size_t n_vectors = VectorizedArray::n_array_elements; MatrixFreeTestGL(const MatrixFree &data, - const Mapping &mapping): - MatrixFreeTest(data, mapping) + const Mapping &mapping): + MatrixFreeTest(data, mapping) {}; void operator() (const MatrixFree &data, - Vector &, - const Vector &src, - const std::pair &cell_range) const + Vector &, + const Vector &src, + const std::pair &cell_range) const { - FEEvaluationGL fe_eval (this->data); + FEEvaluationGL fe_eval (this->data); for(unsigned int cell=cell_range.first;cell reference_values (fe_eval.n_q_points); - std::vector > reference_grads (fe_eval.n_q_points); - std::vector > reference_hess (fe_eval.n_q_points); - fe_eval.read_dof_values(src); - fe_eval.evaluate (true,true,true); - - // compare values with the ones the FEValues - // gives us. Those are seen as reference - for (unsigned int j=0; jfe_val.reinit (data.get_cell_iterator(cell,j)); - this->fe_val.get_function_values(src, reference_values); - this->fe_val.get_function_gradients(src, reference_grads); - this->fe_val.get_function_hessians(src, reference_hess); - - for (int q=0; q<(int)fe_eval.n_q_points; q++) - { - this->errors[0] += std::fabs(fe_eval.get_value(q)[j]- - reference_values[q]); - for (unsigned int d=0; derrors[1] += std::fabs(fe_eval.get_gradient(q)[d][j]- - reference_grads[q][d]); - this->errors[2] += std::fabs(fe_eval.get_laplacian(q)[j]- - trace(reference_hess[q])); - this->total[0] += std::fabs(reference_values[q]); - for (unsigned int d=0; dtotal[1] += std::fabs(reference_grads[q][d]); - this->total[2] += std::fabs(fe_eval.get_laplacian(q)[j]); - } - } + fe_eval.reinit (cell); + std::vector reference_values (fe_eval.n_q_points); + std::vector > reference_grads (fe_eval.n_q_points); + std::vector > reference_hess (fe_eval.n_q_points); + fe_eval.read_dof_values(src); + fe_eval.evaluate (true,true,true); + + // compare values with the ones the FEValues + // gives us. Those are seen as reference + for (unsigned int j=0; jfe_val.reinit (data.get_cell_iterator(cell,j)); + this->fe_val.get_function_values(src, reference_values); + this->fe_val.get_function_gradients(src, reference_grads); + this->fe_val.get_function_hessians(src, reference_hess); + + for (int q=0; q<(int)fe_eval.n_q_points; q++) + { + this->errors[0] += std::fabs(fe_eval.get_value(q)[j]- + reference_values[q]); + for (unsigned int d=0; derrors[1] += std::fabs(fe_eval.get_gradient(q)[d][j]- + reference_grads[q][d]); + this->errors[2] += std::fabs(fe_eval.get_laplacian(q)[j]- + trace(reference_hess[q])); + this->total[0] += std::fabs(reference_values[q]); + for (unsigned int d=0; dtotal[1] += std::fabs(reference_grads[q][d]); + this->total[2] += std::fabs(fe_eval.get_laplacian(q)[j]); + } + } } } }; @@ -84,7 +84,7 @@ void test () GridGenerator::hyper_ball (tria); static const HyperBallBoundary boundary; tria.set_boundary (0, boundary); - // refine first and last cell + // refine first and last cell tria.begin(tria.n_levels()-1)->set_refine_flag(); tria.last()->set_refine_flag(); tria.execute_coarsening_and_refinement(); @@ -100,17 +100,17 @@ void test () deallog << "Testing " << dof.get_fe().get_name() << std::endl; //std::cout << "Number of cells: " << dof.get_tria().n_active_cells() - // << std::endl; + // << std::endl; //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl; Vector solution (dof.n_dofs()); - // create vector with random entries + // create vector with random entries for (unsigned int i=0; i mf_data; deallog << "Test with fe_degree " << fe_degree - << std::endl; + << std::endl; const QGaussLobatto<1> quad (fe_degree+1); MappingQ mapping (2); typename MatrixFree::AdditionalData data; data.tasks_parallel_scheme = MatrixFree::AdditionalData::none; data.mapping_update_flags = update_gradients | update_second_derivatives; mf_data.reinit (mapping, dof, constraints, quad, data); - MatrixFreeTestGL mf (mf_data, mapping); + MatrixFreeTestGL mf (mf_data, mapping); mf.test_functions (solution); } diff --git a/tests/matrix_free/get_functions_mappingq.cc b/tests/matrix_free/get_functions_mappingq.cc index 5b4358e6ae..4d98107741 100644 --- a/tests/matrix_free/get_functions_mappingq.cc +++ b/tests/matrix_free/get_functions_mappingq.cc @@ -26,7 +26,7 @@ void test () GridGenerator::hyper_ball (tria); static const HyperBallBoundary boundary; tria.set_boundary (0, boundary); - // refine first and last cell + // refine first and last cell tria.begin(tria.n_levels()-1)->set_refine_flag(); tria.last()->set_refine_flag(); tria.execute_coarsening_and_refinement(); @@ -40,22 +40,22 @@ void test () DoFTools::make_hanging_node_constraints (dof, constraints); constraints.close(); - // in the other functions, use do_test in - // get_functions_common, but here we have to - // manually choose another mapping + // in the other functions, use do_test in + // get_functions_common, but here we have to + // manually choose another mapping deallog << "Testing " << dof.get_fe().get_name() << std::endl; //std::cout << "Number of cells: " << dof.get_tria().n_active_cells() - // << std::endl; + // << std::endl; //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl; Vector solution (dof.n_dofs()); - // create vector with random entries + // create vector with random entries for (unsigned int i=0; i mf (mf_data, mapping); + MatrixFreeTest mf (mf_data, mapping); mf.test_functions(solution); deallog << std::endl; } diff --git a/tests/matrix_free/get_functions_multife.cc b/tests/matrix_free/get_functions_multife.cc index 3d019d2eae..7ecb02f458 100644 --- a/tests/matrix_free/get_functions_multife.cc +++ b/tests/matrix_free/get_functions_multife.cc @@ -34,7 +34,7 @@ std::ofstream logfile("get_functions_multife/output"); -template +template class MatrixFreeTest { public: @@ -45,21 +45,21 @@ class MatrixFreeTest MatrixFreeTest(const MatrixFree &data_in): data (data_in), fe_val0 (data.get_dof_handler(0).get_fe(), - Quadrature(data.get_quad(0)), - update_values | update_gradients | update_hessians), + Quadrature(data.get_quad(0)), + update_values | update_gradients | update_hessians), fe_val1 (data.get_dof_handler(1).get_fe(), - Quadrature(data.get_quad(1)), - update_values | update_gradients | update_hessians) + Quadrature(data.get_quad(1)), + update_values | update_gradients | update_hessians) {}; void operator () (const MatrixFree &data, - VectorType &, - const VectorType &src, - const std::pair &cell_range) const + VectorType &, + const VectorType &src, + const std::pair &cell_range) const { - FEEvaluation fe_eval0 (data,0,0); - FEEvaluation fe_eval1 (data,1,1); + FEEvaluation fe_eval0 (data,0,0); + FEEvaluation fe_eval1 (data,1,1); std::vector reference_values0 (fe_eval0.n_q_points); std::vector > reference_grads0 (fe_eval0.n_q_points); std::vector > reference_hess0 (fe_eval0.n_q_points); @@ -68,60 +68,60 @@ class MatrixFreeTest std::vector > reference_hess1 (fe_eval1.n_q_points); for(unsigned int cell=cell_range.first;cell::operator(), - this, dst_dummy, src); + data.cell_loop (&MatrixFreeTest::operator(), + this, dst_dummy, src); - // for doubles, use a stricter condition then - // for floats for the relative error size + // for doubles, use a stricter condition then + // for floats for the relative error size for (unsigned int i=0; i<2; ++i) { - if (types_are_equal::value == true) - { - deallog.threshold_double (4e-14); - deallog << "Error function values FE " << i << ": " - << errors[i*3+0]/total[i*3+0] << std::endl; - deallog << "Error function gradients FE " << i << ": " - << errors[i*3+1]/total[i*3+1] << std::endl; - - // need to set quite a loose tolerance because - // FEValues approximates Hessians with finite - // differences, which are not so - // accurate. moreover, Hessians are quite - // large since we chose random numbers. for - // some elements, it might also be zero - // (linear elements on quadrilaterals), so - // need to check for division by 0, too. - deallog.threshold_double (5e-7); - const double output2 = total[i*3+2] == 0 ? 0. : errors[i*3+2] / total[i*3+2]; - deallog << "Error function Laplacians FE " << i << ": " << output2 << std::endl; - } - else if (types_are_equal::value == true) - { - deallog.threshold_double (1e-6); - deallog << "Error function values FE " << i << ": " - << errors[i*3+0]/total[i*3+0] << std::endl; - deallog << "Error function gradients FE " << i << ": " - << errors[i*3+1]/total[i*3+1] << std::endl; - const double output2 = total[i*3+2] == 0 ? 0. : errors[i*3+2] / total[i*3+2]; - deallog.threshold_double (1e-6); - deallog << "Error function Laplacians FE " << i << ": " << output2 << std::endl; - } + if (types_are_equal::value == true) + { + deallog.threshold_double (4e-14); + deallog << "Error function values FE " << i << ": " + << errors[i*3+0]/total[i*3+0] << std::endl; + deallog << "Error function gradients FE " << i << ": " + << errors[i*3+1]/total[i*3+1] << std::endl; + + // need to set quite a loose tolerance because + // FEValues approximates Hessians with finite + // differences, which are not so + // accurate. moreover, Hessians are quite + // large since we chose random numbers. for + // some elements, it might also be zero + // (linear elements on quadrilaterals), so + // need to check for division by 0, too. + deallog.threshold_double (5e-7); + const double output2 = total[i*3+2] == 0 ? 0. : errors[i*3+2] / total[i*3+2]; + deallog << "Error function Laplacians FE " << i << ": " << output2 << std::endl; + } + else if (types_are_equal::value == true) + { + deallog.threshold_double (1e-6); + deallog << "Error function values FE " << i << ": " + << errors[i*3+0]/total[i*3+0] << std::endl; + deallog << "Error function gradients FE " << i << ": " + << errors[i*3+1]/total[i*3+1] << std::endl; + const double output2 = total[i*3+2] == 0 ? 0. : errors[i*3+2] / total[i*3+2]; + deallog.threshold_double (1e-6); + deallog << "Error function Laplacians FE " << i << ": " << output2 << std::endl; + } } }; @@ -238,10 +238,10 @@ void test () for (unsigned int no=0; no<2; ++no) for (unsigned int i=0; in_dofs(); ++i) { - if(constraints[no]->is_constrained(i)) - continue; - const double entry = rand()/(double)RAND_MAX; - src[no](i) = entry; + if(constraints[no]->is_constrained(i)) + continue; + const double entry = rand()/(double)RAND_MAX; + src[no](i) = entry; } @@ -253,12 +253,12 @@ void test () for (unsigned int no=0; no<2; ++no) quad.push_back(QGauss<1>(fe_degree+1+no)); mf_data.reinit (dof, constraints, quad, - typename MatrixFree::AdditionalData - (MPI_COMM_SELF, - MatrixFree::AdditionalData::none)); + typename MatrixFree::AdditionalData + (MPI_COMM_SELF, + MatrixFree::AdditionalData::none)); } - MatrixFreeTest mf (mf_data); + MatrixFreeTest mf (mf_data); mf.test_functions(src); deallog << std::endl; } @@ -268,9 +268,9 @@ int main () { deallog.attach(logfile); deallog.depth_console(0); - // need to set quite a loose tolerance because - // FEValues approximates Hessians with finite - // differences, which are not so accurate + // need to set quite a loose tolerance because + // FEValues approximates Hessians with finite + // differences, which are not so accurate deallog.threshold_double(2.e-5); deallog << std::setprecision (3); diff --git a/tests/matrix_free/get_functions_multife2.cc b/tests/matrix_free/get_functions_multife2.cc index c500271072..61499d7c9b 100644 --- a/tests/matrix_free/get_functions_multife2.cc +++ b/tests/matrix_free/get_functions_multife2.cc @@ -36,7 +36,7 @@ std::ofstream logfile("get_functions_multife2/output"); -template +template class MatrixFreeTest { public: @@ -47,25 +47,25 @@ class MatrixFreeTest MatrixFreeTest(const MatrixFree &data_in): data (data_in), fe_val0 (data.get_dof_handler(0).get_fe(), - Quadrature(data.get_quad(0)), - update_values | update_gradients | update_hessians), + Quadrature(data.get_quad(0)), + update_values | update_gradients | update_hessians), fe_val1 (data.get_dof_handler(1).get_fe(), - Quadrature(data.get_quad(1)), - update_values | update_gradients | update_hessians), + Quadrature(data.get_quad(1)), + update_values | update_gradients | update_hessians), fe_val2 (data.get_dof_handler(2).get_fe(), - Quadrature(data.get_quad(1)), - update_values | update_gradients | update_hessians) + Quadrature(data.get_quad(1)), + update_values | update_gradients | update_hessians) {}; void operator () (const MatrixFree &data, - VectorType &, - const VectorType &src, - const std::pair &cell_range) const + VectorType &, + const VectorType &src, + const std::pair &cell_range) const { - FEEvaluation fe_eval0 (data,0,0); - FEEvaluation fe_eval1 (data,1,1); - FEEvaluation fe_eval2 (data,2,1); + FEEvaluation fe_eval0 (data,0,0); + FEEvaluation fe_eval1 (data,1,1); + FEEvaluation fe_eval2 (data,2,1); std::vector reference_values0 (fe_eval0.n_q_points); std::vector > reference_grads0 (fe_eval0.n_q_points); std::vector > reference_hess0 (fe_eval0.n_q_points); @@ -77,85 +77,85 @@ class MatrixFreeTest std::vector > reference_hess2 (fe_eval2.n_q_points); for(unsigned int cell=cell_range.first;cell::operator(), - this, dst_dummy, src); + data.cell_loop (&MatrixFreeTest::operator(), + this, dst_dummy, src); - // avoid dividing by zero + // avoid dividing by zero for (unsigned int i=0; i<9; ++i) if (std::fabs(total[i]) < 1e-20) - total[i] = 1; + total[i] = 1; - // for doubles, use a stricter condition then - // for floats for the relative error size + // for doubles, use a stricter condition then + // for floats for the relative error size for (unsigned int i=0; i<3; ++i) { - if (types_are_equal::value == true) - { - deallog.threshold_double (4e-14); - deallog << "Error function values FE " << i << ": " - << errors[i*3+0]/total[i*3+0] << std::endl; - deallog << "Error function gradients FE " << i << ": " - << errors[i*3+1]/total[i*3+1] << std::endl; - - // need to set quite a loose tolerance because - // FEValues approximates Hessians with finite - // differences, which are not so - // accurate. moreover, Hessians are quite - // large since we chose random numbers. for - // some elements, it might also be zero - // (linear elements on quadrilaterals), so - // need to check for division by 0, too. - deallog.threshold_double (2e-6); - const double output2 = total[i*3+2] == 0 ? 0. : errors[i*3+2] / total[i*3+2]; - deallog << "Error function Laplacians FE " << i << ": " << output2 << std::endl; - } - else if (types_are_equal::value == true) - { - deallog.threshold_double (1e-6); - deallog << "Error function values FE " << i << ": " - << errors[i*3+0]/total[i*3+0] << std::endl; - deallog << "Error function gradients FE " << i << ": " - << errors[i*3+1]/total[i*3+1] << std::endl; - const double output2 = total[i*3+2] == 0 ? 0. : errors[i*3+2] / total[i*3+2]; - deallog.threshold_double (1e-6); - deallog << "Error function Laplacians FE " << i << ": " << output2 << std::endl; - } + if (types_are_equal::value == true) + { + deallog.threshold_double (4e-14); + deallog << "Error function values FE " << i << ": " + << errors[i*3+0]/total[i*3+0] << std::endl; + deallog << "Error function gradients FE " << i << ": " + << errors[i*3+1]/total[i*3+1] << std::endl; + + // need to set quite a loose tolerance because + // FEValues approximates Hessians with finite + // differences, which are not so + // accurate. moreover, Hessians are quite + // large since we chose random numbers. for + // some elements, it might also be zero + // (linear elements on quadrilaterals), so + // need to check for division by 0, too. + deallog.threshold_double (2e-6); + const double output2 = total[i*3+2] == 0 ? 0. : errors[i*3+2] / total[i*3+2]; + deallog << "Error function Laplacians FE " << i << ": " << output2 << std::endl; + } + else if (types_are_equal::value == true) + { + deallog.threshold_double (1e-6); + deallog << "Error function values FE " << i << ": " + << errors[i*3+0]/total[i*3+0] << std::endl; + deallog << "Error function gradients FE " << i << ": " + << errors[i*3+1]/total[i*3+1] << std::endl; + const double output2 = total[i*3+2] == 0 ? 0. : errors[i*3+2] / total[i*3+2]; + deallog.threshold_double (1e-6); + deallog << "Error function Laplacians FE " << i << ": " << output2 << std::endl; + } } }; @@ -257,7 +257,7 @@ void test () dof[2] = &dof2; deallog << "Testing " << fe0.get_name() << ", " << fe1.get_name() - << ", and " << fe1.get_name() << std::endl; + << ", and " << fe1.get_name() << std::endl; //std::cout << "Number of cells: " << tria.n_active_cells() << std::endl; std::vector > src (dof.size()); @@ -289,10 +289,10 @@ void test () for (unsigned int no=0; no<3; ++no) for (unsigned int i=0; in_dofs(); ++i) { - if(constraints[no]->is_constrained(i)) - continue; - const double entry = rand()/(double)RAND_MAX; - src[no](i) = entry; + if(constraints[no]->is_constrained(i)) + continue; + const double entry = rand()/(double)RAND_MAX; + src[no](i) = entry; } @@ -305,12 +305,12 @@ void test () quad.push_back (QGauss<1>(1)); quad.push_back (QGauss<1>(fe_degree+1)); mf_data.reinit (dof, constraints, quad, - typename MatrixFree::AdditionalData - (MPI_COMM_SELF, - MatrixFree::AdditionalData::none)); + typename MatrixFree::AdditionalData + (MPI_COMM_SELF, + MatrixFree::AdditionalData::none)); } - MatrixFreeTest mf (mf_data); + MatrixFreeTest mf (mf_data); mf.test_functions(src); deallog << std::endl; } @@ -320,9 +320,9 @@ int main () { deallog.attach(logfile); deallog.depth_console(0); - // need to set quite a loose tolerance because - // FEValues approximates Hessians with finite - // differences, which are not so accurate + // need to set quite a loose tolerance because + // FEValues approximates Hessians with finite + // differences, which are not so accurate deallog.threshold_double(2.e-5); deallog << std::setprecision (3); diff --git a/tests/matrix_free/get_functions_q_hierarchical.cc b/tests/matrix_free/get_functions_q_hierarchical.cc index 4bff0d5fee..b1ca17475b 100644 --- a/tests/matrix_free/get_functions_q_hierarchical.cc +++ b/tests/matrix_free/get_functions_q_hierarchical.cc @@ -21,59 +21,59 @@ std::ofstream logfile("get_functions_q_hierarchical/output"); #include "get_functions_common.h" -template -class MatrixFreeTestGen : public MatrixFreeTest +template +class MatrixFreeTestGen : public MatrixFreeTest { public: typedef VectorizedArray vector_t; static const std::size_t n_vectors = VectorizedArray::n_array_elements; MatrixFreeTestGen(const MatrixFree &data, - const Mapping &mapping): - MatrixFreeTest(data, mapping) + const Mapping &mapping): + MatrixFreeTest(data, mapping) {}; void operator () (const MatrixFree &data, - Vector &, - const Vector &src, - const std::pair &cell_range) const + Vector &, + const Vector &src, + const std::pair &cell_range) const { - FEEvaluationGeneral fe_eval (data); + FEEvaluationGeneral fe_eval (data); for(unsigned int cell=cell_range.first;cell reference_values (fe_eval.n_q_points); - std::vector > reference_grads (fe_eval.n_q_points); - std::vector > reference_hess (fe_eval.n_q_points); - fe_eval.read_dof_values(src); - fe_eval.evaluate (true,true,true); - - // compare values with the ones the FEValues - // gives us. Those are seen as reference - for (unsigned int j=0; jfe_val.reinit (data.get_cell_iterator(cell,j)); - this->fe_val.get_function_values(src, reference_values); - this->fe_val.get_function_gradients(src, reference_grads); - this->fe_val.get_function_hessians(src, reference_hess); - - for (int q=0; q<(int)fe_eval.n_q_points; q++) - { - this->errors[0] += std::fabs(fe_eval.get_value(q)[j]- - reference_values[q]); - for (unsigned int d=0; derrors[1] += std::fabs(fe_eval.get_gradient(q)[d][j]- - reference_grads[q][d]); - } - this->errors[2] += std::fabs(fe_eval.get_laplacian(q)[j]- - trace(reference_hess[q])); - this->total[0] += std::fabs(reference_values[q]); - for (unsigned int d=0; dtotal[1] += std::fabs(reference_grads[q][d]); - this->total[2] += std::fabs(fe_eval.get_laplacian(q)[j]); - } - } + fe_eval.reinit (cell); + std::vector reference_values (fe_eval.n_q_points); + std::vector > reference_grads (fe_eval.n_q_points); + std::vector > reference_hess (fe_eval.n_q_points); + fe_eval.read_dof_values(src); + fe_eval.evaluate (true,true,true); + + // compare values with the ones the FEValues + // gives us. Those are seen as reference + for (unsigned int j=0; jfe_val.reinit (data.get_cell_iterator(cell,j)); + this->fe_val.get_function_values(src, reference_values); + this->fe_val.get_function_gradients(src, reference_grads); + this->fe_val.get_function_hessians(src, reference_hess); + + for (int q=0; q<(int)fe_eval.n_q_points; q++) + { + this->errors[0] += std::fabs(fe_eval.get_value(q)[j]- + reference_values[q]); + for (unsigned int d=0; derrors[1] += std::fabs(fe_eval.get_gradient(q)[d][j]- + reference_grads[q][d]); + } + this->errors[2] += std::fabs(fe_eval.get_laplacian(q)[j]- + trace(reference_hess[q])); + this->total[0] += std::fabs(reference_values[q]); + for (unsigned int d=0; dtotal[1] += std::fabs(reference_grads[q][d]); + this->total[2] += std::fabs(fe_eval.get_laplacian(q)[j]); + } + } } } }; @@ -88,7 +88,7 @@ void test () GridGenerator::hyper_ball (tria); static const HyperBallBoundary boundary; tria.set_boundary (0, boundary); - // refine first and last cell + // refine first and last cell tria.begin(tria.n_levels()-1)->set_refine_flag(); tria.last()->set_refine_flag(); tria.execute_coarsening_and_refinement(); @@ -104,17 +104,17 @@ void test () deallog << "Testing " << dof.get_fe().get_name() << std::endl; //std::cout << "Number of cells: " << dof.get_tria().n_active_cells() - // << std::endl; + // << std::endl; //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl; Vector solution (dof.n_dofs()); - // create vector with random entries + // create vector with random entries for (unsigned int i=0; i mf_data; deallog << "Test with fe_degree " << fe_degree - << std::endl; + << std::endl; const QGauss<1> quad (fe_degree+1); MappingQ mapping (4); typename MatrixFree::AdditionalData data; data.tasks_parallel_scheme = MatrixFree::AdditionalData::none; data.mapping_update_flags = update_gradients | update_second_derivatives; mf_data.reinit (mapping, dof, constraints, quad, data); - MatrixFreeTestGen mf (mf_data, mapping); + MatrixFreeTestGen mf (mf_data, mapping); mf.test_functions (solution); } diff --git a/tests/matrix_free/get_functions_rect.cc b/tests/matrix_free/get_functions_rect.cc index 45a8ac922f..5cb26618e4 100644 --- a/tests/matrix_free/get_functions_rect.cc +++ b/tests/matrix_free/get_functions_rect.cc @@ -21,19 +21,19 @@ std::ofstream logfile("get_functions_rect/output"); template void sub_test (const DoFHandler &dof, - const ConstraintMatrix &constraints, - MatrixFree &mf_data, - Vector &solution) + const ConstraintMatrix &constraints, + MatrixFree &mf_data, + Vector &solution) { deallog << "Test with fe_degree " << fe_degree - << ", n_q_points_1d: " << (n_q_points_1d) << std::endl; + << ", n_q_points_1d: " << (n_q_points_1d) << std::endl; const QGauss<1> quad (n_q_points_1d); MappingQ mapping (2); typename MatrixFree::AdditionalData data; data.tasks_parallel_scheme = MatrixFree::AdditionalData::none; data.mapping_update_flags = update_gradients | update_second_derivatives; mf_data.reinit (mapping, dof, constraints, quad, data); - MatrixFreeTest mf (mf_data, mapping); + MatrixFreeTest mf (mf_data, mapping); mf.test_functions (solution); } @@ -47,7 +47,7 @@ void test () GridGenerator::hyper_ball (tria); static const HyperBallBoundary boundary; tria.set_boundary (0, boundary); - // refine first and last cell + // refine first and last cell tria.begin(tria.n_levels()-1)->set_refine_flag(); tria.last()->set_refine_flag(); tria.execute_coarsening_and_refinement(); @@ -62,22 +62,22 @@ void test () constraints.close(); - // in the other functions, use do_test in - // get_functions_common, but here we have to - // manually choose non-rectangular tests. + // in the other functions, use do_test in + // get_functions_common, but here we have to + // manually choose non-rectangular tests. deallog << "Testing " << dof.get_fe().get_name() << std::endl; //std::cout << "Number of cells: " << dof.get_tria().n_active_cells() - // << std::endl; + // << std::endl; //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl; Vector solution (dof.n_dofs()); - // create vector with random entries + // create vector with random entries for (unsigned int i=0; i mf_data; if (fe_degree > 1) sub_test (dof, constraints, mf_data, - solution); + solution); sub_test (dof, constraints, mf_data, - solution); + solution); sub_test (dof, constraints, mf_data, - solution); + solution); if (dim == 2) sub_test (dof, constraints, mf_data, - solution); + solution); } diff --git a/tests/matrix_free/get_functions_variants.cc b/tests/matrix_free/get_functions_variants.cc index 11f248b141..5dd4c9d91c 100644 --- a/tests/matrix_free/get_functions_variants.cc +++ b/tests/matrix_free/get_functions_variants.cc @@ -33,7 +33,7 @@ std::ofstream logfile("get_functions_variants/output"); -template +template class MatrixFreeTest { public: @@ -46,27 +46,27 @@ class MatrixFreeTest {}; void operator () (const MatrixFree &data, - VectorType &dst, - const VectorType &src, - const std::pair &cell_range) const; + VectorType &dst, + const VectorType &src, + const std::pair &cell_range) const; void test_functions (const VectorType &src) const { for (unsigned int i=0; i<5; ++i) errors[i] = 0; - data.cell_loop (&MatrixFreeTest::operator(), this, - const_cast(src), src); + data.cell_loop (&MatrixFreeTest::operator(), this, + const_cast(src), src); deallog << "Error val, function values alone: " - << errors[0] << std::endl; + << errors[0] << std::endl; deallog << "Error grad, function gradients alone: " - << errors[1] << std::endl; + << errors[1] << std::endl; deallog << "Error val, function values and gradients alone: " - << errors[2] << std::endl; + << errors[2] << std::endl; deallog << "Error grad, function values and gradients alone: " - << errors[3] << std::endl; + << errors[3] << std::endl; deallog << "Error Lapl, function Laplacians alone: " - << errors[4] << std::endl; + << errors[4] << std::endl; }; private: @@ -77,66 +77,66 @@ private: -template -void MatrixFreeTest:: +template +void MatrixFreeTest:: operator () (const MatrixFree &data, - VectorType &, - const VectorType &src, - const std::pair &cell_range) const + VectorType &, + const VectorType &src, + const std::pair &cell_range) const { - FEEvaluation fe_eval (data); - FEEvaluation fe_eval2 (data); - FEEvaluation fe_eval3 (data); - FEEvaluation fe_eval4 (data); - FEEvaluation fe_eval5 (data); + FEEvaluation fe_eval (data); + FEEvaluation fe_eval2 (data); + FEEvaluation fe_eval3 (data); + FEEvaluation fe_eval4 (data); + FEEvaluation fe_eval5 (data); for(unsigned int cell=cell_range.first;cell solution_dist (dof.n_dofs()); - // create vector with random entries + // create vector with random entries for (unsigned int i=0; i mf (mf_data); + MatrixFreeTest mf (mf_data); mf.test_functions(solution_dist); deallog << std::endl; } diff --git a/tests/matrix_free/get_values_plain.cc b/tests/matrix_free/get_values_plain.cc index 31ffec46bf..709f985288 100644 --- a/tests/matrix_free/get_values_plain.cc +++ b/tests/matrix_free/get_values_plain.cc @@ -34,7 +34,7 @@ std::ofstream logfile("get_values_plain/output"); -template +template class MatrixFreeTest { public: @@ -44,33 +44,33 @@ class MatrixFreeTest data (data_in) {}; - // make function virtual to allow derived - // classes to define a different function + // make function virtual to allow derived + // classes to define a different function virtual void operator () (const MatrixFree &data, - Vector &, - const Vector &src, - const std::pair &cell_range) const + Vector &, + const Vector &src, + const std::pair &cell_range) const { typedef VectorizedArray vector_t; const unsigned int n_vectors = sizeof(vector_t)/sizeof(Number); - FEEvaluation fe_eval (data); - FEEvaluation fe_eval_plain (data); + FEEvaluation fe_eval (data); + FEEvaluation fe_eval_plain (data); for(unsigned int cell=cell_range.first;cell dst_dummy; - data.cell_loop (&MatrixFreeTest::operator(), - this, dst_dummy, src); + data.cell_loop (&MatrixFreeTest::operator(), + this, dst_dummy, src); deallog.threshold_double(1e-10); deallog << "Error read_dof_values vs read_dof_values_plain: " - << error/total << std::endl << std::endl; + << error/total << std::endl << std::endl; }; protected: @@ -98,21 +98,21 @@ protected: template void do_test (const DoFHandler &dof, - const ConstraintMatrix&constraints) + const ConstraintMatrix&constraints) { deallog << "Testing " << dof.get_fe().get_name() << std::endl; //std::cout << "Number of cells: " << dof.get_tria().n_active_cells() - // << std::endl; + // << std::endl; //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl; Vector solution (dof.n_dofs()); - // create vector with random entries + // create vector with random entries for (unsigned int i=0; i &dof, mf_data.reinit (dof, constraints, quad, data); } - MatrixFreeTest mf (mf_data); + MatrixFreeTest mf (mf_data); mf.test_functions(solution); } @@ -140,16 +140,16 @@ void test () tria.set_boundary (0, boundary); tria.set_boundary (1, boundary); - // refine a few cells + // refine a few cells for (unsigned int i=0; i<11-3*dim; ++i) { typename Triangulation::active_cell_iterator - cell = tria.begin_active (), - endc = tria.end(); + cell = tria.begin_active (), + endc = tria.end(); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -160,7 +160,7 @@ void test () ConstraintMatrix constraints; DoFTools::make_hanging_node_constraints(dof, constraints); VectorTools::interpolate_boundary_values (dof, 1, ZeroFunction(), - constraints); + constraints); constraints.close(); do_test (dof, constraints); diff --git a/tests/matrix_free/integrate_functions.cc b/tests/matrix_free/integrate_functions.cc index 95faee6e62..12dce33f76 100644 --- a/tests/matrix_free/integrate_functions.cc +++ b/tests/matrix_free/integrate_functions.cc @@ -32,7 +32,7 @@ std::ofstream logfile("integrate_functions/output"); -template +template class MatrixFreeTest { public: @@ -43,17 +43,17 @@ class MatrixFreeTest MatrixFreeTest(const MatrixFree &data_in): data (data_in), fe_val (data.get_dof_handler().get_fe(), - Quadrature(data.get_quad(0)), - update_values | update_gradients | update_JxW_values) + Quadrature(data.get_quad(0)), + update_values | update_gradients | update_JxW_values) {}; void operator () (const MatrixFree &data, - VectorType &dst, - const VectorType &src, - const std::pair &cell_range) const; + VectorType &dst, + const VectorType &src, + const std::pair &cell_range) const; void test_functions (Vector &dst, - Vector &dst_deal) const + Vector &dst_deal) const { dst = 0; dst_deal = 0; @@ -61,8 +61,8 @@ class MatrixFreeTest dst_data[0] = &dst; dst_data[1] = &dst_deal; VectorType src_dummy; - data.cell_loop (&MatrixFreeTest::operator(), this, - dst_data, src_dummy); + data.cell_loop (&MatrixFreeTest::operator(), this, + dst_data, src_dummy); }; private: @@ -73,14 +73,14 @@ private: -template -void MatrixFreeTest:: +template +void MatrixFreeTest:: operator () (const MatrixFree &data, - std::vector*> &dst, - const std::vector*> &, - const std::pair &cell_range) const + std::vector*> &dst, + const std::vector*> &, + const std::pair &cell_range) const { - FEEvaluation fe_eval (data); + FEEvaluation fe_eval (data); const unsigned int n_q_points = fe_eval.n_q_points; const unsigned int dofs_per_cell = fe_eval.dofs_per_cell; AlignedVector values (n_q_points); @@ -89,43 +89,43 @@ operator () (const MatrixFree &data, for(unsigned int cell=cell_range.first;cellget_dof_indices(dof_indices); - - for (unsigned int i=0; iget_dof_indices(dof_indices); + + for (unsigned int i=0; i submit (false); - for (unsigned int d=0; d submit (false); + for (unsigned int d=0; dset_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -184,10 +184,10 @@ void test () { const QGauss<1> quad (fe_degree+1); mf_data.reinit (dof, constraints, quad, - typename MatrixFree::AdditionalData(MPI_COMM_SELF,MatrixFree::AdditionalData::none)); + typename MatrixFree::AdditionalData(MPI_COMM_SELF,MatrixFree::AdditionalData::none)); } - MatrixFreeTest mf (mf_data); + MatrixFreeTest mf (mf_data); Vector solution (dof.n_dofs()); Vector solution_dist (dof.n_dofs()); diff --git a/tests/matrix_free/integrate_functions_multife.cc b/tests/matrix_free/integrate_functions_multife.cc index 9b3bcaf00a..5796664c9b 100644 --- a/tests/matrix_free/integrate_functions_multife.cc +++ b/tests/matrix_free/integrate_functions_multife.cc @@ -33,7 +33,7 @@ std::ofstream logfile("integrate_functions_multife/output"); -template +template class MatrixFreeTest { public: @@ -44,28 +44,28 @@ class MatrixFreeTest MatrixFreeTest(const MatrixFree &data_in): data (data_in), fe_val0 (data.get_dof_handler(0).get_fe(), - Quadrature(data.get_quad(0)), - update_values | update_gradients | update_JxW_values), + Quadrature(data.get_quad(0)), + update_values | update_gradients | update_JxW_values), fe_val01 (data.get_dof_handler(0).get_fe(), - Quadrature(data.get_quad(1)), - update_values | update_gradients | update_JxW_values), + Quadrature(data.get_quad(1)), + update_values | update_gradients | update_JxW_values), fe_val1 (data.get_dof_handler(1).get_fe(), - Quadrature(data.get_quad(1)), - update_values | update_gradients | update_JxW_values) + Quadrature(data.get_quad(1)), + update_values | update_gradients | update_JxW_values) {}; void operator () (const MatrixFree &data, - VectorType &dst, - const VectorType &src, - const std::pair &cell_range) const; + VectorType &dst, + const VectorType &src, + const std::pair &cell_range) const; void test_functions (VectorType &dst) const { for (unsigned int comp=0; comp::operator(), this, - dst, src_dummy); + data.cell_loop (&MatrixFreeTest::operator(), this, + dst, src_dummy); }; private: @@ -78,16 +78,16 @@ private: -template -void MatrixFreeTest:: +template +void MatrixFreeTest:: operator () (const MatrixFree &data, - std::vector > &dst, - const std::vector > &, - const std::pair &cell_range) const + std::vector > &dst, + const std::vector > &, + const std::pair &cell_range) const { - FEEvaluation fe_eval0 (data, 0, 0); - FEEvaluation fe_eval1 (data, 1, 1); - FEEvaluation fe_eval01 (data, 0, 1); + FEEvaluation fe_eval0 (data, 0, 0); + FEEvaluation fe_eval1 (data, 1, 1); + FEEvaluation fe_eval01 (data, 0, 1); const unsigned int n_q_points0 = fe_eval0.n_q_points; const unsigned int n_q_points1 = fe_eval1.n_q_points; const unsigned int dofs_per_cell0 = fe_eval0.dofs_per_cell; @@ -104,108 +104,108 @@ operator () (const MatrixFree &data, fe_eval1.reinit(cell); fe_eval01.reinit(cell); - // compare values with the ones the FEValues - // gives us. Those are seen as reference + // compare values with the ones the FEValues + // gives us. Those are seen as reference for (unsigned int j=0; jget_dof_indices(dof_indices0); - - for (unsigned int i=0; iget_dof_indices(dof_indices1); - - for (unsigned int q=0; qget_dof_indices(dof_indices0); + + for (unsigned int i=0; iget_dof_indices(dof_indices1); + + for (unsigned int q=0; q submit (false); - for (unsigned int d=0; d submit (false); + for (unsigned int d=0; d submit (false); - for (unsigned int d=0; d submit (false); + for (unsigned int d=0; d submit (false); - for (unsigned int d=0; d submit (false); + for (unsigned int d=0; d &data, template void test () { - // create hyper ball geometry and refine some - // cells + // create hyper ball geometry and refine some + // cells Triangulation tria; GridGenerator::hyper_ball (tria); static const HyperBallBoundary boundary; @@ -245,8 +245,8 @@ void test () cell = tria.begin_active (); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -293,10 +293,10 @@ void test () for (unsigned int no=0; no<2; ++no) quad.push_back(QGauss<1>(fe_degree+1+no)); mf_data.reinit (dof, constraints, quad, - typename MatrixFree::AdditionalData(MPI_COMM_SELF,MatrixFree::AdditionalData::none)); + typename MatrixFree::AdditionalData(MPI_COMM_SELF,MatrixFree::AdditionalData::none)); } - MatrixFreeTest mf (mf_data); + MatrixFreeTest mf (mf_data); mf.test_functions(dst); constraints[0]->condense(dst[1]); diff --git a/tests/matrix_free/integrate_functions_multife2.cc b/tests/matrix_free/integrate_functions_multife2.cc index ec6e28bb07..c94c0077b9 100644 --- a/tests/matrix_free/integrate_functions_multife2.cc +++ b/tests/matrix_free/integrate_functions_multife2.cc @@ -34,7 +34,7 @@ std::ofstream logfile("integrate_functions_multife2/output"); -template +template class MatrixFreeTest { public: @@ -45,28 +45,28 @@ class MatrixFreeTest MatrixFreeTest(const MatrixFree &data_in): data (data_in), fe_val0 (data.get_dof_handler(0).get_fe(), - Quadrature(data.get_quad(0)), - update_values | update_gradients | update_JxW_values), + Quadrature(data.get_quad(0)), + update_values | update_gradients | update_JxW_values), fe_val01 (data.get_dof_handler(0).get_fe(), - Quadrature(data.get_quad(1)), - update_values | update_gradients | update_JxW_values), + Quadrature(data.get_quad(1)), + update_values | update_gradients | update_JxW_values), fe_val1 (data.get_dof_handler(1).get_fe(), - Quadrature(data.get_quad(1)), - update_values | update_gradients | update_JxW_values) + Quadrature(data.get_quad(1)), + update_values | update_gradients | update_JxW_values) {}; void operator () (const MatrixFree &data, - VectorType &dst, - const VectorType &src, - const std::pair &cell_range) const; + VectorType &dst, + const VectorType &src, + const std::pair &cell_range) const; void test_functions (VectorType &dst) const { for (unsigned int comp=0; comp::operator(), this, - dst, src_dummy); + data.cell_loop (&MatrixFreeTest::operator(), this, + dst, src_dummy); }; private: @@ -79,16 +79,16 @@ private: -template -void MatrixFreeTest:: +template +void MatrixFreeTest:: operator () (const MatrixFree &data, - std::vector > &dst, - const std::vector > &, - const std::pair &cell_range) const + std::vector > &dst, + const std::vector > &, + const std::pair &cell_range) const { - FEEvaluation fe_eval0 (data, 0, 0); - FEEvaluation fe_eval1 (data, 1, 1); - FEEvaluation fe_eval01 (data, 0, 1); + FEEvaluation fe_eval0 (data, 0, 0); + FEEvaluation fe_eval1 (data, 1, 1); + FEEvaluation fe_eval01 (data, 0, 1); const unsigned int n_q_points0 = fe_eval0.n_q_points; const unsigned int n_q_points1 = fe_eval1.n_q_points; const unsigned int dofs_per_cell0 = fe_eval0.dofs_per_cell; @@ -105,108 +105,108 @@ operator () (const MatrixFree &data, fe_eval1.reinit(cell); fe_eval01.reinit(cell); - // compare values with the ones the FEValues - // gives us. Those are seen as reference + // compare values with the ones the FEValues + // gives us. Those are seen as reference for (unsigned int j=0; jget_dof_indices(dof_indices0); - - for (unsigned int i=0; iget_dof_indices(dof_indices1); - - for (unsigned int q=0; qget_dof_indices(dof_indices0); + + for (unsigned int i=0; iget_dof_indices(dof_indices1); + + for (unsigned int q=0; q submit (false); - for (unsigned int d=0; d submit (false); + for (unsigned int d=0; d submit (false); - for (unsigned int d=0; d submit (false); + for (unsigned int d=0; d submit (false); - for (unsigned int d=0; d submit (false); + for (unsigned int d=0; d &data, template void test () { - // create hyper ball geometry and refine some - // cells + // create hyper ball geometry and refine some + // cells Triangulation tria; GridGenerator::hyper_ball (tria); static const HyperBallBoundary boundary; @@ -246,8 +246,8 @@ void test () cell = tria.begin_active (); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -293,10 +293,10 @@ void test () quad.push_back (QGauss<1>(1)); quad.push_back (QGauss<1>(fe_degree+1)); mf_data.reinit (dof, constraints, quad, - typename MatrixFree::AdditionalData(MPI_COMM_SELF,MatrixFree::AdditionalData::none)); + typename MatrixFree::AdditionalData(MPI_COMM_SELF,MatrixFree::AdditionalData::none)); } - MatrixFreeTest mf (mf_data); + MatrixFreeTest mf (mf_data); mf.test_functions(dst); constraints[0]->condense(dst[1]); diff --git a/tests/matrix_free/matrix_vector_02.cc b/tests/matrix_free/matrix_vector_02.cc index 758b33c639..fa8f01c005 100644 --- a/tests/matrix_free/matrix_vector_02.cc +++ b/tests/matrix_free/matrix_vector_02.cc @@ -30,7 +30,7 @@ void test () dof.distribute_dofs(fe); ConstraintMatrix constraints; VectorTools::interpolate_boundary_values (dof, 0, ZeroFunction(), - constraints); + constraints); constraints.close(); do_test (dof, constraints); diff --git a/tests/matrix_free/matrix_vector_03.cc b/tests/matrix_free/matrix_vector_03.cc index 030c3bf951..4470cb77b6 100644 --- a/tests/matrix_free/matrix_vector_03.cc +++ b/tests/matrix_free/matrix_vector_03.cc @@ -47,8 +47,8 @@ void test () cell = tria.begin_active (); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -58,7 +58,7 @@ void test () ConstraintMatrix constraints; DoFTools::make_hanging_node_constraints(dof, constraints); VectorTools::interpolate_boundary_values (dof, 0, ZeroFunction(), - constraints); + constraints); constraints.close(); do_test (dof, constraints); diff --git a/tests/matrix_free/matrix_vector_05.cc b/tests/matrix_free/matrix_vector_05.cc index eeed34c4b7..838bf0790f 100644 --- a/tests/matrix_free/matrix_vector_05.cc +++ b/tests/matrix_free/matrix_vector_05.cc @@ -52,8 +52,8 @@ void test () cell = tria.begin_active (); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } diff --git a/tests/matrix_free/matrix_vector_06.cc b/tests/matrix_free/matrix_vector_06.cc index 62ae39486f..fc0d926027 100644 --- a/tests/matrix_free/matrix_vector_06.cc +++ b/tests/matrix_free/matrix_vector_06.cc @@ -46,8 +46,8 @@ void test () endc = tria.end(); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -57,7 +57,7 @@ void test () ConstraintMatrix constraints; DoFTools::make_hanging_node_constraints(dof, constraints); VectorTools::interpolate_boundary_values (dof, 0, ZeroFunction(), - constraints); + constraints); constraints.close(); do_test (dof, constraints); diff --git a/tests/matrix_free/matrix_vector_07.cc b/tests/matrix_free/matrix_vector_07.cc index 274fc22eac..104d592e3b 100644 --- a/tests/matrix_free/matrix_vector_07.cc +++ b/tests/matrix_free/matrix_vector_07.cc @@ -53,8 +53,8 @@ void test () cell = tria.begin_active (); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -62,17 +62,17 @@ void test () DoFHandler dof (tria); dof.distribute_dofs(fe); ConstraintMatrix constraints; - // there should not be any hanging nodes or - // boundary conditions for FE_DGQ as there are - // only interior DoFs on the elements, but try - // anyway + // there should not be any hanging nodes or + // boundary conditions for FE_DGQ as there are + // only interior DoFs on the elements, but try + // anyway DoFTools::make_hanging_node_constraints(dof, constraints); VectorTools::interpolate_boundary_values (dof, 0, ZeroFunction(), - constraints); + constraints); constraints.close(); do_test (dof, constraints); - // test with coloring only as well + // test with coloring only as well do_test (dof, constraints, 2); } diff --git a/tests/matrix_free/matrix_vector_08.cc b/tests/matrix_free/matrix_vector_08.cc index 6d0a5782b2..3511799f87 100644 --- a/tests/matrix_free/matrix_vector_08.cc +++ b/tests/matrix_free/matrix_vector_08.cc @@ -44,8 +44,8 @@ void test () endc = tria.end(); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -55,7 +55,7 @@ void test () ConstraintMatrix constraints; DoFTools::make_hanging_node_constraints(dof, constraints); VectorTools::interpolate_boundary_values (dof, 0, ZeroFunction(), - constraints); + constraints); constraints.close(); do_test (dof, constraints); diff --git a/tests/matrix_free/matrix_vector_09.cc b/tests/matrix_free/matrix_vector_09.cc index a0509e8c3c..20ca29bab8 100644 --- a/tests/matrix_free/matrix_vector_09.cc +++ b/tests/matrix_free/matrix_vector_09.cc @@ -44,8 +44,8 @@ void test () endc = tria.end(); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -55,7 +55,7 @@ void test () ConstraintMatrix constraints; DoFTools::make_hanging_node_constraints(dof, constraints); VectorTools::interpolate_boundary_values (dof, 0, ZeroFunction(), - constraints); + constraints); constraints.close(); do_test (dof, constraints); diff --git a/tests/matrix_free/matrix_vector_common.h b/tests/matrix_free/matrix_vector_common.h index a4e5b05e0b..054e084812 100644 --- a/tests/matrix_free/matrix_vector_common.h +++ b/tests/matrix_free/matrix_vector_common.h @@ -39,29 +39,29 @@ void test (); -template +template void helmholtz_operator (const MatrixFree &data, - Vector &dst, - const Vector &src, - const std::pair &cell_range) + Vector &dst, + const Vector &src, + const std::pair &cell_range) { - FEEvaluation fe_eval (data); + FEEvaluation fe_eval (data); const unsigned int n_q_points = fe_eval.n_q_points; for(unsigned int cell=cell_range.first;cell &data, -template +template class MatrixFreeTest { public: @@ -81,14 +81,14 @@ class MatrixFreeTest {}; void vmult (Vector &dst, - const Vector &src) const + const Vector &src) const { dst = 0; const std_cxx1x::function &, - Vector &, - const Vector &, - const std::pair&)> - wrap = helmholtz_operator; + Vector &, + const Vector &, + const std::pair&)> + wrap = helmholtz_operator; data.cell_loop (wrap, dst, src); }; @@ -102,8 +102,8 @@ private: template void do_test (const DoFHandler &dof, - const ConstraintMatrix&constraints, - const unsigned int parallel_option = 0) + const ConstraintMatrix&constraints, + const unsigned int parallel_option = 0) { deallog << "Testing " << dof.get_fe().get_name() << std::endl; @@ -119,22 +119,22 @@ void do_test (const DoFHandler &dof, typename MatrixFree::AdditionalData data; if (parallel_option == 1) data.tasks_parallel_scheme = - MatrixFree::AdditionalData::partition_color; + MatrixFree::AdditionalData::partition_color; else if (parallel_option == 2) data.tasks_parallel_scheme = - MatrixFree::AdditionalData::color; + MatrixFree::AdditionalData::color; else { - Assert (parallel_option == 0, ExcInternalError()); - data.tasks_parallel_scheme = - MatrixFree::AdditionalData::partition_partition; + Assert (parallel_option == 0, ExcInternalError()); + data.tasks_parallel_scheme = + MatrixFree::AdditionalData::partition_partition; } data.tasks_block_size = 7; mf_data.reinit (dof, constraints, quad, data); } - MatrixFreeTest mf (mf_data); + MatrixFreeTest mf (mf_data); Vector in (dof.n_dofs()), out (dof.n_dofs()); Vector in_dist (dof.n_dofs()); Vector out_dist (in_dist); @@ -142,7 +142,7 @@ void do_test (const DoFHandler &dof, for (unsigned int i=0; i &dof, mf.vmult (out_dist, in_dist); - // assemble sparse matrix with (\nabla v, - // \nabla u) + (v, 10 * u) + // assemble sparse matrix with (\nabla v, + // \nabla u) + (v, 10 * u) SparsityPattern sparsity; { CompressedSimpleSparsityPattern csp(dof.n_dofs(), dof.n_dofs()); @@ -164,8 +164,8 @@ void do_test (const DoFHandler &dof, QGauss quadrature_formula(fe_degree+1); FEValues fe_values (dof.get_fe(), quadrature_formula, - update_values | update_gradients | - update_JxW_values); + update_values | update_gradients | + update_JxW_values); const unsigned int dofs_per_cell = dof.get_fe().dofs_per_cell; const unsigned int n_q_points = quadrature_formula.size(); @@ -178,26 +178,26 @@ void do_test (const DoFHandler &dof, endc = dof.end(); for (; cell!=endc; ++cell) { - cell_matrix = 0; - fe_values.reinit (cell); - - for (unsigned int q_point=0; q_pointget_dof_indices(local_dof_indices); - constraints.distribute_local_to_global (cell_matrix, - local_dof_indices, - sparse_matrix); + cell_matrix = 0; + fe_values.reinit (cell); + + for (unsigned int q_point=0; q_pointget_dof_indices(local_dof_indices); + constraints.distribute_local_to_global (cell_matrix, + local_dof_indices, + sparse_matrix); } } diff --git a/tests/matrix_free/matrix_vector_curl.cc b/tests/matrix_free/matrix_vector_curl.cc index c90f385562..6a8f53b32d 100644 --- a/tests/matrix_free/matrix_vector_curl.cc +++ b/tests/matrix_free/matrix_vector_curl.cc @@ -55,36 +55,36 @@ class MatrixFreeTest void local_apply (const MatrixFree &data, - VectorType &dst, - const VectorType &src, - const std::pair &cell_range) const + VectorType &dst, + const VectorType &src, + const std::pair &cell_range) const { typedef VectorizedArray vector_t; - FEEvaluation phi (data); + FEEvaluation phi (data); vector_t coeff = make_vectorized_array(global_coefficient); for(unsigned int cell=cell_range.first;cell::local_apply, - this, dst, src); + this, dst, src); }; private: @@ -102,16 +102,16 @@ void test () tria.set_boundary (0, boundary); tria.refine_global(4-dim); - // refine a few cells + // refine a few cells for (unsigned int i=0; i<10-3*dim; ++i) { typename Triangulation::active_cell_iterator - cell = tria.begin_active (), - endc = tria.end(); + cell = tria.begin_active (), + endc = tria.end(); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -144,7 +144,7 @@ void test () BlockCompressedSimpleSparsityPattern csp (dim,dim); for (unsigned int d=0; d quadrature_formula(fe_degree+1); FEValues fe_values (fe, quadrature_formula, - update_values | - update_JxW_values | - update_gradients); + update_values | + update_JxW_values | + update_gradients); const unsigned int dofs_per_cell = fe.dofs_per_cell; const unsigned int n_q_points = quadrature_formula.size(); @@ -197,63 +197,63 @@ void test () endc = dof_handler.end(); for (; cell!=endc; ++cell) { - fe_values.reinit (cell); - local_matrix = 0; - - for (unsigned int q=0; q phi_grad = fe_values[sc].gradient(k,q); - if (dim == 2) - phi_curl[k][0] = phi_grad[1][0] - phi_grad[0][1]; - else - { - phi_curl[k][0] = phi_grad[2][1] - phi_grad[1][2]; - phi_curl[k][1] = phi_grad[0][2] - phi_grad[2][0]; - phi_curl[k][2] = phi_grad[1][0] - phi_grad[0][1]; - } - } - - for (unsigned int i=0; iget_dof_indices (local_dof_indices); - constraints.distribute_local_to_global (local_matrix, - local_dof_indices, - system_matrix); + fe_values.reinit (cell); + local_matrix = 0; + + for (unsigned int q=0; q phi_grad = fe_values[sc].gradient(k,q); + if (dim == 2) + phi_curl[k][0] = phi_grad[1][0] - phi_grad[0][1]; + else + { + phi_curl[k][0] = phi_grad[2][1] - phi_grad[1][2]; + phi_curl[k][1] = phi_grad[0][2] - phi_grad[2][0]; + phi_curl[k][2] = phi_grad[1][0] - phi_grad[0][1]; + } + } + + for (unsigned int i=0; iget_dof_indices (local_dof_indices); + constraints.distribute_local_to_global (local_matrix, + local_dof_indices, + system_matrix); } } - // first system_rhs with random numbers + // first system_rhs with random numbers for (unsigned int i=0; i quad(fe_degree+1); mf_data.reinit (dof_handler_sca, constraints, quad, - typename MatrixFree::AdditionalData - (MPI_COMM_WORLD, - MatrixFree::AdditionalData::none)); + typename MatrixFree::AdditionalData + (MPI_COMM_WORLD, + MatrixFree::AdditionalData::none)); } system_matrix.vmult (solution, system_rhs); @@ -262,14 +262,14 @@ void test () MatrixFreeTest mf (mf_data); mf.vmult (vec2, vec1); - // Verification + // Verification double error = 0.; for (unsigned int i=0; iset_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } diff --git a/tests/matrix_free/matrix_vector_hp.cc b/tests/matrix_free/matrix_vector_hp.cc index 7c048fcecd..0577fe6a37 100644 --- a/tests/matrix_free/matrix_vector_hp.cc +++ b/tests/matrix_free/matrix_vector_hp.cc @@ -33,44 +33,44 @@ class MatrixFreeTestHP {}; void local_apply(const MatrixFree &data, - Vector &dst, - const Vector &src, - const std::pair &cell_range) const + Vector &dst, + const Vector &src, + const std::pair &cell_range) const { // ask MatrixFree for cell_range for different orders std::pair subrange_deg = data.create_cell_subrange_hp (cell_range, 1); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); subrange_deg = data.create_cell_subrange_hp (cell_range, 2); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); subrange_deg = data.create_cell_subrange_hp (cell_range, 3); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); subrange_deg = data.create_cell_subrange_hp (cell_range, 4); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); subrange_deg = data.create_cell_subrange_hp (cell_range, 5); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); subrange_deg = data.create_cell_subrange_hp (cell_range, 6); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); subrange_deg = data.create_cell_subrange_hp (cell_range, 7); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); } void vmult (Vector &dst, - const Vector &src) const + const Vector &src) const { dst = 0; data.cell_loop (&MatrixFreeTestHP::local_apply, this, dst, src); @@ -95,16 +95,16 @@ void test () tria.set_boundary (0, boundary); tria.refine_global(1); - // refine a few cells + // refine a few cells for (unsigned int i=0; i<11-3*dim; ++i) { typename Triangulation::active_cell_iterator - cell = tria.begin_active (), - endc = tria.end(); + cell = tria.begin_active (), + endc = tria.end(); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -122,30 +122,30 @@ void test () } hp::DoFHandler dof(tria); - // set the active FE index in a random order + // set the active FE index in a random order { typename hp::DoFHandler::active_cell_iterator cell = dof.begin_active(), endc = dof.end(); for (; cell!=endc; ++cell) { - const unsigned int fe_index = rand() % max_degree; - cell->set_active_fe_index (fe_index); + const unsigned int fe_index = rand() % max_degree; + cell->set_active_fe_index (fe_index); } } - // setup DoFs + // setup DoFs dof.distribute_dofs(fe_collection); ConstraintMatrix constraints; DoFTools::make_hanging_node_constraints (dof, - constraints); + constraints); VectorTools::interpolate_boundary_values (dof, - 0, - ZeroFunction(), - constraints); + 0, + ZeroFunction(), + constraints); constraints.close (); CompressedSimpleSparsityPattern csp (dof.n_dofs(), - dof.n_dofs()); + dof.n_dofs()); DoFTools::make_sparsity_pattern (dof, csp, constraints, false); SparsityPattern sparsity; sparsity.copy_from (csp); @@ -155,7 +155,7 @@ void test () //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl; - // set up MatrixFree + // set up MatrixFree MatrixFree mf_data; typename MatrixFree::AdditionalData data; data.tasks_parallel_scheme = @@ -163,13 +163,13 @@ void test () mf_data.reinit (dof, constraints, quadrature_collection_mf, data); MatrixFreeTestHP mf (mf_data); - // assemble sparse matrix with (\nabla v, - // \nabla u) + (v, 10 * u) + // assemble sparse matrix with (\nabla v, + // \nabla u) + (v, 10 * u) { hp::FEValues hp_fe_values (fe_collection, - quadrature_collection, - update_values | update_gradients | - update_JxW_values); + quadrature_collection, + update_values | update_gradients | + update_JxW_values); FullMatrix cell_matrix; std::vector local_dof_indices; @@ -178,47 +178,47 @@ void test () endc = dof.end(); for (; cell!=endc; ++cell) { - const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell; - - cell_matrix.reinit (dofs_per_cell, dofs_per_cell); - cell_matrix = 0; - hp_fe_values.reinit (cell); - const FEValues &fe_values = hp_fe_values.get_present_fe_values (); - - for (unsigned int q_point=0; - q_pointget_dof_indices (local_dof_indices); - - constraints.distribute_local_to_global (cell_matrix, - local_dof_indices, - system_matrix); + const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell; + + cell_matrix.reinit (dofs_per_cell, dofs_per_cell); + cell_matrix = 0; + hp_fe_values.reinit (cell); + const FEValues &fe_values = hp_fe_values.get_present_fe_values (); + + for (unsigned int q_point=0; + q_pointget_dof_indices (local_dof_indices); + + constraints.distribute_local_to_global (cell_matrix, + local_dof_indices, + system_matrix); } } - // fill a right hand side vector with random - // numbers in unconstrained degrees of freedom + // fill a right hand side vector with random + // numbers in unconstrained degrees of freedom Vector src (dof.n_dofs()); Vector result_spmv(src), result_mf (src); for (unsigned int i=0; i fe (fe_degree); - // setup DoFs + // setup DoFs MGDoFHandler dof(tria); dof.distribute_dofs(fe); ConstraintMatrix constraints; VectorTools::interpolate_boundary_values (dof, - 0, - ZeroFunction(), - constraints); + 0, + ZeroFunction(), + constraints); constraints.close (); //std::cout << "Number of cells: " << dof.get_tria().n_active_cells() << std::endl; //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; - // set up MatrixFree + // set up MatrixFree QGauss<1> quad (fe_degree+1); MatrixFree mf_data; mf_data.reinit (dof, constraints, quad); @@ -55,12 +55,12 @@ void test () { CompressedSimpleSparsityPattern csp (dof.n_dofs(), dof.n_dofs()); DoFTools::make_sparsity_pattern (static_cast&>(dof), - csp, constraints, false); + csp, constraints, false); sparsity.copy_from (csp); } system_matrix.reinit (sparsity); - // setup MG levels + // setup MG levels const unsigned int nlevels = tria.n_levels(); typedef MatrixFree MatrixFreeTestType; MGLevelObject mg_matrices; @@ -94,14 +94,14 @@ void test () mg_ref_matrices[level].reinit (mg_sparsities[level]); } - // assemble sparse matrix with (\nabla v, - // \nabla u) + (v, 10 * u) on the actual - // discretization and on all levels + // assemble sparse matrix with (\nabla v, + // \nabla u) + (v, 10 * u) on the actual + // discretization and on all levels { QGauss quad (fe_degree+1); FEValues fe_values (fe, quad, - update_values | update_gradients | - update_JxW_values); + update_values | update_gradients | + update_JxW_values); const unsigned int n_quadrature_points = quad.size(); const unsigned int dofs_per_cell = fe.dofs_per_cell; FullMatrix cell_matrix (dofs_per_cell, dofs_per_cell); @@ -112,23 +112,23 @@ void test () endc = dof.end(); for (; cell!=endc; ++cell) { - cell_matrix = 0; - fe_values.reinit (cell); - - for (unsigned int q_point=0; q_pointget_dof_indices (local_dof_indices); - constraints.distribute_local_to_global (cell_matrix, - local_dof_indices, - system_matrix); + cell_matrix = 0; + fe_values.reinit (cell); + + for (unsigned int q_point=0; q_pointget_dof_indices (local_dof_indices); + constraints.distribute_local_to_global (cell_matrix, + local_dof_indices, + system_matrix); } // now to the MG assembly @@ -137,42 +137,42 @@ void test () endcm = dof.end(); for (; cellm!=endcm; ++cellm) { - cell_matrix = 0; - fe_values.reinit (cellm); - - for (unsigned int q_point=0; q_pointget_mg_dof_indices (local_dof_indices); - mg_constraints[cellm->level()] - .distribute_local_to_global (cell_matrix, - local_dof_indices, - mg_ref_matrices[cellm->level()]); + cell_matrix = 0; + fe_values.reinit (cellm); + + for (unsigned int q_point=0; q_pointget_mg_dof_indices (local_dof_indices); + mg_constraints[cellm->level()] + .distribute_local_to_global (cell_matrix, + local_dof_indices, + mg_ref_matrices[cellm->level()]); } } - // fill a right hand side vector with random - // numbers in unconstrained degrees of freedom + // fill a right hand side vector with random + // numbers in unconstrained degrees of freedom Vector src (dof.n_dofs()); Vector result_spmv(src), result_mf (src); for (unsigned int i=0; i mf (mf_data); + MatrixFreeTest mf (mf_data); mf.vmult (result_mf, src); result_mf -= result_spmv; @@ -185,21 +185,21 @@ void test () Vector result_spmv(src), result_mf (src); for (unsigned int i=0; i mf_lev (mg_matrices[level]); + MatrixFreeTest mf_lev (mg_matrices[level]); mf_lev.vmult (result_mf, src); result_mf -= result_spmv; const double diff_norm = result_mf.linfty_norm(); deallog << "Norm of difference MG level " << level - << ": " << diff_norm << std::endl; + << ": " << diff_norm << std::endl; } deallog << std::endl; } diff --git a/tests/matrix_free/matrix_vector_stokes.cc b/tests/matrix_free/matrix_vector_stokes.cc index 508aa84dfb..f1caacaf72 100644 --- a/tests/matrix_free/matrix_vector_stokes.cc +++ b/tests/matrix_free/matrix_vector_stokes.cc @@ -53,54 +53,54 @@ class MatrixFreeTest void local_apply (const MatrixFree &data, - VectorType &dst, - const VectorType &src, - const std::pair &cell_range) const + VectorType &dst, + const VectorType &src, + const std::pair &cell_range) const { typedef VectorizedArray vector_t; - FEEvaluation velocity (data, 0); - FEEvaluation pressure (data, 1); + FEEvaluation velocity (data, 0); + FEEvaluation pressure (data, 1); for(unsigned int cell=cell_range.first;cell sym_grad_u = - velocity.get_symmetric_gradient (q); - vector_t pres = pressure.get_value(q); - vector_t div = -velocity.get_divergence(q); - pressure.submit_value (div, q); - - // subtract p * I - for (unsigned int d=0; d sym_grad_u = + velocity.get_symmetric_gradient (q); + vector_t pres = pressure.get_value(q); + vector_t div = -velocity.get_divergence(q); + pressure.submit_value (div, q); + + // subtract p * I + for (unsigned int d=0; d::local_apply, - this, dst, src); + this, dst, src); }; private: @@ -118,16 +118,16 @@ void test () subdivisions[0] = 4; const Point bottom_left = (dim == 2 ? - Point(-2,-1) : - Point(-2,0,-1)); + Point(-2,-1) : + Point(-2,0,-1)); const Point top_right = (dim == 2 ? - Point(2,0) : - Point(2,1,0)); + Point(2,0) : + Point(2,1,0)); GridGenerator::subdivided_hyper_rectangle (triangulation, - subdivisions, - bottom_left, - top_right); + subdivisions, + bottom_left, + top_right); } triangulation.refine_global (4-dim); @@ -172,7 +172,7 @@ void test () for (unsigned int d=0; d quadrature_formula(fe_degree+2); FEValues fe_values (fe, quadrature_formula, - update_values | - update_JxW_values | - update_gradients); + update_values | + update_JxW_values | + update_gradients); const unsigned int dofs_per_cell = fe.dofs_per_cell; const unsigned int n_q_points = quadrature_formula.size(); @@ -229,50 +229,50 @@ void test () endc = dof_handler.end(); for (; cell!=endc; ++cell) { - fe_values.reinit (cell); - local_matrix = 0; - - for (unsigned int q=0; qget_dof_indices (local_dof_indices); - constraints.distribute_local_to_global (local_matrix, - local_dof_indices, - system_matrix); + fe_values.reinit (cell); + local_matrix = 0; + + for (unsigned int q=0; qget_dof_indices (local_dof_indices); + constraints.distribute_local_to_global (local_matrix, + local_dof_indices, + system_matrix); } } - // first system_rhs with random numbers + // first system_rhs with random numbers for (unsigned int i=0; i*> dofs; dofs.push_back(&dof_handler_u); @@ -284,9 +284,9 @@ void test () constraints.push_back (&dummy_constraints); QGauss<1> quad(fe_degree+2); mf_data.reinit (dofs, constraints, quad, - typename MatrixFree::AdditionalData - (MPI_COMM_WORLD, - MatrixFree::AdditionalData::none)); + typename MatrixFree::AdditionalData + (MPI_COMM_WORLD, + MatrixFree::AdditionalData::none)); } system_matrix.vmult (solution, system_rhs); @@ -295,14 +295,14 @@ void test () MatrixFreeTest mf (mf_data); mf.vmult (vec2, vec1); - // Verification + // Verification double error = 0.; for (unsigned int i=0; i &data, - VectorType &dst, - const VectorType &src, - const std::pair &cell_range) const + VectorType &dst, + const VectorType &src, + const std::pair &cell_range) const { typedef VectorizedArray vector_t; - FEEvaluation velocity (data, 0); - FEEvaluation pressure (data, 1); + FEEvaluation velocity (data, 0); + FEEvaluation pressure (data, 1); for(unsigned int cell=cell_range.first;cell sym_grad_u = - velocity.get_symmetric_gradient (q); - vector_t pres = pressure.get_value(q); - vector_t div = -velocity.get_divergence(q); - pressure.submit_value (div, q); - - // subtract p * I - for (unsigned int d=0; d sym_grad_u = + velocity.get_symmetric_gradient (q); + vector_t pres = pressure.get_value(q); + vector_t div = -velocity.get_divergence(q); + pressure.submit_value (div, q); + + // subtract p * I + for (unsigned int d=0; d::local_apply, - this, dst, src); + this, dst, src); }; private: @@ -115,7 +115,7 @@ void test () { Triangulation triangulation; GridGenerator::hyper_shell (triangulation, Point(), - 0.5, 1., 96, true); + 0.5, 1., 96, true); static HyperShellBoundary boundary; triangulation.set_boundary (0, boundary); triangulation.set_boundary (1, boundary); @@ -157,39 +157,39 @@ void test () no_normal_flux_boundaries.insert (0); no_normal_flux_boundaries.insert (1); DoFTools::make_hanging_node_constraints (dof_handler, - constraints); + constraints); VectorTools::compute_no_normal_flux_constraints (dof_handler, 0, - no_normal_flux_boundaries, - constraints, mapping); + no_normal_flux_boundaries, + constraints, mapping); constraints.close (); DoFTools::make_hanging_node_constraints (dof_handler_u, - constraints_u); + constraints_u); VectorTools::compute_no_normal_flux_constraints (dof_handler_u, 0, - no_normal_flux_boundaries, - constraints_u, mapping); + no_normal_flux_boundaries, + constraints_u, mapping); constraints_u.close (); DoFTools::make_hanging_node_constraints (dof_handler_p, - constraints_p); + constraints_p); constraints_p.close (); std::vector dofs_per_block (2); DoFTools::count_dofs_per_block (dof_handler, dofs_per_block, - stokes_sub_blocks); + stokes_sub_blocks); //std::cout << "Number of active cells: " - // << triangulation.n_active_cells() - // << std::endl - // << "Number of degrees of freedom: " - // << dof_handler.n_dofs() - // << " (" << n_u << '+' << n_p << ')' - // << std::endl; + // << triangulation.n_active_cells() + // << std::endl + // << "Number of degrees of freedom: " + // << dof_handler.n_dofs() + // << " (" << n_u << '+' << n_p << ')' + // << std::endl; { BlockCompressedSimpleSparsityPattern csp (2,2); for (unsigned int d=0; d<2; ++d) for (unsigned int e=0; e<2; ++e) - csp.block(d,e).reinit (dofs_per_block[d], dofs_per_block[e]); + csp.block(d,e).reinit (dofs_per_block[d], dofs_per_block[e]); csp.collect_sizes(); @@ -199,14 +199,14 @@ void test () system_matrix.reinit (sparsity_pattern); - // this is from step-22 + // this is from step-22 { QGauss quadrature_formula(fe_degree+2); FEValues fe_values (mapping, fe, quadrature_formula, - update_values | - update_JxW_values | - update_gradients); + update_values | + update_JxW_values | + update_gradients); const unsigned int dofs_per_cell = fe.dofs_per_cell; const unsigned int n_q_points = quadrature_formula.size(); @@ -227,37 +227,37 @@ void test () endc = dof_handler.end(); for (; cell!=endc; ++cell) { - fe_values.reinit (cell); - local_matrix = 0; - - for (unsigned int q=0; qget_dof_indices (local_dof_indices); - constraints.distribute_local_to_global (local_matrix, - local_dof_indices, - system_matrix); + fe_values.reinit (cell); + local_matrix = 0; + + for (unsigned int q=0; qget_dof_indices (local_dof_indices); + constraints.distribute_local_to_global (local_matrix, + local_dof_indices, + system_matrix); } } @@ -277,23 +277,23 @@ void test () vec2[d].reinit (vec1[d]); } - // fill system_rhs with random numbers + // fill system_rhs with random numbers for (unsigned int j=0; j*> dofs; dofs.push_back(&dof_handler_u); @@ -302,11 +302,11 @@ void test () constraints.push_back (&constraints_u); constraints.push_back (&constraints_p); QGauss<1> quad(fe_degree+2); - // no parallelism + // no parallelism mf_data.reinit (mapping, dofs, constraints, quad, - typename MatrixFree::AdditionalData - (MPI_COMM_WORLD, - MatrixFree::AdditionalData::none)); + typename MatrixFree::AdditionalData + (MPI_COMM_WORLD, + MatrixFree::AdditionalData::none)); } system_matrix.vmult (solution, system_rhs); @@ -315,14 +315,14 @@ void test () MatrixFreeTest mf (mf_data); mf.vmult (vec2, vec1); - // Verification + // Verification double error = 0.; for (unsigned int i=0; i<2; ++i) for (unsigned int j=0; j fe_eval (mf_data); + FEEvaluation fe_eval (mf_data); FEValues fe_values (mapping, fe, mf_data.get_quad(), - update_quadrature_points); + update_quadrature_points); typedef VectorizedArray vector_t; for (unsigned int cell=0; cell dof (tria); deallog << "Testing " << fe.get_name() << std::endl; - // run test for several different meshes + // run test for several different meshes for (unsigned int i=0; i<8-2*dim; ++i) { cell = tria.begin_active (); endc = tria.end(); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (counter % (9-i) == 0) - cell->set_refine_flag(); + if (counter % (9-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); dof.distribute_dofs(fe); ConstraintMatrix constraints; DoFTools::make_hanging_node_constraints(dof, constraints); VectorTools::interpolate_boundary_values (dof, 0, ZeroFunction(), - constraints); + constraints); constraints.close(); //std::cout << "Number of cells: " << dof.get_tria().n_active_cells() << std::endl; @@ -69,60 +69,60 @@ void sub_test() MatrixFree mf_data, mf_data_color, mf_data_partition; { - const QGauss<1> quad (fe_degree+1); - mf_data.reinit (dof, constraints, quad, - typename MatrixFree::AdditionalData(MPI_COMM_SELF,MatrixFree::AdditionalData::none)); - - // choose block size of 3 which introduces - // some irregularity to the blocks (stress the - // non-overlapping computation harder) - mf_data_color.reinit (dof, constraints, quad, - typename MatrixFree::AdditionalData - (MPI_COMM_SELF, - MatrixFree::AdditionalData::partition_color, - 3)); - mf_data_partition.reinit (dof, constraints, quad, - typename MatrixFree::AdditionalData - (MPI_COMM_SELF, - MatrixFree::AdditionalData::partition_partition, - 3)); + const QGauss<1> quad (fe_degree+1); + mf_data.reinit (dof, constraints, quad, + typename MatrixFree::AdditionalData(MPI_COMM_SELF,MatrixFree::AdditionalData::none)); + + // choose block size of 3 which introduces + // some irregularity to the blocks (stress the + // non-overlapping computation harder) + mf_data_color.reinit (dof, constraints, quad, + typename MatrixFree::AdditionalData + (MPI_COMM_SELF, + MatrixFree::AdditionalData::partition_color, + 3)); + mf_data_partition.reinit (dof, constraints, quad, + typename MatrixFree::AdditionalData + (MPI_COMM_SELF, + MatrixFree::AdditionalData::partition_partition, + 3)); } - MatrixFreeTest mf_ref (mf_data); - MatrixFreeTest mf_color (mf_data_color); - MatrixFreeTest mf_partition (mf_data_partition); + MatrixFreeTest mf_ref (mf_data); + MatrixFreeTest mf_color (mf_data_color); + MatrixFreeTest mf_partition (mf_data_partition); Vector in_dist (dof.n_dofs()); Vector out_dist (in_dist), out_color (in_dist), - out_partition(in_dist); + out_partition(in_dist); for (unsigned int i=0; i &data, - Vector &dst, - const Vector &src, - const std::pair &cell_range) const + Vector &dst, + const Vector &src, + const std::pair &cell_range) const { - // Ask MatrixFree for cell_range for different - // orders + // Ask MatrixFree for cell_range for different + // orders std::pair subrange_deg = data.create_cell_subrange_hp (cell_range, 1); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); subrange_deg = data.create_cell_subrange_hp (cell_range, 2); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); subrange_deg = data.create_cell_subrange_hp (cell_range, 3); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); subrange_deg = data.create_cell_subrange_hp (cell_range, 4); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); subrange_deg = data.create_cell_subrange_hp (cell_range, 5); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); subrange_deg = data.create_cell_subrange_hp (cell_range, 6); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); subrange_deg = data.create_cell_subrange_hp (cell_range, 7); if (subrange_deg.second > subrange_deg.first) - helmholtz_operator (data, dst, src, - subrange_deg); + helmholtz_operator (data, dst, src, + subrange_deg); } void vmult (Vector &dst, - const Vector &src) const + const Vector &src) const { dst = 0; data.cell_loop (&MatrixFreeTestHP::local_apply, this, dst, src); @@ -92,15 +92,15 @@ void do_test (const unsigned int parallel_option) create_mesh (tria); tria.refine_global(2); - // refine a few cells + // refine a few cells for (unsigned int i=0; i<11-3*dim; ++i) { typename Triangulation::active_cell_iterator - cell = tria.begin_active (), - endc = tria.end(); + cell = tria.begin_active (), + endc = tria.end(); for (; cell!=endc; ++cell) - if (rand() % (7-i) == 0) - cell->set_refine_flag(); + if (rand() % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -116,34 +116,34 @@ void do_test (const unsigned int parallel_option) } hp::DoFHandler dof(tria); - // set the active FE index in a random order + // set the active FE index in a random order { typename hp::DoFHandler::active_cell_iterator cell = dof.begin_active(), endc = dof.end(); for (; cell!=endc; ++cell) { - const unsigned int fe_index = rand() % max_degree; - cell->set_active_fe_index (fe_index); + const unsigned int fe_index = rand() % max_degree; + cell->set_active_fe_index (fe_index); } } - // setup DoFs + // setup DoFs dof.distribute_dofs(fe_collection); ConstraintMatrix constraints; DoFTools::make_hanging_node_constraints (dof, - constraints); + constraints); VectorTools::interpolate_boundary_values (dof, - 0, - ZeroFunction(), - constraints); + 0, + ZeroFunction(), + constraints); constraints.close (); //std::cout << "Number of cells: " << dof.get_tria().n_active_cells() << std::endl; //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl; - // set up reference MatrixFree + // set up reference MatrixFree MatrixFree mf_data; typename MatrixFree::AdditionalData data; data.tasks_parallel_scheme = @@ -155,34 +155,34 @@ void do_test (const unsigned int parallel_option) if (parallel_option == 0) { data.tasks_parallel_scheme = - MatrixFree::AdditionalData::partition_partition; + MatrixFree::AdditionalData::partition_partition; deallog << "Parallel option partition/partition" << std::endl; } else { data.tasks_parallel_scheme = - MatrixFree::AdditionalData::partition_color; + MatrixFree::AdditionalData::partition_color; deallog << "Parallel option partition/color" << std::endl; } data.tasks_block_size = 1; mf_data_par.reinit (dof, constraints, quadrature_collection_mf, data); MatrixFreeTestHP mf_par(mf_data_par); - // fill a right hand side vector with random - // numbers in unconstrained degrees of freedom + // fill a right hand side vector with random + // numbers in unconstrained degrees of freedom Vector src (dof.n_dofs()); Vector result_ref(src), result_mf (src); for (unsigned int i=0; i void test () { - // 'misuse' fe_degree for setting the parallel - // option here + // 'misuse' fe_degree for setting the parallel + // option here unsigned int parallel_option = 0; if (fe_degree == 1) parallel_option = 0; diff --git a/tests/mpi/matrix_free_01.cc b/tests/mpi/matrix_free_01.cc index 93bb5157e6..c1d5d52cba 100644 --- a/tests/mpi/matrix_free_01.cc +++ b/tests/mpi/matrix_free_01.cc @@ -38,29 +38,29 @@ #include -template +template void helmholtz_operator (const MatrixFree &data, - parallel::distributed::Vector &dst, - const parallel::distributed::Vector &src, - const std::pair &cell_range) + parallel::distributed::Vector &dst, + const parallel::distributed::Vector &src, + const std::pair &cell_range) { - FEEvaluation fe_eval (data); + FEEvaluation fe_eval (data); const unsigned int n_q_points = fe_eval.n_q_points; for(unsigned int cell=cell_range.first;cell &data, -template +template class MatrixFreeTest { public: @@ -80,14 +80,14 @@ class MatrixFreeTest {}; void vmult (parallel::distributed::Vector &dst, - const parallel::distributed::Vector &src) const + const parallel::distributed::Vector &src) const { dst = 0; const std_cxx1x::function &, - parallel::distributed::Vector&, - const parallel::distributed::Vector&, - const std::pair&)> - wrap = helmholtz_operator; + parallel::distributed::Vector&, + const parallel::distributed::Vector&, + const std::pair&)> + wrap = helmholtz_operator; data.cell_loop (wrap, dst, src); }; @@ -114,7 +114,7 @@ void test () for (; cell!=endc; ++cell) if (cell->is_locally_owned()) if (cell->center().norm()<0.2) - cell->set_refine_flag(); + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); if (dim < 3 && fe_degree < 2) tria.refine_global(2); @@ -131,9 +131,9 @@ void test () cell = tria.begin_active (); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (cell->is_locally_owned()) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (cell->is_locally_owned()) + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -167,7 +167,7 @@ void test () mf_data.reinit (dof, constraints, quad, data); } - MatrixFreeTest mf (mf_data); + MatrixFreeTest mf (mf_data); parallel::distributed::Vector in, out, ref; mf_data.initialize_dof_vector (in); out.reinit (in); @@ -176,23 +176,23 @@ void test () for (unsigned int i=0; i quadrature_formula(fe_degree+1); FEValues fe_values (dof.get_fe(), quadrature_formula, - update_values | update_gradients | - update_JxW_values); + update_values | update_gradients | + update_JxW_values); const unsigned int dofs_per_cell = dof.get_fe().dofs_per_cell; const unsigned int n_q_points = quadrature_formula.size(); @@ -215,26 +215,26 @@ void test () for (; cell!=endc; ++cell) if (cell->is_locally_owned()) { - cell_matrix = 0; - fe_values.reinit (cell); - - for (unsigned int q_point=0; q_pointget_dof_indices(local_dof_indices); - constraints.distribute_local_to_global (cell_matrix, - local_dof_indices, - sparse_matrix); + cell_matrix = 0; + fe_values.reinit (cell); + + for (unsigned int q_point=0; q_pointget_dof_indices(local_dof_indices); + constraints.distribute_local_to_global (cell_matrix, + local_dof_indices, + sparse_matrix); } } sparse_matrix.compress(); diff --git a/tests/mpi/matrix_free_02.cc b/tests/mpi/matrix_free_02.cc index fd46b07a6a..d1a66497d4 100644 --- a/tests/mpi/matrix_free_02.cc +++ b/tests/mpi/matrix_free_02.cc @@ -30,29 +30,29 @@ #include -template +template void helmholtz_operator (const MatrixFree &data, - parallel::distributed::Vector &dst, - const parallel::distributed::Vector &src, - const std::pair &cell_range) + parallel::distributed::Vector &dst, + const parallel::distributed::Vector &src, + const std::pair &cell_range) { - FEEvaluation fe_eval (data); + FEEvaluation fe_eval (data); const unsigned int n_q_points = fe_eval.n_q_points; for(unsigned int cell=cell_range.first;cell &data, -template +template class MatrixFreeTest { public: @@ -72,14 +72,14 @@ class MatrixFreeTest {}; void vmult (parallel::distributed::Vector &dst, - const parallel::distributed::Vector &src) const + const parallel::distributed::Vector &src) const { dst = 0; const std_cxx1x::function &, - parallel::distributed::Vector&, - const parallel::distributed::Vector&, - const std::pair&)> - wrap = helmholtz_operator; + parallel::distributed::Vector&, + const parallel::distributed::Vector&, + const std::pair&)> + wrap = helmholtz_operator; data.cell_loop (wrap, dst, src); }; @@ -106,7 +106,7 @@ void test () for (; cell!=endc; ++cell) if (cell->is_locally_owned()) if (cell->center().norm()<0.2) - cell->set_refine_flag(); + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); if (fe_degree < 2) tria.refine_global(2); @@ -123,9 +123,9 @@ void test () cell = tria.begin_active (); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (cell->is_locally_owned()) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (cell->is_locally_owned()) + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -159,7 +159,7 @@ void test () mf_data.reinit (dof, constraints, quad, data); } - MatrixFreeTest mf (mf_data); + MatrixFreeTest mf (mf_data); parallel::distributed::Vector in, out, ref; mf_data.initialize_dof_vector (in); out.reinit (in); @@ -168,9 +168,9 @@ void test () for (unsigned int i=0; i::AdditionalData data; data.mpi_communicator = MPI_COMM_WORLD; if (parallel_option == 0) - { - data.tasks_parallel_scheme = - MatrixFree::AdditionalData::partition_partition; - deallog << "Parallel option: partition partition" << std::endl; - } + { + data.tasks_parallel_scheme = + MatrixFree::AdditionalData::partition_partition; + deallog << "Parallel option: partition partition" << std::endl; + } else if (parallel_option == 1) - { - data.tasks_parallel_scheme = - MatrixFree::AdditionalData::partition_color; - deallog << "Parallel option: partition color" << std::endl; - } + { + data.tasks_parallel_scheme = + MatrixFree::AdditionalData::partition_color; + deallog << "Parallel option: partition color" << std::endl; + } else if (parallel_option == 2) - { - data.tasks_parallel_scheme = - MatrixFree::AdditionalData::color; - deallog << "Parallel option: color" << std::endl; - } + { + data.tasks_parallel_scheme = + MatrixFree::AdditionalData::color; + deallog << "Parallel option: color" << std::endl; + } data.tasks_block_size = 3; mf_data.reinit (dof, constraints, quad, data); - MatrixFreeTest mf (mf_data); + MatrixFreeTest mf (mf_data); MPI_Barrier(MPI_COMM_WORLD); deallog << "Norm of difference:"; - // run 10 times to make a possible error more - // likely to show up + // run 10 times to make a possible error more + // likely to show up for (unsigned int run=0; run<10; ++run) - { - mf.vmult (out, in); - out -= ref; - const double diff_norm = out.linfty_norm(); - deallog << " " << diff_norm; - } + { + mf.vmult (out, in); + out -= ref; + const double diff_norm = out.linfty_norm(); + deallog << " " << diff_norm; + } deallog << std::endl; } deallog << std::endl; diff --git a/tests/mpi/matrix_free_03.cc b/tests/mpi/matrix_free_03.cc index cc0589a4d7..8c1e5e53ee 100644 --- a/tests/mpi/matrix_free_03.cc +++ b/tests/mpi/matrix_free_03.cc @@ -32,30 +32,30 @@ #include -template +template void helmholtz_operator (const MatrixFree &data, - std::vector > &dst, - const std::vector > &src, - const std::pair &cell_range) + std::vector > &dst, + const std::vector > &src, + const std::pair &cell_range) { - FEEvaluation fe_eval (data); + FEEvaluation fe_eval (data); const unsigned int n_q_points = fe_eval.n_q_points; for(unsigned int cell=cell_range.first;cell &data, -template +template class MatrixFreeTest { public: @@ -75,15 +75,15 @@ class MatrixFreeTest {}; void vmult (std::vector > &dst, - const std::vector > &src) const + const std::vector > &src) const { for (unsigned int i=0; i &, - std::vector >&, - const std::vector >&, - const std::pair&)> - wrap = helmholtz_operator; + std::vector >&, + const std::vector >&, + const std::pair&)> + wrap = helmholtz_operator; data.cell_loop (wrap, dst, src); }; @@ -110,7 +110,7 @@ void test () for (; cell!=endc; ++cell) if (cell->is_locally_owned()) if (cell->center().norm()<0.2) - cell->set_refine_flag(); + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); if (dim < 3 && fe_degree < 2) tria.refine_global(2); @@ -127,9 +127,9 @@ void test () cell = tria.begin_active (); unsigned int counter = 0; for (; cell!=endc; ++cell, ++counter) - if (cell->is_locally_owned()) - if (counter % (7-i) == 0) - cell->set_refine_flag(); + if (cell->is_locally_owned()) + if (counter % (7-i) == 0) + cell->set_refine_flag(); tria.execute_coarsening_and_refinement(); } @@ -163,7 +163,7 @@ void test () mf_data.reinit (dof, constraints, quad, data); } - MatrixFreeTest mf (mf_data); + MatrixFreeTest mf (mf_data); parallel::distributed::Vector ref; std::vector > in(2), out(2); for (unsigned int i=0; i<2; ++i) @@ -176,9 +176,9 @@ void test () for (unsigned int i=0; i quadrature_formula(fe_degree+1); FEValues fe_values (dof.get_fe(), quadrature_formula, - update_values | update_gradients | - update_JxW_values); + update_values | update_gradients | + update_JxW_values); const unsigned int dofs_per_cell = dof.get_fe().dofs_per_cell; const unsigned int n_q_points = quadrature_formula.size(); @@ -216,26 +216,26 @@ void test () for (; cell!=endc; ++cell) if (cell->is_locally_owned()) { - cell_matrix = 0; - fe_values.reinit (cell); - - for (unsigned int q_point=0; q_pointget_dof_indices(local_dof_indices); - constraints.distribute_local_to_global (cell_matrix, - local_dof_indices, - sparse_matrix); + cell_matrix = 0; + fe_values.reinit (cell); + + for (unsigned int q_point=0; q_pointget_dof_indices(local_dof_indices); + constraints.distribute_local_to_global (cell_matrix, + local_dof_indices, + sparse_matrix); } } sparse_matrix.compress(); diff --git a/tests/mpi/parallel_partitioner_01.cc b/tests/mpi/parallel_partitioner_01.cc index b93ee0f17b..595fd2e535 100644 --- a/tests/mpi/parallel_partitioner_01.cc +++ b/tests/mpi/parallel_partitioner_01.cc @@ -39,9 +39,9 @@ void test () { global_size += set - i; if (i= my_start+local_size) { - AssertDimension (local_size+count, v.global_to_local(ghost_indices[i])); - AssertDimension (ghost_indices[i], v.local_to_global(local_size+count)); - ++count; + AssertDimension (local_size+count, v.global_to_local(ghost_indices[i])); + AssertDimension (ghost_indices[i], v.local_to_global(local_size+count)); + ++count; } - // check that loc->glob and glob->loc form an - // identity operation + // check that loc->glob and glob->loc form an + // identity operation for (unsigned int i=0; i v2; v2.swap (v0); AssertDimension (v0.size(), 0); -- 2.39.5