libMesh
Loading...
Searching...
No Matches
Public Member Functions | Private Attributes | List of all members
libMesh::BoundaryProjectSolution Class Reference

This class implements projecting an arbitrary boundary function to the current mesh. More...

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

210 :
211 b(b_in),
212 variables(variables_in),
213 system(system_in),
214 f(f_in ? f_in->clone() : std::unique_ptr<FunctionBase<Number>>()),
215 g(g_in ? g_in->clone() : std::unique_ptr<FunctionBase<Gradient>>()),
216 parameters(parameters_in),
217 new_vector(new_v_in)
218 {
219 libmesh_assert(f.get());
220 f->init();
221 if (g.get())
222 g->init();
223 }
const std::vector< unsigned int > & variables
std::unique_ptr< FunctionBase< Gradient > > g
std::unique_ptr< FunctionBase< Number > > f
NumericVector< Number > & new_vector
const std::set< boundary_id_type > & b
virtual std::unique_ptr< FunctionBase< Output > > clone() const =0
NumberVectorValue Gradient
libmesh_assert(ctx)

References libMesh::libmesh_assert().

◆ BoundaryProjectSolution() [2/2]

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

Definition at line 225 of file system_projection.C.

225 :
226 b(in.b),
227 variables(in.variables),
228 system(in.system),
229 f(in.f.get() ? in.f->clone() : std::unique_ptr<FunctionBase<Number>>()),
230 g(in.g.get() ? in.g->clone() : std::unique_ptr<FunctionBase<Gradient>>()),
233 {
234 libmesh_assert(f.get());
235 f->init();
236 if (g.get())
237 g->init();
238 }
const Elem & get(const ElemType type_in)

References libMesh::libmesh_assert().

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

