Reference documentation for deal.II version 8.5.1
fe_tools.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2017 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II 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 deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #include <deal.II/base/quadrature_lib.h>
18 #include <deal.II/base/qprojector.h>
19 #include <deal.II/base/thread_management.h>
20 #include <deal.II/base/utilities.h>
21 #include <deal.II/lac/full_matrix.h>
22 #include <deal.II/lac/householder.h>
23 #include <deal.II/lac/constraint_matrix.h>
24 #include <deal.II/grid/tria.h>
25 #include <deal.II/grid/tria_iterator.h>
26 #include <deal.II/grid/grid_generator.h>
27 #include <deal.II/fe/fe_tools.h>
28 #include <deal.II/fe/fe.h>
29 #include <deal.II/fe/fe_face.h>
30 #include <deal.II/fe/fe_q_iso_q1.h>
31 #include <deal.II/fe/fe_q.h>
32 #include <deal.II/fe/fe_q_dg0.h>
33 #include <deal.II/fe/fe_q_bubbles.h>
34 #include <deal.II/fe/fe_bernstein.h>
35 #include <deal.II/fe/fe_q_hierarchical.h>
36 #include <deal.II/fe/fe_dgq.h>
37 #include <deal.II/fe/fe_dgp.h>
38 #include <deal.II/fe/fe_dgp_monomial.h>
39 #include <deal.II/fe/fe_dgp_nonparametric.h>
40 #include <deal.II/fe/fe_dg_vector.h>
41 #include <deal.II/fe/fe_nedelec.h>
42 #include <deal.II/fe/fe_abf.h>
43 #include <deal.II/fe/fe_bdm.h>
44 #include <deal.II/fe/fe_raviart_thomas.h>
45 #include <deal.II/fe/fe_rannacher_turek.h>
46 #include <deal.II/fe/fe_nothing.h>
47 #include <deal.II/fe/fe_system.h>
48 #include <deal.II/fe/fe_values.h>
49 #include <deal.II/fe/mapping_cartesian.h>
50 #include <deal.II/fe/mapping_q1.h>
51 #include <deal.II/dofs/dof_handler.h>
52 #include <deal.II/dofs/dof_accessor.h>
53 #include <deal.II/dofs/dof_tools.h>
54 #include <deal.II/hp/dof_handler.h>
55 
56 #include <deal.II/base/std_cxx11/shared_ptr.h>
57 
58 #include <deal.II/base/index_set.h>
59 
60 #include <cctype>
61 #include <iostream>
62 
63 
64 DEAL_II_NAMESPACE_OPEN
65 
66 namespace FETools
67 {
68  namespace Compositing
69  {
70 
71  template <int dim, int spacedim>
73  multiply_dof_numbers (const std::vector<const FiniteElement<dim,spacedim>*> &fes,
74  const std::vector<unsigned int> &multiplicities,
75  const bool do_tensor_product)
76  {
77  AssertDimension(fes.size(), multiplicities.size());
78 
79  unsigned int multiplied_dofs_per_vertex = 0;
80  unsigned int multiplied_dofs_per_line = 0;
81  unsigned int multiplied_dofs_per_quad = 0;
82  unsigned int multiplied_dofs_per_hex = 0;
83 
84  unsigned int multiplied_n_components = 0;
85 
86  unsigned int degree = 0; // degree is the maximal degree of the components
87 
88  unsigned int n_components = 0;
89  // Get the number of components from the first given finite element.
90  for (unsigned int i=0; i<fes.size(); i++)
91  if (multiplicities[i]>0)
92  {
93  n_components = fes[i]->n_components();
94  break;
95  }
96 
97  for (unsigned int i=0; i<fes.size(); i++)
98  if (multiplicities[i]>0)
99  {
100  multiplied_dofs_per_vertex += fes[i]->dofs_per_vertex * multiplicities[i];
101  multiplied_dofs_per_line += fes[i]->dofs_per_line * multiplicities[i];
102  multiplied_dofs_per_quad += fes[i]->dofs_per_quad * multiplicities[i];
103  multiplied_dofs_per_hex += fes[i]->dofs_per_hex * multiplicities[i];
104 
105  multiplied_n_components+=fes[i]->n_components() * multiplicities[i];
106 
107  Assert (do_tensor_product || (n_components == fes[i]->n_components()),
108  ExcDimensionMismatch(n_components, fes[i]->n_components()));
109 
110  degree = std::max(degree, fes[i]->tensor_degree() );
111  }
112 
113  // assume conformity of the first finite element and then take away
114  // bits as indicated by the base elements. if all multiplicities
115  // happen to be zero, then it doesn't matter what we set it to.
116  typename FiniteElementData<dim>::Conformity total_conformity
118  {
119  unsigned int index = 0;
120  for (index=0; index<fes.size(); ++index)
121  if (multiplicities[index]>0)
122  {
123  total_conformity = fes[index]->conforming_space;
124  break;
125  }
126 
127  for (; index<fes.size(); ++index)
128  if (multiplicities[index]>0)
129  total_conformity =
130  typename FiniteElementData<dim>::Conformity(total_conformity
131  &
132  fes[index]->conforming_space);
133  }
134 
135  std::vector<unsigned int> dpo;
136  dpo.push_back(multiplied_dofs_per_vertex);
137  dpo.push_back(multiplied_dofs_per_line);
138  if (dim>1) dpo.push_back(multiplied_dofs_per_quad);
139  if (dim>2) dpo.push_back(multiplied_dofs_per_hex);
140 
141  BlockIndices block_indices (0,0);
142 
143  for (unsigned int base=0; base < fes.size(); ++base)
144  for (unsigned int m = 0; m < multiplicities[base]; ++m)
145  block_indices.push_back(fes[base]->dofs_per_cell);
146 
147  return FiniteElementData<dim> (dpo,
148  (do_tensor_product ? multiplied_n_components : n_components),
149  degree,
150  total_conformity,
151  block_indices);
152  }
153 
154 
155 
156  template <int dim, int spacedim>
159  const unsigned int N1,
160  const FiniteElement<dim,spacedim> *fe2,
161  const unsigned int N2,
162  const FiniteElement<dim,spacedim> *fe3,
163  const unsigned int N3,
164  const FiniteElement<dim,spacedim> *fe4,
165  const unsigned int N4,
166  const FiniteElement<dim,spacedim> *fe5,
167  const unsigned int N5)
168  {
169  std::vector<const FiniteElement<dim,spacedim>*> fes;
170  fes.push_back(fe1);
171  fes.push_back(fe2);
172  fes.push_back(fe3);
173  fes.push_back(fe4);
174  fes.push_back(fe5);
175 
176  std::vector<unsigned int> mult;
177  mult.push_back(N1);
178  mult.push_back(N2);
179  mult.push_back(N3);
180  mult.push_back(N4);
181  mult.push_back(N5);
182  return multiply_dof_numbers(fes, mult);
183  }
184 
185 
186 
187  template <int dim, int spacedim>
188  std::vector<bool>
190  const std::vector<unsigned int> &multiplicities)
191  {
192  AssertDimension(fes.size(), multiplicities.size());
193 
194  // first count the number of dofs and components that will emerge from the
195  // given FEs
196  unsigned int n_shape_functions = 0;
197  for (unsigned int i=0; i<fes.size(); ++i)
198  if (multiplicities[i]>0) // check needed as fe might be NULL
199  n_shape_functions += fes[i]->dofs_per_cell * multiplicities[i];
200 
201  // generate the array that will hold the output
202  std::vector<bool> retval (n_shape_functions, false);
203 
204  // finally go through all the shape functions of the base elements, and copy
205  // their flags. this somehow copies the code in build_cell_table, which is
206  // not nice as it uses too much implicit knowledge about the layout of the
207  // individual bases in the composed FE, but there seems no way around...
208  //
209  // for each shape function, copy the flags from the base element to this
210  // one, taking into account multiplicities, and other complications
211  unsigned int total_index = 0;
212  for (unsigned int vertex_number=0;
213  vertex_number<GeometryInfo<dim>::vertices_per_cell;
214  ++vertex_number)
215  {
216  for (unsigned int base=0; base<fes.size(); ++base)
217  for (unsigned int m=0; m<multiplicities[base]; ++m)
218  for (unsigned int local_index = 0;
219  local_index < fes[base]->dofs_per_vertex;
220  ++local_index, ++total_index)
221  {
222  const unsigned int index_in_base
223  = (fes[base]->dofs_per_vertex*vertex_number +
224  local_index);
225 
226  Assert (index_in_base < fes[base]->dofs_per_cell,
227  ExcInternalError());
228  retval[total_index] = fes[base]->restriction_is_additive(index_in_base);
229  }
230  }
231 
232  // 2. Lines
234  for (unsigned int line_number= 0;
235  line_number != GeometryInfo<dim>::lines_per_cell;
236  ++line_number)
237  {
238  for (unsigned int base=0; base<fes.size(); ++base)
239  for (unsigned int m=0; m<multiplicities[base]; ++m)
240  for (unsigned int local_index = 0;
241  local_index < fes[base]->dofs_per_line;
242  ++local_index, ++total_index)
243  {
244  const unsigned int index_in_base
245  = (fes[base]->dofs_per_line*line_number +
246  local_index +
247  fes[base]->first_line_index);
248 
249  Assert (index_in_base < fes[base]->dofs_per_cell,
250  ExcInternalError());
251  retval[total_index] = fes[base]->restriction_is_additive(index_in_base);
252  }
253  }
254 
255  // 3. Quads
257  for (unsigned int quad_number= 0;
258  quad_number != GeometryInfo<dim>::quads_per_cell;
259  ++quad_number)
260  {
261  for (unsigned int base=0; base<fes.size(); ++base)
262  for (unsigned int m=0; m<multiplicities[base]; ++m)
263  for (unsigned int local_index = 0;
264  local_index < fes[base]->dofs_per_quad;
265  ++local_index, ++total_index)
266  {
267  const unsigned int index_in_base
268  = (fes[base]->dofs_per_quad*quad_number +
269  local_index +
270  fes[base]->first_quad_index);
271 
272  Assert (index_in_base < fes[base]->dofs_per_cell,
273  ExcInternalError());
274  retval[total_index] = fes[base]->restriction_is_additive(index_in_base);
275  }
276  }
277 
278  // 4. Hexes
280  for (unsigned int hex_number= 0;
281  hex_number != GeometryInfo<dim>::hexes_per_cell;
282  ++hex_number)
283  {
284  for (unsigned int base=0; base<fes.size(); ++base)
285  for (unsigned int m=0; m<multiplicities[base]; ++m)
286  for (unsigned int local_index = 0;
287  local_index < fes[base]->dofs_per_hex;
288  ++local_index, ++total_index)
289  {
290  const unsigned int index_in_base
291  = (fes[base]->dofs_per_hex*hex_number +
292  local_index +
293  fes[base]->first_hex_index);
294 
295  Assert (index_in_base < fes[base]->dofs_per_cell,
296  ExcInternalError());
297  retval[total_index] = fes[base]->restriction_is_additive(index_in_base);
298  }
299  }
300 
301  Assert (total_index == n_shape_functions, ExcInternalError());
302 
303  return retval;
304  }
305 
306 
307 
314  template <int dim, int spacedim>
315  std::vector<bool>
317  const unsigned int N1,
318  const FiniteElement<dim,spacedim> *fe2,
319  const unsigned int N2,
320  const FiniteElement<dim,spacedim> *fe3,
321  const unsigned int N3,
322  const FiniteElement<dim,spacedim> *fe4,
323  const unsigned int N4,
324  const FiniteElement<dim,spacedim> *fe5,
325  const unsigned int N5)
326  {
327  std::vector<const FiniteElement<dim,spacedim>*> fe_list;
328  std::vector<unsigned int> multiplicities;
329 
330  fe_list.push_back (fe1);
331  multiplicities.push_back (N1);
332 
333  fe_list.push_back (fe2);
334  multiplicities.push_back (N2);
335 
336  fe_list.push_back (fe3);
337  multiplicities.push_back (N3);
338 
339  fe_list.push_back (fe4);
340  multiplicities.push_back (N4);
341 
342  fe_list.push_back (fe5);
343  multiplicities.push_back (N5);
344  return compute_restriction_is_additive_flags (fe_list, multiplicities);
345  }
346 
347 
348 
349  template <int dim, int spacedim>
350  std::vector<ComponentMask>
352  const std::vector<unsigned int> &multiplicities,
353  const bool do_tensor_product)
354  {
355  AssertDimension(fes.size(), multiplicities.size());
356 
357  // first count the number of dofs and components that will emerge from the
358  // given FEs
359  unsigned int n_shape_functions = 0;
360  for (unsigned int i=0; i<fes.size(); ++i)
361  if (multiplicities[i]>0) //needed because fe might be NULL
362  n_shape_functions += fes[i]->dofs_per_cell * multiplicities[i];
363 
364  unsigned int n_components = 0;
365  if (do_tensor_product)
366  {
367  for (unsigned int i=0; i<fes.size(); ++i)
368  if (multiplicities[i]>0) //needed because fe might be NULL
369  n_components += fes[i]->n_components() * multiplicities[i];
370  }
371  else
372  {
373  for (unsigned int i=0; i<fes.size(); ++i)
374  if (multiplicities[i]>0) //needed because fe might be NULL
375  {
376  n_components = fes[i]->n_components();
377  break;
378  }
379  // Now check that all FEs have the same number of components:
380  for (unsigned int i=0; i<fes.size(); ++i)
381  if (multiplicities[i]>0) //needed because fe might be NULL
382  Assert (n_components == fes[i]->n_components(),
383  ExcDimensionMismatch(n_components,fes[i]->n_components()));
384  }
385 
386  // generate the array that will hold the output
387  std::vector<std::vector<bool> >
388  retval (n_shape_functions, std::vector<bool> (n_components, false));
389 
390  // finally go through all the shape functions of the base elements, and copy
391  // their flags. this somehow copies the code in build_cell_table, which is
392  // not nice as it uses too much implicit knowledge about the layout of the
393  // individual bases in the composed FE, but there seems no way around...
394  //
395  // for each shape function, copy the non-zero flags from the base element to
396  // this one, taking into account multiplicities, multiple components in base
397  // elements, and other complications
398  unsigned int total_index = 0;
399  for (unsigned int vertex_number=0;
400  vertex_number<GeometryInfo<dim>::vertices_per_cell;
401  ++vertex_number)
402  {
403  unsigned int comp_start = 0;
404  for (unsigned int base=0; base<fes.size(); ++base)
405  for (unsigned int m=0; m<multiplicities[base];
406  ++m, comp_start+=fes[base]->n_components() * do_tensor_product)
407  for (unsigned int local_index = 0;
408  local_index < fes[base]->dofs_per_vertex;
409  ++local_index, ++total_index)
410  {
411  const unsigned int index_in_base
412  = (fes[base]->dofs_per_vertex*vertex_number +
413  local_index);
414 
415  Assert (comp_start+fes[base]->n_components() <=
416  retval[total_index].size(),
417  ExcInternalError());
418  for (unsigned int c=0; c<fes[base]->n_components(); ++c)
419  {
420  Assert (c < fes[base]->get_nonzero_components(index_in_base).size(),
421  ExcInternalError());
422  retval[total_index][comp_start+c]
423  = fes[base]->get_nonzero_components(index_in_base)[c];
424  }
425  }
426  }
427 
428  // 2. Lines
430  for (unsigned int line_number= 0;
431  line_number != GeometryInfo<dim>::lines_per_cell;
432  ++line_number)
433  {
434  unsigned int comp_start = 0;
435  for (unsigned int base=0; base<fes.size(); ++base)
436  for (unsigned int m=0; m<multiplicities[base];
437  ++m, comp_start+=fes[base]->n_components() * do_tensor_product)
438  for (unsigned int local_index = 0;
439  local_index < fes[base]->dofs_per_line;
440  ++local_index, ++total_index)
441  {
442  const unsigned int index_in_base
443  = (fes[base]->dofs_per_line*line_number +
444  local_index +
445  fes[base]->first_line_index);
446 
447  Assert (comp_start+fes[base]->n_components() <=
448  retval[total_index].size(),
449  ExcInternalError());
450  for (unsigned int c=0; c<fes[base]->n_components(); ++c)
451  {
452  Assert (c < fes[base]->get_nonzero_components(index_in_base).size(),
453  ExcInternalError());
454  retval[total_index][comp_start+c]
455  = fes[base]->get_nonzero_components(index_in_base)[c];
456  }
457  }
458  }
459 
460  // 3. Quads
462  for (unsigned int quad_number= 0;
463  quad_number != GeometryInfo<dim>::quads_per_cell;
464  ++quad_number)
465  {
466  unsigned int comp_start = 0;
467  for (unsigned int base=0; base<fes.size(); ++base)
468  for (unsigned int m=0; m<multiplicities[base];
469  ++m, comp_start+=fes[base]->n_components() * do_tensor_product)
470  for (unsigned int local_index = 0;
471  local_index < fes[base]->dofs_per_quad;
472  ++local_index, ++total_index)
473  {
474  const unsigned int index_in_base
475  = (fes[base]->dofs_per_quad*quad_number +
476  local_index +
477  fes[base]->first_quad_index);
478 
479  Assert (comp_start+fes[base]->n_components() <=
480  retval[total_index].size(),
481  ExcInternalError());
482  for (unsigned int c=0; c<fes[base]->n_components(); ++c)
483  {
484  Assert (c < fes[base]->get_nonzero_components(index_in_base).size(),
485  ExcInternalError());
486  retval[total_index][comp_start+c]
487  = fes[base]->get_nonzero_components(index_in_base)[c];
488  }
489  }
490  }
491 
492  // 4. Hexes
494  for (unsigned int hex_number= 0;
495  hex_number != GeometryInfo<dim>::hexes_per_cell;
496  ++hex_number)
497  {
498  unsigned int comp_start = 0;
499  for (unsigned int base=0; base<fes.size(); ++base)
500  for (unsigned int m=0; m<multiplicities[base];
501  ++m, comp_start+=fes[base]->n_components() * do_tensor_product)
502  for (unsigned int local_index = 0;
503  local_index < fes[base]->dofs_per_hex;
504  ++local_index, ++total_index)
505  {
506  const unsigned int index_in_base
507  = (fes[base]->dofs_per_hex*hex_number +
508  local_index +
509  fes[base]->first_hex_index);
510 
511  Assert (comp_start+fes[base]->n_components() <=
512  retval[total_index].size(),
513  ExcInternalError());
514  for (unsigned int c=0; c<fes[base]->n_components(); ++c)
515  {
516  Assert (c < fes[base]->get_nonzero_components(index_in_base).size(),
517  ExcInternalError());
518  retval[total_index][comp_start+c]
519  = fes[base]->get_nonzero_components(index_in_base)[c];
520  }
521  }
522  }
523 
524  Assert (total_index == n_shape_functions, ExcInternalError());
525 
526  // now copy the vector<vector<bool> > into a vector<ComponentMask>.
527  // this appears complicated but we do it this way since it's just
528  // awkward to generate ComponentMasks directly and so we need the
529  // recourse of the inner vector<bool> anyway.
530  std::vector<ComponentMask> xretval (retval.size());
531  for (unsigned int i=0; i<retval.size(); ++i)
532  xretval[i] = ComponentMask(retval[i]);
533  return xretval;
534  }
535 
536 
537 
541  template <int dim, int spacedim>
542  std::vector<ComponentMask>
544  const unsigned int N1,
545  const FiniteElement<dim,spacedim> *fe2,
546  const unsigned int N2,
547  const FiniteElement<dim,spacedim> *fe3,
548  const unsigned int N3,
549  const FiniteElement<dim,spacedim> *fe4,
550  const unsigned int N4,
551  const FiniteElement<dim,spacedim> *fe5,
552  const unsigned int N5,
553  const bool do_tensor_product)
554  {
555  std::vector<const FiniteElement<dim,spacedim>*> fe_list;
556  std::vector<unsigned int> multiplicities;
557 
558  fe_list.push_back (fe1);
559  multiplicities.push_back (N1);
560 
561  fe_list.push_back (fe2);
562  multiplicities.push_back (N2);
563 
564  fe_list.push_back (fe3);
565  multiplicities.push_back (N3);
566 
567  fe_list.push_back (fe4);
568  multiplicities.push_back (N4);
569 
570  fe_list.push_back (fe5);
571  multiplicities.push_back (N5);
572 
573  return compute_nonzero_components (fe_list, multiplicities,
574  do_tensor_product);
575  }
576 
577 
578 
579  template <int dim, int spacedim>
580  void
581  build_cell_tables(std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > &system_to_base_table,
582  std::vector< std::pair< unsigned int, unsigned int > > &system_to_component_table,
583  std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > &component_to_base_table,
584  const FiniteElement<dim,spacedim> &fe,
585  const bool do_tensor_product)
586  {
587  unsigned int total_index = 0;
588 
589  if (do_tensor_product)
590  {
591  for (unsigned int base=0; base < fe.n_base_elements(); ++base)
592  for (unsigned int m = 0; m < fe.element_multiplicity(base); ++m)
593  {
594  for (unsigned int k=0; k<fe.base_element(base).n_components(); ++k)
595  component_to_base_table[total_index++]
596  = std::make_pair(std::make_pair(base,k), m);
597  }
598  Assert (total_index == component_to_base_table.size(),
599  ExcInternalError());
600  }
601  else
602  {
603  // The base element establishing a component does not make sense in this case.
604  // Set up to something meaningless:
605  for (unsigned int i = 0; i < component_to_base_table.size(); i++)
606  component_to_base_table[i] = std::make_pair(std::make_pair(numbers::invalid_unsigned_int,numbers::invalid_unsigned_int), numbers::invalid_unsigned_int);
607 
608  }
609 
610 
611  // Initialize index tables. Multi-component base elements have to be
612  // thought of. For non-primitive shape functions, have a special invalid
613  // index.
614  const std::pair<unsigned int, unsigned int>
615  non_primitive_index (numbers::invalid_unsigned_int,
617 
618  // First enumerate vertex indices, where we first enumerate all indices on
619  // the first vertex in the order of the base elements, then of the second
620  // vertex, etc
621  total_index = 0;
622  for (unsigned int vertex_number=0;
623  vertex_number<GeometryInfo<dim>::vertices_per_cell;
624  ++vertex_number)
625  {
626  unsigned int comp_start = 0;
627  for (unsigned int base=0; base<fe.n_base_elements(); ++base)
628  for (unsigned int m=0; m<fe.element_multiplicity(base);
629  ++m, comp_start+=fe.base_element(base).n_components() * do_tensor_product)
630  for (unsigned int local_index = 0;
631  local_index < fe.base_element(base).dofs_per_vertex;
632  ++local_index, ++total_index)
633  {
634  const unsigned int index_in_base
635  = (fe.base_element(base).dofs_per_vertex*vertex_number +
636  local_index);
637 
638  system_to_base_table[total_index]
639  = std::make_pair (std::make_pair(base, m), index_in_base);
640 
641  if (fe.base_element(base).is_primitive(index_in_base))
642  {
643  const unsigned int comp_in_base
644  = fe.base_element(base).system_to_component_index(index_in_base).first;
645  const unsigned int comp
646  = comp_start + comp_in_base;
647  const unsigned int index_in_comp
648  = fe.base_element(base).system_to_component_index(index_in_base).second;
649  system_to_component_table[total_index]
650  = std::make_pair (comp, index_in_comp);
651  }
652  else
653  system_to_component_table[total_index] = non_primitive_index;
654  }
655  }
656 
657  // 2. Lines
659  for (unsigned int line_number= 0;
660  line_number != GeometryInfo<dim>::lines_per_cell;
661  ++line_number)
662  {
663  unsigned int comp_start = 0;
664  for (unsigned int base=0; base<fe.n_base_elements(); ++base)
665  for (unsigned int m=0; m<fe.element_multiplicity(base);
666  ++m, comp_start+=fe.base_element(base).n_components() * do_tensor_product)
667  for (unsigned int local_index = 0;
668  local_index < fe.base_element(base).dofs_per_line;
669  ++local_index, ++total_index)
670  {
671  const unsigned int index_in_base
672  = (fe.base_element(base).dofs_per_line*line_number +
673  local_index +
674  fe.base_element(base).first_line_index);
675 
676  system_to_base_table[total_index]
677  = std::make_pair (std::make_pair(base,m), index_in_base);
678 
679  if (fe.base_element(base).is_primitive(index_in_base))
680  {
681  const unsigned int comp_in_base
682  = fe.base_element(base).system_to_component_index(index_in_base).first;
683  const unsigned int comp
684  = comp_start + comp_in_base;
685  const unsigned int index_in_comp
686  = fe.base_element(base).system_to_component_index(index_in_base).second;
687  system_to_component_table[total_index]
688  = std::make_pair (comp, index_in_comp);
689  }
690  else
691  system_to_component_table[total_index] = non_primitive_index;
692  }
693  }
694 
695  // 3. Quads
697  for (unsigned int quad_number= 0;
698  quad_number != GeometryInfo<dim>::quads_per_cell;
699  ++quad_number)
700  {
701  unsigned int comp_start = 0;
702  for (unsigned int base=0; base<fe.n_base_elements(); ++base)
703  for (unsigned int m=0; m<fe.element_multiplicity(base);
704  ++m, comp_start += fe.base_element(base).n_components() * do_tensor_product)
705  for (unsigned int local_index = 0;
706  local_index < fe.base_element(base).dofs_per_quad;
707  ++local_index, ++total_index)
708  {
709  const unsigned int index_in_base
710  = (fe.base_element(base).dofs_per_quad*quad_number +
711  local_index +
712  fe.base_element(base).first_quad_index);
713 
714  system_to_base_table[total_index]
715  = std::make_pair (std::make_pair(base,m), index_in_base);
716 
717  if (fe.base_element(base).is_primitive(index_in_base))
718  {
719  const unsigned int comp_in_base
720  = fe.base_element(base).system_to_component_index(index_in_base).first;
721  const unsigned int comp
722  = comp_start + comp_in_base;
723  const unsigned int index_in_comp
724  = fe.base_element(base).system_to_component_index(index_in_base).second;
725  system_to_component_table[total_index]
726  = std::make_pair (comp, index_in_comp);
727  }
728  else
729  system_to_component_table[total_index] = non_primitive_index;
730  }
731  }
732 
733  // 4. Hexes
735  for (unsigned int hex_number= 0;
736  hex_number != GeometryInfo<dim>::hexes_per_cell;
737  ++hex_number)
738  {
739  unsigned int comp_start = 0;
740  for (unsigned int base=0; base<fe.n_base_elements(); ++base)
741  for (unsigned int m=0; m<fe.element_multiplicity(base);
742  ++m, comp_start+=fe.base_element(base).n_components() * do_tensor_product)
743  for (unsigned int local_index = 0;
744  local_index < fe.base_element(base).dofs_per_hex;
745  ++local_index, ++total_index)
746  {
747  const unsigned int index_in_base
748  = (fe.base_element(base).dofs_per_hex*hex_number +
749  local_index +
750  fe.base_element(base).first_hex_index);
751 
752  system_to_base_table[total_index]
753  = std::make_pair (std::make_pair(base,m), index_in_base);
754 
755  if (fe.base_element(base).is_primitive(index_in_base))
756  {
757  const unsigned int comp_in_base
758  = fe.base_element(base).system_to_component_index(index_in_base).first;
759  const unsigned int comp
760  = comp_start + comp_in_base;
761  const unsigned int index_in_comp
762  = fe.base_element(base).system_to_component_index(index_in_base).second;
763  system_to_component_table[total_index]
764  = std::make_pair (comp, index_in_comp);
765  }
766  else
767  system_to_component_table[total_index] = non_primitive_index;
768  }
769  }
770  }
771 
772 
773 
774  template <int dim, int spacedim>
775  void
776  build_face_tables(std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > &face_system_to_base_table,
777  std::vector< std::pair< unsigned int, unsigned int > > &face_system_to_component_table,
778  const FiniteElement<dim,spacedim> &fe,
779  const bool do_tensor_product)
780  {
781  // Initialize index tables. do this in the same way as done for the cell
782  // tables, except that we now loop over the objects of faces
783 
784  // For non-primitive shape functions, have a special invalid index
785  const std::pair<unsigned int, unsigned int>
786  non_primitive_index (numbers::invalid_unsigned_int,
788 
789  // 1. Vertices
790  unsigned int total_index = 0;
791  for (unsigned int vertex_number=0;
792  vertex_number<GeometryInfo<dim>::vertices_per_face;
793  ++vertex_number)
794  {
795  unsigned int comp_start = 0;
796  for (unsigned int base=0; base<fe.n_base_elements(); ++base)
797  for (unsigned int m=0; m<fe.element_multiplicity(base);
798  ++m, comp_start += fe.base_element(base).n_components() * do_tensor_product)
799  for (unsigned int local_index = 0;
800  local_index < fe.base_element(base).dofs_per_vertex;
801  ++local_index, ++total_index)
802  {
803  // get (cell) index of this shape function inside the base
804  // element to see whether the shape function is primitive
805  // (assume that all shape functions on vertices share the same
806  // primitivity property; assume likewise for all shape functions
807  // located on lines, quads, etc. this way, we can ask for
808  // primitivity of only _one_ shape function, which is taken as
809  // representative for all others located on the same type of
810  // object):
811  const unsigned int index_in_base
812  = (fe.base_element(base).dofs_per_vertex*vertex_number +
813  local_index);
814 
815  const unsigned int face_index_in_base
816  = (fe.base_element(base).dofs_per_vertex*vertex_number +
817  local_index);
818 
819  face_system_to_base_table[total_index]
820  = std::make_pair (std::make_pair(base,m), face_index_in_base);
821 
822  if (fe.base_element(base).is_primitive(index_in_base))
823  {
824  const unsigned int comp_in_base
825  = fe.base_element(base).face_system_to_component_index(face_index_in_base).first;
826  const unsigned int comp
827  = comp_start + comp_in_base;
828  const unsigned int face_index_in_comp
829  = fe.base_element(base).face_system_to_component_index(face_index_in_base).second;
830  face_system_to_component_table[total_index]
831  = std::make_pair (comp, face_index_in_comp);
832  }
833  else
834  face_system_to_component_table[total_index] = non_primitive_index;
835  }
836  }
837 
838  // 2. Lines
840  for (unsigned int line_number= 0;
841  line_number != GeometryInfo<dim>::lines_per_face;
842  ++line_number)
843  {
844  unsigned int comp_start = 0;
845  for (unsigned int base = 0; base < fe.n_base_elements(); ++base)
846  for (unsigned int m=0; m<fe.element_multiplicity(base);
847  ++m, comp_start += fe.base_element(base).n_components() * do_tensor_product)
848  for (unsigned int local_index = 0;
849  local_index < fe.base_element(base).dofs_per_line;
850  ++local_index, ++total_index)
851  {
852  // do everything alike for this type of object
853  const unsigned int index_in_base
854  = (fe.base_element(base).dofs_per_line*line_number +
855  local_index +
856  fe.base_element(base).first_line_index);
857 
858  const unsigned int face_index_in_base
859  = (fe.base_element(base).first_face_line_index +
860  fe.base_element(base).dofs_per_line * line_number +
861  local_index);
862 
863  face_system_to_base_table[total_index]
864  = std::make_pair (std::make_pair(base,m), face_index_in_base);
865 
866  if (fe.base_element(base).is_primitive(index_in_base))
867  {
868  const unsigned int comp_in_base
869  = fe.base_element(base).face_system_to_component_index(face_index_in_base).first;
870  const unsigned int comp
871  = comp_start + comp_in_base;
872  const unsigned int face_index_in_comp
873  = fe.base_element(base).face_system_to_component_index(face_index_in_base).second;
874  face_system_to_component_table[total_index]
875  = std::make_pair (comp, face_index_in_comp);
876  }
877  else
878  face_system_to_component_table[total_index] = non_primitive_index;
879  }
880  }
881 
882  // 3. Quads
884  for (unsigned int quad_number= 0;
885  quad_number != GeometryInfo<dim>::quads_per_face;
886  ++quad_number)
887  {
888  unsigned int comp_start = 0;
889  for (unsigned int base=0; base<fe.n_base_elements(); ++base)
890  for (unsigned int m=0; m<fe.element_multiplicity(base);
891  ++m, comp_start += fe.base_element(base).n_components() * do_tensor_product)
892  for (unsigned int local_index = 0;
893  local_index < fe.base_element(base).dofs_per_quad;
894  ++local_index, ++total_index)
895  {
896  // do everything alike for this type of object
897  const unsigned int index_in_base
898  = (fe.base_element(base).dofs_per_quad*quad_number +
899  local_index +
900  fe.base_element(base).first_quad_index);
901 
902  const unsigned int face_index_in_base
903  = (fe.base_element(base).first_face_quad_index +
904  fe.base_element(base).dofs_per_quad * quad_number +
905  local_index);
906 
907  face_system_to_base_table[total_index]
908  = std::make_pair (std::make_pair(base,m), face_index_in_base);
909 
910  if (fe.base_element(base).is_primitive(index_in_base))
911  {
912  const unsigned int comp_in_base
913  = fe.base_element(base).face_system_to_component_index(face_index_in_base).first;
914  const unsigned int comp
915  = comp_start + comp_in_base;
916  const unsigned int face_index_in_comp
917  = fe.base_element(base).face_system_to_component_index(face_index_in_base).second;
918  face_system_to_component_table[total_index]
919  = std::make_pair (comp, face_index_in_comp);
920  }
921  else
922  face_system_to_component_table[total_index] = non_primitive_index;
923  }
924  }
925  Assert (total_index == fe.dofs_per_face, ExcInternalError());
926  Assert (total_index == face_system_to_component_table.size(),
927  ExcInternalError());
928  Assert (total_index == face_system_to_base_table.size(),
929  ExcInternalError());
930  }
931  }
932 
933 
934 
935  // Not implemented in the general case.
936  template <class FE>
939  {
940  Assert(false, ExcNotImplemented());
941  return 0;
942  }
943 
944  // Specializations for FE_Q.
945  template <>
947  FEFactory<FE_Q<1, 1> >::get (const Quadrature<1> &quad) const
948  {
949  return new FE_Q<1>(quad);
950  }
951 
952  template <>
954  FEFactory<FE_Q<2, 2> >::get (const Quadrature<1> &quad) const
955  {
956  return new FE_Q<2>(quad);
957  }
958 
959  template <>
961  FEFactory<FE_Q<3, 3> >::get (const Quadrature<1> &quad) const
962  {
963  return new FE_Q<3>(quad);
964  }
965 
966  // Specializations for FE_Q_DG0.
967  template <>
969  FEFactory<FE_Q_DG0<1, 1> >::get (const Quadrature<1> &quad) const
970  {
971  return new FE_Q_DG0<1>(quad);
972  }
973 
974  template <>
976  FEFactory<FE_Q_DG0<2, 2> >::get (const Quadrature<1> &quad) const
977  {
978  return new FE_Q_DG0<2>(quad);
979  }
980 
981  template <>
983  FEFactory<FE_Q_DG0<3, 3> >::get (const Quadrature<1> &quad) const
984  {
985  return new FE_Q_DG0<3>(quad);
986  }
987 
988  // Specializations for FE_Q_Bubbles.
989  template <>
991  FEFactory<FE_Q_Bubbles<1, 1> >::get (const Quadrature<1> &quad) const
992  {
993  return new FE_Q_Bubbles<1>(quad);
994  }
995 
996  template <>
998  FEFactory<FE_Q_Bubbles<2, 2> >::get (const Quadrature<1> &quad) const
999  {
1000  return new FE_Q_Bubbles<2>(quad);
1001  }
1002 
1003  template <>
1005  FEFactory<FE_Q_Bubbles<3, 3> >::get (const Quadrature<1> &quad) const
1006  {
1007  return new FE_Q_Bubbles<3>(quad);
1008  }
1009 
1010  // Specializations for FE_DGQArbitraryNodes.
1011  template <>
1013  FEFactory<FE_DGQ<1> >::get (const Quadrature<1> &quad) const
1014  {
1015  return new FE_DGQArbitraryNodes<1>(quad);
1016  }
1017 
1018  template <>
1020  FEFactory<FE_DGQ<1, 2> >::get (const Quadrature<1> &quad) const
1021  {
1022  return new FE_DGQArbitraryNodes<1, 2>(quad);
1023  }
1024 
1025  template <>
1027  FEFactory<FE_DGQ<1, 3> >::get (const Quadrature<1> &quad) const
1028  {
1029  return new FE_DGQArbitraryNodes<1, 3>(quad);
1030  }
1031 
1032  template <>
1034  FEFactory<FE_DGQ<2> >::get (const Quadrature<1> &quad) const
1035  {
1036  return new FE_DGQArbitraryNodes<2>(quad);
1037  }
1038 
1039  template <>
1041  FEFactory<FE_DGQ<2, 3> >::get (const Quadrature<1> &quad) const
1042  {
1043  return new FE_DGQArbitraryNodes<2, 3>(quad);
1044  }
1045 
1046  template <>
1048  FEFactory<FE_DGQ<3> >::get (const Quadrature<1> &quad) const
1049  {
1050  return new FE_DGQArbitraryNodes<3>(quad);
1051  }
1052 }
1053 
1054 namespace
1055 {
1056  // The following three functions serve to fill the maps from element
1057  // names to elements fe_name_map below. The first one exists because
1058  // we have finite elements which are not implemented for nonzero
1059  // codimension. These should be transferred to the second function
1060  // eventually.
1061 
1062  template <int dim>
1063  void
1064  fill_no_codim_fe_names (std::map<std::string,std_cxx11::shared_ptr<const Subscriptor> > &result)
1065  {
1066  typedef std_cxx11::shared_ptr<const Subscriptor> FEFactoryPointer;
1067 
1068  result["FE_Q_Hierarchical"]
1069  = FEFactoryPointer(new FETools::FEFactory<FE_Q_Hierarchical<dim> >);
1070  result["FE_ABF"]
1071  = FEFactoryPointer(new FETools::FEFactory<FE_ABF<dim> >);
1072  result["FE_Bernstein"]
1073  = FEFactoryPointer(new FETools::FEFactory<FE_Bernstein<dim> >);
1074  result["FE_BDM"]
1075  = FEFactoryPointer(new FETools::FEFactory<FE_BDM<dim> >);
1076  result["FE_DGBDM"]
1077  = FEFactoryPointer(new FETools::FEFactory<FE_DGBDM<dim> >);
1078  result["FE_DGNedelec"]
1079  = FEFactoryPointer(new FETools::FEFactory<FE_DGNedelec<dim> >);
1080  result["FE_DGRaviartThomas"]
1081  = FEFactoryPointer(new FETools::FEFactory<FE_DGRaviartThomas<dim> >);
1082  result["FE_RaviartThomas"]
1083  = FEFactoryPointer(new FETools::FEFactory<FE_RaviartThomas<dim> >);
1084  result["FE_RaviartThomasNodal"]
1085  = FEFactoryPointer(new FETools::FEFactory<FE_RaviartThomasNodal<dim> >);
1086  result["FE_Nedelec"]
1087  = FEFactoryPointer(new FETools::FEFactory<FE_Nedelec<dim> >);
1088  result["FE_DGPNonparametric"]
1089  = FEFactoryPointer(new FETools::FEFactory<FE_DGPNonparametric<dim> >);
1090  result["FE_DGP"]
1091  = FEFactoryPointer(new FETools::FEFactory<FE_DGP<dim> >);
1092  result["FE_DGPMonomial"]
1093  = FEFactoryPointer(new FETools::FEFactory<FE_DGPMonomial<dim> >);
1094  result["FE_DGQ"]
1095  = FEFactoryPointer(new FETools::FEFactory<FE_DGQ<dim> >);
1096  result["FE_DGQArbitraryNodes"]
1097  = FEFactoryPointer(new FETools::FEFactory<FE_DGQ<dim> >);
1098  result["FE_DGQLegendre"]
1099  = FEFactoryPointer(new FETools::FEFactory<FE_DGQLegendre<dim> >);
1100  result["FE_DGQHermite"]
1101  = FEFactoryPointer(new FETools::FEFactory<FE_DGQHermite<dim> >);
1102  result["FE_FaceQ"]
1103  = FEFactoryPointer(new FETools::FEFactory<FE_FaceQ<dim> >);
1104  result["FE_FaceP"]
1105  = FEFactoryPointer(new FETools::FEFactory<FE_FaceP<dim> >);
1106  result["FE_Q"]
1107  = FEFactoryPointer(new FETools::FEFactory<FE_Q<dim> >);
1108  result["FE_Q_DG0"]
1109  = FEFactoryPointer(new FETools::FEFactory<FE_Q_DG0<dim> >);
1110  result["FE_Q_Bubbles"]
1111  = FEFactoryPointer(new FETools::FEFactory<FE_Q_Bubbles<dim> >);
1112  result["FE_Q_iso_Q1"]
1113  = FEFactoryPointer(new FETools::FEFactory<FE_Q_iso_Q1<dim> >);
1114  result["FE_Nothing"]
1115  = FEFactoryPointer(new FETools::FEFactory<FE_Nothing<dim> >);
1116  result["FE_RannacherTurek"]
1117  = FEFactoryPointer(new FETools::FEFactory<FE_RannacherTurek<dim> >);
1118  }
1119 
1120 
1121 
1122  // This function fills a map from names to finite elements for any
1123  // dimension and codimension for those elements which support
1124  // nonzero codimension.
1125  template <int dim, int spacedim>
1126  void
1127  fill_codim_fe_names (std::map<std::string,std_cxx11::shared_ptr<const Subscriptor> > &result)
1128  {
1129  typedef std_cxx11::shared_ptr<const Subscriptor> FEFactoryPointer;
1130 
1131  result["FE_Bernstein"]
1132  = FEFactoryPointer(new FETools::FEFactory<FE_Bernstein<dim,spacedim> >);
1133  result["FE_DGP"]
1134  = FEFactoryPointer(new FETools::FEFactory<FE_DGP<dim,spacedim> >);
1135  result["FE_DGQ"]
1136  = FEFactoryPointer(new FETools::FEFactory<FE_DGQ<dim,spacedim> >);
1137  result["FE_Nothing"]
1138  = FEFactoryPointer(new FETools::FEFactory<FE_Nothing<dim,spacedim> >);
1139  result["FE_DGQArbitraryNodes"]
1140  = FEFactoryPointer(new FETools::FEFactory<FE_DGQ<dim,spacedim> >);
1141  result["FE_DGQLegendre"]
1142  = FEFactoryPointer(new FETools::FEFactory<FE_DGQLegendre<dim,spacedim> >);
1143  result["FE_DGQHermite"]
1144  = FEFactoryPointer(new FETools::FEFactory<FE_DGQHermite<dim,spacedim> >);
1145  result["FE_Q_Bubbles"]
1146  = FEFactoryPointer(new FETools::FEFactory<FE_Q_Bubbles<dim,spacedim> >);
1147  result["FE_Q_DG0"]
1148  = FEFactoryPointer(new FETools::FEFactory<FE_Q_DG0<dim,spacedim> >);
1149  result["FE_Q_iso_Q1"]
1150  = FEFactoryPointer(new FETools::FEFactory<FE_Q_iso_Q1<dim,spacedim> >);
1151  result["FE_Q"]
1152  = FEFactoryPointer(new FETools::FEFactory<FE_Q<dim,spacedim> >);
1153  result["FE_Bernstein"]
1154  = FEFactoryPointer(new FETools::FEFactory<FE_Bernstein<dim,spacedim> >);
1155  }
1156 
1157  // The function filling the vector fe_name_map below. It iterates
1158  // through all legal dimension/spacedimension pairs and fills
1159  // fe_name_map[dimension][spacedimension] with the maps generated
1160  // by the functions above.
1161  std::vector<std::vector<
1162  std::map<std::string,
1163  std_cxx11::shared_ptr<const Subscriptor> > > >
1164  fill_default_map()
1165  {
1166  std::vector<std::vector<
1167  std::map<std::string,
1168  std_cxx11::shared_ptr<const Subscriptor> > > >
1169  result(4);
1170 
1171  for (unsigned int d=0; d<4; ++d)
1172  result[d].resize(4);
1173 
1174  fill_no_codim_fe_names<1> (result[1][1]);
1175  fill_no_codim_fe_names<2> (result[2][2]);
1176  fill_no_codim_fe_names<3> (result[3][3]);
1177 
1178  fill_codim_fe_names<1,2> (result[1][2]);
1179  fill_codim_fe_names<1,3> (result[1][3]);
1180  fill_codim_fe_names<2,3> (result[2][3]);
1181 
1182  return result;
1183  }
1184 
1185 
1186  // have a lock that guarantees that at most one thread is changing
1187  // and accessing the fe_name_map variable. make this lock local to
1188  // this file.
1189  //
1190  // this and the next variable are declared static (even though
1191  // they're in an anonymous namespace) in order to make icc happy
1192  // (which otherwise reports a multiply defined symbol when linking
1193  // libraries for more than one space dimension together
1194  static
1195  Threads::Mutex fe_name_map_lock;
1196 
1197  // This is the map used by FETools::get_fe_by_name and
1198  // FETools::add_fe_name. It is only accessed by functions in this
1199  // file, so it is safe to make it a static variable here. It must be
1200  // static so that we can link several dimensions together.
1201 
1202  // The organization of this storage is such that
1203  // fe_name_map[dim][spacedim][name] points to an
1204  // FEFactoryBase<dim,spacedim> with the name given. Since
1205  // all entries of this vector are of different type, we store
1206  // pointers to generic objects and cast them when needed.
1207 
1208  // We use a shared pointer to factory objects, to ensure that they
1209  // get deleted at the end of the program run and don't end up as
1210  // apparent memory leaks to programs like valgrind.
1211 
1212  // This vector is initialized at program start time using the
1213  // function above. because at this time there are no threads
1214  // running, there are no thread-safety issues here. since this is
1215  // compiled for all dimensions at once, need to create objects for
1216  // each dimension and then separate between them further down
1217  static
1218  std::vector<std::vector<
1219  std::map<std::string,
1220  std_cxx11::shared_ptr<const Subscriptor> > > >
1221  fe_name_map = fill_default_map();
1222 }
1223 
1224 
1225 
1226 
1227 
1228 
1229 namespace
1230 {
1231 
1232  // forwarder function for
1233  // FE::get_interpolation_matrix. we
1234  // will want to call that function
1235  // for arbitrary FullMatrix<T>
1236  // types, but it only accepts
1237  // double arguments. since it is a
1238  // virtual function, this can also
1239  // not be changed. so have a
1240  // forwarder function that calls
1241  // that function directly if
1242  // T==double, and otherwise uses a
1243  // temporary
1244  template <int dim, int spacedim>
1245  inline
1246  void gim_forwarder (const FiniteElement<dim,spacedim> &fe1,
1247  const FiniteElement<dim,spacedim> &fe2,
1248  FullMatrix<double> &interpolation_matrix)
1249  {
1250  fe2.get_interpolation_matrix (fe1, interpolation_matrix);
1251  }
1252 
1253 
1254 
1255  template <int dim, typename number, int spacedim>
1256  inline
1257  void gim_forwarder (const FiniteElement<dim,spacedim> &fe1,
1258  const FiniteElement<dim,spacedim> &fe2,
1259  FullMatrix<number> &interpolation_matrix)
1260  {
1261  FullMatrix<double> tmp (interpolation_matrix.m(),
1262  interpolation_matrix.n());
1263  fe2.get_interpolation_matrix (fe1, tmp);
1264  interpolation_matrix = tmp;
1265  }
1266 
1267 
1268 
1269  // return how many characters
1270  // starting at the given position
1271  // of the string match either the
1272  // generic string "<dim>" or the
1273  // specialized string with "dim"
1274  // replaced with the numeric value
1275  // of the template argument
1276  template <int dim, int spacedim>
1277  inline
1278  unsigned int match_dimension (const std::string &name,
1279  const unsigned int position)
1280  {
1281  if (position >= name.size())
1282  return 0;
1283 
1284  if ((position+5 < name.size())
1285  &&
1286  (name[position] == '<')
1287  &&
1288  (name[position+1] == 'd')
1289  &&
1290  (name[position+2] == 'i')
1291  &&
1292  (name[position+3] == 'm')
1293  &&
1294  (name[position+4] == '>'))
1295  return 5;
1296 
1297  Assert (dim<10, ExcNotImplemented());
1298  const char dim_char = '0'+dim;
1299 
1300  if ((position+3 < name.size())
1301  &&
1302  (name[position] == '<')
1303  &&
1304  (name[position+1] == dim_char)
1305  &&
1306  (name[position+2] == '>'))
1307  return 3;
1308 
1309  // some other string that doesn't
1310  // match
1311  return 0;
1312  }
1313 }
1314 
1315 
1316 namespace FETools
1317 {
1318  template <int dim, int spacedim>
1320  {}
1321 
1322 
1323 
1324  template<int dim, int spacedim>
1326  const FiniteElement<dim,spacedim> &element,
1327  std::vector<unsigned int> &renumbering,
1328  std::vector<std::vector<unsigned int> > &comp_start)
1329  {
1330  Assert(renumbering.size() == element.dofs_per_cell,
1331  ExcDimensionMismatch(renumbering.size(),
1332  element.dofs_per_cell));
1333 
1334  comp_start.resize(element.n_base_elements());
1335 
1336  unsigned int k=0;
1337  for (unsigned int i=0; i<comp_start.size(); ++i)
1338  {
1339  comp_start[i].resize(element.element_multiplicity(i));
1340  const unsigned int increment
1341  = element.base_element(i).dofs_per_cell;
1342 
1343  for (unsigned int j=0; j<comp_start[i].size(); ++j)
1344  {
1345  comp_start[i][j] = k;
1346  k += increment;
1347  }
1348  }
1349 
1350  // For each index i of the
1351  // unstructured cellwise
1352  // numbering, renumbering
1353  // contains the index of the
1354  // cell-block numbering
1355  for (unsigned int i=0; i<element.dofs_per_cell; ++i)
1356  {
1357  std::pair<std::pair<unsigned int, unsigned int>, unsigned int>
1358  indices = element.system_to_base_index(i);
1359  renumbering[i] = comp_start[indices.first.first][indices.first.second]
1360  +indices.second;
1361  }
1362  }
1363 
1364 
1365 
1366  template<int dim, int spacedim>
1368  const FiniteElement<dim,spacedim> &element,
1369  std::vector<types::global_dof_index> &renumbering,
1370  std::vector<types::global_dof_index> &block_data,
1371  bool return_start_indices)
1372  {
1373  Assert(renumbering.size() == element.dofs_per_cell,
1374  ExcDimensionMismatch(renumbering.size(),
1375  element.dofs_per_cell));
1376  Assert(block_data.size() == element.n_blocks(),
1377  ExcDimensionMismatch(block_data.size(),
1378  element.n_blocks()));
1379 
1381  unsigned int count=0;
1382  for (unsigned int b=0; b<element.n_base_elements(); ++b)
1383  for (unsigned int m=0; m<element.element_multiplicity(b); ++m)
1384  {
1385  block_data[count++] = (return_start_indices)
1386  ? k
1387  : (element.base_element(b).n_dofs_per_cell());
1388  k += element.base_element(b).n_dofs_per_cell();
1389  }
1390  Assert (count == element.n_blocks(), ExcInternalError());
1391 
1392  std::vector<types::global_dof_index> start_indices(block_data.size());
1393  k = 0;
1394  for (unsigned int i=0; i<block_data.size(); ++i)
1395  if (return_start_indices)
1396  start_indices[i] = block_data[i];
1397  else
1398  {
1399  start_indices[i] = k;
1400  k += block_data[i];
1401  }
1402 
1403  for (unsigned int i=0; i<element.dofs_per_cell; ++i)
1404  {
1405  std::pair<unsigned int, types::global_dof_index>
1406  indices = element.system_to_block_index(i);
1407  renumbering[i] = start_indices[indices.first]
1408  +indices.second;
1409  }
1410  }
1411 
1412 
1413 
1414  template <int dim, typename number, int spacedim>
1416  const FiniteElement<dim,spacedim> &fe2,
1417  FullMatrix<number> &interpolation_matrix)
1418  {
1419  Assert (fe1.n_components() == fe2.n_components(),
1421  Assert(interpolation_matrix.m()==fe2.dofs_per_cell &&
1422  interpolation_matrix.n()==fe1.dofs_per_cell,
1423  ExcMatrixDimensionMismatch(interpolation_matrix.m(),
1424  interpolation_matrix.n(),
1425  fe2.dofs_per_cell,
1426  fe1.dofs_per_cell));
1427 
1428  // first try the easy way: maybe
1429  // the FE wants to implement things
1430  // itself:
1431  bool fe_implements_interpolation = true;
1432  try
1433  {
1434  gim_forwarder (fe1, fe2, interpolation_matrix);
1435  }
1437  {
1438  // too bad....
1439  fe_implements_interpolation = false;
1440  }
1441  if (fe_implements_interpolation == true)
1442  return;
1443 
1444  // uh, so this was not the
1445  // case. hm. then do it the hard
1446  // way. note that this will only
1447  // work if the element is
1448  // primitive, so check this first
1449  Assert (fe1.is_primitive() == true, ExcFENotPrimitive());
1450  Assert (fe2.is_primitive() == true, ExcFENotPrimitive());
1451 
1452  // Initialize FEValues for fe1 at
1453  // the unit support points of the
1454  // fe2 element.
1455  const std::vector<Point<dim> > &
1456  fe2_support_points = fe2.get_unit_support_points ();
1457 
1458  typedef FiniteElement<dim,spacedim> FEL;
1459  Assert(fe2_support_points.size()==fe2.dofs_per_cell,
1460  typename FEL::ExcFEHasNoSupportPoints());
1461 
1462  for (unsigned int i=0; i<fe2.dofs_per_cell; ++i)
1463  {
1464  const unsigned int i1 = fe2.system_to_component_index(i).first;
1465  for (unsigned int j=0; j<fe1.dofs_per_cell; ++j)
1466  {
1467  const unsigned int j1 = fe1.system_to_component_index(j).first;
1468  if (i1==j1)
1469  interpolation_matrix(i,j) = fe1.shape_value (j,fe2_support_points[i]);
1470  else
1471  interpolation_matrix(i,j)=0.;
1472  }
1473  }
1474  }
1475 
1476 
1477 
1478  template <int dim, typename number, int spacedim>
1480  const FiniteElement<dim,spacedim> &fe2,
1481  FullMatrix<number> &interpolation_matrix)
1482  {
1483  Assert (fe1.n_components() == fe2.n_components(),
1485  Assert(interpolation_matrix.m()==fe1.dofs_per_cell &&
1486  interpolation_matrix.n()==fe1.dofs_per_cell,
1487  ExcMatrixDimensionMismatch(interpolation_matrix.m(),
1488  interpolation_matrix.n(),
1489  fe1.dofs_per_cell,
1490  fe1.dofs_per_cell));
1491 
1492  FullMatrix<number> first_matrix (fe2.dofs_per_cell, fe1.dofs_per_cell);
1493  FullMatrix<number> second_matrix(fe1.dofs_per_cell, fe2.dofs_per_cell);
1494 
1495  get_interpolation_matrix(fe1, fe2, first_matrix);
1496  get_interpolation_matrix(fe2, fe1, second_matrix);
1497 
1498  // int_matrix=second_matrix*first_matrix
1499  second_matrix.mmult(interpolation_matrix, first_matrix);
1500  }
1501 
1502 
1503 
1504  template <int dim, typename number, int spacedim>
1506  const FiniteElement<dim,spacedim> &fe2,
1507  FullMatrix<number> &difference_matrix)
1508  {
1509  Assert (fe1.n_components() == fe2.n_components(),
1511  Assert(difference_matrix.m()==fe1.dofs_per_cell &&
1512  difference_matrix.n()==fe1.dofs_per_cell,
1513  ExcMatrixDimensionMismatch(difference_matrix.m(),
1514  difference_matrix.n(),
1515  fe1.dofs_per_cell,
1516  fe1.dofs_per_cell));
1517 
1518  FullMatrix<number> interpolation_matrix(fe1.dofs_per_cell);
1519  get_back_interpolation_matrix(fe1, fe2, interpolation_matrix);
1520 
1521  for (unsigned int i=0; i<fe1.dofs_per_cell; ++i)
1522  difference_matrix(i,i) = 1.;
1523 
1524  // compute difference
1525  difference_matrix.add (-1, interpolation_matrix);
1526  }
1527 
1528 
1529 
1530  template <int dim, typename number, int spacedim>
1532  const FiniteElement<dim,spacedim> &fe2,
1533  FullMatrix<number> &matrix)
1534  {
1535  Assert (fe1.n_components() == 1, ExcNotImplemented());
1536  Assert (fe1.n_components() == fe2.n_components(),
1538  Assert(matrix.m()==fe2.dofs_per_cell && matrix.n()==fe1.dofs_per_cell,
1539  ExcMatrixDimensionMismatch(matrix.m(), matrix.n(),
1540  fe2.dofs_per_cell,
1541  fe1.dofs_per_cell));
1542  matrix = 0;
1543 
1544  unsigned int n1 = fe1.dofs_per_cell;
1545  unsigned int n2 = fe2.dofs_per_cell;
1546 
1547  // First, create a local mass matrix for
1548  // the unit cell
1551 
1552  // Choose a quadrature rule
1553  // Gauss is exact up to degree 2n-1
1554  const unsigned int degree = std::max(fe1.tensor_degree(), fe2.tensor_degree());
1556  ExcNotImplemented());
1557 
1558  QGauss<dim> quadrature(degree+1);
1559  // Set up FEValues.
1561  FEValues<dim> val1 (fe1, quadrature, update_values);
1562  val1.reinit (tr.begin_active());
1563  FEValues<dim> val2 (fe2, quadrature, flags);
1564  val2.reinit (tr.begin_active());
1565 
1566  // Integrate and invert mass matrix
1567  // This happens in the target space
1568  FullMatrix<double> mass (n2, n2);
1569 
1570  for (unsigned int k=0; k<quadrature.size(); ++k)
1571  {
1572  const double w = val2.JxW(k);
1573  for (unsigned int i=0; i<n2; ++i)
1574  {
1575  const double v = val2.shape_value(i,k);
1576  for (unsigned int j=0; j<n2; ++j)
1577  mass(i,j) += w*v * val2.shape_value(j,k);
1578  }
1579  }
1580  // Gauss-Jordan should be
1581  // sufficient since we expect the
1582  // mass matrix to be
1583  // well-conditioned
1584  mass.gauss_jordan();
1585 
1586  // Now, test every function of fe1
1587  // with test functions of fe2 and
1588  // compute the projection of each
1589  // unit vector.
1590  Vector<double> b(n2);
1591  Vector<double> x(n2);
1592 
1593  for (unsigned int j=0; j<n1; ++j)
1594  {
1595  b = 0.;
1596  for (unsigned int i=0; i<n2; ++i)
1597  for (unsigned int k=0; k<quadrature.size(); ++k)
1598  {
1599  const double w = val2.JxW(k);
1600  const double u = val1.shape_value(j,k);
1601  const double v = val2.shape_value(i,k);
1602  b(i) += u*v*w;
1603  }
1604 
1605  // Multiply by the inverse
1606  mass.vmult(x,b);
1607  for (unsigned int i=0; i<n2; ++i)
1608  matrix(i,j) = x(i);
1609  }
1610  }
1611 
1612 
1613 
1614  template<int dim, int spacedim>
1617  {
1618  const unsigned int n_dofs = fe.dofs_per_cell;
1619 
1620  FullMatrix<double> N (n_dofs, n_dofs);
1621 
1623  Assert (fe.n_components() == dim, ExcNotImplemented());
1624 
1625  const std::vector<Point<dim> > &points = fe.get_generalized_support_points();
1626 
1627  // We need the values of the polynomials in all generalized support points.
1628  // This function specifically works for the case where shape functions
1629  // have 'dim' vector components, so allocate that much space
1630  std::vector<Vector<double> >
1631  support_point_values (points.size(), Vector<double>(dim));
1632 
1633  // In this vector, we store the
1634  // result of the interpolation
1635  std::vector<double> nodal_values(n_dofs);
1636 
1637  // Get the values of each shape function in turn. Remember that these
1638  // are the 'raw' shape functions (i.e., where the element has not yet
1639  // computed the expansion coefficients with regard to the basis
1640  // provided by the polynomial space).
1641  for (unsigned int i=0; i<n_dofs; ++i)
1642  {
1643  // get the values of the current set of shape functions
1644  // at the generalized support points
1645  for (unsigned int k=0; k<points.size(); ++k)
1646  for (unsigned int d=0; d<dim; ++d)
1647  {
1648  support_point_values[k][d] = fe.shape_value_component(i, points[k], d);
1649  Assert (numbers::is_finite(support_point_values[k][d]), ExcInternalError());
1650  }
1651 
1653  nodal_values);
1654 
1655  // Enter the interpolated dofs into the matrix
1656  for (unsigned int j=0; j<n_dofs; ++j)
1657  {
1658  N(j,i) = nodal_values[j];
1659  Assert (numbers::is_finite(nodal_values[j]), ExcInternalError());
1660  }
1661  }
1662 
1663  return N;
1664  }
1665 
1666 
1667 
1668  template<int dim, int spacedim>
1669  void
1671  const FiniteElement<dim,spacedim> &fe)
1672  {
1673  M = compute_node_matrix (fe);
1674  }
1675 
1676 
1677 
1678  /*
1679  template<>
1680  void
1681  compute_embedding_matrices(const FiniteElement<1,2> &,
1682  std::vector<std::vector<FullMatrix<double> > > &,
1683  const bool)
1684  {
1685  Assert(false, ExcNotImplemented());
1686  }
1687 
1688 
1689  template<>
1690  void
1691  compute_embedding_matrices(const FiniteElement<1,3> &,
1692  std::vector<std::vector<FullMatrix<double> > > &,
1693  const bool)
1694  {
1695  Assert(false, ExcNotImplemented());
1696  }
1697 
1698 
1699 
1700  template<>
1701  void
1702  compute_embedding_matrices(const FiniteElement<2,3>&,
1703  std::vector<std::vector<FullMatrix<double> > >&,
1704  const bool)
1705  {
1706  Assert(false, ExcNotImplemented());
1707  }
1708 
1709  */
1710 
1711  namespace
1712  {
1713  template<int dim, typename number, int spacedim>
1714  void
1715  compute_embedding_for_shape_function (
1716  const unsigned int i,
1717  const FiniteElement<dim, spacedim> &fe,
1718  const FEValues<dim, spacedim> &coarse,
1719  const Householder<double> &H,
1720  FullMatrix<number> &this_matrix,
1721  const double threshold)
1722  {
1723  const unsigned int n = fe.dofs_per_cell;
1724  const unsigned int nd = fe.n_components ();
1725  const unsigned int nq = coarse.n_quadrature_points;
1726 
1727  Vector<number> v_coarse(nq*nd);
1728  Vector<number> v_fine(n);
1729 
1730  // The right hand side of
1731  // the least squares
1732  // problem consists of the
1733  // function values of the
1734  // coarse grid function in
1735  // each quadrature point.
1736  if (fe.is_primitive ())
1737  {
1738  const unsigned int
1739  d = fe.system_to_component_index (i).first;
1740  const double *phi_i = &coarse.shape_value (i, 0);
1741 
1742  for (unsigned int k = 0; k < nq; ++k)
1743  v_coarse (k * nd + d) = phi_i[k];
1744  }
1745 
1746  else
1747  for (unsigned int d = 0; d < nd; ++d)
1748  for (unsigned int k = 0; k < nq; ++k)
1749  v_coarse (k * nd + d) = coarse.shape_value_component (i, k, d);
1750 
1751  // solve the least squares
1752  // problem.
1753  const double result = H.least_squares (v_fine, v_coarse);
1754  Assert (result <= threshold, ExcLeastSquaresError (result));
1755  // Avoid warnings in release mode
1756  (void)result;
1757  (void)threshold;
1758 
1759  // Copy into the result
1760  // matrix. Since the matrix
1761  // maps a coarse grid
1762  // function to a fine grid
1763  // function, the columns
1764  // are fine grid.
1765  for (unsigned int j = 0; j < n; ++j)
1766  this_matrix(j, i) = v_fine(j);
1767  }
1768 
1769 
1770 
1771  template<int dim, typename number, int spacedim>
1772  void
1773  compute_embedding_matrices_for_refinement_case (
1774  const FiniteElement<dim, spacedim> &fe,
1775  std::vector<FullMatrix<number> > &matrices,
1776  const unsigned int ref_case,
1777  const double threshold)
1778  {
1779  const unsigned int n = fe.dofs_per_cell;
1780  const unsigned int nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
1781  for (unsigned int i = 0; i < nc; ++i)
1782  {
1783  Assert(matrices[i].n() == n, ExcDimensionMismatch(matrices[i].n (), n));
1784  Assert(matrices[i].m() == n, ExcDimensionMismatch(matrices[i].m (), n));
1785  }
1786 
1787  // Set up meshes, one with a single
1788  // reference cell and refine it once
1790  GridGenerator::hyper_cube (tria, 0, 1);
1791  tria.begin_active()->set_refine_flag (RefinementCase<dim>(ref_case));
1793 
1794  const unsigned int degree = fe.degree;
1795  QGauss<dim> q_fine (degree+1);
1796  const unsigned int nq = q_fine.size();
1797 
1798  FEValues<dim,spacedim> fine (fe, q_fine,
1801  update_values);
1802 
1803  // We search for the polynomial on
1804  // the small cell, being equal to
1805  // the coarse polynomial in all
1806  // quadrature points.
1807 
1808  // First build the matrix for this
1809  // least squares problem. This
1810  // contains the values of the fine
1811  // cell polynomials in the fine
1812  // cell grid points.
1813 
1814  // This matrix is the same for all
1815  // children.
1816  fine.reinit (tria.begin_active ());
1817  const unsigned int nd = fe.n_components ();
1818  FullMatrix<number> A (nq*nd, n);
1819 
1820  for (unsigned int j = 0; j < n; ++j)
1821  for (unsigned int d = 0; d < nd; ++d)
1822  for (unsigned int k = 0; k < nq; ++k)
1823  A (k * nd + d, j) = fine.shape_value_component (j, k, d);
1824 
1825  Householder<double> H (A);
1826  unsigned int cell_number = 0;
1827 
1828  Threads::TaskGroup<void> task_group;
1829 
1831  fine_cell = tria.begin_active (); fine_cell != tria.end ();
1832  ++fine_cell, ++cell_number)
1833  {
1834  fine.reinit (fine_cell);
1835 
1836  // evaluate on the coarse cell (which
1837  // is the first -- inactive -- cell on
1838  // the lowest level of the
1839  // triangulation we have created)
1840  const std::vector<Point<spacedim> > &q_points_fine = fine.get_quadrature_points();
1841  std::vector<Point<dim> > q_points_coarse(q_points_fine.size());
1842  for (unsigned int i=0; i<q_points_fine.size(); ++i)
1843  for (unsigned int j=0; j<dim; ++j)
1844  q_points_coarse[i](j) = q_points_fine[i](j);
1845  const Quadrature<dim> q_coarse (q_points_coarse,
1846  fine.get_JxW_values ());
1847  FEValues<dim,spacedim> coarse (fe, q_coarse, update_values);
1848 
1849  coarse.reinit (tria.begin (0));
1850 
1851  FullMatrix<double> &this_matrix = matrices[cell_number];
1852 
1853  // Compute this once for each
1854  // coarse grid basis function. can
1855  // spawn subtasks if n is
1856  // sufficiently large so that there
1857  // are more than about 5000
1858  // operations in the inner loop
1859  // (which is basically const * n^2
1860  // operations).
1861  if (n > 30)
1862  {
1863  for (unsigned int i = 0; i < n; ++i)
1864  {
1865  task_group +=
1866  Threads::new_task (&compute_embedding_for_shape_function<dim, number, spacedim>,
1867  i, fe, coarse, H, this_matrix, threshold);
1868  }
1869  task_group.join_all();
1870  }
1871  else
1872  {
1873  for (unsigned int i = 0; i < n; ++i)
1874  {
1875  compute_embedding_for_shape_function<dim, number, spacedim>
1876  (i, fe, coarse, H, this_matrix, threshold);
1877  }
1878  }
1879 
1880  // Remove small entries from
1881  // the matrix
1882  for (unsigned int i = 0; i < this_matrix.m (); ++i)
1883  for (unsigned int j = 0; j < this_matrix.n (); ++j)
1884  if (std::fabs (this_matrix (i, j)) < 1e-12)
1885  this_matrix (i, j) = 0.;
1886  }
1887 
1888  Assert (cell_number == GeometryInfo<dim>::n_children (RefinementCase<dim> (ref_case)),
1889  ExcInternalError ());
1890  }
1891  }
1892 
1893 
1894 
1895  template <int dim, typename number, int spacedim>
1896  void
1898  std::vector<std::vector<FullMatrix<number> > > &matrices,
1899  const bool isotropic_only,
1900  const double threshold)
1901  {
1902  Threads::TaskGroup<void> task_group;
1903 
1904  // loop over all possible refinement cases
1905  unsigned int ref_case = (isotropic_only)
1908 
1909  for (; ref_case <= RefinementCase<dim>::isotropic_refinement; ++ref_case)
1910  task_group += Threads::new_task (&compute_embedding_matrices_for_refinement_case<dim, number, spacedim>,
1911  fe, matrices[ref_case-1], ref_case, threshold);
1912 
1913  task_group.join_all ();
1914  }
1915 
1916 
1917 
1918  template <int dim, typename number, int spacedim>
1919  void
1922  const unsigned int face_coarse,
1923  const unsigned int face_fine,
1924  const double threshold)
1925  {
1926  Assert(face_coarse==0, ExcNotImplemented());
1927  Assert(face_fine==0, ExcNotImplemented());
1928 
1929  const unsigned int nc = GeometryInfo<dim>::max_children_per_face;
1930  const unsigned int n = fe.dofs_per_face;
1931  const unsigned int nd = fe.n_components();
1932  const unsigned int degree = fe.degree;
1933 
1934  const bool normal = fe.conforms(FiniteElementData<dim>::Hdiv);
1935  const bool tangential = fe.conforms(FiniteElementData<dim>::Hcurl);
1936 
1937  for (unsigned int i=0; i<nc; ++i)
1938  {
1939  Assert(matrices[i].n() == n, ExcDimensionMismatch(matrices[i].n(),n));
1940  Assert(matrices[i].m() == n, ExcDimensionMismatch(matrices[i].m(),n));
1941  }
1942 
1943  // In order to make the loops below
1944  // simpler, we introduce vectors
1945  // containing for indices 0-n the
1946  // number of the corresponding
1947  // shape value on the cell.
1948  std::vector<unsigned int> face_c_dofs(n);
1949  std::vector<unsigned int> face_f_dofs(n);
1950  {
1951  unsigned int face_dof=0;
1952  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
1953  {
1954  const unsigned int offset_c = GeometryInfo<dim>::face_to_cell_vertices(face_coarse, i)
1955  *fe.dofs_per_vertex;
1956  const unsigned int offset_f = GeometryInfo<dim>::face_to_cell_vertices(face_fine, i)
1957  *fe.dofs_per_vertex;
1958  for (unsigned int j=0; j<fe.dofs_per_vertex; ++j)
1959  {
1960  face_c_dofs[face_dof] = offset_c + j;
1961  face_f_dofs[face_dof] = offset_f + j;
1962  ++face_dof;
1963  }
1964  }
1965  for (unsigned int i=1; i<=GeometryInfo<dim>::lines_per_face; ++i)
1966  {
1967  const unsigned int offset_c = fe.first_line_index
1968  + GeometryInfo<dim>::face_to_cell_lines(face_coarse, i-1)
1969  *fe.dofs_per_line;
1970  const unsigned int offset_f = fe.first_line_index
1971  + GeometryInfo<dim>::face_to_cell_lines(face_fine, i-1)
1972  *fe.dofs_per_line;
1973  for (unsigned int j=0; j<fe.dofs_per_line; ++j)
1974  {
1975  face_c_dofs[face_dof] = offset_c + j;
1976  face_f_dofs[face_dof] = offset_f + j;
1977  ++face_dof;
1978  }
1979  }
1980  for (unsigned int i=1; i<=GeometryInfo<dim>::quads_per_face; ++i)
1981  {
1982  const unsigned int offset_c = fe.first_quad_index
1983  + face_coarse
1984  *fe.dofs_per_quad;
1985  const unsigned int offset_f = fe.first_quad_index
1986  + face_fine
1987  *fe.dofs_per_quad;
1988  for (unsigned int j=0; j<fe.dofs_per_quad; ++j)
1989  {
1990  face_c_dofs[face_dof] = offset_c + j;
1991  face_f_dofs[face_dof] = offset_f + j;
1992  ++face_dof;
1993  }
1994  }
1995  Assert (face_dof == fe.dofs_per_face, ExcInternalError());
1996  }
1997 
1998  // Set up meshes, one with a single
1999  // reference cell and refine it once
2001  GridGenerator::hyper_cube (tria, 0, 1);
2002  tria.refine_global(1);
2003  MappingCartesian<dim> mapping;
2004 
2005  // Setup quadrature and FEValues
2006  // for a face. We cannot use
2007  // FEFaceValues and
2008  // FESubfaceValues because of
2009  // some nifty handling of
2010  // refinement cases. Guido stops
2011  // disliking and instead starts
2012  // hating the anisotropic implementation
2013  QGauss<dim-1> q_gauss(degree+1);
2014  const Quadrature<dim> q_fine = QProjector<dim>::project_to_face(q_gauss, face_fine);
2015  const unsigned int nq = q_fine.size();
2016 
2017  FEValues<dim> fine (mapping, fe, q_fine,
2019 
2020  // We search for the polynomial on
2021  // the small cell, being equal to
2022  // the coarse polynomial in all
2023  // quadrature points.
2024 
2025  // First build the matrix for this
2026  // least squares problem. This
2027  // contains the values of the fine
2028  // cell polynomials in the fine
2029  // cell grid points.
2030 
2031  // This matrix is the same for all
2032  // children.
2033  fine.reinit(tria.begin_active());
2034  FullMatrix<number> A(nq*nd, n);
2035  for (unsigned int j=0; j<n; ++j)
2036  for (unsigned int k=0; k<nq; ++k)
2037  if (nd != dim)
2038  for (unsigned int d=0; d<nd; ++d)
2039  A(k*nd+d,j) = fine.shape_value_component(face_f_dofs[j],k,d);
2040  else
2041  {
2042  if (normal)
2043  A(k*nd,j) = fine.shape_value_component(face_f_dofs[j],k,0);
2044  if (tangential)
2045  for (unsigned int d=1; d<dim; ++d)
2046  A(k*nd+d,j) = fine.shape_value_component(face_f_dofs[j],k,d);
2047  }
2048 
2049  Householder<double> H(A);
2050 
2051  Vector<number> v_coarse(nq*nd);
2052  Vector<number> v_fine(n);
2053 
2054 
2055 
2056  for (unsigned int cell_number = 0; cell_number < GeometryInfo<dim>::max_children_per_face;
2057  ++cell_number)
2058  {
2059  const Quadrature<dim> q_coarse
2060  = QProjector<dim>::project_to_subface(q_gauss, face_coarse, cell_number);
2061  FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
2062 
2065  tria.begin(0)->refinement_case(), face_coarse, cell_number));
2066  fine.reinit(fine_cell);
2067  coarse.reinit(tria.begin(0));
2068 
2069  FullMatrix<double> &this_matrix = matrices[cell_number];
2070 
2071  // Compute this once for each
2072  // coarse grid basis function
2073  for (unsigned int i=0; i<n; ++i)
2074  {
2075  // The right hand side of
2076  // the least squares
2077  // problem consists of the
2078  // function values of the
2079  // coarse grid function in
2080  // each quadrature point.
2081  for (unsigned int k=0; k<nq; ++k)
2082  if (nd != dim)
2083  for (unsigned int d=0; d<nd; ++d)
2084  v_coarse(k*nd+d) = coarse.shape_value_component (face_c_dofs[i],k,d);
2085  else
2086  {
2087  if (normal)
2088  v_coarse(k*nd) = coarse.shape_value_component(face_c_dofs[i],k,0);
2089  if (tangential)
2090  for (unsigned int d=1; d<dim; ++d)
2091  v_coarse(k*nd+d) = coarse.shape_value_component(face_c_dofs[i],k,d);
2092  }
2093  // solve the least squares
2094  // problem.
2095  const double result = H.least_squares(v_fine, v_coarse);
2096  Assert (result <= threshold, ExcLeastSquaresError(result));
2097  // Avoid compiler warnings in Release mode
2098  (void)result;
2099  (void)threshold;
2100 
2101  // Copy into the result
2102  // matrix. Since the matrix
2103  // maps a coarse grid
2104  // function to a fine grid
2105  // function, the columns
2106  // are fine grid.
2107  for (unsigned int j=0; j<n; ++j)
2108  this_matrix(j,i) = v_fine(j);
2109  }
2110  // Remove small entries from
2111  // the matrix
2112  for (unsigned int i=0; i<this_matrix.m(); ++i)
2113  for (unsigned int j=0; j<this_matrix.n(); ++j)
2114  if (std::fabs(this_matrix(i,j)) < 1e-12)
2115  this_matrix(i,j) = 0.;
2116  }
2117  }
2118 
2119 
2120 
2121  template <int dim, typename number, int spacedim>
2122  void
2124  std::vector<std::vector<FullMatrix<number> > > &matrices,
2125  const bool isotropic_only)
2126  {
2127  const unsigned int n = fe.dofs_per_cell;
2128  const unsigned int nd = fe.n_components();
2129  const unsigned int degree = fe.degree;
2130 
2131  // prepare FEValues, quadrature etc on
2132  // coarse cell
2133  QGauss<dim> q_fine(degree+1);
2134  const unsigned int nq = q_fine.size();
2135 
2136  // create mass matrix on coarse cell.
2137  FullMatrix<number> mass(n, n);
2138  {
2139  // set up a triangulation for coarse cell
2141  GridGenerator::hyper_cube (tr, 0, 1);
2142 
2143  FEValues<dim,spacedim> coarse (fe, q_fine,
2145 
2146  typename Triangulation<dim,spacedim>::cell_iterator coarse_cell
2147  = tr.begin(0);
2148  coarse.reinit (coarse_cell);
2149 
2150  const std::vector<double> &JxW = coarse.get_JxW_values();
2151  for (unsigned int i=0; i<n; ++i)
2152  for (unsigned int j=0; j<n; ++j)
2153  if (fe.is_primitive())
2154  {
2155  const double *coarse_i = &coarse.shape_value(i,0);
2156  const double *coarse_j = &coarse.shape_value(j,0);
2157  double mass_ij = 0;
2158  for (unsigned int k=0; k<nq; ++k)
2159  mass_ij += JxW[k] * coarse_i[k] * coarse_j[k];
2160  mass(i,j) = mass_ij;
2161  }
2162  else
2163  {
2164  double mass_ij = 0;
2165  for (unsigned int d=0; d<nd; ++d)
2166  for (unsigned int k=0; k<nq; ++k)
2167  mass_ij += JxW[k] * coarse.shape_value_component(i,k,d)
2168  * coarse.shape_value_component(j,k,d);
2169  mass(i,j) = mass_ij;
2170  }
2171 
2172  // invert mass matrix
2173  mass.gauss_jordan();
2174  }
2175 
2176  // loop over all possible
2177  // refinement cases
2178  unsigned int ref_case = (isotropic_only)
2181  for (; ref_case <= RefinementCase<dim>::isotropic_refinement; ++ref_case)
2182  {
2183  const unsigned int
2185 
2186  for (unsigned int i=0; i<nc; ++i)
2187  {
2188  Assert(matrices[ref_case-1][i].n() == n,
2189  ExcDimensionMismatch(matrices[ref_case-1][i].n(),n));
2190  Assert(matrices[ref_case-1][i].m() == n,
2191  ExcDimensionMismatch(matrices[ref_case-1][i].m(),n));
2192  }
2193 
2194  // create a respective refinement on the
2195  // triangulation
2197  GridGenerator::hyper_cube (tr, 0, 1);
2198  tr.begin_active()->set_refine_flag(RefinementCase<dim>(ref_case));
2200 
2203  update_values);
2204 
2205  typename Triangulation<dim,spacedim>::cell_iterator coarse_cell
2206  = tr.begin(0);
2207 
2208  Vector<number> v_coarse(n);
2209  Vector<number> v_fine(n);
2210 
2211  for (unsigned int cell_number=0; cell_number<nc; ++cell_number)
2212  {
2213  FullMatrix<double> &this_matrix = matrices[ref_case-1][cell_number];
2214 
2215  // Compute right hand side,
2216  // which is a fine level basis
2217  // function tested with the
2218  // coarse level functions.
2219  fine.reinit(coarse_cell->child(cell_number));
2220  const std::vector<Point<spacedim> > &q_points_fine = fine.get_quadrature_points();
2221  std::vector<Point<dim> > q_points_coarse(q_points_fine.size());
2222  for (unsigned int q=0; q<q_points_fine.size(); ++q)
2223  for (unsigned int j=0; j<dim; ++j)
2224  q_points_coarse[q](j) = q_points_fine[q](j);
2225  Quadrature<dim> q_coarse (q_points_coarse,
2226  fine.get_JxW_values());
2228  coarse.reinit(coarse_cell);
2229 
2230  // Build RHS
2231 
2232  const std::vector<double> &JxW = fine.get_JxW_values();
2233 
2234  // Outer loop over all fine
2235  // grid shape functions phi_j
2236  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
2237  {
2238  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
2239  {
2240  if (fe.is_primitive())
2241  {
2242  const double *coarse_i = &coarse.shape_value(i,0);
2243  const double *fine_j = &fine.shape_value(j,0);
2244 
2245  double update = 0;
2246  for (unsigned int k=0; k<nq; ++k)
2247  update += JxW[k] * coarse_i[k] * fine_j[k];
2248  v_fine(i) = update;
2249  }
2250  else
2251  {
2252  double update = 0;
2253  for (unsigned int d=0; d<nd; ++d)
2254  for (unsigned int k=0; k<nq; ++k)
2255  update += JxW[k] * coarse.shape_value_component(i,k,d)
2256  * fine.shape_value_component(j,k,d);
2257  v_fine(i) = update;
2258  }
2259  }
2260 
2261  // RHS ready. Solve system
2262  // and enter row into
2263  // matrix
2264  mass.vmult (v_coarse, v_fine);
2265  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
2266  this_matrix(i,j) = v_coarse(i);
2267  }
2268 
2269  // Remove small entries from
2270  // the matrix
2271  for (unsigned int i=0; i<this_matrix.m(); ++i)
2272  for (unsigned int j=0; j<this_matrix.n(); ++j)
2273  if (std::fabs(this_matrix(i,j)) < 1e-12)
2274  this_matrix(i,j) = 0.;
2275  }
2276  }
2277  }
2278 
2279 
2280 
2281  template <int dim, int spacedim>
2282  void
2283  add_fe_name(const std::string &parameter_name,
2284  const FEFactoryBase<dim,spacedim> *factory)
2285  {
2286  // Erase everything after the
2287  // actual class name
2288  std::string name = parameter_name;
2289  unsigned int name_end =
2290  name.find_first_not_of(std::string("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"));
2291  if (name_end < name.size())
2292  name.erase(name_end);
2293  // first make sure that no other
2294  // thread intercepts the
2295  // operation of this function;
2296  // for this, acquire the lock
2297  // until we quit this function
2298  Threads::Mutex::ScopedLock lock(fe_name_map_lock);
2299 
2300  Assert(fe_name_map[dim][spacedim].find(name) == fe_name_map[dim][spacedim].end(),
2301  ExcMessage("Cannot change existing element in finite element name list"));
2302 
2303  // Insert the normalized name into
2304  // the map
2305  fe_name_map[dim][spacedim][name] =
2306  std_cxx11::shared_ptr<const Subscriptor> (factory);
2307  }
2308 
2309 
2310  namespace internal
2311  {
2312  namespace
2313  {
2314  // TODO: this encapsulates the call to the
2315  // dimension-dependent fe_name_map so that we
2316  // have a unique interface. could be done
2317  // smarter?
2318  template <int dim, int spacedim>
2320  get_fe_by_name_ext (std::string &name,
2321  const std::map<std::string,
2322  std_cxx11::shared_ptr<const Subscriptor> >
2323  &fe_name_map)
2324  {
2325  // Extract the name of the
2326  // finite element class, which only
2327  // contains characters, numbers and
2328  // underscores.
2329  unsigned int name_end =
2330  name.find_first_not_of(std::string("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"));
2331  const std::string name_part(name, 0, name_end);
2332  name.erase(0, name_part.size());
2333 
2334  // now things get a little more
2335  // complicated: FESystem. it's
2336  // more complicated, since we
2337  // have to figure out what the
2338  // base elements are. this can
2339  // only be done recursively
2340  if (name_part == "FESystem")
2341  {
2342  // next we have to get at the
2343  // base elements. start with
2344  // the first. wrap the whole
2345  // block into try-catch to
2346  // make sure we destroy the
2347  // pointers we got from
2348  // recursive calls if one of
2349  // these calls should throw
2350  // an exception
2351  std::vector<const FiniteElement<dim,spacedim>*> base_fes;
2352  std::vector<unsigned int> base_multiplicities;
2353  try
2354  {
2355  // Now, just the [...]
2356  // part should be left.
2357  if (name.size() == 0 || name[0] != '[')
2358  throw (std::string("Invalid first character in ") + name);
2359  do
2360  {
2361  // Erase the
2362  // leading '[' or '-'
2363  name.erase(0,1);
2364  // Now, the name of the
2365  // first base element is
2366  // first... Let's get it
2367  base_fes.push_back (get_fe_by_name_ext<dim,spacedim> (name,
2368  fe_name_map));
2369  // next check whether
2370  // FESystem placed a
2371  // multiplicity after
2372  // the element name
2373  if (name[0] == '^')
2374  {
2375  // yes. Delete the '^'
2376  // and read this
2377  // multiplicity
2378  name.erase(0,1);
2379 
2380  const std::pair<int,unsigned int> tmp
2382  name.erase(0, tmp.second);
2383  // add to length,
2384  // including the '^'
2385  base_multiplicities.push_back (tmp.first);
2386  }
2387  else
2388  // no, so
2389  // multiplicity is
2390  // 1
2391  base_multiplicities.push_back (1);
2392 
2393  // so that's it for
2394  // this base
2395  // element. base
2396  // elements are
2397  // separated by '-',
2398  // and the list is
2399  // terminated by ']',
2400  // so loop while the
2401  // next character is
2402  // '-'
2403  }
2404  while (name[0] == '-');
2405 
2406  // so we got to the end
2407  // of the '-' separated
2408  // list. make sure that
2409  // we actually had a ']'
2410  // there
2411  if (name.size() == 0 || name[0] != ']')
2412  throw (std::string("Invalid first character in ") + name);
2413  name.erase(0,1);
2414  // just one more sanity check
2415  Assert ((base_fes.size() == base_multiplicities.size())
2416  &&
2417  (base_fes.size() > 0),
2418  ExcInternalError());
2419 
2420  // ok, apparently
2421  // everything went ok. so
2422  // generate the composed
2423  // element
2424  FiniteElement<dim,spacedim> *system_element = 0;
2425 
2426  // uses new FESystem constructor
2427  // which is independent of
2428  // the number of FEs in the system
2429  system_element = new FESystem<dim,spacedim>(base_fes, base_multiplicities);
2430 
2431  // now we don't need the
2432  // list of base elements
2433  // any more
2434  for (unsigned int i=0; i<base_fes.size(); ++i)
2435  delete base_fes[i];
2436 
2437  // finally return our
2438  // findings
2439  // Add the closing ']' to
2440  // the length
2441  return system_element;
2442 
2443  }
2444  catch (...)
2445  {
2446  // ups, some exception
2447  // was thrown. prevent a
2448  // memory leak, and then
2449  // pass on the exception
2450  // to the caller
2451  for (unsigned int i=0; i<base_fes.size(); ++i)
2452  delete base_fes[i];
2453  throw;
2454  }
2455 
2456  // this is a place where we
2457  // should really never get,
2458  // since above we have either
2459  // returned from the
2460  // try-clause, or have
2461  // re-thrown in the catch
2462  // clause. check that we
2463  // never get here
2464  Assert (false, ExcInternalError());
2465  }
2466  else if (name_part == "FE_Nothing")
2467  {
2468  // remove the () from FE_Nothing()
2469  name.erase(0,2);
2470 
2471  // this is a bit of a hack, as
2472  // FE_Nothing does not take a
2473  // degree, but it does take an
2474  // argument, which defaults to 1,
2475  // so this properly returns
2476  // FE_Nothing()
2477  const Subscriptor *ptr = fe_name_map.find(name_part)->second.get();
2478  const FEFactoryBase<dim,spacedim> *fef=dynamic_cast<const FEFactoryBase<dim,spacedim>*>(ptr);
2479  return fef->get(1);
2480  }
2481  else
2482  {
2483  // Make sure no other thread
2484  // is just adding an element
2485  Threads::Mutex::ScopedLock lock (fe_name_map_lock);
2486  AssertThrow (fe_name_map.find(name_part) != fe_name_map.end(),
2487  ExcInvalidFEName(name));
2488 
2489  // Now, just the (degree)
2490  // or (Quadrature<1>(degree+1))
2491  // part should be left.
2492  if (name.size() == 0 || name[0] != '(')
2493  throw (std::string("Invalid first character in ") + name);
2494  name.erase(0,1);
2495  if (name[0] != 'Q')
2496  {
2497  const std::pair<int,unsigned int> tmp
2499  name.erase(0, tmp.second+1);
2500  const Subscriptor *ptr = fe_name_map.find(name_part)->second.get();
2501  const FEFactoryBase<dim,spacedim> *fef=dynamic_cast<const FEFactoryBase<dim,spacedim>*>(ptr);
2502  return fef->get(tmp.first);
2503  }
2504  else
2505  {
2506  unsigned int position = name.find('(');
2507  const std::string quadrature_name(name, 0, position);
2508  name.erase(0,position+1);
2509  if (quadrature_name.compare("QGaussLobatto") == 0)
2510  {
2511  const std::pair<int,unsigned int> tmp
2513  // delete "))"
2514  name.erase(0, tmp.second+2);
2515  const Subscriptor *ptr = fe_name_map.find(name_part)->second.get();
2516  const FEFactoryBase<dim,spacedim> *fef=dynamic_cast<const FEFactoryBase<dim,spacedim>*>(ptr);
2517  return fef->get(QGaussLobatto<1>(tmp.first));
2518  }
2519  else if (quadrature_name.compare("QGauss") == 0)
2520  {
2521  const std::pair<int,unsigned int> tmp
2523  // delete "))"
2524  name.erase(0, tmp.second+2);
2525  const Subscriptor *ptr = fe_name_map.find(name_part)->second.get();
2526  const FEFactoryBase<dim,spacedim> *fef=dynamic_cast<const FEFactoryBase<dim,spacedim>*>(ptr);
2527  return fef->get(QGauss<1>(tmp.first));
2528  }
2529  else if (quadrature_name.compare("QIterated") == 0)
2530  {
2531  // find sub-quadrature
2532  position = name.find('(');
2533  const std::string subquadrature_name(name, 0, position);
2534  AssertThrow(subquadrature_name.compare("QTrapez") == 0,
2535  ExcNotImplemented("Could not detect quadrature of name " + subquadrature_name));
2536  // delete "QTrapez(),"
2537  name.erase(0,position+3);
2538  const std::pair<int,unsigned int> tmp
2540  // delete "))"
2541  name.erase(0, tmp.second+2);
2542  const Subscriptor *ptr = fe_name_map.find(name_part)->second.get();
2543  const FEFactoryBase<dim,spacedim> *fef=dynamic_cast<const FEFactoryBase<dim,spacedim>*>(ptr);
2544  return fef->get(QIterated<1>(QTrapez<1>(),tmp.first));
2545  }
2546  else
2547  {
2548  AssertThrow (false,ExcNotImplemented());
2549  }
2550  }
2551  }
2552 
2553 
2554  // hm, if we have come thus far, we
2555  // didn't know what to do with the
2556  // string we got. so do as the docs
2557  // say: raise an exception
2558  AssertThrow (false, ExcInvalidFEName(name));
2559 
2560  // make some compilers happy that
2561  // do not realize that we can't get
2562  // here after throwing
2563  return 0;
2564  }
2565 
2566 
2567 
2568  template <int dim,int spacedim>
2569  FiniteElement<dim,spacedim> *get_fe_by_name (std::string &name)
2570  {
2571  return get_fe_by_name_ext<dim,spacedim> (name, fe_name_map[dim][spacedim]);
2572  }
2573  }
2574  }
2575 
2576 
2577 
2578  template <int dim>
2580  get_fe_from_name (const std::string &parameter_name)
2581  {
2582  return get_fe_by_name<dim,dim> (parameter_name);
2583  }
2584 
2585 
2586 
2587  template <int dim, int spacedim>
2589  get_fe_by_name (const std::string &parameter_name)
2590  {
2591  std::string name = Utilities::trim(parameter_name);
2592  std::size_t index = 1;
2593  // remove spaces that are not between two word (things that match the
2594  // regular expression [A-Za-z0-9_]) characters.
2595  while (2 < name.size() && index < name.size() - 1)
2596  {
2597  if (name[index] == ' ' &&
2598  (!(std::isalnum(name[index - 1]) || name[index - 1] == '_') ||
2599  !(std::isalnum(name[index + 1]) || name[index + 1] == '_')))
2600  {
2601  name.erase(index, 1);
2602  }
2603  else
2604  {
2605  ++index;
2606  }
2607  }
2608 
2609  // Create a version of the name
2610  // string where all template
2611  // parameters are eliminated.
2612  for (unsigned int pos1 = name.find('<');
2613  pos1 < name.size();
2614  pos1 = name.find('<'))
2615  {
2616 
2617  const unsigned int pos2 = name.find('>');
2618  // If there is only a single
2619  // character between those two,
2620  // it should be 'd' or the number
2621  // representing the dimension.
2622  if (pos2-pos1 == 2)
2623  {
2624  const char dimchar = '0' + dim;
2625  (void)dimchar;
2626  if (name.at(pos1+1) != 'd')
2627  Assert (name.at(pos1+1) == dimchar,
2628  ExcInvalidFEDimension(name.at(pos1+1), dim));
2629  }
2630  else
2631  Assert(pos2-pos1 == 4, ExcInvalidFEName(name));
2632 
2633  // If pos1==pos2, then we are
2634  // probably at the end of the
2635  // string
2636  if (pos2 != pos1)
2637  name.erase(pos1, pos2-pos1+1);
2638  }
2639  // Replace all occurrences of "^dim"
2640  // by "^d" to be handled by the
2641  // next loop
2642  for (unsigned int pos = name.find("^dim");
2643  pos < name.size();
2644  pos = name.find("^dim"))
2645  name.erase(pos+2, 2);
2646 
2647  // Replace all occurrences of "^d"
2648  // by using the actual dimension
2649  for (unsigned int pos = name.find("^d");
2650  pos < name.size();
2651  pos = name.find("^d"))
2652  name.at(pos+1) = '0' + dim;
2653 
2654  try
2655  {
2656  FiniteElement<dim,spacedim> *fe = internal::get_fe_by_name<dim,spacedim> (name);
2657 
2658  // Make sure the auxiliary function
2659  // ate up all characters of the name.
2660  AssertThrow (name.size() == 0,
2661  ExcInvalidFEName(parameter_name
2662  + std::string(" extra characters after "
2663  "end of name")));
2664  return fe;
2665  }
2666  catch (const std::string &errline)
2667  {
2668  AssertThrow(false, ExcInvalidFEName(parameter_name
2669  + std::string(" at ")
2670  + errline));
2671  return 0;
2672  }
2673  }
2674 
2675 
2676 
2677  template <int dim, int spacedim>
2678  void
2680  const Quadrature<dim> &lhs_quadrature,
2681  const Quadrature<dim> &rhs_quadrature,
2682  FullMatrix<double> &X)
2683  {
2684  Assert (fe.n_components() == 1, ExcNotImplemented());
2685 
2686  // first build the matrices M and Q
2687  // described in the documentation
2689  FullMatrix<double> Q (fe.dofs_per_cell, rhs_quadrature.size());
2690 
2691  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
2692  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
2693  for (unsigned int q=0; q<lhs_quadrature.size(); ++q)
2694  M(i,j) += fe.shape_value (i, lhs_quadrature.point(q)) *
2695  fe.shape_value (j, lhs_quadrature.point(q)) *
2696  lhs_quadrature.weight(q);
2697 
2698  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
2699  for (unsigned int q=0; q<rhs_quadrature.size(); ++q)
2700  Q(i,q) += fe.shape_value (i, rhs_quadrature.point(q)) *
2701  rhs_quadrature.weight(q);
2702 
2703  // then invert M
2704  FullMatrix<double> M_inverse (fe.dofs_per_cell, fe.dofs_per_cell);
2705  M_inverse.invert (M);
2706 
2707  // finally compute the result
2708  X.reinit (fe.dofs_per_cell, rhs_quadrature.size());
2709  M_inverse.mmult (X, Q);
2710 
2711  Assert (X.m() == fe.dofs_per_cell, ExcInternalError());
2712  Assert (X.n() == rhs_quadrature.size(), ExcInternalError());
2713  }
2714 
2715 
2716 
2717  template <int dim, int spacedim>
2718  void
2720  const Quadrature<dim> &quadrature,
2721  FullMatrix<double> &I_q)
2722  {
2723  Assert (fe.n_components() == 1, ExcNotImplemented());
2724  Assert (I_q.m() == quadrature.size(),
2725  ExcMessage ("Wrong matrix size"));
2726  Assert (I_q.n() == fe.dofs_per_cell, ExcMessage ("Wrong matrix size"));
2727 
2728  for (unsigned int q=0; q<quadrature.size(); ++q)
2729  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
2730  I_q(q,i) = fe.shape_value (i, quadrature.point(q));
2731  }
2732 
2733 
2734 
2735  template <int dim>
2736  void
2738  const FullMatrix<double> &projection_matrix,
2739  const std::vector< Tensor<1, dim > > &vector_of_tensors_at_qp,
2740  std::vector< Tensor<1, dim > > &vector_of_tensors_at_nodes)
2741  {
2742 
2743  // check that the number columns of the projection_matrix
2744  // matches the size of the vector_of_tensors_at_qp
2745  Assert(projection_matrix.n_cols() == vector_of_tensors_at_qp.size(),
2746  ExcDimensionMismatch(projection_matrix.n_cols(),
2747  vector_of_tensors_at_qp.size()));
2748 
2749  // check that the number rows of the projection_matrix
2750  // matches the size of the vector_of_tensors_at_nodes
2751  Assert(projection_matrix.n_rows() == vector_of_tensors_at_nodes.size(),
2752  ExcDimensionMismatch(projection_matrix.n_rows(),
2753  vector_of_tensors_at_nodes.size()));
2754 
2755  // number of support points (nodes) to project to
2756  const unsigned int n_support_points = projection_matrix.n_rows();
2757  // number of quadrature points to project from
2758  const unsigned int n_quad_points = projection_matrix.n_cols();
2759 
2760  // component projected to the nodes
2761  Vector<double> component_at_node(n_support_points);
2762  // component at the quadrature point
2763  Vector<double> component_at_qp(n_quad_points);
2764 
2765  for (unsigned int ii = 0; ii < dim; ++ii)
2766  {
2767 
2768  component_at_qp = 0;
2769 
2770  // populate the vector of components at the qps
2771  // from vector_of_tensors_at_qp
2772  // vector_of_tensors_at_qp data is in form:
2773  // columns: 0, 1, ..., dim
2774  // rows: 0,1,...., n_quad_points
2775  // so extract the ii'th column of vector_of_tensors_at_qp
2776  for (unsigned int q = 0; q < n_quad_points; ++q)
2777  {
2778  component_at_qp(q) = vector_of_tensors_at_qp[q][ii];
2779  }
2780 
2781  // project from the qps -> nodes
2782  // component_at_node = projection_matrix_u * component_at_qp
2783  projection_matrix.vmult(component_at_node, component_at_qp);
2784 
2785  // rewrite the projection of the components
2786  // back into the vector of tensors
2787  for (unsigned int nn =0; nn <n_support_points; ++nn)
2788  {
2789  vector_of_tensors_at_nodes[nn][ii] = component_at_node(nn);
2790  }
2791  }
2792  }
2793 
2794 
2795 
2796  template <int dim>
2797  void
2799  const FullMatrix<double> &projection_matrix,
2800  const std::vector< SymmetricTensor<2, dim > > &vector_of_tensors_at_qp,
2801  std::vector< SymmetricTensor<2, dim > > &vector_of_tensors_at_nodes)
2802  {
2803 
2804  // check that the number columns of the projection_matrix
2805  // matches the size of the vector_of_tensors_at_qp
2806  Assert(projection_matrix.n_cols() == vector_of_tensors_at_qp.size(),
2807  ExcDimensionMismatch(projection_matrix.n_cols(),
2808  vector_of_tensors_at_qp.size()));
2809 
2810  // check that the number rows of the projection_matrix
2811  // matches the size of the vector_of_tensors_at_nodes
2812  Assert(projection_matrix.n_rows() == vector_of_tensors_at_nodes.size(),
2813  ExcDimensionMismatch(projection_matrix.n_rows(),
2814  vector_of_tensors_at_nodes.size()));
2815 
2816  // number of support points (nodes)
2817  const unsigned int n_support_points = projection_matrix.n_rows();
2818  // number of quadrature points to project from
2819  const unsigned int n_quad_points = projection_matrix.n_cols();
2820 
2821  // number of unique entries in a symmetric second-order tensor
2822  const unsigned int n_independent_components =
2824 
2825  // component projected to the nodes
2826  Vector<double> component_at_node(n_support_points);
2827  // component at the quadrature point
2828  Vector<double> component_at_qp(n_quad_points);
2829 
2830  // loop over the number of unique dimensions of the tensor
2831  for (unsigned int ii = 0; ii < n_independent_components; ++ii)
2832  {
2833 
2834  component_at_qp = 0;
2835 
2836  // row-column entry of tensor corresponding the unrolled index
2838  const unsigned int row = row_column_index[0];
2839  const unsigned int column = row_column_index[1];
2840 
2841  // populate the vector of components at the qps
2842  // from vector_of_tensors_at_qp
2843  // vector_of_tensors_at_qp is in form:
2844  // columns: 0, 1, ..., n_independent_components
2845  // rows: 0,1,...., n_quad_points
2846  // so extract the ii'th column of vector_of_tensors_at_qp
2847  for (unsigned int q = 0; q < n_quad_points; ++q)
2848  {
2849  component_at_qp(q) = (vector_of_tensors_at_qp[q])[row][column];
2850  }
2851 
2852  // project from the qps -> nodes
2853  // component_at_node = projection_matrix_u * component_at_qp
2854  projection_matrix.vmult(component_at_node, component_at_qp);
2855 
2856  // rewrite the projection of the components back into the vector of tensors
2857  for (unsigned int nn =0; nn <n_support_points; ++nn)
2858  {
2859  (vector_of_tensors_at_nodes[nn])[row][column] = component_at_node(nn);
2860  }
2861  }
2862  }
2863 
2864 
2865 
2866  template <int dim, int spacedim>
2867  void
2869  const Quadrature<dim-1> &lhs_quadrature,
2870  const Quadrature<dim-1> &rhs_quadrature,
2872  const unsigned int face,
2873  FullMatrix<double> &X)
2874  {
2875  Assert (fe.n_components() == 1, ExcNotImplemented());
2876  Assert (lhs_quadrature.size () > fe.degree, ExcNotGreaterThan (lhs_quadrature.size (), fe.degree));
2877 
2878 
2879 
2880  // build the matrices M and Q
2881  // described in the documentation
2883  FullMatrix<double> Q (fe.dofs_per_cell, rhs_quadrature.size());
2884 
2885  {
2886  // need an FEFaceValues object to evaluate shape function
2887  // values on the specified face.
2888  FEFaceValues <dim> fe_face_values (fe, lhs_quadrature, update_values);
2889  fe_face_values.reinit (cell, face); // setup shape_value on this face.
2890 
2891  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
2892  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
2893  for (unsigned int q=0; q<lhs_quadrature.size(); ++q)
2894  M(i,j) += fe_face_values.shape_value (i, q) *
2895  fe_face_values.shape_value (j, q) *
2896  lhs_quadrature.weight(q);
2897  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
2898  {
2899  M(i,i) = (M(i,i) == 0 ? 1 : M(i,i));
2900  }
2901  }
2902 
2903  {
2904  FEFaceValues <dim> fe_face_values (fe, rhs_quadrature, update_values);
2905  fe_face_values.reinit (cell, face); // setup shape_value on this face.
2906 
2907  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
2908  for (unsigned int q=0; q<rhs_quadrature.size(); ++q)
2909  Q(i,q) += fe_face_values.shape_value (i, q) *
2910  rhs_quadrature.weight(q);
2911  }
2912  // then invert M
2913  FullMatrix<double> M_inverse (fe.dofs_per_cell, fe.dofs_per_cell);
2914  M_inverse.invert (M);
2915 
2916  // finally compute the result
2917  X.reinit (fe.dofs_per_cell, rhs_quadrature.size());
2918  M_inverse.mmult (X, Q);
2919 
2920  Assert (X.m() == fe.dofs_per_cell, ExcInternalError());
2921  Assert (X.n() == rhs_quadrature.size(), ExcInternalError());
2922  }
2923 
2924 
2925 
2926  template <int dim>
2927  void
2928  hierarchic_to_lexicographic_numbering (unsigned int degree, std::vector<unsigned int> &h2l)
2929  {
2930  // number of support points in each
2931  // direction
2932  const unsigned int n = degree+1;
2933 
2934  unsigned int dofs_per_cell = n;
2935  for (unsigned int i=1; i<dim; ++i)
2936  dofs_per_cell *= n;
2937 
2938  // Assert size maches degree
2939  AssertDimension (h2l.size(), dofs_per_cell);
2940 
2941  // polynomial degree
2942  const unsigned int dofs_per_line = degree - 1;
2943 
2944  // the following lines of code are somewhat odd, due to the way the
2945  // hierarchic numbering is organized. if someone would really want to
2946  // understand these lines, you better draw some pictures where you
2947  // indicate the indices and orders of vertices, lines, etc, along with the
2948  // numbers of the degrees of freedom in hierarchical and lexicographical
2949  // order
2950  switch (dim)
2951  {
2952  case 1:
2953  {
2954  h2l[0] = 0;
2955  h2l[1] = dofs_per_cell-1;
2956  for (unsigned int i=2; i<dofs_per_cell; ++i)
2957  h2l[i] = i-1;
2958 
2959  break;
2960  }
2961 
2962  case 2:
2963  {
2964  unsigned int next_index = 0;
2965  // first the four vertices
2966  h2l[next_index++] = 0;
2967  h2l[next_index++] = n-1;
2968  h2l[next_index++] = n*(n-1);
2969  h2l[next_index++] = n*n-1;
2970 
2971  // left line
2972  for (unsigned int i=0; i<dofs_per_line; ++i)
2973  h2l[next_index++] = (1+i)*n;
2974 
2975  // right line
2976  for (unsigned int i=0; i<dofs_per_line; ++i)
2977  h2l[next_index++] = (2+i)*n-1;
2978 
2979  // bottom line
2980  for (unsigned int i=0; i<dofs_per_line; ++i)
2981  h2l[next_index++] = 1+i;
2982 
2983  // top line
2984  for (unsigned int i=0; i<dofs_per_line; ++i)
2985  h2l[next_index++] = n*(n-1)+i+1;
2986 
2987  // inside quad
2988  for (unsigned int i=0; i<dofs_per_line; ++i)
2989  for (unsigned int j=0; j<dofs_per_line; ++j)
2990  h2l[next_index++] = n*(i+1)+j+1;
2991 
2992  Assert (next_index == dofs_per_cell, ExcInternalError());
2993 
2994  break;
2995  }
2996 
2997  case 3:
2998  {
2999  unsigned int next_index = 0;
3000  // first the eight vertices
3001  h2l[next_index++] = 0; // 0
3002  h2l[next_index++] = ( 1)*degree; // 1
3003  h2l[next_index++] = ( n )*degree; // 2
3004  h2l[next_index++] = ( n+1)*degree; // 3
3005  h2l[next_index++] = (n*n )*degree; // 4
3006  h2l[next_index++] = (n*n +1)*degree; // 5
3007  h2l[next_index++] = (n*n+n )*degree; // 6
3008  h2l[next_index++] = (n*n+n+1)*degree; // 7
3009 
3010  // line 0
3011  for (unsigned int i=0; i<dofs_per_line; ++i)
3012  h2l[next_index++] = (i+1)*n;
3013  // line 1
3014  for (unsigned int i=0; i<dofs_per_line; ++i)
3015  h2l[next_index++] = n-1+(i+1)*n;
3016  // line 2
3017  for (unsigned int i=0; i<dofs_per_line; ++i)
3018  h2l[next_index++] = 1+i;
3019  // line 3
3020  for (unsigned int i=0; i<dofs_per_line; ++i)
3021  h2l[next_index++] = 1+i+n*(n-1);
3022 
3023  // line 4
3024  for (unsigned int i=0; i<dofs_per_line; ++i)
3025  h2l[next_index++] = (n-1)*n*n+(i+1)*n;
3026  // line 5
3027  for (unsigned int i=0; i<dofs_per_line; ++i)
3028  h2l[next_index++] = (n-1)*(n*n+1)+(i+1)*n;
3029  // line 6
3030  for (unsigned int i=0; i<dofs_per_line; ++i)
3031  h2l[next_index++] = n*n*(n-1)+i+1;
3032  // line 7
3033  for (unsigned int i=0; i<dofs_per_line; ++i)
3034  h2l[next_index++] = n*n*(n-1)+i+1+n*(n-1);
3035 
3036  // line 8
3037  for (unsigned int i=0; i<dofs_per_line; ++i)
3038  h2l[next_index++] = (i+1)*n*n;
3039  // line 9
3040  for (unsigned int i=0; i<dofs_per_line; ++i)
3041  h2l[next_index++] = n-1+(i+1)*n*n;
3042  // line 10
3043  for (unsigned int i=0; i<dofs_per_line; ++i)
3044  h2l[next_index++] = (i+1)*n*n+n*(n-1);
3045  // line 11
3046  for (unsigned int i=0; i<dofs_per_line; ++i)
3047  h2l[next_index++] = n-1+(i+1)*n*n+n*(n-1);
3048 
3049 
3050  // inside quads
3051  // face 0
3052  for (unsigned int i=0; i<dofs_per_line; ++i)
3053  for (unsigned int j=0; j<dofs_per_line; ++j)
3054  h2l[next_index++] = (i+1)*n*n+n*(j+1);
3055  // face 1
3056  for (unsigned int i=0; i<dofs_per_line; ++i)
3057  for (unsigned int j=0; j<dofs_per_line; ++j)
3058  h2l[next_index++] = (i+1)*n*n+n-1+n*(j+1);
3059  // face 2, note the orientation!
3060  for (unsigned int i=0; i<dofs_per_line; ++i)
3061  for (unsigned int j=0; j<dofs_per_line; ++j)
3062  h2l[next_index++] = (j+1)*n*n+i+1;
3063  // face 3, note the orientation!
3064  for (unsigned int i=0; i<dofs_per_line; ++i)
3065  for (unsigned int j=0; j<dofs_per_line; ++j)
3066  h2l[next_index++] = (j+1)*n*n+n*(n-1)+i+1;
3067  // face 4
3068  for (unsigned int i=0; i<dofs_per_line; ++i)
3069  for (unsigned int j=0; j<dofs_per_line; ++j)
3070  h2l[next_index++] = n*(i+1)+j+1;
3071  // face 5
3072  for (unsigned int i=0; i<dofs_per_line; ++i)
3073  for (unsigned int j=0; j<dofs_per_line; ++j)
3074  h2l[next_index++] = (n-1)*n*n+n*(i+1)+j+1;
3075 
3076  // inside hex
3077  for (unsigned int i=0; i<dofs_per_line; ++i)
3078  for (unsigned int j=0; j<dofs_per_line; ++j)
3079  for (unsigned int k=0; k<dofs_per_line; ++k)
3080  h2l[next_index++] = n*n*(i+1)+n*(j+1)+k+1;
3081 
3082  Assert (next_index == dofs_per_cell, ExcInternalError());
3083 
3084  break;
3085  }
3086 
3087  default:
3088  Assert (false, ExcNotImplemented());
3089  }
3090  }
3091 
3092 
3093 
3094  template <int dim>
3095  void
3097  std::vector<unsigned int> &h2l)
3098  {
3099  Assert (h2l.size() == fe.dofs_per_cell,
3100  ExcDimensionMismatch (h2l.size(), fe.dofs_per_cell));
3101  hierarchic_to_lexicographic_numbering<dim> (fe.dofs_per_line+1, h2l);
3102  }
3103 
3104 
3105 
3106  template <int dim>
3107  std::vector<unsigned int>
3109  {
3110  Assert (fe.n_components() == 1, ExcInvalidFE());
3111  std::vector<unsigned int> h2l(fe.dofs_per_cell);
3112  hierarchic_to_lexicographic_numbering<dim> (fe.dofs_per_line+1, h2l);
3113  return (h2l);
3114  }
3115 
3116 
3117 
3118  template <int dim>
3119  void
3121  std::vector<unsigned int> &l2h)
3122  {
3124  }
3125 
3126 
3127 
3128  template <int dim>
3129  std::vector<unsigned int>
3131  {
3133  }
3134 
3135 } // end of namespace FETools
3136 
3137 
3138 
3139 /*-------------- Explicit Instantiations -------------------------------*/
3140 #include "fe_tools.inst"
3141 
3142 
3143 /*---------------------------- fe_tools.cc ---------------------------*/
3144 
3145 DEAL_II_NAMESPACE_CLOSE
Transformed quadrature weights.
Shape function values.
size_type m() const
Definition: tria.h:67
static const unsigned int invalid_unsigned_int
Definition: types.h:170
static ::ExceptionBase & ExcLeastSquaresError(double arg1)
void compute_interpolation_to_quadrature_points_matrix(const FiniteElement< dim, spacedim > &fe, const Quadrature< dim > &quadrature, FullMatrix< double > &I_q)
Definition: fe_tools.cc:2719
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1146
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
void compute_component_wise(const FiniteElement< dim, spacedim > &fe, std::vector< unsigned int > &renumbering, std::vector< std::vector< unsigned int > > &start_indices)
Definition: fe_tools.cc:1325
virtual double shape_value_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
Definition: fe.cc:174
void compute_block_renumbering(const FiniteElement< dim, spacedim > &fe, std::vector< types::global_dof_index > &renumbering, std::vector< types::global_dof_index > &block_data, bool return_start_indices=true)
Definition: fe_tools.cc:1367
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
virtual void get_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
Definition: fe.cc:850
void gauss_jordan()
const std::vector< Point< dim > > & get_generalized_support_points() const
Definition: fe.cc:980
static unsigned int face_to_cell_vertices(const unsigned int face, const unsigned int vertex, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
FiniteElement< dim, dim > * get_fe_from_name(const std::string &name) 1
Definition: fe_tools.cc:2580
Definition: fe_dgq.h:105
std::string trim(const std::string &input)
Definition: utilities.cc:134
void compute_face_embedding_matrices(const FiniteElement< dim, spacedim > &fe, FullMatrix< number >(&matrices)[GeometryInfo< dim >::max_children_per_face], const unsigned int face_coarse, const unsigned int face_fine, const double threshold=1.e-12)
Definition: fe_tools.cc:1920
const unsigned int dofs_per_quad
Definition: fe_base.h:250
static TableIndices< rank > unrolled_to_component_indices(const unsigned int i)
std::pair< int, unsigned int > get_integer_at_position(const std::string &name, const unsigned int position)
Definition: utilities.cc:409
void build_face_tables(std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > &face_system_to_base_table, std::vector< std::pair< unsigned int, unsigned int > > &face_system_to_component_table, const FiniteElement< dim, spacedim > &finite_element, const bool do_tensor_product=true)
Definition: fe_tools.cc:776
void hierarchic_to_lexicographic_numbering(unsigned int degree, std::vector< unsigned int > &h2l)
Definition: fe_tools.cc:2928
const unsigned int degree
Definition: fe_base.h:311
const Point< dim > & point(const unsigned int i) const
bool has_generalized_support_points() const
Definition: fe.cc:995
std::vector< ComponentMask > compute_nonzero_components(const std::vector< const FiniteElement< dim, spacedim > *> &fes, const std::vector< unsigned int > &multiplicities, const bool do_tensor_product=true)
Definition: fe_tools.cc:351
ActiveSelector::active_cell_iterator active_cell_iterator
Definition: dof_handler.h:228
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: tria.cc:10668
void compute_embedding_matrices(const FiniteElement< dim, spacedim > &fe, std::vector< std::vector< FullMatrix< number > > > &matrices, const bool isotropic_only=false, const double threshold=1.e-12)
Definition: fe_tools.cc:1897
Transformed quadrature points.
static ::ExceptionBase & ExcNotInitialized()
#define AssertThrow(cond, exc)
Definition: exceptions.h:369
bool is_primitive() const
Definition: fe.h:3034
const unsigned int dofs_per_line
Definition: fe_base.h:244
cell_iterator begin(const unsigned int level=0) const
Definition: tria.cc:10648
Definition: fe_bdm.h:56
virtual void convert_generalized_support_point_values_to_nodal_values(const std::vector< Vector< double > > &support_point_values, std::vector< double > &nodal_values) const
Definition: fe.cc:1103
double shape_value_component(const unsigned int function_no, const unsigned int point_no, const unsigned int component) const
static ::ExceptionBase & ExcFENotPrimitive()
bool is_finite(const double x)
Definition: numbers.h:275
unsigned int n_blocks() const
void get_projection_matrix(const FiniteElement< dim, spacedim > &fe1, const FiniteElement< dim, spacedim > &fe2, FullMatrix< number > &matrix)
Definition: fe_tools.cc:1531
Definition: fe_abf.h:101
cell_iterator end() const
Definition: tria.cc:10736
const std::vector< Point< spacedim > > & get_quadrature_points() const
virtual void execute_coarsening_and_refinement()
Definition: tria.cc:11899
Definition: fe_dgp.h:309
static ::ExceptionBase & ExcMatrixDimensionMismatch(int arg1, int arg2, int arg3, int arg4)
static ::ExceptionBase & ExcMessage(std::string arg1)
Definition: fe_q.h:552
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
const unsigned int first_quad_index
Definition: fe_base.h:266
size_type n() const
void get_interpolation_matrix(const FiniteElement< dim, spacedim > &fe1, const FiniteElement< dim, spacedim > &fe2, FullMatrix< number > &interpolation_matrix)
Definition: fe_tools.cc:1415
const double & shape_value(const unsigned int function_no, const unsigned int point_no) const
static ::ExceptionBase & ExcNotGreaterThan(int arg1, int arg2)
void invert(const FullMatrix< number2 > &M)
void compute_projection_from_face_quadrature_points_matrix(const FiniteElement< dim, spacedim > &fe, const Quadrature< dim-1 > &lhs_quadrature, const Quadrature< dim-1 > &rhs_quadrature, const typename DoFHandler< dim, spacedim >::active_cell_iterator &cell, const unsigned int face, FullMatrix< double > &X)
Definition: fe_tools.cc:2868
unsigned int global_dof_index
Definition: types.h:88
static unsigned int face_to_cell_lines(const unsigned int face, const unsigned int line, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
void reinit(const TableIndices< N > &new_size, const bool omit_default_initialization=false)
#define Assert(cond, exc)
Definition: exceptions.h:313
unsigned int element_multiplicity(const unsigned int index) const
Definition: fe.h:2863
UpdateFlags
static void project_to_subface(const SubQuadrature &quadrature, const unsigned int face_no, const unsigned int subface_no, std::vector< Point< dim > > &q_points, const RefinementCase< dim-1 > &ref_case=RefinementCase< dim-1 >::isotropic_refinement)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access > > &cell, const unsigned int face_no)
Definition: fe_values.cc:3927
Definition: fe.h:33
void compute_projection_from_quadrature_points_matrix(const FiniteElement< dim, spacedim > &fe, const Quadrature< dim > &lhs_quadrature, const Quadrature< dim > &rhs_quadrature, FullMatrix< double > &X)
Definition: fe_tools.cc:2679
void get_back_interpolation_matrix(const FiniteElement< dim, spacedim > &fe1, const FiniteElement< dim, spacedim > &fe2, FullMatrix< number > &interpolation_matrix)
Definition: fe_tools.cc:1479
void compute_projection_from_quadrature_points(const FullMatrix< double > &projection_matrix, const std::vector< Tensor< 1, dim > > &vector_of_tensors_at_qp, std::vector< Tensor< 1, dim > > &vector_of_tensors_at_nodes)
Definition: fe_tools.cc:2737
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
Definition: fe.cc:1251
virtual ~FEFactoryBase()
Definition: fe_tools.cc:1319
FiniteElementData< dim > multiply_dof_numbers(const std::vector< const FiniteElement< dim, spacedim > *> &fes, const std::vector< unsigned int > &multiplicities, const bool do_tensor_product=true)
Definition: fe_tools.cc:73
std::vector< unsigned int > invert_permutation(const std::vector< unsigned int > &permutation)
Definition: utilities.cc:486
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
virtual FiniteElement< FE::dimension, FE::space_dimension > * get(const unsigned int degree) const
std::vector< bool > compute_restriction_is_additive_flags(const std::vector< const FiniteElement< dim, spacedim > *> &fes, const std::vector< unsigned int > &multiplicities)
Definition: fe_tools.cc:189
unsigned int size() const
const unsigned int dofs_per_cell
Definition: fe_base.h:295
static ::ExceptionBase & ExcInvalidFEDimension(char arg1, int arg2)
void lexicographic_to_hierarchic_numbering(const FiniteElementData< dim > &fe_data, std::vector< unsigned int > &l2h)
Definition: fe_tools.cc:3120
static ::ExceptionBase & ExcInvalidFE()
const unsigned int n_quadrature_points
Definition: fe_values.h:1452
void mmult(FullMatrix< number2 > &C, const FullMatrix< number2 > &B, const bool adding=false) const
const std::vector< Point< dim > > & get_unit_support_points() const
Definition: fe.cc:955
FullMatrix< double > compute_node_matrix(const FiniteElement< dim, spacedim > &fe)
Definition: fe_tools.cc:1616
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
Definition: fe.h:2839
void add_fe_name(const std::string &name, const FEFactoryBase< dim, spacedim > *factory)
Definition: fe_tools.cc:2283
virtual double shape_value(const unsigned int i, const Point< dim > &p) const
Definition: fe.cc:163
unsigned int n_components() const
std::pair< std::pair< unsigned int, unsigned int >, unsigned int > system_to_base_index(const unsigned int index) const
Definition: fe.h:2924
const std::vector< double > & get_JxW_values() const
std::pair< unsigned int, types::global_dof_index > system_to_block_index(const unsigned int component) const
Definition: fe.h:2982
double JxW(const unsigned int quadrature_point) const
static void project_to_face(const SubQuadrature &quadrature, const unsigned int face_no, std::vector< Point< dim > > &q_points)
bool conforms(const Conformity) const
void build_cell_tables(std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > &system_to_base_table, std::vector< std::pair< unsigned int, unsigned int > > &system_to_component_table, std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > &component_to_base_table, const FiniteElement< dim, spacedim > &finite_element, const bool do_tensor_product=true)
Definition: fe_tools.cc:581
void get_interpolation_difference_matrix(const FiniteElement< dim, spacedim > &fe1, const FiniteElement< dim, spacedim > &fe2, FullMatrix< number > &difference_matrix)
Definition: fe_tools.cc:1505
void add(const number a, const FullMatrix< number2 > &A)
const Conformity conforming_space
Definition: fe_base.h:316
static ::ExceptionBase & ExcInvalidFEName(std::string arg1)
void hyper_cube(Triangulation< dim, spacedim > &tria, const double left=0., const double right=1., const bool colorize=false)
void push_back(const size_type size)
const unsigned int dofs_per_face
Definition: fe_base.h:288
const unsigned int first_line_index
Definition: fe_base.h:261
double least_squares(Vector< number2 > &dst, const Vector< number2 > &src) const
void refine_global(const unsigned int times=1)
Definition: tria.cc:9608
void compute_projection_matrices(const FiniteElement< dim, spacedim > &fe, std::vector< std::vector< FullMatrix< number > > > &matrices, const bool isotropic_only=false)
Definition: fe_tools.cc:2123
static ::ExceptionBase & ExcNotImplemented()
const unsigned int dofs_per_vertex
Definition: fe_base.h:238
FiniteElement< dim, spacedim > * get_fe_by_name(const std::string &name)
Definition: fe_tools.cc:2589
unsigned int size(const unsigned int i) const
unsigned int n_base_elements() const
Definition: fe.h:2853
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access > > &cell)
Definition: fe_values.cc:3729
double weight(const unsigned int i) const
Task< RT > new_task(const std_cxx11::function< RT()> &function)
unsigned int tensor_degree() const
static ::ExceptionBase & ExcInternalError()