* @ref{FiniteElementBase} should be private base classes of
* @ref{FiniteElement}.
*
- * @author Wolfgang Bangerth, Guido Kanschat, 1998, 1999, 2000, 2001
+ * @author Wolfgang Bangerth, Guido Kanschat, 1998, 1999, 2000, 2001, 2003
*/
template<int dim>
class FiniteElementData
*/
const unsigned int components;
+ /**
+ * Maximal polynomial degree of a
+ * shape function in a single
+ * coordinate direction.
+ */
+ const unsigned int degree;
+
/**
* Default
* constructor. Constructs an
*
* Hence this constructor requires
* @p{dofs_per_object.size()==dim+1}.
+ *
+ * @param n_components Number of
+ * vector components of the
+ * element.
+ * @param degree
+ * Maximal polynomial degree in a
+ * single direction.
*/
FiniteElementData (const std::vector<unsigned int> &dofs_per_object,
- const unsigned int n_components);
+ const unsigned int n_components,
+ const unsigned int degree = deal_II_numbers::invalid_unsigned_int);
/**
* Return the @p{dofs_per_vertex}.
*/
unsigned int n_components () const;
+ /**
+ * Maximal polynomial degree of a
+ * shape function in a single
+ * coordinate direction.
+ *
+ * This function can be used to
+ * determine the optimal
+ * quadrature rule.
+ */
+ unsigned int tensor_degree () const;
+
/**
* Comparison operator.
*/
+template <int dim>
+inline
+unsigned int
+FiniteElementData<dim>::tensor_degree () const
+{
+ return degree;
+}
+
+
+
template <int dim>
inline
std::pair<unsigned int,unsigned int>
template <int dim>
FiniteElementData<dim>::FiniteElementData (const std::vector<unsigned int> &dofs_per_object,
- const unsigned int n_components) :
+ const unsigned int n_components,
+ const unsigned int degree) :
dofs_per_vertex(dofs_per_object[0]),
dofs_per_line(dofs_per_object[1]),
dofs_per_quad(dim>1? dofs_per_object[2]:0),
GeometryInfo<dim>::lines_per_cell * dofs_per_line +
GeometryInfo<dim>::quads_per_cell * dofs_per_quad +
GeometryInfo<dim>::hexes_per_cell * dofs_per_hex),
- components(n_components)
+ components(n_components),
+ degree(degree)
{
Assert(dofs_per_object.size()==dim+1, ExcDimensionMismatch(dofs_per_object.size()-1,dim));
}
template <int dim>
FE_DGP<dim>::FE_DGP (const unsigned int degree)
:
- FiniteElement<dim> (FiniteElementData<dim>(get_dpo_vector(degree),1),
- std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree),1).dofs_per_cell,true),
- std::vector<std::vector<bool> >(FiniteElementData<dim>(get_dpo_vector(degree),1).dofs_per_cell,
+ FiniteElement<dim> (FiniteElementData<dim>(get_dpo_vector(degree), 1, degree),
+ std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree), 1, degree).dofs_per_cell,true),
+ std::vector<std::vector<bool> >(FiniteElementData<dim>(get_dpo_vector(degree), 1, degree).dofs_per_cell,
std::vector<bool>(1,true))),
degree(degree),
polynomial_space (Polynomials::Legendre::generate_complete_basis(degree))
// given an integer N, compute its
// integer square root (if it
// exists, otherwise give up)
- unsigned int int_sqrt (const unsigned int N)
+ inline unsigned int int_sqrt (const unsigned int N)
{
for (unsigned int i=0; i<=N; ++i)
if (i*i == N)
// given an integer N, compute its
// integer cube root (if it
// exists, otherwise give up)
- unsigned int int_cuberoot (const unsigned int N)
+ inline unsigned int int_cuberoot (const unsigned int N)
{
for (unsigned int i=0; i<=N; ++i)
if (i*i*i == N)
// given N, generate i=0...N-1
// equidistant points in the
// interior of the interval [0,1]
- Point<1>
+ inline Point<1>
generate_unit_point (const unsigned int i,
const unsigned int N,
const int2type<1> )
// given N, generate i=0...N-1
// equidistant points in the domain
// [0,1]^2
- Point<2>
+ inline Point<2>
generate_unit_point (const unsigned int i,
const unsigned int N,
const int2type<2> )
// given N, generate i=0...N-1
// equidistant points in the domain
// [0,1]^3
- Point<3>
+ inline Point<3>
generate_unit_point (const unsigned int i,
const unsigned int N,
const int2type<3> )
template <int dim>
FE_DGQ<dim>::FE_DGQ (const unsigned int degree)
:
- FiniteElement<dim> (FiniteElementData<dim>(get_dpo_vector(degree),1),
- std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree),1).dofs_per_cell,
+ FiniteElement<dim> (FiniteElementData<dim>(get_dpo_vector(degree), 1, degree),
+ std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell,
true),
- std::vector<std::vector<bool> >(FiniteElementData<dim>(get_dpo_vector(degree),1).dofs_per_cell,
+ std::vector<std::vector<bool> >(FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell,
std::vector<bool>(1,true))),
degree(degree),
polynomial_space (Polynomials::LagrangeEquidistant::generate_complete_basis(degree))
template <int dim>
FE_Q<dim>::FE_Q (const unsigned int degree)
:
- FiniteElement<dim> (FiniteElementData<dim>(get_dpo_vector(degree),1),
- std::vector<bool> (FiniteElementData<dim>(get_dpo_vector(degree),1).dofs_per_cell,
+ FiniteElement<dim> (FiniteElementData<dim>(get_dpo_vector(degree),1, degree),
+ std::vector<bool> (FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell,
false),
- std::vector<std::vector<bool> >(FiniteElementData<dim>(get_dpo_vector(degree),1).dofs_per_cell,
+ std::vector<std::vector<bool> >(FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell,
std::vector<bool>(1,true))),
degree(degree),
renumber(lexicographic_to_hierarchic_numbering (*this, degree)),
template <int dim>
FE_Q_Hierarchical<dim>::FE_Q_Hierarchical (const unsigned int degree)
:
- FiniteElement<dim> (FiniteElementData<dim>(get_dpo_vector(degree),1),
- std::vector<bool> (FiniteElementData<dim>(get_dpo_vector(degree),1).dofs_per_cell,
+ FiniteElement<dim> (FiniteElementData<dim>(get_dpo_vector(degree),1, degree),
+ std::vector<bool> (FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell,
false),
- std::vector<std::vector<bool> >(FiniteElementData<dim>(get_dpo_vector(degree),1).dofs_per_cell,
+ std::vector<std::vector<bool> >(FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell,
std::vector<bool>(1,true))),
degree(degree),
renumber(lexicographic_to_hierarchic_numbering (*this, degree)),
FE_RaviartThomas<dim>::FE_RaviartThomas (const unsigned int degree)
:
FiniteElement<dim> (FiniteElementData<dim>(get_dpo_vector(degree),
- dim),
+ dim, degree+1),
get_ria_vector (degree),
- std::vector<std::vector<bool> >(FiniteElementData<dim>(get_dpo_vector(degree),dim).dofs_per_cell,
+ std::vector<std::vector<bool> >(FiniteElementData<dim>(get_dpo_vector(degree),dim,degree+1).dofs_per_cell,
std::vector<bool>(dim,true))),
degree(degree),
polynomials (create_polynomials(degree)),
#include <fe/mapping.h>
#include <fe/fe_system.h>
#include <fe/fe_values.h>
-
+#include <iostream>
#ifdef HAVE_STD_STRINGSTREAM
# include <sstream>
#else
if (dim>1) dpo.push_back(fe_data.dofs_per_quad * N);
if (dim>2) dpo.push_back(fe_data.dofs_per_hex * N);
- return FiniteElementData<dim> (dpo, fe_data.n_components() * N);
+ return FiniteElementData<dim> (dpo, fe_data.n_components() * N, fe_data.tensor_degree());
}
dpo.push_back(fe1.dofs_per_line * N1 + fe2.dofs_per_line * N2);
if (dim>1) dpo.push_back(fe1.dofs_per_quad * N1 + fe2.dofs_per_quad * N2);
if (dim>2) dpo.push_back(fe1.dofs_per_hex * N1 + fe2.dofs_per_hex * N2);
-
+
+ // degree is the maximal degree of
+ // the components. max also makes
+ // sure that one unknown degree
+ // makes the degree of the system
+ // unknown.
+ unsigned int degree = std::max(fe1.tensor_degree(), fe2.tensor_degree());
return FiniteElementData<dim> (dpo,
fe1.n_components() * N1 +
- fe2.n_components() * N2);
+ fe2.n_components() * N2,
+ degree);
}
if (dim>2) dpo.push_back(fe1.dofs_per_hex * N1 +
fe2.dofs_per_hex * N2 +
fe3.dofs_per_hex * N3);
-
+ // degree is the maximal degree of the components
+ unsigned int degree = std::max(fe1.tensor_degree(), fe2.tensor_degree());
+ degree = std::max(degree, fe3.tensor_degree());
return FiniteElementData<dim> (dpo,
fe1.n_components() * N1 +
fe2.n_components() * N2 +
- fe3.n_components() * N3);
+ fe3.n_components() * N3, degree);
}
<h3>deal.II</h3>
<ol>
+
+ <li> <p>
+ Improved: <code class="class">FiniteElementData</code> has a function
+ <class="member">tensor_degree()</code>, returning the degree of the
+ polynomial space suitable for choosing a tensor product quadrature formula.
+ <br>
+ (GK 2003/11/28)
+ </p>
+
<li> <p>
New: Long requested but never implemented before in the
library: there is now a function <code
- <class="member">GridTool::find_active_cell_around_point</code>
+ <class="class">GridTool</code>::<class="member">find_active_cell_around_point</code>
that, given a point, finds the active cell in which this point
lies.
<br>
deallog << "first_face_quad_index=" << fe_data->first_face_quad_index << std::endl;
deallog << "dofs_per_face=" << fe_data->dofs_per_face << std::endl;
deallog << "dofs_per_cell=" << fe_data->dofs_per_cell << std::endl;
- deallog << "components=" << fe_data->components << std::endl;
+ deallog << "components=" << fe_data->components << std::endl
+ << "degree=" << fe_data->tensor_degree() << std::endl;
for (unsigned int f=0;f<GeometryInfo<dim>::faces_per_cell;++f)
{
deallog << '\t' << s;
deallog << std::endl;
}
+ deallog << std::endl;
}
// delete all FiniteElementDatas