deal.II version 9.8.0
\(\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\}}\)
Loading...
Searching...
No Matches
fe.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 1998 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
16
18
19#include <deal.II/fe/fe.h>
21#include <deal.II/fe/mapping.h>
22
23#include <deal.II/grid/tria.h>
26
27#include <algorithm>
28#include <functional>
29#include <numeric>
30#include <typeinfo>
31
33
34
35/*------------------------------- FiniteElement ----------------------*/
36#ifndef DOXYGEN
37
38template <int dim, int spacedim>
40 : update_each(update_default)
41{}
42
43
44
45template <int dim, int spacedim>
46std::size_t
48{
49 return sizeof(*this);
50}
51
52
53
54template <int dim, int spacedim>
56 const FiniteElementData<dim> &fe_data,
57 const std::vector<bool> &r_i_a_f,
58 const std::vector<ComponentMask> &nonzero_c)
59 : FiniteElementData<dim>(fe_data)
63 std::make_pair(std::make_pair(0U, 0U), 0U))
64 ,
65
66 // Special handling of vectors of length one: in this case, we
67 // assume that all entries were supposed to be equal
69 r_i_a_f.size() == 1 ?
70 std::vector<bool>(fe_data.n_dofs_per_cell(), r_i_a_f[0]) :
71 r_i_a_f)
73 nonzero_c.size() == 1 ?
74 std::vector<ComponentMask>(fe_data.n_dofs_per_cell(), nonzero_c[0]) :
75 nonzero_c)
79 [](const unsigned int n_components) {
80 return n_components != 1U;
81 }) == n_nonzero_components_table.end())
82{
83 Assert(restriction_is_additive_flags.size() == this->n_dofs_per_cell(),
84 ExcDimensionMismatch(restriction_is_additive_flags.size(),
85 this->n_dofs_per_cell()));
86 AssertDimension(nonzero_components.size(), this->n_dofs_per_cell());
87 for (unsigned int i = 0; i < nonzero_components.size(); ++i)
88 {
89 Assert(nonzero_components[i].size() == this->n_components(),
91 Assert(nonzero_components[i].n_selected_components() >= 1,
93 Assert(n_nonzero_components_table[i] >= 1, ExcInternalError());
94 Assert(n_nonzero_components_table[i] <= this->n_components(),
96 }
97
98 // initialize some tables in the default way, i.e. if there is only one
99 // (vector-)component; if the element is not primitive, leave these tables
100 // empty.
101 if (this->is_primitive())
102 {
103 system_to_component_table.resize(this->n_dofs_per_cell());
104 for (unsigned int j = 0; j < this->n_dofs_per_cell(); ++j)
105 system_to_component_table[j] = std::pair<unsigned, unsigned>(0, j);
106
107 face_system_to_component_table.resize(this->n_unique_faces());
108 for (unsigned int f = 0; f < this->n_unique_faces(); ++f)
109 {
110 face_system_to_component_table[f].resize(this->n_dofs_per_face(f));
111 for (unsigned int j = 0; j < this->n_dofs_per_face(f); ++j)
112 face_system_to_component_table[f][j] =
113 std::pair<unsigned, unsigned>(0, j);
114 }
115 }
116
117 for (unsigned int j = 0; j < this->n_dofs_per_cell(); ++j)
118 system_to_base_table[j] = std::make_pair(std::make_pair(0U, 0U), j);
119
120 face_system_to_base_table.resize(this->n_unique_faces());
121 for (unsigned int f = 0; f < this->n_unique_faces(); ++f)
122 {
123 face_system_to_base_table[f].resize(this->n_dofs_per_face(f));
124 for (unsigned int j = 0; j < this->n_dofs_per_face(f); ++j)
125 face_system_to_base_table[f][j] =
126 std::make_pair(std::make_pair(0U, 0U), j);
127 }
128
129 // Fill with default value; may be changed by constructor of derived class.
130 base_to_block_indices.reinit(1, 1);
131
132 // initialize the restriction and prolongation matrices. the default
133 // constructor of FullMatrix<dim> initializes them with size zero
136 for (const unsigned int ref_case :
139 {
140 prolongation[ref_case - 1].resize(this->reference_cell().n_children(
141 RefinementCase<dim>(ref_case)),
143 restriction[ref_case - 1].resize(this->reference_cell().n_children(
144 RefinementCase<dim>(ref_case)),
146 }
147
148
149 if (dim == 3)
150 {
151 adjust_quad_dof_index_for_face_orientation_table.resize(
152 this->n_unique_2d_subobjects());
153
154 for (unsigned int f = 0; f < this->n_unique_2d_subobjects(); ++f)
155 {
156 adjust_quad_dof_index_for_face_orientation_table[f] =
157 Table<2, int>(this->n_dofs_per_quad(f),
158 this->reference_cell().n_face_orientations(f));
159 adjust_quad_dof_index_for_face_orientation_table[f].fill(0);
160 }
161 }
162
163 unit_face_support_points.resize(this->n_unique_faces());
164 generalized_face_support_points.resize(this->n_unique_faces());
165}
166
167
168
169template <int dim, int spacedim>
170std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>
171FiniteElement<dim, spacedim>::operator^(const unsigned int multiplicity) const
172{
173 return {this->clone(), multiplicity};
174}
175
176
177
178template <int dim, int spacedim>
179double
181 const Point<dim> &) const
182{
183 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
184 return 0.;
185}
186
187
188
189template <int dim, int spacedim>
190double
192 const Point<dim> &,
193 const unsigned int) const
194{
195 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
196 return 0.;
197}
198
199
200
201template <int dim, int spacedim>
204 const Point<dim> &) const
205{
206 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
207 return Tensor<1, dim>();
208}
209
210
211
212template <int dim, int spacedim>
215 const Point<dim> &,
216 const unsigned int) const
217{
218 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
219 return Tensor<1, dim>();
220}
221
222
223
224template <int dim, int spacedim>
227 const Point<dim> &) const
228{
229 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
230 return Tensor<2, dim>();
231}
232
233
234
235template <int dim, int spacedim>
238 const unsigned int,
239 const Point<dim> &,
240 const unsigned int) const
241{
242 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
243 return Tensor<2, dim>();
244}
245
246
247
248template <int dim, int spacedim>
251 const Point<dim> &) const
252{
253 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
254 return Tensor<3, dim>();
255}
256
257
258
259template <int dim, int spacedim>
262 const unsigned int,
263 const Point<dim> &,
264 const unsigned int) const
265{
266 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
267 return Tensor<3, dim>();
268}
269
270
271
272template <int dim, int spacedim>
275 const Point<dim> &) const
276{
277 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
278 return Tensor<4, dim>();
279}
280
281
282
283template <int dim, int spacedim>
286 const unsigned int,
287 const Point<dim> &,
288 const unsigned int) const
289{
290 AssertThrow(false, ExcUnitShapeValuesDoNotExist());
291 return Tensor<4, dim>();
292}
293
294
295template <int dim, int spacedim>
296void
298 const bool isotropic_restriction_only,
299 const bool isotropic_prolongation_only)
300{
301 for (const unsigned int ref_case :
304 {
305 const unsigned int nc =
306 this->reference_cell().n_children(RefinementCase<dim>(ref_case));
307
308 for (unsigned int i = 0; i < nc; ++i)
309 {
310 if (this->restriction[ref_case - 1][i].m() !=
311 this->n_dofs_per_cell() &&
312 (!isotropic_restriction_only ||
314 this->restriction[ref_case - 1][i].reinit(
315 this->n_dofs_per_cell(), this->n_dofs_per_cell());
316 if (this->prolongation[ref_case - 1][i].m() !=
317 this->n_dofs_per_cell() &&
318 (!isotropic_prolongation_only ||
320 this->prolongation[ref_case - 1][i].reinit(
321 this->n_dofs_per_cell(), this->n_dofs_per_cell());
322 }
323 }
324}
325
326
327template <int dim, int spacedim>
328const FullMatrix<double> &
330 const unsigned int child,
331 const RefinementCase<dim> &refinement_case) const
332{
333 AssertIndexRange(refinement_case,
337 "Restriction matrices are only available for refined cells!"));
338 AssertIndexRange(child,
339 this->reference_cell().n_children(
340 RefinementCase<dim>(refinement_case)));
341 // we use refinement_case-1 here. the -1 takes care of the origin of the
342 // vector, as for RefinementCase<dim>::no_refinement (=0) there is no data
343 // available and so the vector indices are shifted
344 Assert(restriction[refinement_case - 1][child].n() == this->n_dofs_per_cell(),
345 ExcProjectionVoid());
346 return restriction[refinement_case - 1][child];
347}
348
349
350
351template <int dim, int spacedim>
352const FullMatrix<double> &
354 const unsigned int child,
355 const RefinementCase<dim> &refinement_case) const
356{
357 AssertIndexRange(refinement_case,
361 "Prolongation matrices are only available for refined cells!"));
362 AssertIndexRange(child,
363 this->reference_cell().n_children(
364 RefinementCase<dim>(refinement_case)));
365 // we use refinement_case-1 here. the -1 takes care
366 // of the origin of the vector, as for
367 // RefinementCase::no_refinement (=0) there is no
368 // data available and so the vector indices
369 // are shifted
370 Assert(prolongation[refinement_case - 1][child].n() ==
371 this->n_dofs_per_cell(),
372 ExcEmbeddingVoid());
373 return prolongation[refinement_case - 1][child];
374}
375
376
377// TODO:[GK] This is probably not the most efficient way of doing this.
378template <int dim, int spacedim>
379unsigned int
381 const unsigned int index) const
382{
383 AssertIndexRange(index, this->n_components());
384
385 return first_block_of_base(component_to_base_table[index].first.first) +
386 component_to_base_table[index].second;
387}
388
389
390template <int dim, int spacedim>
393 const FEValuesExtractors::Scalar &scalar) const
394{
395 AssertIndexRange(scalar.component, this->n_components());
396
397 // TODO: it would be nice to verify that it is indeed possible
398 // to select this scalar component, i.e., that it is not part
399 // of a non-primitive element. unfortunately, there is no simple
400 // way to write such a condition...
401
402 std::vector<bool> mask(this->n_components(), false);
403 mask[scalar.component] = true;
404 return ComponentMask(mask);
405}
406
407
408template <int dim, int spacedim>
411 const FEValuesExtractors::Vector &vector) const
412{
414 this->n_components());
415
416 // TODO: it would be nice to verify that it is indeed possible
417 // to select these vector components, i.e., that they don't span
418 // beyond the beginning or end of anon-primitive element.
419 // unfortunately, there is no simple way to write such a condition...
420
421 std::vector<bool> mask(this->n_components(), false);
422 for (unsigned int c = vector.first_vector_component;
423 c < vector.first_vector_component + dim;
424 ++c)
425 mask[c] = true;
426 return ComponentMask(mask);
427}
428
429
430template <int dim, int spacedim>
433 const FEValuesExtractors::SymmetricTensor<2> &sym_tensor) const
434{
437 this->n_components());
438
439 // TODO: it would be nice to verify that it is indeed possible
440 // to select these vector components, i.e., that they don't span
441 // beyond the beginning or end of anon-primitive element.
442 // unfortunately, there is no simple way to write such a condition...
443
444 std::vector<bool> mask(this->n_components(), false);
445 for (unsigned int c = sym_tensor.first_tensor_component;
446 c < sym_tensor.first_tensor_component +
448 ++c)
449 mask[c] = true;
450 return ComponentMask(mask);
451}
452
453
454
455template <int dim, int spacedim>
458{
459 // if we get a block mask that represents all blocks, then
460 // do the same for the returned component mask
461 if (block_mask.represents_the_all_selected_mask())
462 return {};
463
464 AssertDimension(block_mask.size(), this->n_blocks());
465
466 std::vector<bool> component_mask(this->n_components(), false);
467 for (unsigned int c = 0; c < this->n_components(); ++c)
468 if (block_mask[component_to_block_index(c)] == true)
469 component_mask[c] = true;
470
471 return ComponentMask(component_mask);
472}
473
474
475
476template <int dim, int spacedim>
479 const FEValuesExtractors::Scalar &scalar) const
480{
481 // simply create the corresponding component mask (a simpler
482 // process) and then convert it to a block mask
483 return block_mask(component_mask(scalar));
484}
485
486
487template <int dim, int spacedim>
490 const FEValuesExtractors::Vector &vector) const
491{
492 // simply create the corresponding component mask (a simpler
493 // process) and then convert it to a block mask
494 return block_mask(component_mask(vector));
495}
496
497
498template <int dim, int spacedim>
501 const FEValuesExtractors::SymmetricTensor<2> &sym_tensor) const
502{
503 // simply create the corresponding component mask (a simpler
504 // process) and then convert it to a block mask
505 return block_mask(component_mask(sym_tensor));
506}
507
508
509
510template <int dim, int spacedim>
513 const ComponentMask &component_mask) const
514{
515 // if we get a component mask that represents all component, then
516 // do the same for the returned block mask
517 if (component_mask.represents_the_all_selected_mask())
518 return {};
519
520 AssertDimension(component_mask.size(), this->n_components());
521
522 // walk over all of the components
523 // of this finite element and see
524 // if we need to set the
525 // corresponding block. inside the
526 // block, walk over all the
527 // components that correspond to
528 // this block and make sure the
529 // component mask is set for all of
530 // them
531 std::vector<bool> block_mask(this->n_blocks(), false);
532 for (unsigned int c = 0; c < this->n_components();)
533 {
534 const unsigned int block = component_to_block_index(c);
535 if (component_mask[c] == true)
536 block_mask[block] = true;
537
538 // now check all of the other
539 // components that correspond
540 // to this block
541 ++c;
542 while ((c < this->n_components()) &&
543 (component_to_block_index(c) == block))
544 {
545 Assert(component_mask[c] == block_mask[block],
547 "The component mask argument given to this function "
548 "is not a mask where the individual components belonging "
549 "to one block of the finite element are either all "
550 "selected or not selected. You can't call this function "
551 "with a component mask that splits blocks."));
552 ++c;
553 }
554 }
555
556
557 return BlockMask(block_mask);
558}
559
560
561
562template <int dim, int spacedim>
563unsigned int
565 const unsigned int face_index,
566 const unsigned int face,
567 const types::geometric_orientation combined_orientation) const
568{
569 AssertIndexRange(face_index, this->n_dofs_per_face(face));
570 AssertIndexRange(face, this->reference_cell().n_faces());
571
572 // see the function's documentation for an explanation of this
573 // assertion -- in essence, derived classes have to implement
574 // an overloaded version of this function if we are to use any
575 // other than default (standard) orientation
576 if (combined_orientation != numbers::default_geometric_orientation)
577 Assert((this->n_dofs_per_line() <= 1) && (this->n_dofs_per_quad(face) <= 1),
579 "The function in this base class can not handle this case. "
580 "Rather, the derived class you are using must provide "
581 "an overloaded version but apparently hasn't done so. See "
582 "the documentation of this function for more information."));
583
584 // we need to distinguish between DoFs on vertices, lines and (in 3d) quads.
585 // do so in a sequence of if-else statements
586 if (face_index < this->get_first_face_line_index(face))
587 // DoF is on a vertex
588 {
589 // get the number of the vertex on the face that corresponds to this DoF,
590 // along with the number of the DoF on this vertex
591 const unsigned int face_vertex = face_index / this->n_dofs_per_vertex();
592 const unsigned int dof_index_on_vertex =
593 face_index % this->n_dofs_per_vertex();
594
595 // then get the number of this vertex on the cell and translate
596 // this to a DoF number on the cell
597 return (this->reference_cell().face_to_cell_vertices(
598 face, face_vertex, combined_orientation) *
599 this->n_dofs_per_vertex() +
600 dof_index_on_vertex);
601 }
602 else if (face_index < this->get_first_face_quad_index(face))
603 // DoF is on a face
604 {
605 // do the same kind of translation as before. we need to only consider
606 // DoFs on the lines, i.e., ignoring those on the vertices
607 const unsigned int index =
608 face_index - this->get_first_face_line_index(face);
609
610 const unsigned int face_line = index / this->n_dofs_per_line();
611 const unsigned int dof_index_on_line = index % this->n_dofs_per_line();
612
613 return (this->get_first_line_index() +
614 this->reference_cell().face_to_cell_lines(face,
615 face_line,
616 combined_orientation) *
617 this->n_dofs_per_line() +
618 dof_index_on_line);
619 }
620 else
621 // DoF is on a quad
622 {
623 Assert(dim >= 3, ExcInternalError());
624
625 // ignore vertex and line dofs
626 const unsigned int index =
627 face_index - this->get_first_face_quad_index(face);
628
629 return (this->get_first_quad_index(face) + index);
630 }
631}
632
633
634
635template <int dim, int spacedim>
636unsigned int
638 const unsigned int index,
639 const unsigned int face,
640 const types::geometric_orientation combined_orientation) const
641{
642 // general template for 1d and 2d: not
643 // implemented. in fact, the function
644 // shouldn't even be called unless we are
645 // in 3d, so throw an internal error
646 Assert(dim == 3, ExcInternalError());
647 if (dim < 3)
648 return index;
649
650 // adjust dofs on 3d faces if the face is
651 // flipped. note that we query a table that
652 // derived elements need to have set up
653 // front. the exception are discontinuous
654 // elements for which there should be no
655 // face dofs anyway (i.e. dofs_per_quad==0
656 // in 3d), so we don't need the table, but
657 // the function should also not have been
658 // called
659 AssertIndexRange(index, this->n_dofs_per_quad(face));
660 const auto table_n = this->n_unique_2d_subobjects() == 1 ? 0 : face;
661 Assert(
662 adjust_quad_dof_index_for_face_orientation_table[table_n].n_elements() ==
663 (this->reference_cell().n_face_orientations(face)) *
664 this->n_dofs_per_quad(face),
666 return index + adjust_quad_dof_index_for_face_orientation_table[table_n](
667 index, combined_orientation);
668}
669
670
671
672template <int dim, int spacedim>
673unsigned int
675 const unsigned int index,
676 const types::geometric_orientation combined_orientation) const
677{
678 Assert(combined_orientation == numbers::default_geometric_orientation ||
679 combined_orientation == numbers::reverse_line_orientation,
681
682 AssertIndexRange(index, this->n_dofs_per_line());
683 Assert(adjust_line_dof_index_for_line_orientation_table.size() ==
684 this->n_dofs_per_line(),
686 if (combined_orientation == numbers::default_geometric_orientation)
687 return index;
688 else
689 return index + adjust_line_dof_index_for_line_orientation_table[index];
690}
691
692
693
694template <int dim, int spacedim>
695bool
697{
698 for (const unsigned int ref_case :
701 for (unsigned int c = 0;
702 c < this->reference_cell().n_children(RefinementCase<dim>(ref_case));
703 ++c)
704 {
705 // make sure also the lazily initialized matrices are created
706 get_prolongation_matrix(c, RefinementCase<dim>(ref_case));
707 Assert((prolongation[ref_case - 1][c].m() ==
708 this->n_dofs_per_cell()) ||
709 (prolongation[ref_case - 1][c].m() == 0),
711 Assert((prolongation[ref_case - 1][c].n() ==
712 this->n_dofs_per_cell()) ||
713 (prolongation[ref_case - 1][c].n() == 0),
715 if ((prolongation[ref_case - 1][c].m() == 0) ||
716 (prolongation[ref_case - 1][c].n() == 0))
717 return false;
718 }
719 return true;
720}
721
722
723
724template <int dim, int spacedim>
725bool
727{
728 for (const unsigned int ref_case :
731 for (unsigned int c = 0;
732 c < this->reference_cell().n_children(RefinementCase<dim>(ref_case));
733 ++c)
734 {
735 // make sure also the lazily initialized matrices are created
736 get_restriction_matrix(c, RefinementCase<dim>(ref_case));
737 Assert((restriction[ref_case - 1][c].m() ==
738 this->n_dofs_per_cell()) ||
739 (restriction[ref_case - 1][c].m() == 0),
741 Assert((restriction[ref_case - 1][c].n() ==
742 this->n_dofs_per_cell()) ||
743 (restriction[ref_case - 1][c].n() == 0),
745 if ((restriction[ref_case - 1][c].m() == 0) ||
746 (restriction[ref_case - 1][c].n() == 0))
747 return false;
748 }
749 return true;
750}
751
752
753
754template <int dim, int spacedim>
755bool
757{
758 const RefinementCase<dim> ref_case =
760
761 for (unsigned int c = 0;
762 c < this->reference_cell().n_children(RefinementCase<dim>(ref_case));
763 ++c)
764 {
765 // make sure also the lazily initialized matrices are created
766 get_prolongation_matrix(c, RefinementCase<dim>(ref_case));
767 Assert((prolongation[ref_case - 1][c].m() == this->n_dofs_per_cell()) ||
768 (prolongation[ref_case - 1][c].m() == 0),
770 Assert((prolongation[ref_case - 1][c].n() == this->n_dofs_per_cell()) ||
771 (prolongation[ref_case - 1][c].n() == 0),
773 if ((prolongation[ref_case - 1][c].m() == 0) ||
774 (prolongation[ref_case - 1][c].n() == 0))
775 return false;
776 }
777 return true;
778}
779
780
781
782template <int dim, int spacedim>
783bool
785{
786 const RefinementCase<dim> ref_case =
788
789 for (unsigned int c = 0;
790 c < this->reference_cell().n_children(RefinementCase<dim>(ref_case));
791 ++c)
792 {
793 // make sure also the lazily initialized matrices are created
794 get_restriction_matrix(c, RefinementCase<dim>(ref_case));
795 Assert((restriction[ref_case - 1][c].m() == this->n_dofs_per_cell()) ||
796 (restriction[ref_case - 1][c].m() == 0),
798 Assert((restriction[ref_case - 1][c].n() == this->n_dofs_per_cell()) ||
799 (restriction[ref_case - 1][c].n() == 0),
801 if ((restriction[ref_case - 1][c].m() == 0) ||
802 (restriction[ref_case - 1][c].n() == 0))
803 return false;
804 }
805 return true;
806}
807
808
809
810template <int dim, int spacedim>
811bool
813 const internal::SubfaceCase<dim> &subface_case) const
814{
816 {
817 unsigned int n_dofs_on_faces = 0;
818
819 for (const auto face_no : this->reference_cell().face_indices())
820 n_dofs_on_faces += this->n_dofs_per_face(face_no);
821
822 return (n_dofs_on_faces == 0) || (interface_constraints.m() != 0);
823 }
824 else
825 return false;
826}
827
828
829
830template <int dim, int spacedim>
831bool
833{
834 return false;
835}
836
837
838
839template <int dim, int spacedim>
840const FullMatrix<double> &
842 const internal::SubfaceCase<dim> &subface_case) const
843{
844 // TODO: the implementation makes the assumption that all faces have the
845 // same number of dofs
846 AssertDimension(this->n_unique_faces(), 1);
847 const unsigned int face_no = 0;
848
850 ExcMessage("Constraints for this element are only implemented "
851 "for the case that faces are refined isotropically "
852 "(which is always the case in 2d, and in 3d requires "
853 "that the neighboring cell of a coarse cell presents "
854 "exactly four children on the common face)."));
855 Assert((this->n_dofs_per_face(face_no) == 0) ||
856 (interface_constraints.m() != 0),
857 ExcMessage("The finite element for which you try to obtain "
858 "hanging node constraints does not appear to "
859 "implement them."));
860
861 if (dim == 1)
862 Assert((interface_constraints.m() == 0) && (interface_constraints.n() == 0),
863 ExcWrongInterfaceMatrixSize(interface_constraints.m(),
864 interface_constraints.n()));
865
866 return interface_constraints;
867}
868
869
870
871template <int dim, int spacedim>
874{
875 // TODO: the implementation makes the assumption that all faces have the
876 // same number of dofs
877 AssertDimension(this->n_unique_faces(), 1);
878 const unsigned int face_no = 0;
879
880 switch (dim)
881 {
882 case 1:
883 return {0U, 0U};
884
885 case 2:
886 // We have to interpolate from the DoFs in the interior of the
887 // the two child faces (=lines) and the one central vertex
888 // to the DoFs of the parent face:
889 return {this->n_dofs_per_vertex() + 2 * this->n_dofs_per_line(),
890 this->n_dofs_per_face(face_no)};
891
892 case 3:
893 // We have to interpolate from the DoFs in the interior of the
894 // the child faces (=quads or tris) and the vertices that are
895 // not part of the parent face, to the DoFs of the parent face:
896 if (this->reference_cell().face_reference_cell(face_no) ==
898 return {
899 5 * this->n_dofs_per_vertex() + // 4 vertices at mid-edge points
900 // + 1 at cell center
901 12 * this->n_dofs_per_line() + // 4*2 children of the old edges
902 // + 2*2 edges in the cell interior
903 4 * this->n_dofs_per_quad(face_no), // 4 child faces
904 this->n_dofs_per_face(face_no)};
905 else if (this->reference_cell().face_reference_cell(face_no) ==
907 return {
908 3 * this->n_dofs_per_vertex() + // 3 vertices at mid-edge points
909 9 * this->n_dofs_per_line() + // 3*2 children of the old edges
910 // + 3 edges in the cell interior
911 4 * this->n_dofs_per_quad(face_no), // 4 child faces
912 this->n_dofs_per_face(face_no)};
913 else
915
916 default:
918 }
920}
921
922
923
924template <int dim, int spacedim>
925void
928 FullMatrix<double> &) const
929{
930 // by default, no interpolation
931 // implemented. so throw exception,
932 // as documentation says
934 false,
936}
937
938
939
940template <int dim, int spacedim>
941void
945 const unsigned int) const
946{
947 // by default, no interpolation
948 // implemented. so throw exception,
949 // as documentation says
951 false,
953}
954
955
956
957template <int dim, int spacedim>
958void
961 const unsigned int,
963 const unsigned int) const
964{
965 // by default, no interpolation
966 // implemented. so throw exception,
967 // as documentation says
969 false,
971}
972
973
974
975template <int dim, int spacedim>
976std::vector<std::pair<unsigned int, unsigned int>>
978 const FiniteElement<dim, spacedim> &) const
979{
981 return std::vector<std::pair<unsigned int, unsigned int>>();
982}
983
984
985
986template <int dim, int spacedim>
987std::vector<std::pair<unsigned int, unsigned int>>
989 const FiniteElement<dim, spacedim> &) const
990{
992 return std::vector<std::pair<unsigned int, unsigned int>>();
993}
994
995
996
997template <int dim, int spacedim>
998std::vector<std::pair<unsigned int, unsigned int>>
1001 const unsigned int) const
1002{
1004 return std::vector<std::pair<unsigned int, unsigned int>>();
1005}
1006
1007
1008
1009template <int dim, int spacedim>
1013 const unsigned int) const
1014{
1017}
1018
1019
1020
1021template <int dim, int spacedim>
1022bool
1024 const FiniteElement<dim, spacedim> &f) const
1025{
1026 // Compare fields in roughly increasing order of how expensive the
1027 // comparison is
1028 return ((typeid(*this) == typeid(f)) && (this->get_name() == f.get_name()) &&
1029 (static_cast<const FiniteElementData<dim> &>(*this) ==
1030 static_cast<const FiniteElementData<dim> &>(f)) &&
1031 (interface_constraints == f.interface_constraints));
1032}
1033
1034
1035
1036template <int dim, int spacedim>
1037bool
1039 const FiniteElement<dim, spacedim> &f) const
1040{
1041 return !(*this == f);
1042}
1043
1044
1045
1046template <int dim, int spacedim>
1047const std::vector<Point<dim>> &
1049{
1050 // a finite element may define
1051 // support points, but only if
1052 // there are as many as there are
1053 // degrees of freedom
1054 Assert((unit_support_points.empty()) ||
1055 (unit_support_points.size() == this->n_dofs_per_cell()),
1057 return unit_support_points;
1058}
1059
1060
1061
1062template <int dim, int spacedim>
1063bool
1065{
1066 if (this->dofs_per_cell > 0)
1067 return (unit_support_points.size() != 0);
1068 else
1069 {
1070 // If the FE has no DoFs, we shouldn't expect the array
1071 // size to be anything other than zero:
1073
1074 // A finite element without DoFs *has* support points
1075 // (which is then an empty array)
1076 return true;
1077 }
1078}
1079
1080
1081
1082template <int dim, int spacedim>
1083const std::vector<Point<dim>> &
1085{
1086 // If the finite element implements generalized support points, return
1087 // those. Otherwise fall back to unit support points.
1088 return ((generalized_support_points.empty()) ? unit_support_points :
1089 generalized_support_points);
1090}
1091
1092
1093
1094template <int dim, int spacedim>
1095bool
1097{
1098 if (this->dofs_per_cell > 0)
1099 return (get_generalized_support_points().size() != 0);
1100 else
1101 {
1102 // If the FE has no DoFs, the array size should be zero:
1103 AssertDimension(get_generalized_support_points().size(), 0);
1104
1105 // A finite element without DoFs *has* generalized support points
1106 // (which is then an empty array)
1107 return true;
1108 }
1109}
1110
1111
1112
1113template <int dim, int spacedim>
1115FiniteElement<dim, spacedim>::unit_support_point(const unsigned int index) const
1116{
1117 AssertIndexRange(index, this->n_dofs_per_cell());
1118 Assert(unit_support_points.size() == this->n_dofs_per_cell(),
1119 ExcFEHasNoSupportPoints());
1120 return unit_support_points[index];
1121}
1122
1123
1124
1125template <int dim, int spacedim>
1126const std::vector<Point<dim - 1>> &
1128 const unsigned int face_no) const
1129{
1130 // a finite element may define
1131 // support points, but only if
1132 // there are as many as there are
1133 // degrees of freedom on a face
1134 Assert((unit_face_support_points[this->n_unique_faces() == 1 ? 0 : face_no]
1135 .empty()) ||
1136 (unit_face_support_points[this->n_unique_faces() == 1 ? 0 : face_no]
1137 .size() == this->n_dofs_per_face(face_no)),
1139 return unit_face_support_points[this->n_unique_faces() == 1 ? 0 : face_no];
1140}
1141
1142
1143
1144template <int dim, int spacedim>
1145bool
1147 const unsigned int face_no) const
1148{
1149 const unsigned int face_index = this->n_unique_faces() == 1 ? 0 : face_no;
1150 if (this->n_dofs_per_face(face_index) > 0)
1151 return (unit_face_support_points[face_index].size() != 0);
1152 else
1153 {
1154 // If the FE has no DoFs on face, the array size should be zero
1155 AssertDimension(unit_face_support_points[face_index].size(), 0);
1156
1157 // A finite element without DoFs *has* face support points
1158 // (which is then an empty array)
1159 return true;
1160 }
1161}
1162
1163
1164
1165template <int dim, int spacedim>
1166Point<dim - 1>
1168 const unsigned int index,
1169 const unsigned int face_no) const
1170{
1171 AssertIndexRange(index, this->n_dofs_per_face(face_no));
1172 Assert(unit_face_support_points[this->n_unique_faces() == 1 ? 0 : face_no]
1173 .size() == this->n_dofs_per_face(face_no),
1174 ExcFEHasNoSupportPoints());
1175 return unit_face_support_points[this->n_unique_faces() == 1 ? 0 : face_no]
1176 [index];
1177}
1178
1179
1180
1181template <int dim, int spacedim>
1182bool
1184 const unsigned int) const
1185{
1186 return true;
1187}
1188
1189
1190
1191template <int dim, int spacedim>
1194{
1195 // Translate the ComponentMask into first_selected and n_components after
1196 // some error checking:
1197 const unsigned int n_total_components = this->n_components();
1198 Assert((n_total_components == mask.size()) || (mask.size() == 0),
1199 ExcMessage("The given ComponentMask has the wrong size."));
1200
1201 const unsigned int n_selected =
1202 mask.n_selected_components(n_total_components);
1203 Assert(n_selected > 0,
1204 ExcMessage("You need at least one selected component."));
1205
1206 const unsigned int first_selected =
1207 mask.first_selected_component(n_total_components);
1208
1209 if constexpr (running_in_debug_mode())
1210 {
1211 // check that it is contiguous:
1212 for (unsigned int c = 0; c < n_total_components; ++c)
1213 Assert((c < first_selected && (!mask[c])) ||
1214 (c >= first_selected && c < first_selected + n_selected &&
1215 mask[c]) ||
1216 (c >= first_selected + n_selected && !mask[c]),
1217 ExcMessage(
1218 "The given ComponentMask is not contiguous, but "
1219 "any sub-element of the current element must "
1220 "necessarily occupy a contiguous set of components."));
1221 }
1222
1223 return get_sub_fe(first_selected, n_selected);
1224}
1225
1226
1227
1228template <int dim, int spacedim>
1231 const unsigned int first_component,
1232 const unsigned int n_selected_components) const
1233{
1234 // No complicated logic is needed here, because it is overridden in
1235 // FESystem<dim,spacedim>. Just make sure that what the user chose is valid:
1236 Assert(first_component == 0 && n_selected_components == this->n_components(),
1237 ExcMessage(
1238 "You can only select a whole FiniteElement, not a part of one."));
1239
1240 return *this;
1241}
1242
1243
1244
1245template <int dim, int spacedim>
1246std::pair<Table<2, bool>, std::vector<unsigned int>>
1248{
1250 return std::pair<Table<2, bool>, std::vector<unsigned int>>(
1251 Table<2, bool>(this->n_components(), this->n_dofs_per_cell()),
1252 std::vector<unsigned int>(this->n_components()));
1253}
1254
1255
1256
1257template <int dim, int spacedim>
1258void
1261 const std::vector<Vector<double>> &,
1262 std::vector<double> &) const
1263{
1264 Assert(has_generalized_support_points(),
1265 ExcMessage("The element for which you are calling the current "
1266 "function does not have generalized support points (see "
1267 "the glossary for a definition of generalized support "
1268 "points). Consequently, the current function can not "
1269 "be defined and is not implemented by the element."));
1271}
1272
1273
1274
1275template <int dim, int spacedim>
1276std::size_t
1278{
1279 return (
1280 sizeof(FiniteElementData<dim>) +
1283 MemoryConsumption::memory_consumption(interface_constraints) +
1284 MemoryConsumption::memory_consumption(system_to_component_table) +
1285 MemoryConsumption::memory_consumption(face_system_to_component_table) +
1286 MemoryConsumption::memory_consumption(system_to_base_table) +
1287 MemoryConsumption::memory_consumption(face_system_to_base_table) +
1288 MemoryConsumption::memory_consumption(component_to_base_table) +
1289 MemoryConsumption::memory_consumption(restriction_is_additive_flags) +
1290 MemoryConsumption::memory_consumption(nonzero_components) +
1291 MemoryConsumption::memory_consumption(n_nonzero_components_table));
1292}
1293
1294
1295
1296template <int dim, int spacedim>
1297std::vector<unsigned int>
1299 const std::vector<ComponentMask> &nonzero_components)
1300{
1301 std::vector<unsigned int> retval(nonzero_components.size());
1302 for (unsigned int i = 0; i < nonzero_components.size(); ++i)
1303 retval[i] = nonzero_components[i].n_selected_components();
1304 return retval;
1305}
1306
1307
1308
1309/*------------------------------- FiniteElement ----------------------*/
1310
1311# ifndef DOXYGEN
1312template <int dim, int spacedim>
1313std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1315 const UpdateFlags flags,
1317 const hp::QCollection<dim - 1> &quadrature,
1319 spacedim>
1320 &output_data) const
1321{
1322 return get_data(flags,
1323 mapping,
1325 quadrature),
1326 output_data);
1327}
1328
1329
1330
1331template <int dim, int spacedim>
1332std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1334 const UpdateFlags flags,
1336 const Quadrature<dim - 1> &quadrature,
1338 spacedim>
1339 &output_data) const
1340{
1341 return get_data(flags,
1342 mapping,
1344 quadrature),
1345 output_data);
1346}
1347
1348
1349
1350template <int dim, int spacedim>
1351void
1354 const unsigned int face_no,
1355 const hp::QCollection<dim - 1> &quadrature,
1357 const typename Mapping<dim, spacedim>::InternalDataBase &mapping_internal,
1359 &mapping_data,
1360 const typename FiniteElement<dim, spacedim>::InternalDataBase &fe_internal,
1362 spacedim>
1363 &output_data) const
1364{
1365 // base class version, implement overridden function in derived classes
1366 AssertDimension(quadrature.size(), 1);
1367 fill_fe_face_values(cell,
1368 face_no,
1369 quadrature[0],
1370 mapping,
1371 mapping_internal,
1372 mapping_data,
1373 fe_internal,
1374 output_data);
1375}
1376
1377
1378
1379template <int dim, int spacedim>
1380void
1382 const typename Triangulation<dim, spacedim>::cell_iterator & /* cell */,
1383 const unsigned int /* face_no */,
1384 const Quadrature<dim - 1> & /* quadrature */,
1385 const Mapping<dim, spacedim> & /* mapping */,
1387 & /* mapping_internal */,
1389 & /* mapping_data */,
1391 & /* fe_internal */,
1393 spacedim>
1394 & /* output_data */) const
1395{
1396 Assert(false,
1397 ExcMessage("Use of a deprecated interface, please implement "
1398 "fill_fe_face_values taking a hp::QCollection argument"));
1399}
1400# endif
1401
1402
1403
1404template <int dim, int spacedim>
1405std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1407 const UpdateFlags flags,
1409 const Quadrature<dim - 1> &quadrature,
1411 spacedim>
1412 &output_data) const
1413{
1414 return get_data(flags,
1415 mapping,
1417 this->reference_cell(), quadrature),
1418 output_data);
1419}
1420
1421
1422
1423template <int dim, int spacedim>
1425FiniteElement<dim, spacedim>::base_element(const unsigned int index) const
1426{
1427 AssertIndexRange(index, 1);
1428 // This function should not be
1429 // called for a system element
1430 Assert(base_to_block_indices.size() == 1, ExcInternalError());
1431 return *this;
1432}
1433
1434
1435#endif
1436/*------------------------------- Explicit Instantiations -------------*/
1437#include "fe/fe.inst"
1438
1439
*  iterator end()
*  *  iterator begin()
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:444
unsigned int n_dofs_per_cell() const
unsigned int n_dofs_per_line() const
unsigned int n_components() const
FiniteElementData(const std::vector< unsigned int > &dofs_per_object, const unsigned int n_components, const unsigned int degree, const Conformity conformity=unknown, const BlockIndices &block_indices=BlockIndices())
Definition fe_data.cc:112
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:2731
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:2738
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:2634
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:2670
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:2713
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:2706
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:2573
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:2722
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:318
Definition point.h:111
static Quadrature< dim > project_to_all_faces(const ReferenceCell< dim > &reference_cell, const hp::QCollection< dim - 1 > &quadrature)
static Quadrature< dim > project_to_all_subfaces(const ReferenceCell< dim > &reference_cell, const SubQuadrature &quadrature)
static constexpr std::array< RefinementCase< dim >, n_refinement_cases > all_refinement_cases()
static constexpr unsigned int n_independent_components
unsigned int size() const
Definition collection.h:314
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
constexpr bool running_in_debug_mode()
Definition config.h:76
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
#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 & ExcInterpolationNotImplemented()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
Definition tria.h:1624
UpdateFlags
@ update_default
No update.
MappingQ< dim, spacedim > StaticMappingQ1< dim, spacedim >::mapping
Definition mapping_q1.h:101
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell< dim > &reference_cell)
constexpr char U
std::enable_if_t< IsBlockVector< VectorType >::value, unsigned int > n_blocks(const VectorType &vector)
Definition operators.h:47
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
*  *  *  *  std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters   const
constexpr ReferenceCell< 2 > Quadrilateral
constexpr ReferenceCell< 2 > Triangle
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:236
constexpr types::geometric_orientation reverse_line_orientation
Definition types.h:363
constexpr types::geometric_orientation default_geometric_orientation
Definition types.h:350
std::uint8_t geometric_orientation
Definition types.h:38
*  const unsigned int dofs_per_cell