Rheolef  7.2
an efficient C++ finite element environment
basis_rep.cc
Go to the documentation of this file.
1 #include "rheolef/basis.h"
22 #include "rheolef/basis_get.h"
23 
24 namespace rheolef {
25 using namespace std;
26 
27 // =========================================================================
28 // naming scheme for standard FEM families
29 // =========================================================================
30 static
31 bool
32 is_family_no_index (const std::string& family_name)
33 {
34  // TODO: how to merge this keywords list with basis_lex.flex ?
35  // basis::have_index_parameter() givzes the response, but requires a
36  // previously builded basis
37  if (family_name == "bubble") return true;
38  if (family_name == "P1qd") return true;
39  if (family_name == "empty") return true;
40  return false;
41 }
42 template <class T>
43 std::string
45  std::string family_name,
46  size_type index,
47  const basis_option& sopt)
48 {
49  string opt_d = (sopt.is_continuous() || (family_name == "P" && index == 0)) ? "" : "d";
50  string basename = is_family_no_index (family_name) ? family_name : family_name + std::to_string(index) + opt_d;
51  string name_opt = basename + sopt.stamp();
52  if (sopt.valued_tag() == space_constant::scalar) {
53  trace_macro("standard_naming("<<family_name<<","<<index<<",opts)=\""<<name_opt<<"\"");
54  if (! sopt.is_trace_n()) {
55  return name_opt;
56  } else {
57  return "trace_n(" + name_opt + ")";
58  }
59  }
60  // here: non-scalar basis
61  const size_type unset = std::numeric_limits<basis_option::size_type>::max();
62  string opt_dim = (sopt.dimension() == unset) ? "" : "d=" + std::to_string(sopt.dimension());
63  string opt_sc = (sopt.valued_tag() == space_constant::vector || sopt.coordinate_system() == space_constant::cartesian) ?
65  string coma = (opt_dim == "" || opt_sc == "") ? "" : ",";
66  string opt_valued = (opt_dim == "" && opt_sc == "") ? "" : "[" + opt_dim + coma + opt_sc + "]";
67  string braced_name = sopt.valued() + opt_valued + "(" + name_opt + ")";
68  if (! sopt.is_trace_n()) {
69  return braced_name;
70  } else {
71  return "trace_n(" + braced_name + ")";
72  }
73 }
74 // =========================================================================
75 // basis members (should be inlined)
76 // =========================================================================
77 template<class T>
78 void
79 basis_basic<T>::reset (std::string& name_in)
80 {
81  if (name_in == "") {
82  base::operator= (0);
83  } else {
84  // strip name_in as name: drop "scalar(Pk)" as "Pk" or "P0d" as "P0", to get unique name scheme
86  basis_parse_from_string (name_in, fio);
87  std::string name = basis_rep<T>::standard_naming (fio.family, fio.index, fio.option);
88  base::operator= (persistent_table<basis_basic<T>>::load (name));
89  _clear();
90  }
91 }
92 template<class T>
93 void
95 {
96  std::string fname = family_name();
97  basis_option bopt = option();
98  std::string name = basis_rep<T>::standard_naming (fname, k, bopt); \
99  reset (name);
100 }
101 template <class T>
103 {
104  persistent_table<basis_basic<T>>::unload (_name);
105 }
106 template<class T>
108 : _name(""),
109  _sopt(sopt),
110  _piola_fem(),
111  _have_initialize_data(),
112  _ndof_on_subgeo_internal(),
113  _ndof_on_subgeo(),
114  _nnod_on_subgeo_internal(),
115  _nnod_on_subgeo(),
116  _first_idof_by_dimension_internal(),
117  _first_idof_by_dimension(),
118  _first_inod_by_dimension_internal(),
119  _first_inod_by_dimension()
120 {
121  _clear();
122 }
123 template<class T>
124 void
126 {
127  _have_initialize_data.fill (false);
128 }
129 template <class T>
130 void
132 {
133  if (_have_initialize_data [hat_K.variant()]) return;
134  _have_initialize_data [hat_K.variant()] = true;
135  _initialize_data (hat_K);
136 }
137 // =========================================================================
138 // dof & nof: hierarchial organization by increasing subgeo dimension
139 // =========================================================================
140 // inplace change nxxx_on_subgeo for discontinuous elements
141 template <class T>
142 void
144  bool is_continuous,
145  const
146  std::array<
147  std::array<
148  size_type
150  ,4>& nxxx_on_subgeo_internal,
151  std::array<
152  std::array<
153  size_type
155  ,4>& nxxx_on_subgeo)
156 {
157  if (is_continuous) {
158  nxxx_on_subgeo = nxxx_on_subgeo_internal;
159  return; // no changes
160  }
161  for (size_type map_dim = 0; map_dim < 4; ++map_dim) {
162  nxxx_on_subgeo [map_dim].fill (0);
163  }
164  for (size_type variant = 0;
166  variant++)
167  {
168  reference_element hat_K (variant);
169  size_type map_dim = hat_K.dimension();
170  size_type sum = 0;
171  for (size_type subgeo_variant = 0;
173  subgeo_variant++)
174  {
175  size_type n_subgeo = hat_K.n_subgeo_by_variant (subgeo_variant);
176  sum += n_subgeo*nxxx_on_subgeo_internal [map_dim][subgeo_variant];
177  }
178  nxxx_on_subgeo [map_dim][variant] = sum;
179  }
180 }
181 // deduce automatically first_ixxx_by_dimension from nxxx_on_subgeo
182 template <class T>
183 void
185  const std::array<
186  std::array<
187  size_type
189  ,4>& nxxx_on_subgeo,
190  std::array<
191  std::array<
192  size_type
193  ,5>
194  ,reference_element::max_variant>& first_ixxx_by_dimension)
195 {
196  for (size_type variant = 0;
198  variant++)
199  {
200  reference_element hat_K (variant);
201  size_type map_dim = hat_K.dimension();
202  first_ixxx_by_dimension [variant].fill(0);
203  for (size_type subgeo_dim = 0; subgeo_dim <= map_dim; ++subgeo_dim) {
204  size_type sum = first_ixxx_by_dimension [variant][subgeo_dim];
205  for (size_type subgeo_variant = reference_element::first_variant_by_dimension(subgeo_dim);
206  subgeo_variant < reference_element:: last_variant_by_dimension(subgeo_dim);
207  subgeo_variant++)
208  {
209  size_type n_subgeo = hat_K.n_subgeo_by_variant (subgeo_variant);
210  sum += n_subgeo*nxxx_on_subgeo [map_dim][subgeo_variant];
211  }
212  first_ixxx_by_dimension [variant][subgeo_dim+1] = sum;
213  }
214  }
215 }
216 // ----------------------------------------------------------------------------
217 // instanciation in library
218 // ----------------------------------------------------------------------------
219 #define _RHEOLEF_instanciation(T) \
220 template class basis_rep<T>; \
221 template void basis_basic<T>::reset (std::string&); \
222 template void basis_basic<T>::reset_family_index (size_type); \
223 
225 
226 }// namespace rheolef
see the Float page for the full documentation
rep::size_type size_type
Definition: basis.h:573
void reset_family_index(size_type k)
Definition: basis_rep.cc:94
void reset(std::string &name)
Definition: basis_rep.cc:79
see the basis_option page for the full documentation
Definition: basis_option.h:93
bool is_continuous() const
Definition: basis_option.h:227
bool is_trace_n() const
Definition: basis_option.h:239
coordinate_type coordinate_system() const
Definition: basis_option.h:139
size_type dimension() const
Definition: basis_option.h:138
std::string stamp() const
valued_type valued_tag() const
Definition: basis_option.h:245
const std::string & valued() const
Definition: basis_option.h:251
virtual ~basis_rep()
Definition: basis_rep.cc:102
basis_rep(const basis_option &sopt)
Definition: basis_rep.cc:107
static void _helper_make_discontinuous_ndof_on_subgeo(bool is_continuous, const std::array< std::array< size_type, reference_element::max_variant >, 4 > &nxxx_on_subgeo_internal, std::array< std::array< size_type, reference_element::max_variant >, 4 > &nxxx_on_subgeo)
Definition: basis_rep.cc:143
reference_element::size_type size_type
Definition: basis.h:214
void _initialize_data_guard(reference_element hat_K) const
Definition: basis_rep.cc:131
static std::string standard_naming(std::string family_name, size_t degree, const basis_option &sopt)
Definition: basis_rep.cc:44
void _clear() const
Definition: basis_rep.cc:125
static void _helper_initialize_first_ixxx_by_dimension_from_nxxx_on_subgeo(const std::array< std::array< size_type, reference_element::max_variant >, 4 > &_nxxx_on_subgeo, std::array< std::array< size_type, 5 >, reference_element::max_variant > &_first_ixxx_by_dimension)
Definition: basis_rep.cc:184
see the persistent_table page for the full documentation
see the reference_element page for the full documentation
static const variant_type max_variant
static variant_type last_variant_by_dimension(size_type dim)
static variant_type first_variant_by_dimension(size_type dim)
size_type n_subgeo_by_variant(size_type subgeo_variant) const
variant_type variant() const
#define trace_macro(message)
Definition: dis_macros.h:111
std::string coordinate_system_name(coordinate_type i)
This file is part of Rheolef.
void basis_parse_from_string(const std::string &str, family_index_option_type &fio)
Definition: basis_get.cc:142
_RHEOLEF_instanciation(Float, sequential, std::allocator< Float >) _RHEOLEF_instanciation(Float
void load(idiststream &in, Float &p, field &uh)