//----------------------------------------------------------------------------- void DofMap::check_dimensional_consistency(const ufc::dofmap& dofmap, const Mesh& mesh) { // Check topological dimension if (dofmap.topological_dimension() != mesh.topology().dim()) { dolfin_error("DofMap.cpp", "create mapping of degrees of freedom", "Topological dimension of the UFC dofmap (dim = %d) and the mesh (dim = %d) do not match", dofmap.topological_dimension(), mesh.topology().dim()); } }
//----------------------------------------------------------------------------- void DofMap::check_provided_entities(const ufc::dofmap& dofmap, const Mesh& mesh) { // Check that we have all mesh entities for (std::size_t d = 0; d <= mesh.topology().dim(); ++d) { if (dofmap.needs_mesh_entities(d) && mesh.num_entities(d) == 0) { dolfin_error("DofMap.cpp", "initialize mapping of degrees of freedom", "Missing entities of dimension %d. Try calling mesh.init(%d)", d, d); } } }
//----------------------------------------------------------------------------- std::size_t DofMapBuilder::compute_blocksize(const ufc::dofmap& ufc_dofmap) { bool has_block_structure = false; if (ufc_dofmap.num_sub_dofmaps() > 1) { // Create UFC first sub-dofmap boost::scoped_ptr<ufc::dofmap> ufc_sub_dofmap0(ufc_dofmap.create_sub_dofmap(0)); dolfin_assert(ufc_sub_dofmap0); // Create UFC sub-dofmaps and check that all sub dofmaps have the // same number of dofs per entity if (ufc_sub_dofmap0->num_sub_dofmaps() != 0) has_block_structure = false; else { // Assume dof map has block structure, then check has_block_structure = true; // Create UFC sub-dofmaps and check that all sub dofmaps have the // same number of dofs per entity for (std::size_t i = 1; i < ufc_dofmap.num_sub_dofmaps(); ++i) { boost::scoped_ptr<ufc::dofmap> ufc_sub_dofmap(ufc_dofmap.create_sub_dofmap(i)); dolfin_assert(ufc_sub_dofmap); for (std::size_t d = 0; d <= ufc_dofmap.topological_dimension(); ++d) { if (ufc_sub_dofmap->num_entity_dofs(d) != ufc_sub_dofmap0->num_entity_dofs(d)) { has_block_structure = false; break; } } } } } if (has_block_structure) return ufc_dofmap.num_sub_dofmaps(); else return 1; }
//----------------------------------------------------------------------------- std::shared_ptr<ufc::dofmap> DofMapBuilder::extract_ufc_sub_dofmap( const ufc::dofmap& ufc_dofmap, std::size_t& offset, const std::vector<std::size_t>& component, const std::vector<std::size_t>& num_global_mesh_entities) { // Check if there are any sub systems if (ufc_dofmap.num_sub_dofmaps() == 0) { dolfin_error("DofMap.cpp", "extract subsystem of degree of freedom mapping", "There are no subsystems"); } // Check that a sub system has been specified if (component.empty()) { dolfin_error("DofMap.cpp", "extract subsystem of degree of freedom mapping", "No system was specified"); } // Check the number of available sub systems if (component[0] >= ufc_dofmap.num_sub_dofmaps()) { dolfin_error("DofMap.cpp", "extract subsystem of degree of freedom mapping", "Requested subsystem (%d) out of range [0, %d)", component[0], ufc_dofmap.num_sub_dofmaps()); } // Add to offset if necessary for (std::size_t i = 0; i < component[0]; i++) { // Extract sub dofmap boost::scoped_ptr<ufc::dofmap> ufc_tmp_dofmap(ufc_dofmap.create_sub_dofmap(i)); dolfin_assert(ufc_tmp_dofmap); // Check dimensional consistency between UFC dofmap and the mesh //check_dimensional_consistency(ufc_dofmap, mesh); // Get offset offset += ufc_tmp_dofmap->global_dimension(num_global_mesh_entities); } // Create UFC sub-system std::shared_ptr<ufc::dofmap> sub_dofmap(ufc_dofmap.create_sub_dofmap(component[0])); dolfin_assert(sub_dofmap); // Return sub-system if sub-sub-system should not be extracted, // otherwise recursively extract the sub sub system if (component.size() == 1) return sub_dofmap; else { std::vector<std::size_t> sub_component; for (std::size_t i = 1; i < component.size(); ++i) sub_component.push_back(component[i]); std::shared_ptr<ufc::dofmap> sub_sub_dofmap = extract_ufc_sub_dofmap(*sub_dofmap, offset, sub_component, num_global_mesh_entities); return sub_sub_dofmap; } }