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

References send_list.

1463 {
1464  // Joining simply requires I add the dof indices from the other object
1465  this->send_list.insert(this->send_list.end(),
1466  other.send_list.begin(),
1467  other.send_list.end());
1468 }
std::vector< dof_id_type > send_list

◆ operator()()

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

Definition at line 1345 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().

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

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

1326 {
1327  // Sort the send list. After this duplicated
1328  // elements will be adjacent in the vector
1329  std::sort(this->send_list.begin(),
1330  this->send_list.end());
1331 
1332  // Now use std::unique to remove duplicate entries
1333  std::vector<dof_id_type>::iterator new_end =
1334  std::unique (this->send_list.begin(),
1335  this->send_list.end());
1336 
1337  // Remove the end of the send_list. Use the "swap trick"
1338  // from Effective STL
1339  std::vector<dof_id_type>
1340  (this->send_list.begin(), new_end).swap (this->send_list);
1341 }
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: