void MeshBase::partition (const unsigned int n_parts) { // If we get here and we have unpartitioned elements, we need that // fixed. if (this->n_unpartitioned_elem() > 0) { libmesh_assert (partitioner().get()); libmesh_assert (this->is_serial()); partitioner()->partition (*this, n_parts); } // NULL partitioner means don't repartition // Non-serial meshes may not be ready for repartitioning here. else if(!skip_partitioning() && partitioner().get()) { partitioner()->partition (*this, n_parts); } else { // Adaptive coarsening may have "orphaned" nodes on processors // whose elements no longer share them. We need to check for // and possibly fix that. Partitioner::set_node_processor_ids(*this); // Make sure locally cached partition count this->recalculate_n_partitions(); // Make sure any other locally cached data is correct this->update_post_partitioning(); } }
void MeshBase::partition (const unsigned int n_parts) { // NULL partitioner means don't partition // Non-serial meshes aren't ready for partitioning yet. if(!skip_partitioning() && partitioner().get() && this->is_serial()) { partitioner()->partition (*this, n_parts); } else { // Make sure locally cached partition count this->recalculate_n_partitions(); // Make sure any other locally cached data is correct this->update_post_partitioning(); } }
void MeshBase::prepare_for_use (const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors) { LOG_SCOPE("prepare_for_use()", "MeshBase"); parallel_object_only(); libmesh_assert(this->comm().verify(this->is_serial())); // A distributed mesh may have processors with no elements (or // processors with no elements of higher dimension, if we ever // support mixed-dimension meshes), but we want consistent // mesh_dimension anyways. // // cache_elem_dims() should get the elem_dimensions() and // mesh_dimension() correct later, and we don't need it earlier. // Renumber the nodes and elements so that they in contiguous // blocks. By default, _skip_renumber_nodes_and_elements is false. // // We may currently change that by passing // skip_renumber_nodes_and_elements==true to this function, but we // should use the allow_renumbering() accessor instead. // // Instances where you if prepare_for_use() should not renumber the nodes // and elements include reading in e.g. an xda/r or gmv file. In // this case, the ordering of the nodes may depend on an accompanying // solution, and the node ordering cannot be changed. if (skip_renumber_nodes_and_elements) { libmesh_deprecated(); this->allow_renumbering(false); } // Mesh modification operations might not leave us with consistent // id counts, but our partitioner might need that consistency. if (!_skip_renumber_nodes_and_elements) this->renumber_nodes_and_elements(); else this->update_parallel_id_counts(); // Let all the elements find their neighbors if (!skip_find_neighbors) this->find_neighbors(); // The user may have set boundary conditions. We require that the // boundary conditions were set consistently. Because we examine // neighbors when evaluating non-raw boundary condition IDs, this // assert is only valid when our neighbor links are in place. #ifdef DEBUG MeshTools::libmesh_assert_valid_boundary_ids(*this); #endif // Search the mesh for all the dimensions of the elements // and cache them. this->cache_elem_dims(); // Search the mesh for elements that have a neighboring element // of dim+1 and set that element as the interior parent this->detect_interior_parents(); // Fix up node unique ids in case mesh generation code didn't take // exceptional care to do so. // MeshCommunication().make_node_unique_ids_parallel_consistent(*this); // We're going to still require that mesh generation code gets // element unique ids consistent. #if defined(DEBUG) && defined(LIBMESH_ENABLE_UNIQUE_ID) MeshTools::libmesh_assert_valid_unique_ids(*this); #endif // Reset our PointLocator. Any old locator is invalidated any time // the elements in the underlying elements in the mesh have changed, // so we clear it here. this->clear_point_locator(); // Allow our GhostingFunctor objects to reinit if necessary. // Do this before partitioning and redistributing, and before // deleting remote elements. for (auto & gf : _ghosting_functors) { libmesh_assert(gf); gf->mesh_reinit(); } // Partition the mesh unless *all* partitioning is to be skipped. // If only noncritical partitioning is to be skipped, the // partition() call will still check for orphaned nodes. if (!skip_partitioning()) this->partition(); // If we're using DistributedMesh, we'll probably want it // parallelized. if (this->_allow_remote_element_removal) this->delete_remote_elements(); if (!_skip_renumber_nodes_and_elements) this->renumber_nodes_and_elements(); // The mesh is now prepared for use. _is_prepared = true; #if defined(DEBUG) && defined(LIBMESH_ENABLE_UNIQUE_ID) MeshTools::libmesh_assert_valid_boundary_ids(*this); MeshTools::libmesh_assert_valid_unique_ids(*this); #endif }