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 1523 of file system_projection.C.

References send_list.

1524 {
1525  // Joining simply requires I add the dof indices from the other object
1526  this->send_list.insert(this->send_list.end(),
1527  other.send_list.begin(),
1528  other.send_list.end());
1529 }
std::vector< dof_id_type > send_list

◆ operator()()

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

Definition at line 1406 of file system_projection.C.

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

1407 {
1408  // The DofMap for this system
1409  const DofMap & dof_map = system.get_dof_map();
1410 
1411  const dof_id_type first_old_dof = dof_map.first_old_dof();
1412  const dof_id_type end_old_dof = dof_map.end_old_dof();
1413 
1414  // We can handle all the variables at once.
1415  // The old global DOF indices
1416  std::vector<dof_id_type> di;
1417 
1418  // Iterate over the elements in the range
1419  for (const auto & elem : range)
1420  {
1421  // If this element doesn't have an old_dof_object with dofs for the
1422  // current system, then it must be newly added, so the user
1423  // is responsible for setting the new dofs.
1424 
1425  // ... but we need a better way to test for that; the code
1426  // below breaks on any FE type for which the elem stores no
1427  // dofs.
1428  // if (!elem->get_old_dof_object() || !elem->get_old_dof_object()->has_dofs(system.number()))
1429  // continue;
1430 
1431  // Examining refinement flags instead should distinguish
1432  // between refinement-added and user-added elements lacking
1433  // old_dof_object
1434  const DofObject * old_dof_object = elem->get_old_dof_object();
1435  if (!old_dof_object &&
1436  elem->refinement_flag() != Elem::JUST_REFINED &&
1437  elem->refinement_flag() != Elem::JUST_COARSENED)
1438  continue;
1439 
1440  const Elem * parent = elem->parent();
1441 
1442  if (elem->refinement_flag() == Elem::JUST_REFINED)
1443  {
1444  libmesh_assert(parent);
1445 
1446  // We used to hack_p_level here, but that wasn't thread-safe
1447  // so now we take p refinement flags into account in
1448  // old_dof_indices
1449 
1450  dof_map.old_dof_indices (parent, di);
1451 
1452  for (auto & node : elem->node_ref_range())
1453  {
1454  const DofObject * old_dofs = node.get_old_dof_object();
1455 
1456  if (old_dofs)
1457  {
1458  const unsigned int sysnum = system.number();
1459  const unsigned int nvg = old_dofs->n_var_groups(sysnum);
1460 
1461  for (unsigned int vg=0; vg != nvg; ++vg)
1462  {
1463  const unsigned int nvig =
1464  old_dofs->n_vars(sysnum, vg);
1465  for (unsigned int vig=0; vig != nvig; ++vig)
1466  {
1467  const unsigned int n_comp =
1468  old_dofs->n_comp_group(sysnum, vg);
1469  for (unsigned int c=0; c != n_comp; ++c)
1470  {
1471  const dof_id_type old_id =
1472  old_dofs->dof_number(sysnum, vg, vig,
1473  c, n_comp);
1474 
1475  // We should either have no old id
1476  // (e.g. on a newly expanded subdomain)
1477  // or an id from the old system.
1478  libmesh_assert(old_id < dof_map.n_old_dofs() ||
1479  old_id == DofObject::invalid_id);
1480  di.push_back(old_id);
1481  }
1482  }
1483  }
1484  }
1485  }
1486 
1487  std::sort(di.begin(), di.end());
1488  std::vector<dof_id_type>::iterator new_end =
1489  std::unique(di.begin(), di.end());
1490  std::vector<dof_id_type>(di.begin(), new_end).swap(di);
1491  }
1492  else if (elem->refinement_flag() == Elem::JUST_COARSENED)
1493  {
1494  std::vector<dof_id_type> di_child;
1495  di.clear();
1496  for (auto & child : elem->child_ref_range())
1497  {
1498  dof_map.old_dof_indices (&child, di_child);
1499  di.insert(di.end(), di_child.begin(), di_child.end());
1500  }
1501  }
1502  else
1503  dof_map.old_dof_indices (elem, di);
1504 
1505  for (auto di_i : di)
1506  {
1507  // If we've just expanded a subdomain for a
1508  // subdomain-restricted variable, then we may have an
1509  // old_dof_object that doesn't have an old DoF for every
1510  // local index.
1511  if (di_i == DofObject::invalid_id)
1512  continue;
1513 
1514  libmesh_assert_less(di_i, dof_map.n_old_dofs());
1515  if (di_i < first_old_dof || di_i >= end_old_dof)
1516  this->send_list.push_back(di_i);
1517  }
1518  } // end elem loop
1519 }
unsigned int number() const
Definition: system.h:2393
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:473
libmesh_assert(ctx)
std::vector< dof_id_type > send_list
const DofMap & get_dof_map() const
Definition: system.h:2417
uint8_t dof_id_type
Definition: id_types.h:67

◆ unique()

void libMesh::BuildProjectionList::unique ( )

Definition at line 1386 of file system_projection.C.

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

1387 {
1388  // Sort the send list. After this duplicated
1389  // elements will be adjacent in the vector
1390  std::sort(this->send_list.begin(),
1391  this->send_list.end());
1392 
1393  // Now use std::unique to remove duplicate entries
1394  std::vector<dof_id_type>::iterator new_end =
1395  std::unique (this->send_list.begin(),
1396  this->send_list.end());
1397 
1398  // Remove the end of the send_list. Use the "swap trick"
1399  // from Effective STL
1400  std::vector<dof_id_type>
1401  (this->send_list.begin(), new_end).swap (this->send_list);
1402 }
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: