Loading [MathJax]/extensions/TeX/AMSsymbols.js
 deal.II version GIT relicensing-3083-g7b89508ac7 2025-04-18 12:50:00+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
fe.cc
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 1998 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
18
20
21#include <deal.II/fe/fe.h>
23#include <deal.II/fe/mapping.h>
24
25#include <deal.II/grid/tria.h>
28
29#include <algorithm>
30#include <functional>
31#include <numeric>
32#include <typeinfo>
33
35
36
37/*------------------------------- FiniteElement ----------------------*/
38#ifndef DOXYGEN
39
40template <int dim, int spacedim>
42 : update_each(update_default)
43{}
44
45
46
47template <int dim, int spacedim>
48std::size_t
50{
51 return sizeof(*this);
52}
53
54
55
56template <int dim, int spacedim>
58 const FiniteElementData<dim> &fe_data,
59 const std::vector<bool> &r_i_a_f,
60 const std::vector<ComponentMask> &nonzero_c)
61 : FiniteElementData<dim>(fe_data)
65 std::make_pair(std::make_pair(0U, 0U), 0U))
66 ,
67
68 // Special handling of vectors of length one: in this case, we
69 // assume that all entries were supposed to be equal
71 r_i_a_f.size() == 1 ?
72 std::vector<bool>(fe_data.n_dofs_per_cell(), r_i_a_f[0]) :
73 r_i_a_f)
75 nonzero_c.size() == 1 ?
76 std::vector<ComponentMask>(fe_data.n_dofs_per_cell(), nonzero_c[0]) :
77 nonzero_c)
81 [](const unsigned int n_components) {
82 return n_components != 1U;
83 }) == n_nonzero_components_table.end())
84{
85 Assert(restriction_is_additive_flags.size() == this->n_dofs_per_cell(),
86 ExcDimensionMismatch(restriction_is_additive_flags.size(),
87 this->n_dofs_per_cell()));
88 AssertDimension(nonzero_components.size(), this->n_dofs_per_cell());
89 for (unsigned int i = 0; i < nonzero_components.size(); ++i)
90 {
91 Assert(nonzero_components[i].size() == this->n_components(),
93 Assert(nonzero_components[i].n_selected_components() >= 1,
95 Assert(n_nonzero_components_table[i] >= 1, ExcInternalError());
96 Assert(n_nonzero_components_table[i] <= this->n_components(),
98 }
99
100 // initialize some tables in the default way, i.e. if there is only one
101 // (vector-)component; if the element is not primitive, leave these tables
102 // empty.
103 if (this->is_primitive())
104 {
105 system_to_component_table.resize(this->n_dofs_per_cell());
106 for (unsigned int j = 0; j < this->n_dofs_per_cell(); ++j)
107 system_to_component_table[j] = std::pair<unsigned, unsigned>(0, j);
108
109 face_system_to_component_table.resize(this->n_unique_faces());
110 for (unsigned int f = 0; f < this->n_unique_faces(); ++f)
111 {
112 face_system_to_component_table[f].resize(this->n_dofs_per_face(f));
113 for (unsigned int j = 0; j < this->n_dofs_per_face(f); ++j)
114 face_system_to_component_table[f][j] =
115 std::pair<unsigned, unsigned>(0, j);
116 }
117 }
118
119 for (unsigned int j = 0; j < this->n_dofs_per_cell(); ++j)
120 system_to_base_table[j] = std::make_pair(std::make_pair(0U, 0U), j);
121
122 face_system_to_base_table.resize(this->n_unique_faces());
123 for (unsigned int f = 0; f < this->n_unique_faces(); ++f)
124 {
125 face_system_to_base_table[f].resize(this->n_dofs_per_face(f));
126 for (unsigned int j = 0; j < this->n_dofs_per_face(f); ++j)
127 face_system_to_base_table[f][j] =
128 std::make_pair(std::make_pair(0U, 0U), j);
129 }
130
131 // Fill with default value; may be changed by constructor of derived class.
132 base_to_block_indices.reinit(1, 1);
133
134 // initialize the restriction and prolongation matrices. the default
135 // constructor of FullMatrix<dim> initializes them with size zero
138 for (const unsigned int ref_case :
139 RefinementCase<dim>::all_refinement_cases())
140 if (ref_case != RefinementCase<dim>::no_refinement)
141 {
142 prolongation[ref_case - 1].resize(this->reference_cell().n_children(
143 RefinementCase<dim>(ref_case)),
145 restriction[ref_case - 1].resize(this->reference_cell().n_children(
146 RefinementCase<dim>(ref_case)),
148 }
149
150
151 if (dim == 3)
152 {
153 adjust_quad_dof_index_for_face_orientation_table.resize(
154 this->n_unique_2d_subobjects());
155
156 for (unsigned int f = 0; f < this->n_unique_2d_subobjects(); ++f)
157 {
158 adjust_quad_dof_index_for_face_orientation_table[f] =
159 Table<2, int>(this->n_dofs_per_quad(f),
160 this->reference_cell().n_face_orientations(f));
161 adjust_quad_dof_index_for_face_orientation_table[f].fill(0);
162 }
163 }
164
165 unit_face_support_points.resize(this->n_unique_faces());
166 generalized_face_support_points.resize(this->n_unique_faces());
167}
168
169
170
171template <int dim, int spacedim>
172std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>
173FiniteElement<dim, spacedim>::operator^(const unsigned int multiplicity) const
174{
175 return {this->clone(), multiplicity};
176}
177
178
179
180template <int dim, int spacedim>
181double
183 const Point<dim> &) const
184{
185 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
186 return 0.;
187}
188
189
190
191template <int dim, int spacedim>
192double
194 const Point<dim> &,
195 const unsigned int) const
196{
197 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
198 return 0.;
199}
200
201
202
203template <int dim, int spacedim>
206 const Point<dim> &) const
207{
208 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
209 return Tensor<1, dim>();
210}
211
212
213
214template <int dim, int spacedim>
217 const Point<dim> &,
218 const unsigned int) const
219{
220 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
221 return Tensor<1, dim>();
222}
223
224
225
226template <int dim, int spacedim>
229 const Point<dim> &) const
230{
231 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
232 return Tensor<2, dim>();
233}
234
235
236
237template <int dim, int spacedim>
240 const unsigned int,
241 const Point<dim> &,
242 const unsigned int) const
243{
244 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
245 return Tensor<2, dim>();
246}
247
248
249
250template <int dim, int spacedim>
253 const Point<dim> &) const
254{
255 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
256 return Tensor<3, dim>();
257}
258
259
260
261template <int dim, int spacedim>
264 const unsigned int,
265 const Point<dim> &,
266 const unsigned int) const
267{
268 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
269 return Tensor<3, dim>();
270}
271
272
273
274template <int dim, int spacedim>
277 const Point<dim> &) const
278{
279 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
280 return Tensor<4, dim>();
281}
282
283
284
285template <int dim, int spacedim>
288 const unsigned int,
289 const Point<dim> &,
290 const unsigned int) const
291{
292 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
293 return Tensor<4, dim>();
294}
295
296
297template <int dim, int spacedim>
298void
300 const bool isotropic_restriction_only,
301 const bool isotropic_prolongation_only)
302{
303 for (const unsigned int ref_case :
304 RefinementCase<dim>::all_refinement_cases())
305 if (ref_case != RefinementCase<dim>::no_refinement)
306 {
307 const unsigned int nc =
308 this->reference_cell().n_children(RefinementCase<dim>(ref_case));
309
310 for (unsigned int i = 0; i < nc; ++i)
311 {
312 if (this->restriction[ref_case - 1][i].m() !=
313 this->n_dofs_per_cell() &&
314 (!isotropic_restriction_only ||
316 this->restriction[ref_case - 1][i].reinit(
317 this->n_dofs_per_cell(), this->n_dofs_per_cell());
318 if (this->prolongation[ref_case - 1][i].m() !=
319 this->n_dofs_per_cell() &&
320 (!isotropic_prolongation_only ||
322 this->prolongation[ref_case - 1][i].reinit(
323 this->n_dofs_per_cell(), this->n_dofs_per_cell());
324 }
325 }
326}
327
328
329template <int dim, int spacedim>
330const FullMatrix<double> &
332 const unsigned int child,
333 const RefinementCase<dim> &refinement_case) const
334{
335 AssertIndexRange(refinement_case,
339 "Restriction matrices are only available for refined cells!"));
340 AssertIndexRange(child,
341 this->reference_cell().n_children(
342 RefinementCase<dim>(refinement_case)));
343 // we use refinement_case-1 here. the -1 takes care of the origin of the
344 // vector, as for RefinementCase<dim>::no_refinement (=0) there is no data
345 // available and so the vector indices are shifted
346 Assert(restriction[refinement_case - 1][child].n() == this->n_dofs_per_cell(),
347 ExcProjectionVoid());
348 return restriction[refinement_case - 1][child];
349}
350
351
352
353template <int dim, int spacedim>
354const FullMatrix<double> &
356 const unsigned int child,
357 const RefinementCase<dim> &refinement_case) const
358{
359 AssertIndexRange(refinement_case,
363 "Prolongation matrices are only available for refined cells!"));
364 AssertIndexRange(child,
365 this->reference_cell().n_children(
366 RefinementCase<dim>(refinement_case)));
367 // we use refinement_case-1 here. the -1 takes care
368 // of the origin of the vector, as for
369 // RefinementCase::no_refinement (=0) there is no
370 // data available and so the vector indices
371 // are shifted
372 Assert(prolongation[refinement_case - 1][child].n() ==
373 this->n_dofs_per_cell(),
374 ExcEmbeddingVoid());
375 return prolongation[refinement_case - 1][child];
376}
377
378
379// TODO:[GK] This is probably not the most efficient way of doing this.
380template <int dim, int spacedim>
381unsigned int
383 const unsigned int index) const
384{
385 AssertIndexRange(index, this->n_components());
386
387 return first_block_of_base(component_to_base_table[index].first.first) +
388 component_to_base_table[index].second;
389}
390
391
392template <int dim, int spacedim>
395 const FEValuesExtractors::Scalar &scalar) const
396{
397 AssertIndexRange(scalar.component, this->n_components());
398
399 // TODO: it would be nice to verify that it is indeed possible
400 // to select this scalar component, i.e., that it is not part
401 // of a non-primitive element. unfortunately, there is no simple
402 // way to write such a condition...
403
404 std::vector<bool> mask(this->n_components(), false);
405 mask[scalar.component] = true;
406 return ComponentMask(mask);
407}
408
409
410template <int dim, int spacedim>
413 const FEValuesExtractors::Vector &vector) const
414{
416 this->n_components());
417
418 // TODO: it would be nice to verify that it is indeed possible
419 // to select these vector components, i.e., that they don't span
420 // beyond the beginning or end of anon-primitive element.
421 // unfortunately, there is no simple way to write such a condition...
422
423 std::vector<bool> mask(this->n_components(), false);
424 for (unsigned int c = vector.first_vector_component;
425 c < vector.first_vector_component + dim;
426 ++c)
427 mask[c] = true;
428 return ComponentMask(mask);
429}
430
431
432template <int dim, int spacedim>
435 const FEValuesExtractors::SymmetricTensor<2> &sym_tensor) const
436{
439 this->n_components());
440
441 // TODO: it would be nice to verify that it is indeed possible
442 // to select these vector components, i.e., that they don't span
443 // beyond the beginning or end of anon-primitive element.
444 // unfortunately, there is no simple way to write such a condition...
445
446 std::vector<bool> mask(this->n_components(), false);
447 for (unsigned int c = sym_tensor.first_tensor_component;
448 c < sym_tensor.first_tensor_component +
450 ++c)
451 mask[c] = true;
452 return ComponentMask(mask);
453}
454
455
456
457template <int dim, int spacedim>
460{
461 // if we get a block mask that represents all blocks, then
462 // do the same for the returned component mask
463 if (block_mask.represents_the_all_selected_mask())
464 return {};
465
466 AssertDimension(block_mask.size(), this->n_blocks());
467
468 std::vector<bool> component_mask(this->n_components(), false);
469 for (unsigned int c = 0; c < this->n_components(); ++c)
470 if (block_mask[component_to_block_index(c)] == true)
471 component_mask[c] = true;
472
473 return ComponentMask(component_mask);
474}
475
476
477
478template <int dim, int spacedim>
481 const FEValuesExtractors::Scalar &scalar) const
482{
483 // simply create the corresponding component mask (a simpler
484 // process) and then convert it to a block mask
485 return block_mask(component_mask(scalar));
486}
487
488
489template <int dim, int spacedim>
492 const FEValuesExtractors::Vector &vector) const
493{
494 // simply create the corresponding component mask (a simpler
495 // process) and then convert it to a block mask
496 return block_mask(component_mask(vector));
497}
498
499
500template <int dim, int spacedim>
503 const FEValuesExtractors::SymmetricTensor<2> &sym_tensor) const
504{
505 // simply create the corresponding component mask (a simpler
506 // process) and then convert it to a block mask
507 return block_mask(component_mask(sym_tensor));
508}
509
510
511
512template <int dim, int spacedim>
515 const ComponentMask &component_mask) const
516{
517 // if we get a component mask that represents all component, then
518 // do the same for the returned block mask
519 if (component_mask.represents_the_all_selected_mask())
520 return {};
521
522 AssertDimension(component_mask.size(), this->n_components());
523
524 // walk over all of the components
525 // of this finite element and see
526 // if we need to set the
527 // corresponding block. inside the
528 // block, walk over all the
529 // components that correspond to
530 // this block and make sure the
531 // component mask is set for all of
532 // them
533 std::vector<bool> block_mask(this->n_blocks(), false);
534 for (unsigned int c = 0; c < this->n_components();)
535 {
536 const unsigned int block = component_to_block_index(c);
537 if (component_mask[c] == true)
538 block_mask[block] = true;
539
540 // now check all of the other
541 // components that correspond
542 // to this block
543 ++c;
544 while ((c < this->n_components()) &&
545 (component_to_block_index(c) == block))
546 {
547 Assert(component_mask[c] == block_mask[block],
549 "The component mask argument given to this function "
550 "is not a mask where the individual components belonging "
551 "to one block of the finite element are either all "
552 "selected or not selected. You can't call this function "
553 "with a component mask that splits blocks."));
554 ++c;
555 }
556 }
557
558
559 return BlockMask(block_mask);
560}
561
562
563
564template <int dim, int spacedim>
565unsigned int
567 const unsigned int face_index,
568 const unsigned int face,
569 const types::geometric_orientation combined_orientation) const
570{
571 AssertIndexRange(face_index, this->n_dofs_per_face(face));
572 AssertIndexRange(face, this->reference_cell().n_faces());
573
574 // see the function's documentation for an explanation of this
575 // assertion -- in essence, derived classes have to implement
576 // an overloaded version of this function if we are to use any
577 // other than default (standard) orientation
578 if (combined_orientation != numbers::default_geometric_orientation)
579 Assert((this->n_dofs_per_line() <= 1) && (this->n_dofs_per_quad(face) <= 1),
581 "The function in this base class can not handle this case. "
582 "Rather, the derived class you are using must provide "
583 "an overloaded version but apparently hasn't done so. See "
584 "the documentation of this function for more information."));
585
586 // we need to distinguish between DoFs on vertices, lines and (in 3d) quads.
587 // do so in a sequence of if-else statements
588 if (face_index < this->get_first_face_line_index(face))
589 // DoF is on a vertex
590 {
591 // get the number of the vertex on the face that corresponds to this DoF,
592 // along with the number of the DoF on this vertex
593 const unsigned int face_vertex = face_index / this->n_dofs_per_vertex();
594 const unsigned int dof_index_on_vertex =
595 face_index % this->n_dofs_per_vertex();
596
597 // then get the number of this vertex on the cell and translate
598 // this to a DoF number on the cell
599 return (this->reference_cell().face_to_cell_vertices(
600 face, face_vertex, combined_orientation) *
601 this->n_dofs_per_vertex() +
602 dof_index_on_vertex);
603 }
604 else if (face_index < this->get_first_face_quad_index(face))
605 // DoF is on a face
606 {
607 // do the same kind of translation as before. we need to only consider
608 // DoFs on the lines, i.e., ignoring those on the vertices
609 const unsigned int index =
610 face_index - this->get_first_face_line_index(face);
611
612 const unsigned int face_line = index / this->n_dofs_per_line();
613 const unsigned int dof_index_on_line = index % this->n_dofs_per_line();
614
615 return (this->get_first_line_index() +
616 this->reference_cell().face_to_cell_lines(face,
617 face_line,
618 combined_orientation) *
619 this->n_dofs_per_line() +
620 dof_index_on_line);
621 }
622 else
623 // DoF is on a quad
624 {
625 Assert(dim >= 3, ExcInternalError());
626
627 // ignore vertex and line dofs
628 const unsigned int index =
629 face_index - this->get_first_face_quad_index(face);
630
631 return (this->get_first_quad_index(face) + index);
632 }
633}
634
635
636
637template <int dim, int spacedim>
638unsigned int
640 const unsigned int index,
641 const unsigned int face,
642 const types::geometric_orientation combined_orientation) const
643{
644 // general template for 1d and 2d: not
645 // implemented. in fact, the function
646 // shouldn't even be called unless we are
647 // in 3d, so throw an internal error
648 Assert(dim == 3, ExcInternalError());
649 if (dim < 3)
650 return index;
651
652 // adjust dofs on 3d faces if the face is
653 // flipped. note that we query a table that
654 // derived elements need to have set up
655 // front. the exception are discontinuous
656 // elements for which there should be no
657 // face dofs anyway (i.e. dofs_per_quad==0
658 // in 3d), so we don't need the table, but
659 // the function should also not have been
660 // called
661 AssertIndexRange(index, this->n_dofs_per_quad(face));
662 const auto table_n = this->n_unique_2d_subobjects() == 1 ? 0 : face;
663 Assert(
664 adjust_quad_dof_index_for_face_orientation_table[table_n].n_elements() ==
665 (this->reference_cell().n_face_orientations(face)) *
666 this->n_dofs_per_quad(face),
668 return index + adjust_quad_dof_index_for_face_orientation_table[table_n](
669 index, combined_orientation);
670}
671
672
673
674template <int dim, int spacedim>
675unsigned int
677 const unsigned int index,
678 const types::geometric_orientation combined_orientation) const
679{
680 Assert(combined_orientation == numbers::default_geometric_orientation ||
681 combined_orientation == numbers::reverse_line_orientation,
683
684 AssertIndexRange(index, this->n_dofs_per_line());
685 Assert(adjust_line_dof_index_for_line_orientation_table.size() ==
686 this->n_dofs_per_line(),
688 if (combined_orientation == numbers::default_geometric_orientation)
689 return index;
690 else
691 return index + adjust_line_dof_index_for_line_orientation_table[index];
692}
693
694
695
696template <int dim, int spacedim>
697bool
699{
700 for (const unsigned int ref_case :
701 RefinementCase<dim>::all_refinement_cases())
702 if (ref_case != RefinementCase<dim>::no_refinement)
703 for (unsigned int c = 0;
704 c < this->reference_cell().n_children(RefinementCase<dim>(ref_case));
705 ++c)
706 {
707 // make sure also the lazily initialized matrices are created
708 get_prolongation_matrix(c, RefinementCase<dim>(ref_case));
709 Assert((prolongation[ref_case - 1][c].m() ==
710 this->n_dofs_per_cell()) ||
711 (prolongation[ref_case - 1][c].m() == 0),
713 Assert((prolongation[ref_case - 1][c].n() ==
714 this->n_dofs_per_cell()) ||
715 (prolongation[ref_case - 1][c].n() == 0),
717 if ((prolongation[ref_case - 1][c].m() == 0) ||
718 (prolongation[ref_case - 1][c].n() == 0))
719 return false;
720 }
721 return true;
722}
723
724
725
726template <int dim, int spacedim>
727bool
729{
730 for (const unsigned int ref_case :
731 RefinementCase<dim>::all_refinement_cases())
732 if (ref_case != RefinementCase<dim>::no_refinement)
733 for (unsigned int c = 0;
734 c < this->reference_cell().n_children(RefinementCase<dim>(ref_case));
735 ++c)
736 {
737 // make sure also the lazily initialized matrices are created
738 get_restriction_matrix(c, RefinementCase<dim>(ref_case));
739 Assert((restriction[ref_case - 1][c].m() ==
740 this->n_dofs_per_cell()) ||
741 (restriction[ref_case - 1][c].m() == 0),
743 Assert((restriction[ref_case - 1][c].n() ==
744 this->n_dofs_per_cell()) ||
745 (restriction[ref_case - 1][c].n() == 0),
747 if ((restriction[ref_case - 1][c].m() == 0) ||
748 (restriction[ref_case - 1][c].n() == 0))
749 return false;
750 }
751 return true;
752}
753
754
755
756template <int dim, int spacedim>
757bool
759{
760 const RefinementCase<dim> ref_case =
762
763 for (unsigned int c = 0;
764 c < this->reference_cell().n_children(RefinementCase<dim>(ref_case));
765 ++c)
766 {
767 // make sure also the lazily initialized matrices are created
768 get_prolongation_matrix(c, RefinementCase<dim>(ref_case));
769 Assert((prolongation[ref_case - 1][c].m() == this->n_dofs_per_cell()) ||
770 (prolongation[ref_case - 1][c].m() == 0),
772 Assert((prolongation[ref_case - 1][c].n() == this->n_dofs_per_cell()) ||
773 (prolongation[ref_case - 1][c].n() == 0),
775 if ((prolongation[ref_case - 1][c].m() == 0) ||
776 (prolongation[ref_case - 1][c].n() == 0))
777 return false;
778 }
779 return true;
780}
781
782
783
784template <int dim, int spacedim>
785bool
787{
788 const RefinementCase<dim> ref_case =
790
791 for (unsigned int c = 0;
792 c < this->reference_cell().n_children(RefinementCase<dim>(ref_case));
793 ++c)
794 {
795 // make sure also the lazily initialized matrices are created
796 get_restriction_matrix(c, RefinementCase<dim>(ref_case));
797 Assert((restriction[ref_case - 1][c].m() == this->n_dofs_per_cell()) ||
798 (restriction[ref_case - 1][c].m() == 0),
800 Assert((restriction[ref_case - 1][c].n() == this->n_dofs_per_cell()) ||
801 (restriction[ref_case - 1][c].n() == 0),
803 if ((restriction[ref_case - 1][c].m() == 0) ||
804 (restriction[ref_case - 1][c].n() == 0))
805 return false;
806 }
807 return true;
808}
809
810
811
812template <int dim, int spacedim>
813bool
815 const internal::SubfaceCase<dim> &subface_case) const
816{
818 {
819 unsigned int n_dofs_on_faces = 0;
820
821 for (const auto face_no : this->reference_cell().face_indices())
822 n_dofs_on_faces += this->n_dofs_per_face(face_no);
823
824 return (n_dofs_on_faces == 0) || (interface_constraints.m() != 0);
825 }
826 else
827 return false;
828}
829
830
831
832template <int dim, int spacedim>
833bool
835{
836 return false;
837}
838
839
840
841template <int dim, int spacedim>
842const FullMatrix<double> &
844 const internal::SubfaceCase<dim> &subface_case) const
845{
846 // TODO: the implementation makes the assumption that all faces have the
847 // same number of dofs
848 AssertDimension(this->n_unique_faces(), 1);
849 [[maybe_unused]] const unsigned int face_no = 0;
850
852 ExcMessage("Constraints for this element are only implemented "
853 "for the case that faces are refined isotropically "
854 "(which is always the case in 2d, and in 3d requires "
855 "that the neighboring cell of a coarse cell presents "
856 "exactly four children on the common face)."));
857 Assert((this->n_dofs_per_face(face_no) == 0) ||
858 (interface_constraints.m() != 0),
859 ExcMessage("The finite element for which you try to obtain "
860 "hanging node constraints does not appear to "
861 "implement them."));
862
863 if (dim == 1)
864 Assert((interface_constraints.m() == 0) && (interface_constraints.n() == 0),
865 ExcWrongInterfaceMatrixSize(interface_constraints.m(),
866 interface_constraints.n()));
867
868 return interface_constraints;
869}
870
871
872
873template <int dim, int spacedim>
876{
877 // TODO: the implementation makes the assumption that all faces have the
878 // same number of dofs
879 AssertDimension(this->n_unique_faces(), 1);
880 const unsigned int face_no = 0;
881
882 switch (dim)
883 {
884 case 1:
885 return {0U, 0U};
886
887 case 2:
888 // We have to interpolate from the DoFs in the interior of the
889 // the two child faces (=lines) and the one central vertex
890 // to the DoFs of the parent face:
891 return {this->n_dofs_per_vertex() + 2 * this->n_dofs_per_line(),
892 this->n_dofs_per_face(face_no)};
893
894 case 3:
895 // We have to interpolate from the DoFs in the interior of the
896 // the child faces (=quads or tris) and the vertices that are
897 // not part of the parent face, to the DoFs of the parent face:
898 if (this->reference_cell().face_reference_cell(face_no) ==
900 return {
901 5 * this->n_dofs_per_vertex() + // 4 vertices at mid-edge points
902 // + 1 at cell center
903 12 * this->n_dofs_per_line() + // 4*2 children of the old edges
904 // + 2*2 edges in the cell interior
905 4 * this->n_dofs_per_quad(face_no), // 4 child faces
906 this->n_dofs_per_face(face_no)};
907 else if (this->reference_cell().face_reference_cell(face_no) ==
909 return {
910 3 * this->n_dofs_per_vertex() + // 3 vertices at mid-edge points
911 9 * this->n_dofs_per_line() + // 3*2 children of the old edges
912 // + 3 edges in the cell interior
913 4 * this->n_dofs_per_quad(face_no), // 4 child faces
914 this->n_dofs_per_face(face_no)};
915 else
917
918 default:
920 }
922}
923
924
925
926template <int dim, int spacedim>
927void
930 FullMatrix<double> &) const
931{
932 // by default, no interpolation
933 // implemented. so throw exception,
934 // as documentation says
936 false,
938}
939
940
941
942template <int dim, int spacedim>
943void
947 const unsigned int) const
948{
949 // by default, no interpolation
950 // implemented. so throw exception,
951 // as documentation says
953 false,
955}
956
957
958
959template <int dim, int spacedim>
960void
963 const unsigned int,
965 const unsigned int) const
966{
967 // by default, no interpolation
968 // implemented. so throw exception,
969 // as documentation says
971 false,
973}
974
975
976
977template <int dim, int spacedim>
978std::vector<std::pair<unsigned int, unsigned int>>
980 const FiniteElement<dim, spacedim> &) const
981{
983 return std::vector<std::pair<unsigned int, unsigned int>>();
984}
985
986
987
988template <int dim, int spacedim>
989std::vector<std::pair<unsigned int, unsigned int>>
991 const FiniteElement<dim, spacedim> &) const
992{
994 return std::vector<std::pair<unsigned int, unsigned int>>();
995}
996
997
998
999template <int dim, int spacedim>
1000std::vector<std::pair<unsigned int, unsigned int>>
1003 const unsigned int) const
1004{
1006 return std::vector<std::pair<unsigned int, unsigned int>>();
1007}
1008
1009
1010
1011template <int dim, int spacedim>
1015 const unsigned int) const
1016{
1019}
1020
1021
1022
1023template <int dim, int spacedim>
1024bool
1026 const FiniteElement<dim, spacedim> &f) const
1027{
1028 // Compare fields in roughly increasing order of how expensive the
1029 // comparison is
1030 return ((typeid(*this) == typeid(f)) && (this->get_name() == f.get_name()) &&
1031 (static_cast<const FiniteElementData<dim> &>(*this) ==
1032 static_cast<const FiniteElementData<dim> &>(f)) &&
1033 (interface_constraints == f.interface_constraints));
1034}
1035
1036
1037
1038template <int dim, int spacedim>
1039bool
1041 const FiniteElement<dim, spacedim> &f) const
1042{
1043 return !(*this == f);
1044}
1045
1046
1047
1048template <int dim, int spacedim>
1049const std::vector<Point<dim>> &
1051{
1052 // a finite element may define
1053 // support points, but only if
1054 // there are as many as there are
1055 // degrees of freedom
1056 Assert((unit_support_points.empty()) ||
1057 (unit_support_points.size() == this->n_dofs_per_cell()),
1059 return unit_support_points;
1060}
1061
1062
1063
1064template <int dim, int spacedim>
1065bool
1067{
1068 if (this->dofs_per_cell > 0)
1069 return (unit_support_points.size() != 0);
1070 else
1071 {
1072 // If the FE has no DoFs, we shouldn't expect the array
1073 // size to be anything other than zero:
1075
1076 // A finite element without DoFs *has* support points
1077 // (which is then an empty array)
1078 return true;
1079 }
1080}
1081
1082
1083
1084template <int dim, int spacedim>
1085const std::vector<Point<dim>> &
1087{
1088 // If the finite element implements generalized support points, return
1089 // those. Otherwise fall back to unit support points.
1090 return ((generalized_support_points.empty()) ? unit_support_points :
1091 generalized_support_points);
1092}
1093
1094
1095
1096template <int dim, int spacedim>
1097bool
1099{
1100 if (this->dofs_per_cell > 0)
1101 return (get_generalized_support_points().size() != 0);
1102 else
1103 {
1104 // If the FE has no DoFs, the array size should be zero:
1105 AssertDimension(get_generalized_support_points().size(), 0);
1106
1107 // A finite element without DoFs *has* generalized support points
1108 // (which is then an empty array)
1109 return true;
1110 }
1111}
1112
1113
1114
1115template <int dim, int spacedim>
1117FiniteElement<dim, spacedim>::unit_support_point(const unsigned int index) const
1118{
1119 AssertIndexRange(index, this->n_dofs_per_cell());
1120 Assert(unit_support_points.size() == this->n_dofs_per_cell(),
1121 ExcFEHasNoSupportPoints());
1122 return unit_support_points[index];
1123}
1124
1125
1126
1127template <int dim, int spacedim>
1128const std::vector<Point<dim - 1>> &
1130 const unsigned int face_no) const
1131{
1132 // a finite element may define
1133 // support points, but only if
1134 // there are as many as there are
1135 // degrees of freedom on a face
1136 Assert((unit_face_support_points[this->n_unique_faces() == 1 ? 0 : face_no]
1137 .empty()) ||
1138 (unit_face_support_points[this->n_unique_faces() == 1 ? 0 : face_no]
1139 .size() == this->n_dofs_per_face(face_no)),
1141 return unit_face_support_points[this->n_unique_faces() == 1 ? 0 : face_no];
1142}
1143
1144
1145
1146template <int dim, int spacedim>
1147bool
1149 const unsigned int face_no) const
1150{
1151 const unsigned int face_index = this->n_unique_faces() == 1 ? 0 : face_no;
1152 if (this->n_dofs_per_face(face_index) > 0)
1153 return (unit_face_support_points[face_index].size() != 0);
1154 else
1155 {
1156 // If the FE has no DoFs on face, the array size should be zero
1157 AssertDimension(unit_face_support_points[face_index].size(), 0);
1158
1159 // A finite element without DoFs *has* face support points
1160 // (which is then an empty array)
1161 return true;
1162 }
1163}
1164
1165
1166
1167template <int dim, int spacedim>
1168Point<dim - 1>
1170 const unsigned int index,
1171 const unsigned int face_no) const
1172{
1173 AssertIndexRange(index, this->n_dofs_per_face(face_no));
1174 Assert(unit_face_support_points[this->n_unique_faces() == 1 ? 0 : face_no]
1175 .size() == this->n_dofs_per_face(face_no),
1176 ExcFEHasNoSupportPoints());
1177 return unit_face_support_points[this->n_unique_faces() == 1 ? 0 : face_no]
1178 [index];
1179}
1180
1181
1182
1183template <int dim, int spacedim>
1184bool
1186 const unsigned int) const
1187{
1188 return true;
1189}
1190
1191
1192
1193template <int dim, int spacedim>
1196{
1197 // Translate the ComponentMask into first_selected and n_components after
1198 // some error checking:
1199 const unsigned int n_total_components = this->n_components();
1200 Assert((n_total_components == mask.size()) || (mask.size() == 0),
1201 ExcMessage("The given ComponentMask has the wrong size."));
1202
1203 const unsigned int n_selected =
1204 mask.n_selected_components(n_total_components);
1205 Assert(n_selected > 0,
1206 ExcMessage("You need at least one selected component."));
1207
1208 const unsigned int first_selected =
1209 mask.first_selected_component(n_total_components);
1210
1211 if constexpr (running_in_debug_mode())
1212 {
1213 // check that it is contiguous:
1214 for (unsigned int c = 0; c < n_total_components; ++c)
1215 Assert((c < first_selected && (!mask[c])) ||
1216 (c >= first_selected && c < first_selected + n_selected &&
1217 mask[c]) ||
1218 (c >= first_selected + n_selected && !mask[c]),
1219 ExcMessage("Error: the given ComponentMask is not contiguous!"));
1220 }
1221
1222 return get_sub_fe(first_selected, n_selected);
1223}
1224
1225
1226
1227template <int dim, int spacedim>
1230 const unsigned int first_component,
1231 const unsigned int n_selected_components) const
1232{
1233 // No complicated logic is needed here, because it is overridden in
1234 // FESystem<dim,spacedim>. Just make sure that what the user chose is valid:
1235 Assert(first_component == 0 && n_selected_components == this->n_components(),
1236 ExcMessage(
1237 "You can only select a whole FiniteElement, not a part of one."));
1238
1239 return *this;
1240}
1241
1242
1243
1244template <int dim, int spacedim>
1245std::pair<Table<2, bool>, std::vector<unsigned int>>
1247{
1249 return std::pair<Table<2, bool>, std::vector<unsigned int>>(
1250 Table<2, bool>(this->n_components(), this->n_dofs_per_cell()),
1251 std::vector<unsigned int>(this->n_components()));
1252}
1253
1254
1255
1256template <int dim, int spacedim>
1257void
1260 const std::vector<Vector<double>> &,
1261 std::vector<double> &) const
1262{
1263 Assert(has_generalized_support_points(),
1264 ExcMessage("The element for which you are calling the current "
1265 "function does not have generalized support points (see "
1266 "the glossary for a definition of generalized support "
1267 "points). Consequently, the current function can not "
1268 "be defined and is not implemented by the element."));
1270}
1271
1272
1273
1274template <int dim, int spacedim>
1275std::size_t
1277{
1278 return (
1279 sizeof(FiniteElementData<dim>) +
1282 MemoryConsumption::memory_consumption(interface_constraints) +
1283 MemoryConsumption::memory_consumption(system_to_component_table) +
1284 MemoryConsumption::memory_consumption(face_system_to_component_table) +
1285 MemoryConsumption::memory_consumption(system_to_base_table) +
1286 MemoryConsumption::memory_consumption(face_system_to_base_table) +
1287 MemoryConsumption::memory_consumption(component_to_base_table) +
1288 MemoryConsumption::memory_consumption(restriction_is_additive_flags) +
1289 MemoryConsumption::memory_consumption(nonzero_components) +
1290 MemoryConsumption::memory_consumption(n_nonzero_components_table));
1291}
1292
1293
1294
1295template <int dim, int spacedim>
1296std::vector<unsigned int>
1298 const std::vector<ComponentMask> &nonzero_components)
1299{
1300 std::vector<unsigned int> retval(nonzero_components.size());
1301 for (unsigned int i = 0; i < nonzero_components.size(); ++i)
1302 retval[i] = nonzero_components[i].n_selected_components();
1303 return retval;
1304}
1305
1306
1307
1308/*------------------------------- FiniteElement ----------------------*/
1309
1310# ifndef DOXYGEN
1311template <int dim, int spacedim>
1312std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1314 const UpdateFlags flags,
1315 const Mapping<dim, spacedim> &mapping,
1316 const hp::QCollection<dim - 1> &quadrature,
1318 spacedim>
1319 &output_data) const
1320{
1321 return get_data(flags,
1322 mapping,
1324 quadrature),
1325 output_data);
1326}
1327
1328
1329
1330template <int dim, int spacedim>
1331std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1333 const UpdateFlags flags,
1334 const Mapping<dim, spacedim> &mapping,
1335 const Quadrature<dim - 1> &quadrature,
1337 spacedim>
1338 &output_data) const
1339{
1340 return get_data(flags,
1341 mapping,
1343 quadrature),
1344 output_data);
1345}
1346
1347
1348
1349template <int dim, int spacedim>
1350inline void
1353 const unsigned int face_no,
1354 const hp::QCollection<dim - 1> &quadrature,
1355 const Mapping<dim, spacedim> &mapping,
1356 const typename Mapping<dim, spacedim>::InternalDataBase &mapping_internal,
1358 &mapping_data,
1359 const typename FiniteElement<dim, spacedim>::InternalDataBase &fe_internal,
1361 spacedim>
1362 &output_data) const
1363{
1364 // base class version, implement overridden function in derived classes
1365 AssertDimension(quadrature.size(), 1);
1366 fill_fe_face_values(cell,
1367 face_no,
1368 quadrature[0],
1369 mapping,
1370 mapping_internal,
1371 mapping_data,
1372 fe_internal,
1373 output_data);
1374}
1375
1376
1377
1378template <int dim, int spacedim>
1379inline void
1381 const typename Triangulation<dim, spacedim>::cell_iterator & /* cell */,
1382 const unsigned int /* face_no */,
1383 const Quadrature<dim - 1> & /* quadrature */,
1384 const Mapping<dim, spacedim> & /* mapping */,
1386 & /* mapping_internal */,
1388 & /* mapping_data */,
1390 & /* fe_internal */,
1392 spacedim>
1393 & /* output_data */) const
1394{
1395 Assert(false,
1396 ExcMessage("Use of a deprecated interface, please implement "
1397 "fill_fe_face_values taking a hp::QCollection argument"));
1398}
1399# endif
1400
1401
1402
1403template <int dim, int spacedim>
1404std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1406 const UpdateFlags flags,
1407 const Mapping<dim, spacedim> &mapping,
1408 const Quadrature<dim - 1> &quadrature,
1410 spacedim>
1411 &output_data) const
1412{
1413 return get_data(flags,
1414 mapping,
1416 this->reference_cell(), quadrature),
1417 output_data);
1418}
1419
1420
1421
1422template <int dim, int spacedim>
1424FiniteElement<dim, spacedim>::base_element(const unsigned int index) const
1425{
1426 AssertIndexRange(index, 1);
1427 // This function should not be
1428 // called for a system element
1429 Assert(base_to_block_indices.size() == 1, ExcInternalError());
1430 return *this;
1431}
1432
1433
1434#endif
1435/*------------------------------- Explicit Instantiations -------------*/
1436#include "fe/fe.inst"
1437
1438
bool represents_the_all_selected_mask() const
unsigned int size() const
bool represents_the_all_selected_mask() const
unsigned int size() const
const unsigned int components
Definition fe_data.h:446
unsigned int n_dofs_per_cell() const
unsigned int n_dofs_per_line() const
unsigned int n_components() const
virtual std::size_t memory_consumption() const
bool constraints_are_implemented(const ::internal::SubfaceCase< dim > &subface_case=::internal::SubfaceCase< dim >::case_isotropic) const
bool isotropic_prolongation_is_implemented() const
virtual std::string get_name() const =0
virtual Point< dim > unit_support_point(const unsigned int index) const
virtual FiniteElementDomination::Domination compare_for_domination(const FiniteElement< dim, spacedim > &fe_other, const unsigned int codim=0) const
const std::vector< unsigned int > n_nonzero_components_table
Definition fe.h:2707
virtual const FullMatrix< double > & get_restriction_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
bool prolongation_is_implemented() const
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
virtual Tensor< 1, dim > shape_grad(const unsigned int i, const Point< dim > &p) const
virtual std::unique_ptr< InternalDataBase > get_face_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const hp::QCollection< dim - 1 > &quadrature, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const
virtual Point< dim - 1 > unit_face_support_point(const unsigned int index, const unsigned int face_no=0) const
static std::vector< unsigned int > compute_n_nonzero_components(const std::vector< ComponentMask > &nonzero_components)
virtual std::unique_ptr< InternalDataBase > get_subface_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const Quadrature< dim - 1 > &quadrature, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const
bool has_face_support_points(const unsigned int face_no=0) const
const bool cached_primitivity
Definition fe.h:2714
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other, const unsigned int face_no=0) const
ComponentMask component_mask(const FEValuesExtractors::Scalar &scalar) const
bool operator!=(const FiniteElement< dim, spacedim > &) const
bool has_support_points() const
bool has_generalized_support_points() const
virtual Tensor< 2, dim > shape_grad_grad(const unsigned int i, const Point< dim > &p) const
virtual bool operator==(const FiniteElement< dim, spacedim > &fe) const
const std::vector< Point< dim > > & get_unit_support_points() const
virtual void fill_fe_face_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const hp::QCollection< dim - 1 > &quadrature, const Mapping< dim, spacedim > &mapping, const typename Mapping< dim, spacedim >::InternalDataBase &mapping_internal, const internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &mapping_data, const InternalDataBase &fe_internal, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const
void reinit_restriction_and_prolongation_matrices(const bool isotropic_restriction_only=false, const bool isotropic_prolongation_only=false)
const std::vector< Point< dim - 1 > > & get_unit_face_support_points(const unsigned int face_no=0) const
bool isotropic_restriction_is_implemented() const
std::vector< int > adjust_line_dof_index_for_line_orientation_table
Definition fe.h:2610
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const
const FiniteElement< dim, spacedim > & get_sub_fe(const ComponentMask &mask) const
virtual Tensor< 4, dim > shape_4th_derivative_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
virtual double shape_value_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
unsigned int adjust_quad_dof_index_for_face_orientation(const unsigned int index, const unsigned int face_no, const types::geometric_orientation combined_orientation) const
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix, const unsigned int face_no=0) const
unsigned int component_to_block_index(const unsigned int component) const
BlockMask block_mask(const FEValuesExtractors::Scalar &scalar) const
virtual void get_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
virtual Tensor< 3, dim > shape_3rd_derivative(const unsigned int i, const Point< dim > &p) const
std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > system_to_base_table
Definition fe.h:2646
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
virtual void convert_generalized_support_point_values_to_dof_values(const std::vector< Vector< double > > &support_point_values, std::vector< double > &nodal_values) const
FiniteElement(const FiniteElementData< dim > &fe_data, const std::vector< bool > &restriction_is_additive_flags, const std::vector< ComponentMask > &nonzero_components)
virtual Tensor< 3, dim > shape_3rd_derivative_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
const FullMatrix< double > & constraints(const ::internal::SubfaceCase< dim > &subface_case=::internal::SubfaceCase< dim >::case_isotropic) const
std::pair< std::unique_ptr< FiniteElement< dim, spacedim > >, unsigned int > operator^(const unsigned int multiplicity) const
unsigned int adjust_line_dof_index_for_line_orientation(const unsigned int index, const types::geometric_orientation combined_orientation) const
const std::vector< bool > restriction_is_additive_flags
Definition fe.h:2689
virtual unsigned int face_to_cell_index(const unsigned int face_dof_index, const unsigned int face, const types::geometric_orientation combined_orientation=numbers::default_geometric_orientation) const
std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > component_to_base_table
Definition fe.h:2682
TableIndices< 2 > interface_constraints_size() const
virtual Tensor< 1, dim > shape_grad_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
bool restriction_is_implemented() const
FullMatrix< double > interface_constraints
Definition fe.h:2549
const std::vector< Point< dim > > & get_generalized_support_points() const
virtual Tensor< 2, dim > shape_grad_grad_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
virtual double shape_value(const unsigned int i, const Point< dim > &p) const
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix, const unsigned int face_no=0) const
virtual std::size_t memory_consumption() const
virtual Tensor< 4, dim > shape_4th_derivative(const unsigned int i, const Point< dim > &p) const
const std::vector< ComponentMask > nonzero_components
Definition fe.h:2698
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
virtual bool hp_constraints_are_implemented() const
Abstract base class for mapping classes.
Definition mapping.h:320
Definition point.h:113
Class which transforms dim - 1-dimensional quadrature rules to dim-dimensional face quadratures.
Definition qprojector.h:69
unsigned int size() const
Definition collection.h:316
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:35
constexpr bool running_in_debug_mode()
Definition config.h:73
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:36
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
Point< 2 > first
Definition grid_out.cc:4632
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
UpdateFlags
@ update_default
No update.
std::size_t size
Definition mpi.cc:745
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell &reference_cell)
constexpr char U
std::enable_if_t< IsBlockVector< VectorType >::value, unsigned int > n_blocks(const VectorType &vector)
Definition operators.h:49
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
constexpr ReferenceCell Triangle
constexpr ReferenceCell Quadrilateral
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
std::vector< Point< dim > > unit_support_points(const std::vector< Point< 1 > > &line_support_points, const std::vector< unsigned int > &renumbering)
constexpr unsigned int invalid_unsigned_int
Definition types.h:238
constexpr types::geometric_orientation reverse_line_orientation
Definition types.h:365
constexpr types::geometric_orientation default_geometric_orientation
Definition types.h:352
STL namespace.
unsigned char geometric_orientation
Definition types.h:40