1536{
1537 // We need data to project
1538 libmesh_assert(f.get());
1539
1547 // The dimensionality of the current mesh
1548 const unsigned int dim = system.get_mesh().mesh_dimension();
1549
1550 // The DofMap for this system
1551 const DofMap & dof_map = system.get_dof_map();
1552
1553 // Boundary info for the current mesh
1554 const BoundaryInfo & boundary_info =
1556
1557 // The element matrix and RHS for projections.
1558 // Note that Ke is always real-valued, whereas
1559 // Fe may be complex valued if complex number
1560 // support is enabled
1562 DenseVector<Number> Fe;
1563 // The new element coefficients
1564 DenseVector<Number> Ue;
1565
1566
1567 // Loop over all the variables we've been requested to project
1568 for (auto v : make_range(variables.size()))
1569 {
1570 const unsigned int var = variables[v];
1571
1572 const Variable & variable = dof_map.variable(var);
1573
1574 const FEType & fe_type = variable.type();
1575
1576 if (fe_type.family == SCALAR)
1577 continue;
1578
1579 const unsigned int var_component =
1581
1582 // Get FE objects of the appropriate type
1583 std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
1584
1585 // Prepare variables for projection
1586 std::unique_ptr<QBase> qedgerule (fe_type.default_quadrature_rule(1));
1587 std::unique_ptr<QBase> qsiderule (fe_type.default_quadrature_rule(dim-1));
1588
1589 // The values of the shape functions at the quadrature
1590 // points
1591 const std::vector<std::vector<Real>> & phi = fe->get_phi();
1592
1593 // The gradients of the shape functions at the quadrature
1594 // points on the child element.
1595 const std::vector<std::vector<RealGradient>> * dphi = nullptr;
1596
1597 const FEContinuity cont = fe->get_continuity();
1598
1599 if (cont == C_ONE)
1600 {
1601 // We'll need gradient data for a C1 projection
1602 libmesh_assert(g.get());
1603
1604 const std::vector<std::vector<RealGradient>> &
1605 ref_dphi = fe->get_dphi();
1606 dphi = &ref_dphi;
1607 }
1608
1609 // The Jacobian * quadrature weight at the quadrature points
1610 const std::vector<Real> & JxW =
1611 fe->get_JxW();
1612
1613 // The XYZ locations of the quadrature points
1614 const std::vector<Point> & xyz_values =
1615 fe->get_xyz();
1616
1617 // The global DOF indices
1618 std::vector<dof_id_type> dof_indices;
1619 // Side/edge DOF indices
1620 std::vector<unsigned int> side_dofs;
1621
1622 // Container to catch IDs passed back from BoundaryInfo.
1623 std::vector<boundary_id_type> bc_ids;
1624
1625 // Iterate over all the elements in the range
1626 for (const auto & elem : range)
1627 {
1628 // Per-subdomain variables don't need to be projected on
1629 // elements where they're not active
1630 if (!variable.active_on_subdomain(elem->subdomain_id()))
1631 continue;
1632
1633 const unsigned short n_nodes = elem->n_nodes();
1634 const unsigned short n_edges = elem->n_edges();
1635 const unsigned short n_sides = elem->n_sides();
1636
1637 // Find out which nodes, edges and sides are on a requested
1638 // boundary:
1639 std::vector<bool> is_boundary_node(n_nodes, false),
1640 is_boundary_edge(n_edges, false),
1641 is_boundary_side(n_sides, false);
1642
1643 // We also maintain a separate list of nodeset-based boundary nodes
1644 std::vector<bool> is_boundary_nodeset(n_nodes, false);
1645
1646 for (unsigned char s=0; s != n_sides; ++s)
1647 {
1648 // First see if this side has been requested
1649 boundary_info.boundary_ids (elem, s, bc_ids);
1650 bool do_this_side = false;
1651 for (const auto & bc_id : bc_ids)
1652 if (b.count(bc_id))
1653 {
1654 do_this_side = true;
1655 break;
1656 }
1657 if (!do_this_side)
1658 continue;
1659
1660 is_boundary_side[s] = true;
1661
1662 // Then see what nodes and what edges are on it
1663 for (unsigned int n=0; n != n_nodes; ++n)
1664 if (elem->is_node_on_side(n,s))
1665 is_boundary_node[n] = true;
1666 for (unsigned int e=0; e != n_edges; ++e)
1667 if (elem->is_edge_on_side(e,s))
1668 is_boundary_edge[e] = true;
1669 }
1670
1671 // We can also project on nodes, so we should also independently
1672 // check whether the nodes have been requested
1673 for (unsigned int n=0; n != n_nodes; ++n)
1674 {
1675 boundary_info.boundary_ids (elem->node_ptr(n), bc_ids);
1676
1677 for (const auto & bc_id : bc_ids)
1678 if (b.count(bc_id))
1679 {
1680 is_boundary_node[n] = true;
1681 is_boundary_nodeset[n] = true;
1682 }
1683 }
1684
1685 // We can also project on edges, so we should also independently
1686 // check whether the edges have been requested
1687 for (unsigned short e=0; e != n_edges; ++e)
1688 {
1689 boundary_info.edge_boundary_ids (elem, e, bc_ids);
1690
1691 for (const auto & bc_id : bc_ids)
1692 if (b.count(bc_id))
1693 is_boundary_edge[e] = true;
1694 }
1695
1696 // Update the DOF indices for this element based on
1697 // the current mesh
1698 dof_map.dof_indices (elem, dof_indices, var);
1699
1700 // The number of DOFs on the element
1701 const unsigned int n_dofs =
1702 cast_int<unsigned int>(dof_indices.size());
1703
1704 // Fixed vs. free DoFs on edge/face projections
1705 std::vector<char> dof_is_fixed(n_dofs, false); // bools
1706 std::vector<int> free_dof(n_dofs, 0);
1707
1708 // Zero the interpolated values
1709 Ue.resize (n_dofs); Ue.zero();
1710
1711 // In general, we need a series of
1712 // projections to ensure a unique and continuous
1713 // solution. We start by interpolating boundary nodes, then
1714 // hold those fixed and project boundary edges, then hold
1715 // those fixed and project boundary faces,
1716
1717 // Interpolate node values first
1718 unsigned int current_dof = 0;
1719 for (unsigned short n = 0; n != n_nodes; ++n)
1720 {
1721 // FIXME: this should go through the DofMap,
1722 // not duplicate dof_indices code badly!
1723
1724 // This call takes into account elem->p_level() internally.
1725 const unsigned int nc =
1726 FEInterface::n_dofs_at_node (fe_type, elem, n);
1727
1728 if ((!elem->is_vertex(n) || !is_boundary_node[n]) &&
1729 !is_boundary_nodeset[n])
1730 {
1731 current_dof += nc;
1732 continue;
1733 }
1734 if (cont == DISCONTINUOUS)
1735 {
1736 libmesh_assert_equal_to (nc, 0);
1737 }
1738 // Assume that C_ZERO elements have a single nodal
1739 // value shape function
1740 else if (cont == C_ZERO)
1741 {
1742 libmesh_assert_equal_to (nc, 1);
1743 Ue(current_dof) = f->component(var_component,
1744 elem->point(n),
1745 system.time);
1746 dof_is_fixed[current_dof] = true;
1747 current_dof++;
1748 }
1749 // The hermite element vertex shape functions are weird
1750 else if (fe_type.family == HERMITE)
1751 {
1752 Ue(current_dof) = f->component(var_component,
1753 elem->point(n),
1754 system.time);
1755 dof_is_fixed[current_dof] = true;
1756 current_dof++;
1757 Gradient grad = g->component(var_component,
1758 elem->point(n),
1759 system.time);
1760 // x derivative
1761 Ue(current_dof) = grad(0);
1762 dof_is_fixed[current_dof] = true;
1763 current_dof++;
1764#if LIBMESH_DIM > 1
1765 if (dim > 1)
1766 {
1767 // We'll finite difference mixed derivatives
1768 Point nxminus = elem->point(n),
1769 nxplus = elem->point(n);
1770 nxminus(0) -= TOLERANCE;
1771 nxplus(0) += TOLERANCE;
1772 Gradient gxminus = g->component(var_component,
1773 nxminus,
1774 system.time);
1775 Gradient gxplus = g->component(var_component,
1776 nxplus,
1777 system.time);
1778 // y derivative
1779 Ue(current_dof) = grad(1);
1780 dof_is_fixed[current_dof] = true;
1781 current_dof++;
1782 // xy derivative
1783 Ue(current_dof) = (gxplus(1) - gxminus(1))
1784 / 2. / TOLERANCE;
1785 dof_is_fixed[current_dof] = true;
1786 current_dof++;
1787
1788#if LIBMESH_DIM > 2
1789 if (dim > 2)
1790 {
1791 // z derivative
1792 Ue(current_dof) = grad(2);
1793 dof_is_fixed[current_dof] = true;
1794 current_dof++;
1795 // xz derivative
1796 Ue(current_dof) = (gxplus(2) - gxminus(2))
1797 / 2. / TOLERANCE;
1798 dof_is_fixed[current_dof] = true;
1799 current_dof++;
1800 // We need new points for yz
1801 Point nyminus = elem->point(n),
1802 nyplus = elem->point(n);
1803 nyminus(1) -= TOLERANCE;
1804 nyplus(1) += TOLERANCE;
1805 Gradient gyminus = g->component(var_component,
1806 nyminus,
1807 system.time);
1808 Gradient gyplus = g->component(var_component,
1809 nyplus,
1810 system.time);
1811 // xz derivative
1812 Ue(current_dof) = (gyplus(2) - gyminus(2))
1813 / 2. / TOLERANCE;
1814 dof_is_fixed[current_dof] = true;
1815 current_dof++;
1816 // Getting a 2nd order xyz is more tedious
1817 Point nxmym = elem->point(n),
1818 nxmyp = elem->point(n),
1819 nxpym = elem->point(n),
1820 nxpyp = elem->point(n);
1821 nxmym(0) -= TOLERANCE;
1822 nxmym(1) -= TOLERANCE;
1823 nxmyp(0) -= TOLERANCE;
1824 nxmyp(1) += TOLERANCE;
1825 nxpym(0) += TOLERANCE;
1826 nxpym(1) -= TOLERANCE;
1827 nxpyp(0) += TOLERANCE;
1828 nxpyp(1) += TOLERANCE;
1829 Gradient gxmym = g->component(var_component,
1830 nxmym,
1831 system.time);
1832 Gradient gxmyp = g->component(var_component,
1833 nxmyp,
1834 system.time);
1835 Gradient gxpym = g->component(var_component,
1836 nxpym,
1837 system.time);
1838 Gradient gxpyp = g->component(var_component,
1839 nxpyp,
1840 system.time);
1841 Number gxzplus = (gxpyp(2) - gxmyp(2))
1842 / 2. / TOLERANCE;
1843 Number gxzminus = (gxpym(2) - gxmym(2))
1844 / 2. / TOLERANCE;
1845 // xyz derivative
1846 Ue(current_dof) = (gxzplus - gxzminus)
1847 / 2. / TOLERANCE;
1848 dof_is_fixed[current_dof] = true;
1849 current_dof++;
1850 }
1851#endif // LIBMESH_DIM > 2
1852 }
1853#endif // LIBMESH_DIM > 1
1854 }
1855 // Assume that other C_ONE elements have a single nodal
1856 // value shape function and nodal gradient component
1857 // shape functions
1858 else if (cont == C_ONE)
1859 {
1860 libmesh_assert_equal_to (nc, 1 + dim);
1861 Ue(current_dof) = f->component(var_component,
1862 elem->point(n),
1863 system.time);
1864 dof_is_fixed[current_dof] = true;
1865 current_dof++;
1866 Gradient grad = g->component(var_component,
1867 elem->point(n),
1868 system.time);
1869 for (unsigned int i=0; i!= dim; ++i)
1870 {
1871 Ue(current_dof) = grad(i);
1872 dof_is_fixed[current_dof] = true;
1873 current_dof++;
1874 }
1875 }
1876 else
1877 libmesh_error_msg("Unknown continuity " << cont);
1878 }
1879
1880 // In 3D, project any edge values next
1881 if (dim > 2 && cont != DISCONTINUOUS)
1882 for (unsigned short e = 0; e != n_edges; ++e)
1883 {
1884 if (!is_boundary_edge[e])
1885 continue;
1886
1887 FEInterface::dofs_on_edge(elem, dim, fe_type, e,
1888 side_dofs);
1889
1890 const unsigned int n_side_dofs =
1891 cast_int<unsigned int>(side_dofs.size());
1892
1893 // Some edge dofs are on nodes and already
1894 // fixed, others are free to calculate
1895 unsigned int free_dofs = 0;
1896 for (auto i : make_range(n_side_dofs))
1897 if (!dof_is_fixed[side_dofs[i]])
1898 free_dof[free_dofs++] = i;
1899
1900 // There may be nothing to project
1901 if (!free_dofs)
1902 continue;
1903
1904 Ke.resize (free_dofs, free_dofs); Ke.zero();
1905 Fe.resize (free_dofs); Fe.zero();
1906 // The new edge coefficients
1907 DenseVector<Number> Uedge(free_dofs);
1908
1909 // Initialize FE data on the edge
1910 fe->attach_quadrature_rule (qedgerule.get());
1911 fe->edge_reinit (elem, e);
1912 const unsigned int n_qp = qedgerule->n_points();
1913
1914 // Loop over the quadrature points
1915 for (unsigned int qp=0; qp<n_qp; qp++)
1916 {
1917 // solution at the quadrature point
1918 Number fineval = f->component(var_component,
1919 xyz_values[qp],
1920 system.time);
1921 // solution grad at the quadrature point
1922 Gradient finegrad;
1923 if (cont == C_ONE)
1924 finegrad = g->component(var_component,
1925 xyz_values[qp],
1926 system.time);
1927
1928 // Form edge projection matrix
1929 for (unsigned int sidei=0, freei=0;
1930 sidei != n_side_dofs; ++sidei)
1931 {
1932 unsigned int i = side_dofs[sidei];
1933 // fixed DoFs aren't test functions
1934 if (dof_is_fixed[i])
1935 continue;
1936 for (unsigned int sidej=0, freej=0;
1937 sidej != n_side_dofs; ++sidej)
1938 {
1939 unsigned int j = side_dofs[sidej];
1940 if (dof_is_fixed[j])
1941 Fe(freei) -= phi[i][qp] * phi[j][qp] *
1942 JxW[qp] * Ue(j);
1943 else
1944 Ke(freei,freej) += phi[i][qp] *
1945 phi[j][qp] * JxW[qp];
1946 if (cont == C_ONE)
1947 {
1948 if (dof_is_fixed[j])
1949 Fe(freei) -= ((*dphi)[i][qp] *
1950 (*dphi)[j][qp]) *
1951 JxW[qp] * Ue(j);
1952 else
1953 Ke(freei,freej) += ((*dphi)[i][qp] *
1954 (*dphi)[j][qp])
1955 * JxW[qp];
1956 }
1957 if (!dof_is_fixed[j])
1958 freej++;
1959 }
1960 Fe(freei) += phi[i][qp] * fineval * JxW[qp];
1961 if (cont == C_ONE)
1962 Fe(freei) += (finegrad * (*dphi)[i][qp]) *
1963 JxW[qp];
1964 freei++;
1965 }
1966 }
1967
1968 Ke.cholesky_solve(Fe, Uedge);
1969
1970 // Transfer new edge solutions to element
1971 for (unsigned int i=0; i != free_dofs; ++i)
1972 {
1973 Number & ui = Ue(side_dofs[free_dof[i]]);
1974 libmesh_assert(std::abs(ui) < TOLERANCE ||
1975 std::abs(ui - Uedge(i)) < TOLERANCE);
1976 ui = Uedge(i);
1977 dof_is_fixed[side_dofs[free_dof[i]]] = true;
1978 }
1979 }
1980
1981 // Project any side values (edges in 2D, faces in 3D)
1982 if (dim > 1 && cont != DISCONTINUOUS)
1983 for (unsigned short s = 0; s != n_sides; ++s)
1984 {
1985 if (!is_boundary_side[s])
1986 continue;
1987
1988 FEInterface::dofs_on_side(elem, dim, fe_type, s,
1989 side_dofs);
1990
1991 // Some side dofs are on nodes/edges and already
1992 // fixed, others are free to calculate
1993 unsigned int free_dofs = 0;
1994 for (auto i : index_range(side_dofs))
1995 if (!dof_is_fixed[side_dofs[i]])
1996 free_dof[free_dofs++] = i;
1997
1998 // There may be nothing to project
1999 if (!free_dofs)
2000 continue;
2001
2002 Ke.resize (free_dofs, free_dofs); Ke.zero();
2003 Fe.resize (free_dofs); Fe.zero();
2004 // The new side coefficients
2005 DenseVector<Number> Uside(free_dofs);
2006
2007 // Initialize FE data on the side
2008 fe->attach_quadrature_rule (qsiderule.get());
2009 fe->reinit (elem, s);
2010 const unsigned int n_qp = qsiderule->n_points();
2011
2012 const unsigned int n_side_dofs =
2013 cast_int<unsigned int>(side_dofs.size());
2014
2015 // Loop over the quadrature points
2016 for (unsigned int qp=0; qp<n_qp; qp++)
2017 {
2018 // solution at the quadrature point
2019 Number fineval = f->component(var_component,
2020 xyz_values[qp],
2021 system.time);
2022 // solution grad at the quadrature point
2023 Gradient finegrad;
2024 if (cont == C_ONE)
2025 finegrad = g->component(var_component,
2026 xyz_values[qp],
2027 system.time);
2028
2029 // Form side projection matrix
2030 for (unsigned int sidei=0, freei=0;
2031 sidei != n_side_dofs; ++sidei)
2032 {
2033 unsigned int i = side_dofs[sidei];
2034 // fixed DoFs aren't test functions
2035 if (dof_is_fixed[i])
2036 continue;
2037 for (unsigned int sidej=0, freej=0;
2038 sidej != n_side_dofs; ++sidej)
2039 {
2040 unsigned int j = side_dofs[sidej];
2041 if (dof_is_fixed[j])
2042 Fe(freei) -= phi[i][qp] * phi[j][qp] *
2043 JxW[qp] * Ue(j);
2044 else
2045 Ke(freei,freej) += phi[i][qp] *
2046 phi[j][qp] * JxW[qp];
2047 if (cont == C_ONE)
2048 {
2049 if (dof_is_fixed[j])
2050 Fe(freei) -= ((*dphi)[i][qp] *
2051 (*dphi)[j][qp]) *
2052 JxW[qp] * Ue(j);
2053 else
2054 Ke(freei,freej) += ((*dphi)[i][qp] *
2055 (*dphi)[j][qp])
2056 * JxW[qp];
2057 }
2058 if (!dof_is_fixed[j])
2059 freej++;
2060 }
2061 Fe(freei) += (fineval * phi[i][qp]) * JxW[qp];
2062 if (cont == C_ONE)
2063 Fe(freei) += (finegrad * (*dphi)[i][qp]) *
2064 JxW[qp];
2065 freei++;
2066 }
2067 }
2068
2069 Ke.cholesky_solve(Fe, Uside);
2070
2071 // Transfer new side solutions to element
2072 for (unsigned int i=0; i != free_dofs; ++i)
2073 {
2074 Number & ui = Ue(side_dofs[free_dof[i]]);
2075 libmesh_assert(std::abs(ui) < TOLERANCE ||
2076 std::abs(ui - Uside(i)) < TOLERANCE);
2077 ui = Uside(i);
2078 dof_is_fixed[side_dofs[free_dof[i]]] = true;
2079 }
2080 }
2081
2082 const dof_id_type
2083 first = new_vector.first_local_index(),
2085
2086 // Lock the new_vector since it is shared among threads.
2087 {
2088 Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
2089
2090 for (unsigned int i = 0; i < n_dofs; i++)
2091 if (dof_is_fixed[i] &&
2092 (dof_indices[i] >= first) &&
2093 (dof_indices[i] < last))
2094 {
2095 new_vector.set(dof_indices[i], Ue(i));
2096 }
2097 }
2098 } // end elem loop
2099 } // end variables loop
2100}
unsigned int dim
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
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, const bool add_p_level=true)
Fills the vector di with the local degree of freedom indices associated with side s of element elem A...
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
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, const bool add_p_level=true)
Fills the vector di with the local degree of freedom indices associated with edge e of element elem A...
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition mesh_base.h:170
unsigned int mesh_dimension() const
Definition mesh_base.C:430
virtual void set(const numeric_index_type i, const T value)=0
Sets v(i) = value.
virtual numeric_index_type last_local_index() const =0
virtual numeric_index_type first_local_index() const =0
Real time
For time-dependent problems, this is the time t at the beginning of the current timestep.
Definition system.h:1677
unsigned int variable_scalar_number(std::string_view var, unsigned int component) const
Definition system.h:2474
const DofMap & get_dof_map() const
Definition system.h:2417
const MeshBase & get_mesh() const
Definition system.h:2401
spin_mutex spin_mtx
A convenient spin mutex object which can be used for obtaining locks.
Definition threads.C:30
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition int_range.h:153
template class LIBMESH_EXPORT DenseMatrix< Real >
static constexpr Real TOLERANCE
uint8_t dof_id_type
Definition id_types.h:67
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition int_range.h:176
const dof_id_type n_nodes
Definition tecplot_io.C:67

