//----------------------------------------------------------------------------- SubMesh::SubMesh(const Mesh& mesh, const MeshFunction<std::size_t>& sub_domains, std::size_t sub_domain) { // Copy data into std::vector const std::vector<std::size_t> _sub_domains(sub_domains.values(), sub_domains.values() + sub_domains.size()); // Create sub mesh init(mesh, _sub_domains, sub_domain); }
//----------------------------------------------------------------------------- NewDirichletBC::NewDirichletBC(Function& g, MeshFunction<uint>& sub_domains, uint sub_domain, BCMethod method) : BoundaryCondition(), g(g), _mesh(sub_domains.mesh()), sub_domains(&sub_domains), sub_domain(sub_domain), sub_domains_local(false), method(method) { // Do nothing }
//----------------------------------------------------------------------------- void ParallelRefinement::mark(const MeshFunction<bool>& refinement_marker) { const std::size_t entity_dim = refinement_marker.dim(); for (MeshEntityIterator entity(_mesh, entity_dim); !entity.end(); ++entity) { if (refinement_marker[*entity]) { for (EdgeIterator edge(*entity); !edge.end(); ++edge) mark(edge->index()); } } }
//----------------------------------------------------------------------------- void SubDomain::mark(MeshFunction<bool>& sub_domains, bool sub_domain, bool check_midpoint) const { apply_markers(sub_domains, sub_domain, *sub_domains.mesh(), check_midpoint); }
//----------------------------------------------------------------------------- void LocalMeshCoarsening::coarsen_mesh_by_edge_collapse(Mesh& mesh, MeshFunction<bool>& cell_marker, bool coarsen_boundary) { log(TRACE, "Coarsen simplicial mesh by edge collapse."); // Get size of old mesh //const std::size_t num_vertices = mesh.size(0); const std::size_t num_cells = mesh.size(mesh.topology().dim()); // Check cell marker if ( cell_marker.size() != num_cells ) dolfin_error("LocalMeshCoarsening.cpp", "coarsen mesh by collapsing edges", "Number of cell markers (%d) does not match number of cells (%d)", cell_marker.size(), num_cells); // Generate cell - edge connectivity if not generated mesh.init(mesh.topology().dim(), 1); // Generate edge - vertex connectivity if not generated mesh.init(1, 0); // Get cell type //const CellType& cell_type = mesh.type(); // Create new mesh Mesh coarse_mesh(mesh); // Initialise forbidden cells auto _mesh = reference_to_no_delete_pointer(mesh); MeshFunction<bool> cell_forbidden(_mesh); cell_forbidden.init(mesh.topology().dim()); for (CellIterator c(mesh); !c.end(); ++c) cell_forbidden[c->index()] = false; // Init new vertices and cells std::vector<int> old2new_cell(mesh.num_cells()); std::vector<int> old2new_vertex(mesh.num_vertices()); std::list<int> cells_to_coarsen(0); // Compute cells to delete for (CellIterator c(mesh); !c.end(); ++c) { if (cell_marker[*c] == true) { cells_to_coarsen.push_back(c->index()); //cout << "coarsen midpoint: " << c->midpoint() << endl; } } // Define cell mapping between old and new mesh for (CellIterator c(mesh); !c.end(); ++c) old2new_cell[c->index()] = c->index(); bool improving = true; while(improving) { std::size_t presize = cells_to_coarsen.size(); //cout << "presize: " << presize << endl; for(std::list<int>::iterator iter = cells_to_coarsen.begin(); iter != cells_to_coarsen.end(); iter++) { // Map cells to new mesh if(*iter >= 0) *iter = old2new_cell[*iter]; } old2new_cell.resize(mesh.num_cells()); old2new_vertex.resize(mesh.num_vertices()); // Coarsen cells in list for(std::list<int>::iterator iter = cells_to_coarsen.begin(); iter != cells_to_coarsen.end(); iter++) { bool mesh_ok = false; int cid = *iter; if(cid != -1) { mesh_ok = coarsen_cell(mesh, coarse_mesh, cid, old2new_vertex, old2new_cell, coarsen_boundary); if(!mesh_ok) warning("Mesh not ok"); else { mesh = coarse_mesh; cells_to_coarsen.erase(iter); break; } } } if(presize == cells_to_coarsen.size()) break; } }
//----------------------------------------------------------------------------- void X3DFile::write_meshfunction(const MeshFunction<std::size_t>& meshfunction) { // Palette choice const int palette = 2; // Get mesh dolfin_assert( meshfunction.mesh()); const Mesh& mesh = *meshfunction.mesh(); // Ensure connectivity has been computed mesh.init(mesh.topology().dim() - 1 , mesh.topology().dim()); // Mesh geometric dimension const std::size_t gdim = mesh.geometry().dim(); // Mesh topological dimension const std::size_t tdim = mesh.topology().dim(); // MeshFunction dimension const std::size_t cell_dim = meshfunction.dim(); // Check that MeshFunction dimension is handled if (cell_dim != tdim) { dolfin_error("X3DFile.cpp", "output meshfunction", "Can only output CellFunction at present"); } // Check that X3D type is appropriate if (cell_dim == tdim && facet_type == "IndexedLineSet") { dolfin_error("X3DFile.cpp", "output meshfunction", "Cannot output CellFunction with Edge mesh"); } // Check that mesh is in 2D or 3D if (gdim !=2 && gdim !=3) { dolfin_error("X3DFile.cpp", "output mesh", "X3D will only output 2D or 3D meshes"); } // Pointer to MeshFunction data const std::size_t* values = meshfunction.values(); // Get min/max values of MeshFunction std::size_t minval = *std::min_element(values, values + meshfunction.size()); minval = MPI::min(minval); std::size_t maxval = *std::max_element(values, values + meshfunction.size()); maxval = MPI::max(maxval); double dval; if (maxval == minval) dval = 1.0; else dval = 255.0/(double)(maxval - minval); // Get mesh min/max dimensions and viewpoint const std::vector<double> xpos = mesh_min_max(mesh); // Get MPI details const std::size_t num_processes = MPI::num_processes(); const std::size_t process_number = MPI::process_number(); // Create pugi xml document pugi::xml_document xml_doc; // Write XML header output_xml_header(xml_doc, xpos); // Make a set of the indices we wish to use. In 3D, we are ignoring // all interior facets, so reducing the number of vertices // substantially const std::vector<std::size_t> vecindex = vertex_index(mesh); // Write vertices write_vertices(xml_doc, mesh, vecindex); // Iterate over mesh facets std::stringstream local_output; for (FaceIterator f(mesh); !f.end(); ++f) { // Check if topolgical dimension is 2, or if we have a boundary // facet in 3D if (tdim == 2 || f->num_global_entities(tdim) == 1) { // Get cell connected to facet CellIterator cell(*f); // Write mesh function value to string stream local_output << (int)((meshfunction[*cell] - minval)*dval) << " " ; } } // Gather up data on zero std::vector<std::string> gathered_output; MPI::gather(local_output.str(), gathered_output); // Write XML on root process if (process_number == 0) { pugi::xml_node indexed_face_set = xml_doc.child("X3D") .child("Scene").child("Shape").child(facet_type.c_str()); indexed_face_set.append_attribute("colorPerVertex") = "false"; std::stringstream str_output; for (std::size_t i = 0; i < num_processes; ++i) str_output << gathered_output[i]; indexed_face_set.append_attribute("colorIndex") = str_output.str().c_str(); // Output palette pugi::xml_node color = indexed_face_set.append_child("Color"); color.append_attribute("color") = color_palette(palette).c_str(); // Save XML file xml_doc.save_file(_filename.c_str(), " "); } }