libMesh
Public Member Functions | Public Attributes | Private Attributes | List of all members
libMesh::BuildProjectionList Class Reference

This class builds the send_list of old dof indices whose coefficients are needed to perform a projection. More...

Public Member Functions

 BuildProjectionList (const System &system_in)
 
 BuildProjectionList (BuildProjectionList &other, Threads::split)
 
void unique ()
 
void operator() (const ConstElemRange &range)
 
void join (const BuildProjectionList &other)
 

Public Attributes

std::vector< dof_id_typesend_list
 

Private Attributes

const Systemsystem
 

Detailed Description

This class builds the send_list of old dof indices whose coefficients are needed to perform a projection.

This may be executed in parallel on multiple threads. The end result is a send_list vector which is unsorted and may contain duplicate elements. The unique() method can be used to sort and create a unique list.

Definition at line 162 of file system_projection.C.

Constructor & Destructor Documentation

◆ BuildProjectionList() [1/2]

libMesh::BuildProjectionList::BuildProjectionList ( const System system_in)
inline

Definition at line 168 of file system_projection.C.

168  :
169  system(system_in),
170  send_list()
171  {}
std::vector< dof_id_type > send_list

◆ BuildProjectionList() [2/2]

libMesh::BuildProjectionList::BuildProjectionList ( BuildProjectionList other,
Threads::split   
)
inline

Definition at line 173 of file system_projection.C.

173  :
174  system(other.system),
175  send_list()
176  {}
std::vector< dof_id_type > send_list

Member Function Documentation

◆ join()

void libMesh::BuildProjectionList::join ( const BuildProjectionList other)

Definition at line 1453 of file system_projection.C.

References send_list.

1454 {
1455  // Joining simply requires I add the dof indices from the other object
1456  this->send_list.insert(this->send_list.end(),
1457  other.send_list.begin(),
1458  other.send_list.end());
1459 }
std::vector< dof_id_type > send_list

◆ operator()()

void libMesh::BuildProjectionList::operator() ( const ConstElemRange range)

Definition at line 1336 of file system_projection.C.

References libMesh::DofObject::dof_number(), libMesh::DofMap::end_old_dof(), libMesh::DofMap::first_old_dof(), libMesh::DofObject::get_old_dof_object(), libMesh::libmesh_assert(), libMesh::DofObject::n_comp_group(), libMesh::DofMap::n_old_dofs(), libMesh::DofObject::n_var_groups(), libMesh::DofObject::n_vars(), libMesh::DofMap::old_dof_indices(), and libMesh::Elem::parent().