References libMesh::Variable::active_on_subdomain(), b, libMesh::BoundaryInfo::boundary_ids(), libMesh::C_ONE, libMesh::C_ZERO, libMesh::DenseMatrix< T >::cholesky_solve(), libMesh::FEType::default_quadrature_rule(), dim, libMesh::DISCONTINUOUS, libMesh::DofMap::dof_indices(), libMesh::BoundaryInfo::edge_boundary_ids(), libMesh::FEType::family, libMesh::HERMITE, libMesh::index_range(), libMesh::libmesh_assert(), libMesh::make_range(), n_nodes, libMesh::DenseVector< T >::resize(), libMesh::DenseMatrix< T >::resize(), libMesh::SCALAR, libMesh::Variable::type(), libMesh::DofMap::variable(), libMesh::DenseMatrix< T >::zero(), and libMesh::DenseVector< T >::zero().

Member Data Documentation

◆ b

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

Definition at line 195 of file system_projection.C.

◆ f

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

Definition at line 198 of file system_projection.C.

◆ g

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

Definition at line 199 of file system_projection.C.

◆ new_vector

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

Definition at line 201 of file system_projection.C.

◆ parameters

const Parameters& libMesh::BoundaryProjectSolution::parameters
private

Definition at line 200 of file system_projection.C.

◆ system

const System& libMesh::BoundaryProjectSolution::system
private

Definition at line 197 of file system_projection.C.

◆ variables

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

Definition at line 196 of file system_projection.C.


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