00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __deal2__mg_constraints_h
00013 #define __deal2__mg_constraints_h
00014
00015 #include <deal.II/base/config.h>
00016 #include <deal.II/base/subscriptor.h>
00017
00018 #include <deal.II/multigrid/mg_tools.h>
00019
00020 #include <vector>
00021 #include <set>
00022
00023 DEAL_II_NAMESPACE_OPEN
00024
00025 template <int dim, int spacedim> class MGDoFHandler;
00026 template <int dim> struct FunctionMap;
00027
00028
00035 class MGConstrainedDoFs : public Subscriptor
00036 {
00037 public:
00049 template <int dim, int spacedim>
00050 void initialize(const MGDoFHandler<dim,spacedim>& dof);
00051
00059 template <int dim, int spacedim>
00060 void initialize(const MGDoFHandler<dim,spacedim>& dof,
00061 const typename FunctionMap<dim>::type& function_map,
00062 const std::vector<bool>& component_mask = std::vector<bool>());
00063
00067 void clear();
00068
00074 bool is_boundary_index (const unsigned int level,
00075 const unsigned int index) const;
00076
00082 bool non_refinement_edge_index (const unsigned int level,
00083 const unsigned int index) const;
00084
00089 bool at_refinement_edge (const unsigned int level,
00090 const unsigned int index) const;
00091
00098 bool at_refinement_edge_boundary (const unsigned int level,
00099 const unsigned int index) const;
00100
00106 const std::vector<std::set<unsigned int> > &
00107 get_boundary_indices () const;
00108
00114 const std::vector<std::set<unsigned int> > &
00115 get_non_refinement_edge_indices () const;
00116
00124 const std::vector<std::vector<bool> > &
00125 get_refinement_edge_indices () const;
00126
00134 const std::vector<std::vector<bool> > &
00135 get_refinement_edge_boundary_indices () const;
00136
00142 bool set_boundary_values () const;
00143
00148 bool continuity_across_refinement_edges () const;
00149 private:
00150
00155 std::vector<std::set<unsigned int> > boundary_indices;
00156
00163 std::vector<std::set<unsigned int> > non_refinement_edge_indices;
00164
00170 std::vector<std::vector<bool> > refinement_edge_indices;
00171
00181 std::vector<std::vector<bool> > refinement_edge_boundary_indices;
00182 };
00183
00184
00185 template <int dim, int spacedim>
00186 inline
00187 void
00188 MGConstrainedDoFs::initialize(const MGDoFHandler<dim,spacedim>& dof)
00189 {
00190 const unsigned int nlevels = dof.get_tria().n_levels();
00191 refinement_edge_indices.resize(nlevels);
00192 refinement_edge_boundary_indices.resize(nlevels);
00193 non_refinement_edge_indices.resize(nlevels);
00194 for(unsigned int l=0; l<nlevels; ++l)
00195 {
00196 refinement_edge_indices[l].resize(dof.n_dofs(l));
00197 refinement_edge_boundary_indices[l].resize(dof.n_dofs(l));
00198 }
00199 MGTools::extract_inner_interface_dofs (dof, refinement_edge_indices,
00200 refinement_edge_boundary_indices);
00201
00202 MGTools::extract_non_interface_dofs (dof, non_refinement_edge_indices);
00203 }
00204
00205
00206 template <int dim, int spacedim>
00207 inline
00208 void
00209 MGConstrainedDoFs::initialize(
00210 const MGDoFHandler<dim,spacedim>& dof,
00211 const typename FunctionMap<dim>::type& function_map,
00212 const std::vector<bool>& component_mask)
00213 {
00214 const unsigned int nlevels = dof.get_tria().n_levels();
00215 boundary_indices.resize(nlevels);
00216 refinement_edge_indices.resize(nlevels);
00217 refinement_edge_boundary_indices.resize(nlevels);
00218 non_refinement_edge_indices.resize(nlevels);
00219
00220 for(unsigned int l=0; l<nlevels; ++l)
00221 {
00222 boundary_indices[l].clear();
00223 refinement_edge_indices[l].resize(dof.n_dofs(l));
00224 refinement_edge_boundary_indices[l].resize(dof.n_dofs(l));
00225 }
00226
00227 MGTools::make_boundary_list (dof, function_map, boundary_indices, component_mask);
00228 MGTools::extract_inner_interface_dofs (dof, refinement_edge_indices,
00229 refinement_edge_boundary_indices);
00230 MGTools::extract_non_interface_dofs (dof, non_refinement_edge_indices);
00231 }
00232
00233
00234 inline
00235 void
00236 MGConstrainedDoFs::clear()
00237 {
00238 for(unsigned int l=0; l<boundary_indices.size(); ++l)
00239 boundary_indices[l].clear();
00240
00241 for(unsigned int l=0; l<refinement_edge_indices.size(); ++l)
00242 refinement_edge_indices[l].clear();
00243
00244 for(unsigned int l=0; l<refinement_edge_boundary_indices.size(); ++l)
00245 refinement_edge_boundary_indices[l].clear();
00246
00247 for(unsigned int l=0; l<non_refinement_edge_indices.size(); ++l)
00248 non_refinement_edge_indices[l].clear();
00249 }
00250
00251
00252 inline
00253 bool
00254 MGConstrainedDoFs::is_boundary_index (const unsigned int level,
00255 const unsigned int index) const
00256 {
00257 AssertIndexRange(level, boundary_indices.size());
00258 if(boundary_indices[level].find(index) != boundary_indices[level].end())
00259 return true;
00260 else
00261 return false;
00262 }
00263
00264 inline
00265 bool
00266 MGConstrainedDoFs::non_refinement_edge_index (const unsigned int level,
00267 const unsigned int index) const
00268 {
00269 AssertIndexRange(level, non_refinement_edge_indices.size());
00270
00271 if(non_refinement_edge_indices[level].find(index) != non_refinement_edge_indices[level].end())
00272 return true;
00273 else
00274 return false;
00275 }
00276
00277 inline
00278 bool
00279 MGConstrainedDoFs::at_refinement_edge (const unsigned int level,
00280 const unsigned int index) const
00281 {
00282 AssertIndexRange(level, refinement_edge_indices.size());
00283 AssertIndexRange(index, refinement_edge_indices[level].size());
00284
00285 return refinement_edge_indices[level][index];
00286 }
00287
00288
00289 inline
00290 bool
00291 MGConstrainedDoFs::at_refinement_edge_boundary (const unsigned int level,
00292 const unsigned int index) const
00293 {
00294 AssertIndexRange(level, refinement_edge_boundary_indices.size());
00295 AssertIndexRange(index, refinement_edge_boundary_indices[level].size());
00296
00297 return refinement_edge_boundary_indices[level][index];
00298 }
00299
00300 inline
00301 const std::vector<std::set<unsigned int> > &
00302 MGConstrainedDoFs::get_boundary_indices () const
00303 {
00304 return boundary_indices;
00305 }
00306
00307 inline
00308 const std::vector<std::set<unsigned int> > &
00309 MGConstrainedDoFs::get_non_refinement_edge_indices () const
00310 {
00311 return non_refinement_edge_indices;
00312 }
00313
00314 inline
00315 const std::vector<std::vector<bool> > &
00316 MGConstrainedDoFs::get_refinement_edge_indices () const
00317 {
00318 return refinement_edge_indices;
00319 }
00320
00321 inline
00322 const std::vector<std::vector<bool> > &
00323 MGConstrainedDoFs::get_refinement_edge_boundary_indices () const
00324 {
00325 return refinement_edge_boundary_indices;
00326 }
00327
00328 inline
00329 bool
00330 MGConstrainedDoFs::set_boundary_values () const
00331 {
00332 const bool boundary_values_need_to_be_set
00333 = boundary_indices.size()!=0;
00334 return boundary_values_need_to_be_set;
00335 }
00336
00337 inline
00338 bool
00339 MGConstrainedDoFs::continuity_across_refinement_edges () const
00340 {
00341 bool is_continuous = false;
00342 for(unsigned int l=0; l<refinement_edge_indices.size(); ++l)
00343 for(unsigned int i=0; i<refinement_edge_indices[l].size(); ++i)
00344 if(refinement_edge_indices[l][i])
00345 {
00346 is_continuous = true;
00347 return is_continuous;
00348 }
00349 return is_continuous;
00350 }
00351
00352 DEAL_II_NAMESPACE_CLOSE
00353
00354 #endif
00355