20 #ifdef LIBMESH_HAVE_PETSC 46 for(
auto dm_it =
_dms.begin(); dm_it <
_dms.end(); ++dm_it )
47 DMDestroy( dm_it->get() );
56 START_LOG (
"init_and_attach_petscdm()",
"PetscDMWrapper");
66 for(
unsigned int level = 0; level <
n_levels; level++)
68 DM & dm = this->
get_dm(level);
77 ierr = DMSetDefaultSection(dm, section);
85 ierr = DMSetDefaultSF(dm, star_forest);
92 ierr = SNESSetDM(snes, dm);
95 STOP_LOG (
"init_and_attach_petscdm()",
"PetscDMWrapper");
100 START_LOG (
"build_section()",
"PetscDMWrapper");
103 ierr = PetscSectionCreate(system.
comm().
get(),§ion);
107 ierr = PetscSectionSetNumFields(section,system.
n_vars());
111 for(
unsigned int v = 0; v < system.
n_vars(); v++ )
126 std::unordered_map<dof_id_type,dof_id_type> node_map;
127 std::unordered_map<dof_id_type,dof_id_type> elem_map;
128 std::map<dof_id_type,unsigned int> scalar_map;
143 libmesh_error_msg(
"ERROR: Must use --node-major-dofs with PetscSection!");
155 ierr = PetscSectionSetUp(section);CHKERRABORT(system.
comm().
get(),
ierr);
160 STOP_LOG (
"build_section()",
"PetscDMWrapper");
165 START_LOG (
"build_sf()",
"PetscDMWrapper");
169 const std::vector<dof_id_type> & send_list = dof_map.
get_send_list();
172 const PetscInt n_leaves = cast_int<PetscInt>(send_list.size());
175 const PetscInt n_roots = dof_map.
n_local_dofs() + n_leaves;
180 static_assert(
sizeof(PetscInt) ==
sizeof(
dof_id_type),
"PetscInt is not a dof_id_type!");
181 PetscInt * local_dofs =
reinterpret_cast<PetscInt *
>(
const_cast<dof_id_type *
>(send_list.data()));
188 std::vector<PetscSFNode> sf_nodes(send_list.size());
190 for(
unsigned int i = 0; i < send_list.size(); i++ )
198 PetscInt index = incoming_dof - dof_map.
first_dof(rank);
200 sf_nodes[i].rank = rank;
201 sf_nodes[i].index = index;
204 PetscSFNode * remote_dofs = sf_nodes.data();
212 ierr = PetscSFSetGraph(star_forest,
221 STOP_LOG (
"build_sf()",
"PetscDMWrapper");
225 PetscSection & section,
226 std::unordered_map<dof_id_type,dof_id_type> & node_map,
227 std::unordered_map<dof_id_type,dof_id_type> & elem_map,
228 std::map<dof_id_type,unsigned int> & scalar_map)
231 libmesh_assert(node_map.empty());
266 node_map.reserve(
mesh.n_local_nodes());
267 elem_map.reserve(
mesh.n_active_local_elem());
273 for (
const auto & elem :
mesh.active_local_element_ptr_range())
275 for (
unsigned int n = 0; n < elem->n_nodes(); n++)
278 const Node & node = elem->node_ref(n);
284 std::vector<dof_id_type> node_dof_indices;
286 if( !node_dof_indices.empty() && dof_map.
local_index(node_dof_indices[0]) )
291 for(
auto dof : node_dof_indices )
297 if( node_map.count(node_id) == 0 )
299 node_map.insert(std::make_pair(node_id,pend));
310 if( elem->n_dofs(system.
number()) > 0 )
313 elem_map.insert(std::make_pair(elem_id,pend));
324 for(
unsigned int v = 0; v < system.
n_vars(); v++ )
328 scalar_map.insert(std::make_pair(pend,v));
336 PetscErrorCode
ierr = PetscSectionSetChart(section, pstart, pend);
341 PetscSection & section,
342 const std::unordered_map<dof_id_type,dof_id_type> & node_map,
343 const std::unordered_map<dof_id_type,dof_id_type> & elem_map,
344 const std::map<dof_id_type,unsigned int> & scalar_map)
356 for (
const auto & nmap : node_map )
361 libmesh_assert(
mesh.query_node_ptr(global_node_id) );
363 const Node & node =
mesh.node_ref(global_node_id);
371 for (
const auto & emap : elem_map )
376 libmesh_assert(
mesh.query_elem_ptr(global_elem_id) );
378 const Elem & elem =
mesh.elem_ref(global_elem_id);
387 for (
const auto & smap : scalar_map )
390 const unsigned int scalar_var = smap.second;
395 ierr = PetscSectionSetFieldDof( section, local_id, scalar_var, n_dofs );
400 ierr = PetscSectionSetDof( section, local_id, n_dofs );
410 PetscSection & section)
412 unsigned int total_n_dofs_at_dofobject = 0;
415 for(
unsigned int v = 0; v < system.
n_vars(); v++ )
417 unsigned int n_dofs_at_dofobject = dof_object.
n_dofs(system.
number(), v);
419 if( n_dofs_at_dofobject > 0 )
421 PetscErrorCode
ierr = PetscSectionSetFieldDof( section,
424 n_dofs_at_dofobject );
428 total_n_dofs_at_dofobject += n_dofs_at_dofobject;
432 libmesh_assert_equal_to(total_n_dofs_at_dofobject, dof_object.
n_dofs(system.
number()));
434 PetscErrorCode
ierr =
435 PetscSectionSetDof( section, local_id, total_n_dofs_at_dofobject );
442 PetscInt n_local_dofs = 0;
445 PetscInt pstart, pend;
446 PetscErrorCode
ierr = PetscSectionGetChart(section, &pstart, &pend);
450 for( PetscInt p = pstart; p < pend; p++ )
453 ierr = PetscSectionGetDof(section,p,&n_dofs);CHKERRABORT(system.
comm().
get(),
ierr);
454 n_local_dofs += n_dofs;
457 static_assert(
sizeof(PetscInt) ==
sizeof(
dof_id_type),
"PetscInt is not a dof_id_type!");
467 for(
unsigned int i = 0; i <
n_levels; i++ )
469 _dms[i] = libmesh_make_unique<DM>();
470 _sections[i] = libmesh_make_unique<PetscSection>();
477 #endif // LIBMESH_HAVE_PETSC
dof_id_type n_local_dofs() const
A geometric point in (x,y,z) space associated with a DOF.
dof_id_type n_SCALAR_dofs() const
const Variable & variable(unsigned int var) const
void set_point_range_in_section(const System &system, PetscSection §ion, std::unordered_map< dof_id_type, dof_id_type > &node_map, std::unordered_map< dof_id_type, dof_id_type > &elem_map, std::map< dof_id_type, unsigned int > &scalar_map)
Helper function for build_section.
processor_id_type dof_owner(const dof_id_type dof) const
dof_id_type check_section_n_dofs(const System &system, PetscSection §ion)
Helper function to sanity check PetscSection construction.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
DM & get_dm(unsigned int level)
Get reference to DM for the given mesh level.
std::vector< std::unique_ptr< PetscSF > > _star_forests
Vector of star forests for all grid levels.
The base class for all geometric element types.
uint8_t processor_id_type
const Parallel::Communicator & comm() const
void add_dofs_to_section(const System &system, PetscSection §ion, const std::unordered_map< dof_id_type, dof_id_type > &node_map, const std::unordered_map< dof_id_type, dof_id_type > &elem_map, const std::map< dof_id_type, unsigned int > &scalar_map)
Helper function for build_section.
dof_id_type n_local_dofs() const
const MeshBase & get_mesh() const
unsigned int n_dofs(const unsigned int s, const unsigned int var=libMesh::invalid_uint) const
Manages the degrees of freedom (DOFs) in a simulation.
processor_id_type n_processors() const
unsigned int number() const
Manages consistently variables, degrees of freedom, and coefficient vectors.
std::vector< std::unique_ptr< PetscSection > > _sections
Vector of PETScSections for all grid levels.
const std::string & variable_name(const unsigned int i) const
PetscSection & get_section(unsigned int level)
Get reference to PetscSection for the given mesh level.
PetscSF & get_star_forest(unsigned int level)
Get reference to PetscSF for the given mesh level.
void add_dofs_helper(const System &system, const DofObject &dof_object, dof_id_type local_id, PetscSection §ion)
Helper function to reduce code duplication when setting dofs in section.
std::vector< std::unique_ptr< DM > > _dms
Vector of DMs for all grid levels.
void init_dm_data(unsigned int n_levels)
Init all the n_mesh_level dependent data structures.
bool on_command_line(std::string arg)
dof_id_type first_dof(const processor_id_type proc) const
void build_section(const System &system, PetscSection §ion)
Takes System, empty PetscSection and populates the PetscSection.
void build_sf(const System &system, PetscSF &star_forest)
Takes System, empty PetscSF and populates the PetscSF.
unsigned int n_vars() const
processor_id_type processor_id() const
void clear()
Destroys and clears all build DM-related data.
const DofMap & get_dof_map() const
void init_and_attach_petscdm(System &system, SNES &snes)
const std::vector< dof_id_type > & get_send_list() const
bool local_index(dof_id_type dof_index) const
const FEType & type() const