From dbc2d787c8bf7169b73d3dfb6c227816c5ea0c75 Mon Sep 17 00:00:00 2001 From: bangerth Date: Thu, 8 Jan 2009 01:18:55 +0000 Subject: [PATCH] Move the remaining private functions of the DoFTools class into an internal namespace that only lives in the .cc file. No need to expose implementation details and cluttering up the documentation. git-svn-id: https://svn.dealii.org/trunk@18129 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/deal.II/include/dofs/dof_tools.h | 56 +- deal.II/deal.II/source/dofs/dof_tools.cc | 1101 +++++++++++----------- 2 files changed, 568 insertions(+), 589 deletions(-) diff --git a/deal.II/deal.II/include/dofs/dof_tools.h b/deal.II/deal.II/include/dofs/dof_tools.h index f10f963d23..b76e1b40c2 100644 --- a/deal.II/deal.II/include/dofs/dof_tools.h +++ b/deal.II/deal.II/include/dofs/dof_tools.h @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors +// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -1816,60 +1816,6 @@ class DoFTools private: - /** - * This is a helper function that - * is used in the computation of - * integrid constraints. See the - * function for a thorough - * description of how it works. - */ - template - static unsigned int - compute_intergrid_weights_1 (const DoFHandler &coarse_grid, - const unsigned int coarse_component, - const DoFHandler &fine_grid, - const unsigned int fine_component, - const InterGridMap > &coarse_to_fine_grid_map, - std::vector > &weights, - std::vector &weight_mapping); - - /** - * This is a helper function that - * is used in the computation of - * integrid constraints. See the - * function for a thorough - * description of how it works. - */ - template - static void - compute_intergrid_weights_2 (const DoFHandler &coarse_grid, - const unsigned int coarse_component, - const InterGridMap > &coarse_to_fine_grid_map, - const std::vector > ¶meter_dofs, - const std::vector &weight_mapping, - std::vector > &weights); - - /** - * This is a function that is - * called by the previous one and - * that operates on a range of - * cells only. It is used to - * split up the whole range of - * cells into chunks which are - * then worked on in parallel, if - * multithreading is available. - */ - template - static void - compute_intergrid_weights_3 (const DoFHandler &coarse_grid, - const unsigned int coarse_component, - const InterGridMap > &coarse_to_fine_grid_map, - const std::vector > ¶meter_dofs, - const std::vector &weight_mapping, - std::vector > &weights, - const typename DoFHandler::active_cell_iterator &begin, - const typename DoFHandler::active_cell_iterator &end); - /** * Compute coupling of dofs from * coupling of components. diff --git a/deal.II/deal.II/source/dofs/dof_tools.cc b/deal.II/deal.II/source/dofs/dof_tools.cc index 7fae1afa9f..58e319be5e 100644 --- a/deal.II/deal.II/source/dofs/dof_tools.cc +++ b/deal.II/deal.II/source/dofs/dof_tools.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors +// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -681,6 +681,69 @@ DoFTools::make_flux_sparsity_pattern ( #endif +namespace internal +{ + namespace + { + template + void + compute_dof_couplings(Table<2,DoFTools::Coupling>& dof_couplings, + const Table<2,DoFTools::Coupling>& component_couplings, + const FiniteElement& fe) + { + Assert(component_couplings.n_rows() == fe.n_components(), + ExcDimensionMismatch(component_couplings.n_rows(), + fe.n_components())); + Assert(component_couplings.n_cols() == fe.n_components(), + ExcDimensionMismatch(component_couplings.n_cols(), + fe.n_components())); + + const unsigned int n_dofs = fe.dofs_per_cell; + + Assert(dof_couplings.n_rows() == n_dofs, + ExcDimensionMismatch(dof_couplings.n_rows(), n_dofs)); + Assert(dof_couplings.n_cols() == n_dofs, + ExcDimensionMismatch(dof_couplings.n_cols(), n_dofs)); + + for (unsigned int i=0; i void DoFTools::make_flux_sparsity_pattern ( @@ -718,8 +781,8 @@ DoFTools::make_flux_sparsity_pattern ( Table<2,Coupling> int_dof_mask(total_dofs, total_dofs); Table<2,Coupling> flux_dof_mask(total_dofs, total_dofs); - compute_dof_couplings(int_dof_mask, int_mask, fe); - compute_dof_couplings(flux_dof_mask, flux_mask, fe); + internal::compute_dof_couplings(int_dof_mask, int_mask, fe); + internal::compute_dof_couplings(flux_dof_mask, flux_mask, fe); for (unsigned int i=0; i::faces_per_cell;++f) @@ -4071,6 +4134,499 @@ DoFTools::count_dofs_per_component ( } + + +namespace internal +{ + namespace + { + /** + * This is a helper function that + * is used in the computation of + * integrid constraints. See the + * function for a thorough + * description of how it works. + */ + template + unsigned int + compute_intergrid_weights_1 ( + const dealii::DoFHandler &coarse_grid, + const unsigned int coarse_component, + const dealii::DoFHandler &fine_grid, + const unsigned int fine_component, + const InterGridMap > &coarse_to_fine_grid_map, + std::vector > &weights, + std::vector &weight_mapping) + { + // aliases to the finite elements + // used by the dof handlers: + const FiniteElement &coarse_fe = coarse_grid.get_fe(), + &fine_fe = fine_grid.get_fe(); + + // global numbers of dofs + const unsigned int n_coarse_dofs = coarse_grid.n_dofs(), + n_fine_dofs = fine_grid.n_dofs(); + + // local numbers of dofs + const unsigned int fine_dofs_per_cell = fine_fe.dofs_per_cell; + + // alias the number of dofs per + // cell belonging to the + // coarse_component which is to be + // the restriction of the fine + // grid: + const unsigned int coarse_dofs_per_cell_component + = coarse_fe.base_element(coarse_fe.component_to_base_index(coarse_component).first).dofs_per_cell; + + + // Try to find out whether the + // grids stem from the same coarse + // grid. This is a rather crude + // test, but better than nothing + Assert (coarse_grid.get_tria().n_cells(0) == fine_grid.get_tria().n_cells(0), + dealii::DoFTools::ExcGridsDontMatch()); + + // check whether the map correlates + // the right objects + Assert (&coarse_to_fine_grid_map.get_source_grid() == &coarse_grid, + dealii::DoFTools::ExcGridsDontMatch ()); + Assert (&coarse_to_fine_grid_map.get_destination_grid() == &fine_grid, + dealii::DoFTools::ExcGridsDontMatch ()); + + + // check whether component numbers + // are valid + Assert (coarse_component < coarse_fe.n_components(), + dealii::DoFTools::ExcInvalidComponent (coarse_component, coarse_fe.n_components())); + Assert (fine_component < fine_fe.n_components(), + dealii::DoFTools::ExcInvalidComponent (fine_component, fine_fe.n_components())); + // check whether respective finite + // elements are equal + Assert (coarse_fe.base_element (coarse_fe.component_to_base_index(coarse_component).first) + == + fine_fe.base_element (fine_fe.component_to_base_index(fine_component).first), + dealii::DoFTools::ExcFiniteElementsDontMatch()); + +#ifdef DEBUG + // if in debug mode, check whether + // the coarse grid is indeed + // coarser everywhere than the fine + // grid + for (typename dealii::DoFHandler::active_cell_iterator + cell=coarse_grid.begin_active(); + cell != coarse_grid.end(); ++cell) + Assert (cell->level() <= coarse_to_fine_grid_map[cell]->level(), + dealii::DoFTools::ExcGridNotCoarser()); +#endif + + + +/* + * From here on: the term `parameter' refers to the selected component + * on the coarse grid and its analogon on the fine grid. The naming of + * variables containing this term is due to the fact that + * `selected_component' is longer, but also due to the fact that the + * code of this function was initially written for a program where the + * component which we wanted to match between grids was actually the + * `parameter' variable. + * + * Likewise, the terms `parameter grid' and `state grid' refer to the + * coarse and fine grids, respectively. + * + * Changing the names of variables would in principle be a good idea, + * but would not make things simpler and would be another source of + * errors. If anyone feels like doing so: patches would be welcome! + */ + + + + // set up vectors of cell-local + // data; each vector represents one + // degree of freedom of the + // coarse-grid variable in the + // fine-grid element + std::vector > parameter_dofs (coarse_dofs_per_cell_component, + Vector(fine_dofs_per_cell)); + // for each coarse dof: find its + // position within the fine element + // and set this value to one in the + // respective vector (all other values + // are zero by construction) + for (unsigned int local_coarse_dof=0; + local_coarse_dof dof_is_interesting (fine_grid.n_dofs(), false); + std::vector local_dof_indices (fine_fe.dofs_per_cell); + + for (typename dealii::DoFHandler::active_cell_iterator + cell=fine_grid.begin_active(); + cell!=fine_grid.end(); ++cell) + { + cell->get_dof_indices (local_dof_indices); + for (unsigned int i=0; i local_dof_indices(fine_fe.dofs_per_cell); + unsigned int next_free_index=0; + for (typename dealii::DoFHandler::active_cell_iterator + cell=fine_grid.begin_active(); + cell != fine_grid.end(); ++cell) + { + cell->get_dof_indices (local_dof_indices); + for (unsigned int i=0; i1) && (sum==0)), ExcInternalError()); + }; +#endif + + + return n_parameters_on_fine_grid; + } + + + /** + * This is a function that is + * called by the _2 function and + * that operates on a range of + * cells only. It is used to + * split up the whole range of + * cells into chunks which are + * then worked on in parallel, if + * multithreading is available. + */ + template + void + compute_intergrid_weights_3 ( + const dealii::DoFHandler &coarse_grid, + const unsigned int coarse_component, + const InterGridMap > &coarse_to_fine_grid_map, + const std::vector > ¶meter_dofs, + const std::vector &weight_mapping, + std::vector > &weights, + const typename dealii::DoFHandler::active_cell_iterator &begin, + const typename dealii::DoFHandler::active_cell_iterator &end) + { + // aliases to the finite elements + // used by the dof handlers: + const FiniteElement &coarse_fe = coarse_grid.get_fe(); + + // for each cell on the parameter grid: + // find out which degrees of freedom on the + // fine grid correspond in which way to + // the degrees of freedom on the parameter + // grid + // + // since for continuous FEs some + // dofs exist on more than one + // cell, we have to track which + // ones were already visited. the + // problem is that if we visit a + // dof first on one cell and + // compute its weight with respect + // to some global dofs to be + // non-zero, and later visit the + // dof again on another cell and + // (since we are on another cell) + // recompute the weights with + // respect to the same dofs as + // above to be zero now, we have to + // preserve them. we therefore + // overwrite all weights if they + // are nonzero and do not enforce + // zero weights since that might be + // only due to the fact that we are + // on another cell. + // + // example: + // coarse grid + // | | | + // *-----*-----* + // | cell|cell | + // | 1 | 2 | + // | | | + // 0-----1-----* + // + // fine grid + // | | | | | + // *--*--*--*--* + // | | | | | + // *--*--*--*--* + // | | | | | + // *--x--y--*--* + // + // when on cell 1, we compute the + // weights of dof 'x' to be 1/2 + // from parameter dofs 0 and 1, + // respectively. however, when + // later we are on cell 2, we again + // compute the prolongation of + // shape function 1 restricted to + // cell 2 to the globla grid and + // find that the weight of global + // dof 'x' now is zero. however, we + // should not overwrite the old + // value. + // + // we therefore always only set + // nonzero values. why adding up is + // not useful: dof 'y' would get + // weight 1 from parameter dof 1 on + // both cells 1 and 2, but the + // correct weight is nevertheless + // only 1. + + // vector to hold the representation of + // a single degree of freedom on the + // coarse grid (for the selected fe) + // on the fine grid + const unsigned int n_fine_dofs = weight_mapping.size(); + Vector global_parameter_representation (n_fine_dofs); + + typename dealii::DoFHandler::active_cell_iterator cell; + std::vector parameter_dof_indices (coarse_fe.dofs_per_cell); + + for (cell=begin; cell!=end; ++cell) + { + // get the global indices of the + // parameter dofs on this parameter + // grid cell + cell->get_dof_indices (parameter_dof_indices); + + // loop over all dofs on this + // cell and check whether they + // are interesting for us + for (unsigned int local_dof=0; + local_dof + set_dof_values_by_interpolation (parameter_dofs[local_parameter_dof], + global_parameter_representation); + // now that we've got the global + // representation of each parameter + // dof, we've only got to clobber the + // non-zero entries in that vector and + // store the result + // + // what we have learned: if entry @p{i} + // of the global vector holds the value + // @p{v[i]}, then this is the weight with + // which the present dof contributes + // to @p{i}. there may be several such + // @p{i}s and their weights' sum should + // be one. Then, @p{v[i]} should be + // equal to @p{\sum_j w_{ij} p[j]} with + // @p{p[j]} be the values of the degrees + // of freedom on the coarse grid. we + // can thus compute constraints which + // link the degrees of freedom @p{v[i]} + // on the fine grid to those on the + // coarse grid, @p{p[j]}. Now to use + // these as real constraints, rather + // than as additional equations, we + // have to identify representants + // among the @p{i} for each @p{j}. this will + // be done by simply taking the first + // @p{i} for which @p{w_{ij}==1}. + // + // guard modification of + // the weights array by a + // Mutex. since it should + // happen rather rarely + // that there are several + // threads operating on + // different intergrid + // weights, have only one + // mutex for all of them + static Threads::ThreadMutex mutex; + Threads::ThreadMutex::ScopedLock lock (mutex); + for (unsigned int i=0; i + void + compute_intergrid_weights_2 ( + const dealii::DoFHandler &coarse_grid, + const unsigned int coarse_component, + const InterGridMap > &coarse_to_fine_grid_map, + const std::vector > ¶meter_dofs, + const std::vector &weight_mapping, + std::vector > &weights) + { + // simply distribute the range of + // cells to different threads + typedef typename dealii::DoFHandler::active_cell_iterator active_cell_iterator; + std::vector > + cell_intervals = Threads::split_range (coarse_grid.begin_active(), + coarse_grid.end(), + multithread_info.n_default_threads); + + Threads::ThreadGroup<> threads; + void (*fun_ptr) (const dealii::DoFHandler &, + const unsigned int , + const InterGridMap > &, + const std::vector > &, + const std::vector &, + std::vector > &, + const typename dealii::DoFHandler::active_cell_iterator &, + const typename dealii::DoFHandler::active_cell_iterator &) + = &compute_intergrid_weights_3; + for (unsigned int i=0; i void DoFTools::compute_intergrid_constraints ( @@ -4130,8 +4686,10 @@ DoFTools::compute_intergrid_constraints ( std::vector weight_mapping; const unsigned int n_parameters_on_fine_grid - = compute_intergrid_weights_1 (coarse_grid, coarse_component, fine_grid, fine_component, - coarse_to_fine_grid_map, weights, weight_mapping); + = internal::compute_intergrid_weights_1 (coarse_grid, coarse_component, + fine_grid, fine_component, + coarse_to_fine_grid_map, + weights, weight_mapping); // global numbers of dofs const unsigned int n_coarse_dofs = coarse_grid.n_dofs(), @@ -4353,8 +4911,10 @@ compute_intergrid_transfer_representation ( // indicating an error std::vector weight_mapping; - compute_intergrid_weights_1 (coarse_grid, coarse_component, fine_grid, fine_component, - coarse_to_fine_grid_map, weights, weight_mapping); + internal::compute_intergrid_weights_1 (coarse_grid, coarse_component, + fine_grid, fine_component, + coarse_to_fine_grid_map, + weights, weight_mapping); // now compute the requested // representation @@ -4405,470 +4965,6 @@ compute_intergrid_transfer_representation ( -template -unsigned int -DoFTools::compute_intergrid_weights_1 ( - const DoFHandler &coarse_grid, - const unsigned int coarse_component, - const DoFHandler &fine_grid, - const unsigned int fine_component, - const InterGridMap > &coarse_to_fine_grid_map, - std::vector > &weights, - std::vector &weight_mapping) -{ - // aliases to the finite elements - // used by the dof handlers: - const FiniteElement &coarse_fe = coarse_grid.get_fe(), - &fine_fe = fine_grid.get_fe(); - - // global numbers of dofs - const unsigned int n_coarse_dofs = coarse_grid.n_dofs(), - n_fine_dofs = fine_grid.n_dofs(); - - // local numbers of dofs - const unsigned int fine_dofs_per_cell = fine_fe.dofs_per_cell; - - // alias the number of dofs per - // cell belonging to the - // coarse_component which is to be - // the restriction of the fine - // grid: - const unsigned int coarse_dofs_per_cell_component - = coarse_fe.base_element(coarse_fe.component_to_base_index(coarse_component).first).dofs_per_cell; - - - // Try to find out whether the - // grids stem from the same coarse - // grid. This is a rather crude - // test, but better than nothing - Assert (coarse_grid.get_tria().n_cells(0) == fine_grid.get_tria().n_cells(0), - ExcGridsDontMatch()); - - // check whether the map correlates - // the right objects - Assert (&coarse_to_fine_grid_map.get_source_grid() == &coarse_grid, - ExcGridsDontMatch ()); - Assert (&coarse_to_fine_grid_map.get_destination_grid() == &fine_grid, - ExcGridsDontMatch ()); - - - // check whether component numbers - // are valid - Assert (coarse_component < coarse_fe.n_components(), - ExcInvalidComponent (coarse_component, coarse_fe.n_components())); - Assert (fine_component < fine_fe.n_components(), - ExcInvalidComponent (fine_component, fine_fe.n_components())); - // check whether respective finite - // elements are equal - Assert (coarse_fe.base_element (coarse_fe.component_to_base_index(coarse_component).first) - == - fine_fe.base_element (fine_fe.component_to_base_index(fine_component).first), - ExcFiniteElementsDontMatch()); - -#ifdef DEBUG - // if in debug mode, check whether - // the coarse grid is indeed - // coarser everywhere than the fine - // grid - for (typename DoFHandler::active_cell_iterator cell=coarse_grid.begin_active(); - cell != coarse_grid.end(); ++cell) - Assert (cell->level() <= coarse_to_fine_grid_map[cell]->level(), - ExcGridNotCoarser()); -#endif - - - -/* - * From here on: the term `parameter' refers to the selected component - * on the coarse grid and its analogon on the fine grid. The naming of - * variables containing this term is due to the fact that - * `selected_component' is longer, but also due to the fact that the - * code of this function was initially written for a program where the - * component which we wanted to match between grids was actually the - * `parameter' variable. - * - * Likewise, the terms `parameter grid' and `state grid' refer to the - * coarse and fine grids, respectively. - * - * Changing the names of variables would in principle be a good idea, - * but would not make things simpler and would be another source of - * errors. If anyone feels like doing so: patches would be welcome! - */ - - - - // set up vectors of cell-local - // data; each vector represents one - // degree of freedom of the - // coarse-grid variable in the - // fine-grid element - std::vector > parameter_dofs (coarse_dofs_per_cell_component, - Vector(fine_dofs_per_cell)); - // for each coarse dof: find its - // position within the fine element - // and set this value to one in the - // respective vector (all other values - // are zero by construction) - for (unsigned int local_coarse_dof=0; - local_coarse_dof dof_is_interesting (fine_grid.n_dofs(), false); - std::vector local_dof_indices (fine_fe.dofs_per_cell); - - for (typename DoFHandler::active_cell_iterator - cell=fine_grid.begin_active(); - cell!=fine_grid.end(); ++cell) - { - cell->get_dof_indices (local_dof_indices); - for (unsigned int i=0; i local_dof_indices(fine_fe.dofs_per_cell); - unsigned int next_free_index=0; - for (typename DoFHandler::active_cell_iterator cell=fine_grid.begin_active(); - cell != fine_grid.end(); ++cell) - { - cell->get_dof_indices (local_dof_indices); - for (unsigned int i=0; i1) && (sum==0)), ExcInternalError()); - }; -#endif - - - return n_parameters_on_fine_grid; -} - - - - -template -void -DoFTools::compute_intergrid_weights_2 ( - const DoFHandler &coarse_grid, - const unsigned int coarse_component, - const InterGridMap > &coarse_to_fine_grid_map, - const std::vector > ¶meter_dofs, - const std::vector &weight_mapping, - std::vector > &weights) -{ - // simply distribute the range of - // cells to different threads - typedef typename DoFHandler::active_cell_iterator active_cell_iterator; - std::vector > - cell_intervals = Threads::split_range (coarse_grid.begin_active(), - coarse_grid.end(), - multithread_info.n_default_threads); - - Threads::ThreadGroup<> threads; - void (*fun_ptr) (const DoFHandler &, - const unsigned int , - const InterGridMap > &, - const std::vector > &, - const std::vector &, - std::vector > &, - const typename DoFHandler::active_cell_iterator &, - const typename DoFHandler::active_cell_iterator &) - = &DoFTools::template compute_intergrid_weights_3; - for (unsigned int i=0; i -void -DoFTools::compute_intergrid_weights_3 ( - const DoFHandler &coarse_grid, - const unsigned int coarse_component, - const InterGridMap > &coarse_to_fine_grid_map, - const std::vector > ¶meter_dofs, - const std::vector &weight_mapping, - std::vector > &weights, - const typename DoFHandler::active_cell_iterator &begin, - const typename DoFHandler::active_cell_iterator &end) -{ - // aliases to the finite elements - // used by the dof handlers: - const FiniteElement &coarse_fe = coarse_grid.get_fe(); - - // for each cell on the parameter grid: - // find out which degrees of freedom on the - // fine grid correspond in which way to - // the degrees of freedom on the parameter - // grid - // - // since for continuous FEs some - // dofs exist on more than one - // cell, we have to track which - // ones were already visited. the - // problem is that if we visit a - // dof first on one cell and - // compute its weight with respect - // to some global dofs to be - // non-zero, and later visit the - // dof again on another cell and - // (since we are on another cell) - // recompute the weights with - // respect to the same dofs as - // above to be zero now, we have to - // preserve them. we therefore - // overwrite all weights if they - // are nonzero and do not enforce - // zero weights since that might be - // only due to the fact that we are - // on another cell. - // - // example: - // coarse grid - // | | | - // *-----*-----* - // | cell|cell | - // | 1 | 2 | - // | | | - // 0-----1-----* - // - // fine grid - // | | | | | - // *--*--*--*--* - // | | | | | - // *--*--*--*--* - // | | | | | - // *--x--y--*--* - // - // when on cell 1, we compute the - // weights of dof 'x' to be 1/2 - // from parameter dofs 0 and 1, - // respectively. however, when - // later we are on cell 2, we again - // compute the prolongation of - // shape function 1 restricted to - // cell 2 to the globla grid and - // find that the weight of global - // dof 'x' now is zero. however, we - // should not overwrite the old - // value. - // - // we therefore always only set - // nonzero values. why adding up is - // not useful: dof 'y' would get - // weight 1 from parameter dof 1 on - // both cells 1 and 2, but the - // correct weight is nevertheless - // only 1. - - // vector to hold the representation of - // a single degree of freedom on the - // coarse grid (for the selected fe) - // on the fine grid - const unsigned int n_fine_dofs = weight_mapping.size(); - Vector global_parameter_representation (n_fine_dofs); - - typename DoFHandler::active_cell_iterator cell; - std::vector parameter_dof_indices (coarse_fe.dofs_per_cell); - - for (cell=begin; cell!=end; ++cell) - { - // get the global indices of the - // parameter dofs on this parameter - // grid cell - cell->get_dof_indices (parameter_dof_indices); - - // loop over all dofs on this - // cell and check whether they - // are interesting for us - for (unsigned int local_dof=0; - local_dof - set_dof_values_by_interpolation (parameter_dofs[local_parameter_dof], - global_parameter_representation); - // now that we've got the global - // representation of each parameter - // dof, we've only got to clobber the - // non-zero entries in that vector and - // store the result - // - // what we have learned: if entry @p{i} - // of the global vector holds the value - // @p{v[i]}, then this is the weight with - // which the present dof contributes - // to @p{i}. there may be several such - // @p{i}s and their weights' sum should - // be one. Then, @p{v[i]} should be - // equal to @p{\sum_j w_{ij} p[j]} with - // @p{p[j]} be the values of the degrees - // of freedom on the coarse grid. we - // can thus compute constraints which - // link the degrees of freedom @p{v[i]} - // on the fine grid to those on the - // coarse grid, @p{p[j]}. Now to use - // these as real constraints, rather - // than as additional equations, we - // have to identify representants - // among the @p{i} for each @p{j}. this will - // be done by simply taking the first - // @p{i} for which @p{w_{ij}==1}. - // - // guard modification of - // the weights array by a - // Mutex. since it should - // happen rather rarely - // that there are several - // threads operating on - // different intergrid - // weights, have only one - // mutex for all of them - static Threads::ThreadMutex mutex; - Threads::ThreadMutex::ScopedLock lock (mutex); - for (unsigned int i=0; i &mapping } -template -void -DoFTools::compute_dof_couplings( - Table<2,Coupling>& dof_couplings, - const Table<2,Coupling>& component_couplings, - const FiniteElement& fe) -{ - Assert(component_couplings.n_rows() == fe.n_components(), - ExcDimensionMismatch(component_couplings.n_rows(), - fe.n_components())); - Assert(component_couplings.n_cols() == fe.n_components(), - ExcDimensionMismatch(component_couplings.n_cols(), - fe.n_components())); - - const unsigned int n_dofs = fe.dofs_per_cell; - - Assert(dof_couplings.n_rows() == n_dofs, - ExcDimensionMismatch(dof_couplings.n_rows(), n_dofs)); - Assert(dof_couplings.n_cols() == n_dofs, - ExcDimensionMismatch(dof_couplings.n_cols(), n_dofs)); - - for (unsigned int i=0; i void DoFTools::convert_couplings_to_blocks ( @@ -6370,12 +6409,6 @@ DoFTools::map_dofs_to_support_points const DoFHandler&, std::vector >&); -template -void -DoFTools::compute_dof_couplings( - Table<2,Coupling>&, const Table<2,Coupling>&, - const FiniteElement&); - template void DoFTools::convert_couplings_to_blocks ( -- 2.39.5