1337 {
1338  // The DofMap for this system
1339  const DofMap & dof_map = system.get_dof_map();
1340 
1341  const dof_id_type first_old_dof = dof_map.first_old_dof();
1342  const dof_id_type end_old_dof = dof_map.end_old_dof();
1343 
1344  // We can handle all the variables at once.
1345  // The old global DOF indices
1346  std::vector<dof_id_type> di;
1347 
1348  // Iterate over the elements in the range
1349  for (const auto & elem : range)
1350  {
1351  // If this element doesn't have an old_dof_object with dofs for the
1352  // current system, then it must be newly added, so the user
1353  // is responsible for setting the new dofs.
1354 
1355  // ... but we need a better way to test for that; the code
1356  // below breaks on any FE type for which the elem stores no
1357  // dofs.
1358  // if (!elem->get_old_dof_object() || !elem->get_old_dof_object()->has_dofs(system.number()))
1359  // continue;
1360 
1361  // Examining refinement flags instead should distinguish
1362  // between refinement-added and user-added elements lacking
1363  // old_dof_object
1364  const DofObject * old_dof_object = elem->get_old_dof_object();
1365  if (!old_dof_object &&
1366  elem->refinement_flag() != Elem::JUST_REFINED &&
1367  elem->refinement_flag() != Elem::JUST_COARSENED)
1368  continue;
1369 
1370  const Elem * parent = elem->parent();
1371 
1372  if (elem->refinement_flag() == Elem::JUST_REFINED)
1373  {
1374  libmesh_assert(parent);
1375 
1376  // We used to hack_p_level here, but that wasn't thread-safe
1377  // so now we take p refinement flags into account in
1378  // old_dof_indices
1379 
1380  dof_map.old_dof_indices (parent, di);
1381 
1382  for (auto & node : elem->node_ref_range())
1383  {
1384  const DofObject * old_dofs = node.get_old_dof_object();
1385 
1386  if (old_dofs)
1387  {
1388  const unsigned int sysnum = system.number();
1389  const unsigned int nvg = old_dofs->n_var_groups(sysnum);
1390 
1391  for (unsigned int vg=0; vg != nvg; ++vg)
1392  {
1393  const unsigned int nvig =
1394  old_dofs->n_vars(sysnum, vg);
1395  for (unsigned int vig=0; vig != nvig; ++vig)
1396  {
1397  const unsigned int n_comp =
1398  old_dofs->n_comp_group(sysnum, vg);
1399  for (unsigned int c=0; c != n_comp; ++c)
1400  {
1401  const dof_id_type old_id =
1402  old_dofs->dof_number(sysnum, vg, vig,
1403  c, n_comp);
1404 
1405  // We should either have no old id
1406  // (e.g. on a newly expanded subdomain)
1407  // or an id from the old system.
1408  libmesh_assert(old_id < dof_map.n_old_dofs() ||
1409  old_id == DofObject::invalid_id);
1410  di.push_back(old_id);
1411  }
1412  }
1413  }
1414  }
1415  }
1416 
1417  std::sort(di.begin(), di.end());
1418  std::vector<dof_id_type>::iterator new_end =
1419  std::unique(di.begin(), di.end());
1420  std::vector<dof_id_type>(di.begin(), new_end).swap(di);
1421  }
1422  else if (elem->refinement_flag() == Elem::JUST_COARSENED)
1423  {
1424  std::vector<dof_id_type> di_child;
1425  di.clear();
1426  for (auto & child : elem->child_ref_range())
1427  {
1428  dof_map.old_dof_indices (&child, di_child);
1429  di.insert(di.end(), di_child.begin(), di_child.end());
1430  }
1431  }
1432  else
1433  dof_map.old_dof_indices (elem, di);
1434 
1435  for (auto di_i : di)
1436  {
1437  // If we've just expanded a subdomain for a
1438  // subdomain-restricted variable, then we may have an
1439  // old_dof_object that doesn't have an old DoF for every
1440  // local index.
1441  if (di_i == DofObject::invalid_id)
1442  continue;
1443 
1444  libmesh_assert_less(di_i, dof_map.n_old_dofs());
1445  if (di_i < first_old_dof || di_i >= end_old_dof)
1446  this->send_list.push_back(di_i);
1447  }
1448  } // end elem loop
1449 }
unsigned int number() const
Definition: system.h:2269
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
std::vector< dof_id_type > send_list
const DofMap & get_dof_map() const
Definition: system.h:2293
uint8_t dof_id_type
Definition: id_types.h:67

◆ unique()

void libMesh::BuildProjectionList::unique ( )

Definition at line 1316 of file system_projection.C.

Referenced by libMesh::System::project_vector().

1317 {
1318  // Sort the send list. After this duplicated
1319  // elements will be adjacent in the vector
1320  std::sort(this->send_list.begin(),
1321  this->send_list.end());
1322 
1323  // Now use std::unique to remove duplicate entries
1324  std::vector<dof_id_type>::iterator new_end =
1325  std::unique (this->send_list.begin(),
1326  this->send_list.end());
1327 
1328  // Remove the end of the send_list. Use the "swap trick"
1329  // from Effective STL
1330  std::vector<dof_id_type>
1331  (this->send_list.begin(), new_end).swap (this->send_list);
1332 }
std::vector< dof_id_type > send_list

Member Data Documentation

◆ send_list

std::vector<dof_id_type> libMesh::BuildProjectionList::send_list

Definition at line 181 of file system_projection.C.

Referenced by join(), and libMesh::System::project_vector().

◆ system

const System& libMesh::BuildProjectionList::system
private

Definition at line 165 of file system_projection.C.


The documentation for this class was generated from the following file: