libMesh::BoundaryProjectSolution Class Reference

Public Member Functions

 BoundaryProjectSolution (const std::set< boundary_id_type > &b_in, const std::vector< unsigned int > &variables_in, const System &system_in, FunctionBase< Number > *f_in, FunctionBase< Gradient > *g_in, const Parameters &parameters_in, NumericVector< Number > &new_v_in)
 
 BoundaryProjectSolution (const BoundaryProjectSolution &in)
 
void operator() (const ConstElemRange &range) const
 

Private Attributes

const std::set< boundary_id_type > & b
 
const std::vector< unsigned int > & variables
 
const Systemsystem
 
std::unique_ptr< FunctionBase< Number > > f
 
std::unique_ptr< FunctionBase< Gradient > > g
 
const Parametersparameters
 
NumericVector< Number > & new_vector
 

Detailed Description

This class implements projecting an arbitrary boundary function to the current mesh. This may be executed in parallel on multiple threads.

Definition at line 157 of file system_projection.C.

Constructor & Destructor Documentation

◆ BoundaryProjectSolution() [1/2]

libMesh::BoundaryProjectSolution::BoundaryProjectSolution ( const std::set< boundary_id_type > &  b_in,
const std::vector< unsigned int > &  variables_in,
const System system_in,
FunctionBase< Number > *  f_in,
FunctionBase< Gradient > *  g_in,
const Parameters parameters_in,
NumericVector< Number > &  new_v_in 
)
inline

Definition at line 169 of file system_projection.C.

References libMesh::NumericVector< T >::init().

175  :
176  b(b_in),
177  variables(variables_in),
178  system(system_in),
179  f(f_in ? f_in->clone() : std::unique_ptr<FunctionBase<Number>>()),
180  g(g_in ? g_in->clone() : std::unique_ptr<FunctionBase<Gradient>>()),
181  parameters(parameters_in),
182  new_vector(new_v_in)
183  {
184  libmesh_assert(f.get());
185  f->init();
186  if (g.get())
187  g->init();
188  }
std::unique_ptr< FunctionBase< Number > > f
const std::vector< unsigned int > & variables
NumericVector< Number > & new_vector
virtual std::unique_ptr< FunctionBase< Output > > clone() const =0
const std::set< boundary_id_type > & b
std::unique_ptr< FunctionBase< Gradient > > g

◆ BoundaryProjectSolution() [2/2]

libMesh::BoundaryProjectSolution::BoundaryProjectSolution ( const BoundaryProjectSolution in)
inline

Definition at line 190 of file system_projection.C.

References libMesh::NumericVector< T >::init().

190  :
191  b(in.b),
192  variables(in.variables),
193  system(in.system),
194  f(in.f.get() ? in.f->clone() : std::unique_ptr<FunctionBase<Number>>()),
195  g(in.g.get() ? in.g->clone() : std::unique_ptr<FunctionBase<Gradient>>()),
196  parameters(in.parameters),
197  new_vector(in.new_vector)
198  {
199  libmesh_assert(f.get());
200  f->init();
201  if (g.get())
202  g->init();
203  }
std::unique_ptr< FunctionBase< Number > > f
const std::vector< unsigned int > & variables
NumericVector< Number > & new_vector
const std::set< boundary_id_type > & b
std::unique_ptr< FunctionBase< Gradient > > g

Member Function Documentation

◆ operator()()

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

This method projects an arbitrary boundary solution to the current mesh. The input function f gives the arbitrary solution, while the new_vector (which should already be correctly sized) gives the solution (to be computed) on the current mesh.

Definition at line 1182 of file system_projection.C.

References std::abs(), libMesh::Variable::active_on_subdomain(), bc_id, libMesh::BoundaryInfo::boundary_ids(), libMesh::C_ONE, libMesh::C_ZERO, libMesh::DenseMatrix< T >::cholesky_solve(), libMesh::FEType::default_quadrature_rule(), libMesh::DISCONTINUOUS, libMesh::DofMap::dof_indices(), libMesh::BoundaryInfo::edge_boundary_ids(), libMesh::FEType::family, libMesh::HERMITE, libMesh::index_range(), n_nodes, libMesh::DenseVector< T >::resize(), libMesh::DenseMatrix< T >::resize(), libMesh::SCALAR, libMesh::Threads::spin_mtx, libMesh::TOLERANCE, libMesh::Variable::type(), libMesh::DofMap::variable(), libMesh::DenseMatrix< T >::zero(), and libMesh::DenseVector< T >::zero().

1183 {
1184  // We need data to project
1185  libmesh_assert(f.get());
1186 
1194  // The dimensionality of the current mesh
1195  const unsigned int dim = system.get_mesh().mesh_dimension();
1196 
1197  // The DofMap for this system
1198  const DofMap & dof_map = system.get_dof_map();
1199 
1200  // Boundary info for the current mesh
1201  const BoundaryInfo & boundary_info =
1203 
1204  // The element matrix and RHS for projections.
1205  // Note that Ke is always real-valued, whereas
1206  // Fe may be complex valued if complex number
1207  // support is enabled
1208  DenseMatrix<Real> Ke;
1209  DenseVector<Number> Fe;
1210  // The new element coefficients
1211  DenseVector<Number> Ue;
1212 
1213 
1214  // Loop over all the variables we've been requested to project
1215  for (std::size_t v=0; v!=variables.size(); v++)
1216  {
1217  const unsigned int var = variables[v];
1218 
1219  const Variable & variable = dof_map.variable(var);
1220 
1221  const FEType & fe_type = variable.type();
1222 
1223  if (fe_type.family == SCALAR)
1224  continue;
1225 
1226  const unsigned int var_component =
1228 
1229  // Get FE objects of the appropriate type
1230  std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
1231 
1232  // Prepare variables for projection
1233  std::unique_ptr<QBase> qedgerule (fe_type.default_quadrature_rule(1));
1234  std::unique_ptr<QBase> qsiderule (fe_type.default_quadrature_rule(dim-1));
1235 
1236  // The values of the shape functions at the quadrature
1237  // points
1238  const std::vector<std::vector<Real>> & phi = fe->get_phi();
1239 
1240  // The gradients of the shape functions at the quadrature
1241  // points on the child element.
1242  const std::vector<std::vector<RealGradient>> * dphi = nullptr;
1243 
1244  const FEContinuity cont = fe->get_continuity();
1245 
1246  if (cont == C_ONE)
1247  {
1248  // We'll need gradient data for a C1 projection
1249  libmesh_assert(g.get());
1250 
1251  const std::vector<std::vector<RealGradient>> &
1252  ref_dphi = fe->get_dphi();
1253  dphi = &ref_dphi;
1254  }
1255 
1256  // The Jacobian * quadrature weight at the quadrature points
1257  const std::vector<Real> & JxW =
1258  fe->get_JxW();
1259 
1260  // The XYZ locations of the quadrature points
1261  const std::vector<Point> & xyz_values =
1262  fe->get_xyz();
1263 
1264  // The global DOF indices
1265  std::vector<dof_id_type> dof_indices;
1266  // Side/edge DOF indices
1267  std::vector<unsigned int> side_dofs;
1268 
1269  // Container to catch IDs passed back from BoundaryInfo.
1270  std::vector<boundary_id_type> bc_ids;
1271 
1272  // Iterate over all the elements in the range
1273  for (const auto & elem : range)
1274  {
1275  // Per-subdomain variables don't need to be projected on
1276  // elements where they're not active
1277  if (!variable.active_on_subdomain(elem->subdomain_id()))
1278  continue;
1279 
1280  const unsigned short n_nodes = elem->n_nodes();
1281  const unsigned short n_edges = elem->n_edges();
1282  const unsigned short n_sides = elem->n_sides();
1283 
1284  // Find out which nodes, edges and sides are on a requested
1285  // boundary:
1286  std::vector<bool> is_boundary_node(n_nodes, false),
1287  is_boundary_edge(n_edges, false),
1288  is_boundary_side(n_sides, false);
1289 
1290  // We also maintain a separate list of nodeset-based boundary nodes
1291  std::vector<bool> is_boundary_nodeset(n_nodes, false);
1292 
1293  for (unsigned char s=0; s != n_sides; ++s)
1294  {
1295  // First see if this side has been requested
1296  boundary_info.boundary_ids (elem, s, bc_ids);
1297  bool do_this_side = false;
1298  for (const auto & bc_id : bc_ids)
1299  if (b.count(bc_id))
1300  {
1301  do_this_side = true;
1302  break;
1303  }
1304  if (!do_this_side)
1305  continue;
1306 
1307  is_boundary_side[s] = true;
1308 
1309  // Then see what nodes and what edges are on it
1310  for (unsigned int n=0; n != n_nodes; ++n)
1311  if (elem->is_node_on_side(n,s))
1312  is_boundary_node[n] = true;
1313  for (unsigned int e=0; e != n_edges; ++e)
1314  if (elem->is_edge_on_side(e,s))
1315  is_boundary_edge[e] = true;
1316  }
1317 
1318  // We can also project on nodes, so we should also independently
1319  // check whether the nodes have been requested
1320  for (unsigned int n=0; n != n_nodes; ++n)
1321  {
1322  boundary_info.boundary_ids (elem->node_ptr(n), bc_ids);
1323 
1324  for (const auto & bc_id : bc_ids)
1325  if (b.count(bc_id))
1326  {
1327  is_boundary_node[n] = true;
1328  is_boundary_nodeset[n] = true;
1329  }
1330  }
1331 
1332  // We can also project on edges, so we should also independently
1333  // check whether the edges have been requested
1334  for (unsigned short e=0; e != n_edges; ++e)
1335  {
1336  boundary_info.edge_boundary_ids (elem, e, bc_ids);
1337 
1338  for (const auto & bc_id : bc_ids)
1339  if (b.count(bc_id))
1340  is_boundary_edge[e] = true;
1341  }
1342 
1343  // Update the DOF indices for this element based on
1344  // the current mesh
1345  dof_map.dof_indices (elem, dof_indices, var);
1346 
1347  // The number of DOFs on the element
1348  const unsigned int n_dofs =
1349  cast_int<unsigned int>(dof_indices.size());
1350 
1351  // Fixed vs. free DoFs on edge/face projections
1352  std::vector<char> dof_is_fixed(n_dofs, false); // bools
1353  std::vector<int> free_dof(n_dofs, 0);
1354 
1355  // The element type
1356  const ElemType elem_type = elem->type();
1357 
1358  // Zero the interpolated values
1359  Ue.resize (n_dofs); Ue.zero();
1360 
1361  // In general, we need a series of
1362  // projections to ensure a unique and continuous
1363  // solution. We start by interpolating boundary nodes, then
1364  // hold those fixed and project boundary edges, then hold
1365  // those fixed and project boundary faces,
1366 
1367  // Interpolate node values first
1368  unsigned int current_dof = 0;
1369  for (unsigned short n = 0; n != n_nodes; ++n)
1370  {
1371  // FIXME: this should go through the DofMap,
1372  // not duplicate dof_indices code badly!
1373  const unsigned int nc =
1374  FEInterface::n_dofs_at_node (dim, fe_type, elem_type,
1375  n);
1376  if ((!elem->is_vertex(n) || !is_boundary_node[n]) &&
1377  !is_boundary_nodeset[n])
1378  {
1379  current_dof += nc;
1380  continue;
1381  }
1382  if (cont == DISCONTINUOUS)
1383  {
1384  libmesh_assert_equal_to (nc, 0);
1385  }
1386  // Assume that C_ZERO elements have a single nodal
1387  // value shape function
1388  else if (cont == C_ZERO)
1389  {
1390  libmesh_assert_equal_to (nc, 1);
1391  Ue(current_dof) = f->component(var_component,
1392  elem->point(n),
1393  system.time);
1394  dof_is_fixed[current_dof] = true;
1395  current_dof++;
1396  }
1397  // The hermite element vertex shape functions are weird
1398  else if (fe_type.family == HERMITE)
1399  {
1400  Ue(current_dof) = f->component(var_component,
1401  elem->point(n),
1402  system.time);
1403  dof_is_fixed[current_dof] = true;
1404  current_dof++;
1405  Gradient grad = g->component(var_component,
1406  elem->point(n),
1407  system.time);
1408  // x derivative
1409  Ue(current_dof) = grad(0);
1410  dof_is_fixed[current_dof] = true;
1411  current_dof++;
1412  if (dim > 1)
1413  {
1414  // We'll finite difference mixed derivatives
1415  Point nxminus = elem->point(n),
1416  nxplus = elem->point(n);
1417  nxminus(0) -= TOLERANCE;
1418  nxplus(0) += TOLERANCE;
1419  Gradient gxminus = g->component(var_component,
1420  nxminus,
1421  system.time);
1422  Gradient gxplus = g->component(var_component,
1423  nxplus,
1424  system.time);
1425  // y derivative
1426  Ue(current_dof) = grad(1);
1427  dof_is_fixed[current_dof] = true;
1428  current_dof++;
1429  // xy derivative
1430  Ue(current_dof) = (gxplus(1) - gxminus(1))
1431  / 2. / TOLERANCE;
1432  dof_is_fixed[current_dof] = true;
1433  current_dof++;
1434 
1435  if (dim > 2)
1436  {
1437  // z derivative
1438  Ue(current_dof) = grad(2);
1439  dof_is_fixed[current_dof] = true;
1440  current_dof++;
1441  // xz derivative
1442  Ue(current_dof) = (gxplus(2) - gxminus(2))
1443  / 2. / TOLERANCE;
1444  dof_is_fixed[current_dof] = true;
1445  current_dof++;
1446  // We need new points for yz
1447  Point nyminus = elem->point(n),
1448  nyplus = elem->point(n);
1449  nyminus(1) -= TOLERANCE;
1450  nyplus(1) += TOLERANCE;
1451  Gradient gyminus = g->component(var_component,
1452  nyminus,
1453  system.time);
1454  Gradient gyplus = g->component(var_component,
1455  nyplus,
1456  system.time);
1457  // xz derivative
1458  Ue(current_dof) = (gyplus(2) - gyminus(2))
1459  / 2. / TOLERANCE;
1460  dof_is_fixed[current_dof] = true;
1461  current_dof++;
1462  // Getting a 2nd order xyz is more tedious
1463  Point nxmym = elem->point(n),
1464  nxmyp = elem->point(n),
1465  nxpym = elem->point(n),
1466  nxpyp = elem->point(n);
1467  nxmym(0) -= TOLERANCE;
1468  nxmym(1) -= TOLERANCE;
1469  nxmyp(0) -= TOLERANCE;
1470  nxmyp(1) += TOLERANCE;
1471  nxpym(0) += TOLERANCE;
1472  nxpym(1) -= TOLERANCE;
1473  nxpyp(0) += TOLERANCE;
1474  nxpyp(1) += TOLERANCE;
1475  Gradient gxmym = g->component(var_component,
1476  nxmym,
1477  system.time);
1478  Gradient gxmyp = g->component(var_component,
1479  nxmyp,
1480  system.time);
1481  Gradient gxpym = g->component(var_component,
1482  nxpym,
1483  system.time);
1484  Gradient gxpyp = g->component(var_component,
1485  nxpyp,
1486  system.time);
1487  Number gxzplus = (gxpyp(2) - gxmyp(2))
1488  / 2. / TOLERANCE;
1489  Number gxzminus = (gxpym(2) - gxmym(2))
1490  / 2. / TOLERANCE;
1491  // xyz derivative
1492  Ue(current_dof) = (gxzplus - gxzminus)
1493  / 2. / TOLERANCE;
1494  dof_is_fixed[current_dof] = true;
1495  current_dof++;
1496  }
1497  }
1498  }
1499  // Assume that other C_ONE elements have a single nodal
1500  // value shape function and nodal gradient component
1501  // shape functions
1502  else if (cont == C_ONE)
1503  {
1504  libmesh_assert_equal_to (nc, 1 + dim);
1505  Ue(current_dof) = f->component(var_component,
1506  elem->point(n),
1507  system.time);
1508  dof_is_fixed[current_dof] = true;
1509  current_dof++;
1510  Gradient grad = g->component(var_component,
1511  elem->point(n),
1512  system.time);
1513  for (unsigned int i=0; i!= dim; ++i)
1514  {
1515  Ue(current_dof) = grad(i);
1516  dof_is_fixed[current_dof] = true;
1517  current_dof++;
1518  }
1519  }
1520  else
1521  libmesh_error_msg("Unknown continuity " << cont);
1522  }
1523 
1524  // In 3D, project any edge values next
1525  if (dim > 2 && cont != DISCONTINUOUS)
1526  for (unsigned short e = 0; e != n_edges; ++e)
1527  {
1528  if (!is_boundary_edge[e])
1529  continue;
1530 
1531  FEInterface::dofs_on_edge(elem, dim, fe_type, e,
1532  side_dofs);
1533 
1534  const unsigned int n_side_dofs =
1535  cast_int<unsigned int>(side_dofs.size());
1536 
1537  // Some edge dofs are on nodes and already
1538  // fixed, others are free to calculate
1539  unsigned int free_dofs = 0;
1540  for (auto i : IntRange<unsigned int>(0, n_side_dofs))
1541  if (!dof_is_fixed[side_dofs[i]])
1542  free_dof[free_dofs++] = i;
1543 
1544  // There may be nothing to project
1545  if (!free_dofs)
1546  continue;
1547 
1548  Ke.resize (free_dofs, free_dofs); Ke.zero();
1549  Fe.resize (free_dofs); Fe.zero();
1550  // The new edge coefficients
1551  DenseVector<Number> Uedge(free_dofs);
1552 
1553  // Initialize FE data on the edge
1554  fe->attach_quadrature_rule (qedgerule.get());
1555  fe->edge_reinit (elem, e);
1556  const unsigned int n_qp = qedgerule->n_points();
1557 
1558  // Loop over the quadrature points
1559  for (unsigned int qp=0; qp<n_qp; qp++)
1560  {
1561  // solution at the quadrature point
1562  Number fineval = f->component(var_component,
1563  xyz_values[qp],
1564  system.time);
1565  // solution grad at the quadrature point
1566  Gradient finegrad;
1567  if (cont == C_ONE)
1568  finegrad = g->component(var_component,
1569  xyz_values[qp],
1570  system.time);
1571 
1572  // Form edge projection matrix
1573  for (unsigned int sidei=0, freei=0;
1574  sidei != n_side_dofs; ++sidei)
1575  {
1576  unsigned int i = side_dofs[sidei];
1577  // fixed DoFs aren't test functions
1578  if (dof_is_fixed[i])
1579  continue;
1580  for (unsigned int sidej=0, freej=0;
1581  sidej != n_side_dofs; ++sidej)
1582  {
1583  unsigned int j = side_dofs[sidej];
1584  if (dof_is_fixed[j])
1585  Fe(freei) -= phi[i][qp] * phi[j][qp] *
1586  JxW[qp] * Ue(j);
1587  else
1588  Ke(freei,freej) += phi[i][qp] *
1589  phi[j][qp] * JxW[qp];
1590  if (cont == C_ONE)
1591  {
1592  if (dof_is_fixed[j])
1593  Fe(freei) -= ((*dphi)[i][qp] *
1594  (*dphi)[j][qp]) *
1595  JxW[qp] * Ue(j);
1596  else
1597  Ke(freei,freej) += ((*dphi)[i][qp] *
1598  (*dphi)[j][qp])
1599  * JxW[qp];
1600  }
1601  if (!dof_is_fixed[j])
1602  freej++;
1603  }
1604  Fe(freei) += phi[i][qp] * fineval * JxW[qp];
1605  if (cont == C_ONE)
1606  Fe(freei) += (finegrad * (*dphi)[i][qp]) *
1607  JxW[qp];
1608  freei++;
1609  }
1610  }
1611 
1612  Ke.cholesky_solve(Fe, Uedge);
1613 
1614  // Transfer new edge solutions to element
1615  for (unsigned int i=0; i != free_dofs; ++i)
1616  {
1617  Number & ui = Ue(side_dofs[free_dof[i]]);
1618  libmesh_assert(std::abs(ui) < TOLERANCE ||
1619  std::abs(ui - Uedge(i)) < TOLERANCE);
1620  ui = Uedge(i);
1621  dof_is_fixed[side_dofs[free_dof[i]]] = true;
1622  }
1623  }
1624 
1625  // Project any side values (edges in 2D, faces in 3D)
1626  if (dim > 1 && cont != DISCONTINUOUS)
1627  for (unsigned short s = 0; s != n_sides; ++s)
1628  {
1629  if (!is_boundary_side[s])
1630  continue;
1631 
1632  FEInterface::dofs_on_side(elem, dim, fe_type, s,
1633  side_dofs);
1634 
1635  // Some side dofs are on nodes/edges and already
1636  // fixed, others are free to calculate
1637  unsigned int free_dofs = 0;
1638  for (auto i : index_range(side_dofs))
1639  if (!dof_is_fixed[side_dofs[i]])
1640  free_dof[free_dofs++] = i;
1641 
1642  // There may be nothing to project
1643  if (!free_dofs)
1644  continue;
1645 
1646  Ke.resize (free_dofs, free_dofs); Ke.zero();
1647  Fe.resize (free_dofs); Fe.zero();
1648  // The new side coefficients
1649  DenseVector<Number> Uside(free_dofs);
1650 
1651  // Initialize FE data on the side
1652  fe->attach_quadrature_rule (qsiderule.get());
1653  fe->reinit (elem, s);
1654  const unsigned int n_qp = qsiderule->n_points();
1655 
1656  const unsigned int n_side_dofs =
1657  cast_int<unsigned int>(side_dofs.size());
1658 
1659  // Loop over the quadrature points
1660  for (unsigned int qp=0; qp<n_qp; qp++)
1661  {
1662  // solution at the quadrature point
1663  Number fineval = f->component(var_component,
1664  xyz_values[qp],
1665  system.time);
1666  // solution grad at the quadrature point
1667  Gradient finegrad;
1668  if (cont == C_ONE)
1669  finegrad = g->component(var_component,
1670  xyz_values[qp],
1671  system.time);
1672 
1673  // Form side projection matrix
1674  for (unsigned int sidei=0, freei=0;
1675  sidei != n_side_dofs; ++sidei)
1676  {
1677  unsigned int i = side_dofs[sidei];
1678  // fixed DoFs aren't test functions
1679  if (dof_is_fixed[i])
1680  continue;
1681  for (unsigned int sidej=0, freej=0;
1682  sidej != n_side_dofs; ++sidej)
1683  {
1684  unsigned int j = side_dofs[sidej];
1685  if (dof_is_fixed[j])
1686  Fe(freei) -= phi[i][qp] * phi[j][qp] *
1687  JxW[qp] * Ue(j);
1688  else
1689  Ke(freei,freej) += phi[i][qp] *
1690  phi[j][qp] * JxW[qp];
1691  if (cont == C_ONE)
1692  {
1693  if (dof_is_fixed[j])
1694  Fe(freei) -= ((*dphi)[i][qp] *
1695  (*dphi)[j][qp]) *
1696  JxW[qp] * Ue(j);
1697  else
1698  Ke(freei,freej) += ((*dphi)[i][qp] *
1699  (*dphi)[j][qp])
1700  * JxW[qp];
1701  }
1702  if (!dof_is_fixed[j])
1703  freej++;
1704  }
1705  Fe(freei) += (fineval * phi[i][qp]) * JxW[qp];
1706  if (cont == C_ONE)
1707  Fe(freei) += (finegrad * (*dphi)[i][qp]) *
1708  JxW[qp];
1709  freei++;
1710  }
1711  }
1712 
1713  Ke.cholesky_solve(Fe, Uside);
1714 
1715  // Transfer new side solutions to element
1716  for (unsigned int i=0; i != free_dofs; ++i)
1717  {
1718  Number & ui = Ue(side_dofs[free_dof[i]]);
1719  libmesh_assert(std::abs(ui) < TOLERANCE ||
1720  std::abs(ui - Uside(i)) < TOLERANCE);
1721  ui = Uside(i);
1722  dof_is_fixed[side_dofs[free_dof[i]]] = true;
1723  }
1724  }
1725 
1726  const dof_id_type
1727  first = new_vector.first_local_index(),
1728  last = new_vector.last_local_index();
1729 
1730  // Lock the new_vector since it is shared among threads.
1731  {
1732  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
1733 
1734  for (unsigned int i = 0; i < n_dofs; i++)
1735  if (dof_is_fixed[i] &&
1736  (dof_indices[i] >= first) &&
1737  (dof_indices[i] < last))
1738  {
1739  new_vector.set(dof_indices[i], Ue(i));
1740  }
1741  }
1742  } // end elem loop
1743  } // end variables loop
1744 }
static void dofs_on_edge(const Elem *const elem, const unsigned int dim, const FEType &fe_t, unsigned int e, std::vector< unsigned int > &di)
Definition: fe_interface.C:536
double abs(double a)
unsigned int variable_scalar_number(const std::string &var, unsigned int component) const
Definition: system.h:2164
static void dofs_on_side(const Elem *const elem, const unsigned int dim, const FEType &fe_t, unsigned int s, std::vector< unsigned int > &di)
Definition: fe_interface.C:523
std::unique_ptr< FunctionBase< Number > > f
IntRange< std::size_t > index_range(const std::vector< T > &vec)
Definition: int_range.h:104
static const Real TOLERANCE
const std::vector< unsigned int > & variables
const BoundaryInfo & get_boundary_info() const
Definition: mesh_base.h:131
const MeshBase & get_mesh() const
Definition: system.h:2033
boundary_id_type bc_id
Definition: xdr_io.C:51
const dof_id_type n_nodes
Definition: tecplot_io.C:68
spin_mutex spin_mtx
Definition: threads.C:29
NumericVector< Number > & new_vector
NumberVectorValue Gradient
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
Definition: fe_interface.C:473
virtual numeric_index_type first_local_index() const =0
unsigned int mesh_dimension() const
Definition: mesh_base.C:126
virtual void set(const numeric_index_type i, const T value)=0
const std::set< boundary_id_type > & b
std::unique_ptr< FunctionBase< Gradient > > g
const DofMap & get_dof_map() const
Definition: system.h:2049
virtual numeric_index_type last_local_index() const =0
uint8_t dof_id_type
Definition: id_types.h:64

Member Data Documentation

◆ b

const std::set<boundary_id_type>& libMesh::BoundaryProjectSolution::b
private

Definition at line 160 of file system_projection.C.

◆ f

std::unique_ptr<FunctionBase<Number> > libMesh::BoundaryProjectSolution::f
private

Definition at line 163 of file system_projection.C.

◆ g

std::unique_ptr<FunctionBase<Gradient> > libMesh::BoundaryProjectSolution::g
private

Definition at line 164 of file system_projection.C.

◆ new_vector

NumericVector<Number>& libMesh::BoundaryProjectSolution::new_vector
private

Definition at line 166 of file system_projection.C.

◆ parameters

const Parameters& libMesh::BoundaryProjectSolution::parameters
private

Definition at line 165 of file system_projection.C.

◆ system

const System& libMesh::BoundaryProjectSolution::system
private

Definition at line 162 of file system_projection.C.

◆ variables

const std::vector<unsigned int>& libMesh::BoundaryProjectSolution::variables
private

Definition at line 161 of file system_projection.C.


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