deal2lkit: A ToolKit library for Deal.II
parsed_finite_element.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------
2 //
3 // Copyright (C) 2015 by the deal2lkit authors
4 //
5 // This file is part of the deal2lkit library.
6 //
7 // The deal2lkit library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal2lkit distribution.
13 //
14 //-----------------------------------------------------------
15 
17 #include <deal2lkit/utilities.h>
18 #include <deal.II/fe/fe_tools.h>
19 
20 #include <algorithm> // std::find
21 
22 D2K_NAMESPACE_OPEN
23 
24 template <int dim, int spacedim>
26  const std::string &default_name,
27  const std::string &default_component_names,
28  const unsigned int n_components) :
29  ParameterAcceptor(name),
30  _n_components(n_components),
31  fe_name(default_name),
32  default_component_names(default_component_names)
33 {
34  component_names = Utilities::split_string_list(default_component_names);
36 }
37 
38 template <int dim, int spacedim>
40 {
41  add_parameter(prm, &fe_name,
42  "Finite element space", fe_name,
44  "The finite element space to use. For vector "
45  "finite elements use the notation "
46  "FESystem[FE_Q(2)^2-FE_DGP(1)] (e.g. Navier-Stokes). ");
47 
49  "Blocking of the finite element", default_component_names,
50  // This ensures that an assert is thrown if you try to
51  // read something with the wrong number of components
54  (_n_components ? _n_components: numbers::invalid_unsigned_int)),
55  "How to partition the finite element. This information can be used "
56  "to construct block matrices and vectors, as well as to create "
57  "names for solution vectors, or error tables. A repeated component "
58  "is interpreted as a vector field, with dimension equal to the "
59  "number of repetitions (up to 3). This is used in conjunction "
60  "with a ParsedFiniteElement class, to generate arbitrary "
61  "finite dimensional spaces.");
62 }
63 
64 template <int dim, int spacedim>
67 {
68  return FETools::get_fe_by_name<dim,spacedim>(fe_name);
69 }
70 
71 
72 template<int dim, int spacedim>
74 {
75  component_blocks.resize(component_names.size());
76  block_names.resize(component_names.size());
77  unsigned int j=0;
78  for (unsigned int i=0; i<component_names.size(); ++i)
79  {
80  if ( (i>0) && (component_names[i-1] != component_names[i]) )
81  j++;
82  component_blocks[i] = j;
84  }
85  block_names.resize(j+1);
86  FiniteElement<dim,spacedim> *fe = (*this)();
87  const unsigned int nc = fe->n_components();
88  delete fe;
89  AssertThrow(component_names.size() == nc,
90  ExcInternalError("Generated FE has the wrong number of components."));
91 }
92 
93 
94 template<int dim, int spacedim>
96 {
97  return component_names.size();
98 }
99 
100 
101 template<int dim, int spacedim>
103 {
104  return block_names.size();
105 }
106 
107 
108 template<int dim, int spacedim>
110 {
111  return print(component_names);
112 }
113 
114 
115 template<int dim, int spacedim>
117 {
118  return print(block_names);
119 }
120 
121 
122 template<int dim, int spacedim>
124 {
125  return component_blocks;
126 }
127 
128 template<int dim, int spacedim>
129 unsigned int ParsedFiniteElement<dim,spacedim>::get_first_occurence(const std::string &var) const
130 {
131  auto pos_it = std::find (component_names.begin(), component_names.end(), var);
132  Assert(pos_it != component_names.end(),
133  ExcInternalError("Component not found!"));
134  return pos_it - component_names.begin();
135 }
136 
137 template<int dim, int spacedim>
138 bool ParsedFiniteElement<dim,spacedim>::is_vector(const std::string &var) const
139 {
140  auto pos_it = std::find (component_names.begin(), component_names.end(), var);
141  Assert(pos_it != component_names.end(),
142  ExcInternalError("Component not found!"));
143  pos_it++;
144  if (pos_it == component_names.end())
145  return false;
146  return (*pos_it == var);
147 }
148 
149 D2K_NAMESPACE_CLOSE
150 
151 
152 template class deal2lkit::ParsedFiniteElement<1,1>;
153 template class deal2lkit::ParsedFiniteElement<1,2>;
154 template class deal2lkit::ParsedFiniteElement<1,3>;
155 template class deal2lkit::ParsedFiniteElement<2,2>;
156 template class deal2lkit::ParsedFiniteElement<2,3>;
157 template class deal2lkit::ParsedFiniteElement<3,3>;
158 
static const unsigned int invalid_unsigned_int
A parameter acceptor base class.
unsigned int get_first_occurence(const std::string &var) const
Return the first occurence of var in default_component_names.
static ParameterHandler prm
Static parameter.
std::string default_component_names
Default component names.
#define AssertThrow(cond, exc)
ParsedFiniteElement(const std::string &name="", const std::string &default_fe="FE_Q(1)", const std::string &default_component_names="u", const unsigned int n_components=0)
Constructor.
std::vector< std::string > block_names
The subdivision, in terms of block names.
virtual void declare_parameters(ParameterHandler &prm)
Declare possible parameters of this class.
unsigned int n_blocks() const
Return the number of blocks of the Finite Element, i.e., the number of variables. ...
virtual void parse_parameters_call_back()
Fill information about blocks after parsing the parameters.
const unsigned int _n_components
Number of components of this FiniteElement.
FiniteElement< dim, spacedim > * operator()() const
Return a shared pointer to a newly created Finite Element.
std::string get_block_names() const
Return the block names for this Finite Element.
#define Assert(cond, exc)
std::vector< unsigned int > component_blocks
The subdivision, in terms of component indices.
std::vector< unsigned int > get_component_blocks() const
Return the blocking of the components for this finite element.
bool is_vector(const std::string &var) const
unsigned int n_components() const
unsigned int n_components() const
Return the number of components of the Finite Element.
std::string print(const std::vector< Type > &list, const std::string sep=",")
Return a string containing the content of the vector, with elements separated by the @ sep parameter...
Definition: utilities.h:425
std::vector< std::string > split_string_list(const std::string &s, const char delimiter=',')
std::string get_component_names() const
Return the component names for this Finite Element.
void add_parameter(ParameterHandler &prm, T *parameter, const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation=std::string())
Add a parameter the given parameter list.
std::string fe_name
Finite Element Name.
static::ExceptionBase & ExcInternalError()
std::vector< std::string > component_names
Block names.