deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+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\}}\)
Loading...
Searching...
No Matches
fe_abf.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) 2003 - 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
13
17#include <deal.II/base/table.h>
19
21
22#include <deal.II/fe/fe.h>
23#include <deal.II/fe/fe_abf.h>
24#include <deal.II/fe/fe_tools.h>
26#include <deal.II/fe/mapping.h>
27
28#include <deal.II/grid/tria.h>
30
31#include <iostream>
32#include <memory>
33#include <sstream>
34
36
37// TODO: implement the adjust_quad_dof_index_for_face_orientation_table and
38// adjust_line_dof_index_for_line_orientation_table fields, and write tests
39// similar to bits/face_orientation_and_fe_q_*
40
41template <int dim>
42FE_ABF<dim>::FE_ABF(const unsigned int deg)
43 : FE_PolyTensor<dim>(
44 PolynomialsABF<dim>(deg),
45 FiniteElementData<dim>(get_dpo_vector(deg),
46 dim,
47 deg + 2,
48 FiniteElementData<dim>::Hdiv),
49 std::vector<bool>(PolynomialsABF<dim>::n_polynomials(deg), true),
50 std::vector<ComponentMask>(PolynomialsABF<dim>::n_polynomials(deg),
51 ComponentMask(std::vector<bool>(dim, true))))
52 , rt_order(deg)
53{
54 Assert(dim >= 2, ExcImpossibleInDim(dim));
55 const unsigned int n_dofs = this->n_dofs_per_cell();
56
58 // First, initialize the
59 // generalized support points and
60 // quadrature weights, since they
61 // are required for interpolation.
63
64 // Now compute the inverse node matrix, generating the correct
65 // basis functions from the raw ones. For a discussion of what
66 // exactly happens here, see FETools::compute_node_matrix.
68 this->inverse_node_matrix.reinit(n_dofs, n_dofs);
70 // From now on, the shape functions provided by FiniteElement::shape_value
71 // and similar functions will be the correct ones, not
72 // the raw shape functions from the polynomial space anymore.
73
74 // Reinit the vectors of
75 // restriction and prolongation
76 // matrices to the right sizes.
77 // Restriction only for isotropic
78 // refinement
80 // Fill prolongation matrices with embedding operators
81 FETools::compute_embedding_matrices(*this, this->prolongation, false, 1.e-10);
82
84
85 // TODO: the implementation makes the assumption that all faces have the
86 // same number of dofs
88 const unsigned int face_no = 0;
89
90 // TODO[TL]: for anisotropic refinement we will probably need a table of
91 // submatrices with an array for each refine case
92 std::vector<FullMatrix<double>> face_embeddings(
93 1 << (dim - 1),
95 this->n_dofs_per_face(face_no)));
96 // TODO: Something goes wrong there. The error of the least squares fit
97 // is to large ...
98 // FETools::compute_face_embedding_matrices(*this, face_embeddings.data(), 0,
99 // 0);
100 this->interface_constraints.reinit((1 << (dim - 1)) *
101 this->n_dofs_per_face(face_no),
102 this->n_dofs_per_face(face_no));
103 unsigned int target_row = 0;
104 for (const auto &face_embedding : face_embeddings)
105 for (unsigned int i = 0; i < face_embedding.m(); ++i)
106 {
107 for (unsigned int j = 0; j < face_embedding.n(); ++j)
108 this->interface_constraints(target_row, j) = face_embedding(i, j);
109 ++target_row;
110 }
111
112 // We need to initialize the dof permutation table and the one for the sign
113 // change.
115}
116
117
118template <int dim>
119void
121{
122 // for 1d and 2d, do nothing
123 if (dim < 3)
124 return;
125
126 // TODO: Implement this for this class
127 return;
128}
129
130
131template <int dim>
132std::string
134{
135 // note that the
136 // FETools::get_fe_by_name
137 // function depends on the
138 // particular format of the string
139 // this function returns, so they
140 // have to be kept in synch
141
142 std::ostringstream namebuf;
143
144 namebuf << "FE_ABF<" << dim << ">(" << rt_order << ")";
145
146 return namebuf.str();
147}
148
149
150
151template <int dim>
152std::unique_ptr<FiniteElement<dim, dim>>
154{
155 return std::make_unique<FE_ABF<dim>>(rt_order);
156}
157
158
159//---------------------------------------------------------------------------
160// Auxiliary and internal functions
161//---------------------------------------------------------------------------
162
163
164
165// Version for 2d and higher. See above for 1d version
166template <int dim>
167void
169{
170 const QGauss<dim> cell_quadrature(deg + 2);
171 const unsigned int n_interior_points = cell_quadrature.size();
172
173 // TODO: the implementation makes the assumption that all faces have the
174 // same number of dofs
175 AssertDimension(this->n_unique_faces(), 1);
176 const unsigned int face_no = 0;
177
178 unsigned int n_face_points = (dim > 1) ? 1 : 0;
179 // compute (deg+1)^(dim-1)
180 for (unsigned int d = 1; d < dim; ++d)
181 n_face_points *= deg + 1;
182
183 this->generalized_support_points.resize(
184 GeometryInfo<dim>::faces_per_cell * n_face_points + n_interior_points);
185 this->generalized_face_support_points[face_no].resize(n_face_points);
186
187
188 // These might be required when the faces contribution is computed
189 // Therefore they will be initialized at this point.
190 std::array<std::unique_ptr<AnisotropicPolynomials<dim>>, dim> polynomials_abf;
191
192 // Generate x_1^{i} x_2^{r+1} ...
193 for (unsigned int dd = 0; dd < dim; ++dd)
194 {
195 std::vector<std::vector<Polynomials::Polynomial<double>>> poly(dim);
196 for (unsigned int d = 0; d < dim; ++d)
199
200 polynomials_abf[dd] = std::make_unique<AnisotropicPolynomials<dim>>(poly);
201 }
202
203 // Number of the point being entered
204 unsigned int current = 0;
205
206 if (dim > 1)
207 {
208 const QGauss<dim - 1> face_points(deg + 1);
209 TensorProductPolynomials<dim - 1> legendre =
211
212 boundary_weights.reinit(n_face_points, legendre.n());
213
214 // Assert (face_points.size() == this->n_dofs_per_face(),
215 // ExcInternalError());
216
217 for (unsigned int k = 0; k < n_face_points; ++k)
218 {
219 this->generalized_face_support_points[face_no][k] =
220 face_points.point(k);
221 // Compute its quadrature
222 // contribution for each
223 // moment.
224 for (unsigned int i = 0; i < legendre.n(); ++i)
225 {
226 boundary_weights(k, i) =
227 face_points.weight(k) *
228 legendre.compute_value(i, face_points.point(k));
229 }
230 }
231
232 Quadrature<dim> faces =
233 QProjector<dim>::project_to_all_faces(this->reference_cell(),
234 face_points);
235 for (unsigned int face_no = 0;
236 face_no < GeometryInfo<dim>::faces_per_cell;
237 ++face_no)
238 {
240 this->reference_cell(),
241 face_no,
243 n_face_points);
244 for (unsigned int face_point = 0; face_point < n_face_points;
245 ++face_point)
246 {
247 // Enter the support point into the vector
248 this->generalized_support_points[current] =
249 faces.point(offset + face_point);
250 ++current;
251 }
252 }
253
254
255 // Now initialize edge interior weights for the ABF elements.
256 // These are completely independent from the usual edge moments. They
257 // stem from applying the Gauss theorem to the nodal values, which
258 // was necessary to cast the ABF elements into the deal.II framework
259 // for vector valued elements.
260 boundary_weights_abf.reinit(faces.size(), polynomials_abf[0]->n() * dim);
261 for (unsigned int k = 0; k < faces.size(); ++k)
262 {
263 for (unsigned int i = 0; i < polynomials_abf[0]->n() * dim; ++i)
264 {
265 boundary_weights_abf(k, i) =
266 polynomials_abf[i % dim]->compute_value(i / dim,
267 faces.point(k)) *
268 faces.weight(k);
269 }
270 }
271 }
272
273 // Create Legendre basis for the
274 // space D_xi Q_k
275 if (deg > 0)
276 {
277 std::array<std::unique_ptr<AnisotropicPolynomials<dim>>, dim> polynomials;
278
279 for (unsigned int dd = 0; dd < dim; ++dd)
280 {
281 std::vector<std::vector<Polynomials::Polynomial<double>>> poly(dim);
282 for (unsigned int d = 0; d < dim; ++d)
285
286 polynomials[dd] = std::make_unique<AnisotropicPolynomials<dim>>(poly);
287 }
288
289 interior_weights.reinit(
290 TableIndices<3>(n_interior_points, polynomials[0]->n(), dim));
291
292 for (unsigned int k = 0; k < cell_quadrature.size(); ++k)
293 {
294 for (unsigned int i = 0; i < polynomials[0]->n(); ++i)
295 for (unsigned int d = 0; d < dim; ++d)
296 interior_weights(k, i, d) =
297 cell_quadrature.weight(k) *
298 polynomials[d]->compute_value(i, cell_quadrature.point(k));
299 }
300 }
301
302
303 // Decouple the creation of the generalized support points
304 // from computation of interior weights.
305 for (unsigned int k = 0; k < cell_quadrature.size(); ++k)
306 this->generalized_support_points[current++] = cell_quadrature.point(k);
307
308 // Additional functionality for the ABF elements
309 // TODO: Here the canonical extension of the principle
310 // behind the ABF elements is implemented. It is unclear,
311 // if this really leads to the ABF spaces in 3d!
312 interior_weights_abf.reinit(TableIndices<3>(cell_quadrature.size(),
313 polynomials_abf[0]->n() * dim,
314 dim));
315 Tensor<1, dim> poly_grad;
316
317 for (unsigned int k = 0; k < cell_quadrature.size(); ++k)
318 {
319 for (unsigned int i = 0; i < polynomials_abf[0]->n() * dim; ++i)
320 {
321 poly_grad =
322 polynomials_abf[i % dim]->compute_grad(i / dim,
323 cell_quadrature.point(k)) *
324 cell_quadrature.weight(k);
325 // The minus sign comes from the use of the Gauss theorem to replace
326 // the divergence.
327 for (unsigned int d = 0; d < dim; ++d)
328 interior_weights_abf(k, i, d) = -poly_grad[d];
329 }
330 }
331
332 Assert(current == this->generalized_support_points.size(),
334}
335
336
337
338// This function is the same Raviart-Thomas interpolation performed by
339// interpolate. Still, we cannot use interpolate, since it was written
340// for smooth functions. The functions interpolated here are not
341// smooth, maybe even not continuous. Therefore, we must double the
342// number of quadrature points in each direction in order to integrate
343// only smooth functions.
344
345// Then again, the interpolated function is chosen such that the
346// moments coincide with the function to be interpolated.
347
348template <int dim>
349void
351{
352 if (dim == 1)
353 {
354 unsigned int iso = RefinementCase<dim>::isotropic_refinement - 1;
355 for (unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_cell;
356 ++i)
357 this->restriction[iso][i].reinit(0, 0);
358 return;
359 }
360 unsigned int iso = RefinementCase<dim>::isotropic_refinement - 1;
361 const QGauss<dim - 1> q_base(rt_order + 1);
362 const unsigned int n_face_points = q_base.size();
363 // First, compute interpolation on
364 // subfaces
365 for (const unsigned int face : GeometryInfo<dim>::face_indices())
366 {
367 // The shape functions of the
368 // child cell are evaluated
369 // in the quadrature points
370 // of a full face.
372 this->reference_cell(),
373 q_base,
374 face,
376 // Store shape values, since the
377 // evaluation suffers if not
378 // ordered by point
379 Table<2, double> cached_values_face(this->n_dofs_per_cell(),
380 q_face.size());
381 for (unsigned int k = 0; k < q_face.size(); ++k)
382 for (unsigned int i = 0; i < this->n_dofs_per_cell(); ++i)
383 cached_values_face(i, k) = this->shape_value_component(
385
386 for (unsigned int sub = 0; sub < GeometryInfo<dim>::max_children_per_face;
387 ++sub)
388 {
389 // The weight functions for
390 // the coarse face are
391 // evaluated on the subface
392 // only.
394 this->reference_cell(),
395 q_base,
396 face,
397 sub,
400 const unsigned int child = GeometryInfo<dim>::child_cell_on_face(
402
403 // On a certain face, we must
404 // compute the moments of ALL
405 // fine level functions with
406 // the coarse level weight
407 // functions belonging to
408 // that face. Due to the
409 // orthogonalization process
410 // when building the shape
411 // functions, these weights
412 // are equal to the
413 // corresponding shape
414 // functions.
415 for (unsigned int k = 0; k < n_face_points; ++k)
416 for (unsigned int i_child = 0; i_child < this->n_dofs_per_cell();
417 ++i_child)
418 for (unsigned int i_face = 0;
419 i_face < this->n_dofs_per_face(face);
420 ++i_face)
421 {
422 // The quadrature
423 // weights on the
424 // subcell are NOT
425 // transformed, so we
426 // have to do it here.
427 this->restriction[iso][child](
428 face * this->n_dofs_per_face(face) + i_face, i_child) +=
429 Utilities::fixed_power<dim - 1>(.5) * q_sub.weight(k) *
430 cached_values_face(i_child, k) *
431 this->shape_value_component(
432 face * this->n_dofs_per_face(face) + i_face,
433 q_sub.point(k),
435 }
436 }
437 }
438
439 if (rt_order == 0)
440 return;
441
442 // Create Legendre basis for the
443 // space D_xi Q_k. Here, we cannot
444 // use the shape functions
445 std::array<std::unique_ptr<AnisotropicPolynomials<dim>>, dim> polynomials;
446 for (unsigned int dd = 0; dd < dim; ++dd)
447 {
448 std::vector<std::vector<Polynomials::Polynomial<double>>> poly(dim);
449 for (unsigned int d = 0; d < dim; ++d)
451 poly[dd] = Polynomials::Legendre::generate_complete_basis(rt_order - 1);
452
453 polynomials[dd] = std::make_unique<AnisotropicPolynomials<dim>>(poly);
454 }
455
456 // TODO: the implementation makes the assumption that all faces have the
457 // same number of dofs
458 AssertDimension(this->n_unique_faces(), 1);
459 const unsigned int face_no = 0;
460
461 const QGauss<dim> q_cell(rt_order + 1);
462 const unsigned int start_cell_dofs =
463 GeometryInfo<dim>::faces_per_cell * this->n_dofs_per_face(face_no);
464
465 // Store shape values, since the
466 // evaluation suffers if not
467 // ordered by point
468 Table<3, double> cached_values_cell(this->n_dofs_per_cell(),
469 q_cell.size(),
470 dim);
471 for (unsigned int k = 0; k < q_cell.size(); ++k)
472 for (unsigned int i = 0; i < this->n_dofs_per_cell(); ++i)
473 for (unsigned int d = 0; d < dim; ++d)
474 cached_values_cell(i, k, d) =
475 this->shape_value_component(i, q_cell.point(k), d);
476
477 for (unsigned int child = 0; child < GeometryInfo<dim>::max_children_per_cell;
478 ++child)
479 {
480 Quadrature<dim> q_sub =
481 QProjector<dim>::project_to_child(this->reference_cell(),
482 q_cell,
483 child);
484
485 for (unsigned int k = 0; k < q_sub.size(); ++k)
486 for (unsigned int i_child = 0; i_child < this->n_dofs_per_cell();
487 ++i_child)
488 for (unsigned int d = 0; d < dim; ++d)
489 for (unsigned int i_weight = 0; i_weight < polynomials[d]->n();
490 ++i_weight)
491 {
492 this->restriction[iso][child](start_cell_dofs + i_weight * dim +
493 d,
494 i_child) +=
495 q_sub.weight(k) * cached_values_cell(i_child, k, d) *
496 polynomials[d]->compute_value(i_weight, q_sub.point(k));
497 }
498 }
499}
500
501
502
503template <int dim>
504std::vector<unsigned int>
505FE_ABF<dim>::get_dpo_vector(const unsigned int rt_order)
506{
507 if (dim == 1)
508 {
509 Assert(false, ExcImpossibleInDim(1));
510 return std::vector<unsigned int>();
511 }
512
513 // the element is face-based (not
514 // to be confused with George
515 // W. Bush's Faith Based
516 // Initiative...), and we have
517 // (rt_order+1)^(dim-1) DoFs per face
518 unsigned int dofs_per_face = 1;
519 for (unsigned int d = 0; d < dim - 1; ++d)
520 dofs_per_face *= rt_order + 1;
521
522 // and then there are interior dofs
523 const unsigned int interior_dofs = dim * (rt_order + 1) * dofs_per_face;
524
525 std::vector<unsigned int> dpo(dim + 1);
526 dpo[dim - 1] = dofs_per_face;
527 dpo[dim] = interior_dofs;
528
529 return dpo;
530}
531
532//---------------------------------------------------------------------------
533// Data field initialization
534//---------------------------------------------------------------------------
535
536template <int dim>
537bool
538FE_ABF<dim>::has_support_on_face(const unsigned int shape_index,
539 const unsigned int face_index) const
540{
541 AssertIndexRange(shape_index, this->n_dofs_per_cell());
543
544 // Return computed values if we
545 // know them easily. Otherwise, it
546 // is always safe to return true.
547 switch (rt_order)
548 {
549 case 0:
550 {
551 switch (dim)
552 {
553 case 2:
554 {
555 // only on the one
556 // non-adjacent face
557 // are the values
558 // actually zero. list
559 // these in a table
560 return (face_index !=
562 }
563
564 default:
565 return true;
566 }
567 }
568
569 default: // other rt_order
570 return true;
571 }
572
573 return true;
574}
575
576
577
578template <int dim>
579void
581 const std::vector<Vector<double>> &support_point_values,
582 std::vector<double> &nodal_values) const
583{
584 Assert(support_point_values.size() == this->generalized_support_points.size(),
585 ExcDimensionMismatch(support_point_values.size(),
586 this->generalized_support_points.size()));
587 Assert(support_point_values[0].size() == this->n_components(),
588 ExcDimensionMismatch(support_point_values[0].size(),
589 this->n_components()));
590 Assert(nodal_values.size() == this->n_dofs_per_cell(),
591 ExcDimensionMismatch(nodal_values.size(), this->n_dofs_per_cell()));
592
593 std::fill(nodal_values.begin(), nodal_values.end(), 0.);
594
595 const unsigned int n_face_points = boundary_weights.size(0);
596 for (const unsigned int face : GeometryInfo<dim>::face_indices())
597 for (unsigned int k = 0; k < n_face_points; ++k)
598 for (unsigned int i = 0; i < boundary_weights.size(1); ++i)
599 {
600 nodal_values[i + face * this->n_dofs_per_face(face)] +=
601 boundary_weights(k, i) *
602 support_point_values[face * n_face_points + k][GeometryInfo<
603 dim>::unit_normal_direction[face]];
604 }
605
606 // TODO: the implementation makes the assumption that all faces have the
607 // same number of dofs
608 AssertDimension(this->n_unique_faces(), 1);
609 const unsigned int face_no = 0;
610
611 const unsigned int start_cell_dofs =
612 GeometryInfo<dim>::faces_per_cell * this->n_dofs_per_face(face_no);
613 const unsigned int start_cell_points =
614 GeometryInfo<dim>::faces_per_cell * n_face_points;
615
616 for (unsigned int k = 0; k < interior_weights.size(0); ++k)
617 for (unsigned int i = 0; i < interior_weights.size(1); ++i)
618 for (unsigned int d = 0; d < dim; ++d)
619 nodal_values[start_cell_dofs + i * dim + d] +=
620 interior_weights(k, i, d) *
621 support_point_values[k + start_cell_points][d];
622
623 const unsigned int start_abf_dofs =
624 start_cell_dofs + interior_weights.size(1) * dim;
625
626 // Cell integral of ABF terms
627 for (unsigned int k = 0; k < interior_weights_abf.size(0); ++k)
628 for (unsigned int i = 0; i < interior_weights_abf.size(1); ++i)
629 for (unsigned int d = 0; d < dim; ++d)
630 nodal_values[start_abf_dofs + i] +=
631 interior_weights_abf(k, i, d) *
632 support_point_values[k + start_cell_points][d];
633
634 // Face integral of ABF terms
635 for (const unsigned int face : GeometryInfo<dim>::face_indices())
636 {
637 const double n_orient = GeometryInfo<dim>::unit_normal_orientation[face];
638 for (unsigned int fp = 0; fp < n_face_points; ++fp)
639 {
640 // TODO: Check what the face_orientation, face_flip and face_rotation
641 // have to be in 3d
643 this->reference_cell(),
644 face,
646 n_face_points);
647 for (unsigned int i = 0; i < boundary_weights_abf.size(1); ++i)
648 nodal_values[start_abf_dofs + i] +=
649 n_orient * boundary_weights_abf(k + fp, i) *
650 support_point_values[face * n_face_points + fp][GeometryInfo<
651 dim>::unit_normal_direction[face]];
652 }
653 }
654
655 // TODO: Check if this "correction" can be removed.
656 for (unsigned int i = 0; i < boundary_weights_abf.size(1); ++i)
657 if (std::fabs(nodal_values[start_abf_dofs + i]) < 1.0e-16)
658 nodal_values[start_abf_dofs + i] = 0.0;
659}
660
661
662
663template <int dim>
664std::size_t
666{
668 return 0;
669}
670
671
672
673/*-------------- Explicit Instantiations -------------------------------*/
674#include "fe/fe_abf.inst"
675
***mech_lbc_system increment_interpolation_handlers push_back(scale_z_handler)
void initialize_quad_dof_index_permutation_and_sign_change()
Definition fe_abf.cc:120
virtual std::unique_ptr< FiniteElement< dim, dim > > clone() const override
Definition fe_abf.cc:153
virtual void convert_generalized_support_point_values_to_dof_values(const std::vector< Vector< double > > &support_point_values, std::vector< double > &nodal_values) const override
Definition fe_abf.cc:580
virtual std::size_t memory_consumption() const override
Definition fe_abf.cc:665
void initialize_restriction()
Definition fe_abf.cc:350
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const override
Definition fe_abf.cc:538
virtual std::string get_name() const override
Definition fe_abf.cc:133
static std::vector< unsigned int > get_dpo_vector(const unsigned int degree)
Definition fe_abf.cc:505
void initialize_support_points(const unsigned int rt_degree)
Definition fe_abf.cc:168
friend class FE_ABF
Definition fe_abf.h:253
FullMatrix< double > inverse_node_matrix
std::vector< MappingKind > mapping_kind
unsigned int n_dofs_per_cell() const
unsigned int n_dofs_per_face(unsigned int face_no=0, unsigned int child=0) const
unsigned int n_unique_faces() const
void reinit_restriction_and_prolongation_matrices(const bool isotropic_restriction_only=false, const bool isotropic_prolongation_only=false)
FullMatrix< double > interface_constraints
Definition fe.h:2573
std::vector< std::vector< FullMatrix< double > > > prolongation
Definition fe.h:2561
void invert(const FullMatrix< number2 > &M)
static std::vector< Polynomial< double > > generate_complete_basis(const unsigned int degree)
static std::vector< Polynomial< number > > generate_complete_basis(const unsigned int degree)
static DataSetDescriptor face(const ReferenceCell< dim > &reference_cell, const unsigned int face_no, const types::geometric_orientation combined_orientation, const unsigned int n_quadrature_points)
static Quadrature< dim > project_to_all_faces(const ReferenceCell< dim > &reference_cell, const hp::QCollection< dim - 1 > &quadrature)
static Quadrature< dim > project_to_face(const ReferenceCell< dim > &reference_cell, const SubQuadrature &quadrature, const unsigned int face_no, const types::geometric_orientation combined_orientation)
static Quadrature< dim > project_to_subface(const ReferenceCell< dim > &reference_cell, const SubQuadrature &quadrature, const unsigned int face_no, const unsigned int subface_no, const types::geometric_orientation combined_orientation, const RefinementCase< dim - 1 > &ref_case)
static Quadrature< dim > project_to_child(const ReferenceCell< dim > &reference_cell, const Quadrature< dim > &quadrature, const unsigned int child_no)
const Point< dim > & point(const unsigned int i) const
double weight(const unsigned int i) const
unsigned int size() const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_NOT_IMPLEMENTED()
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
@ mapping_raviart_thomas
Definition mapping.h:134
std::size_t size
Definition mpi.cc:733
void compute_embedding_matrices(const FiniteElement< dim, spacedim > &fe, std::vector< std::vector< FullMatrix< number > > > &matrices, const bool isotropic_only=false, const double threshold=1.e-12)
FullMatrix< double > compute_node_matrix(const FiniteElement< dim, spacedim > &fe)
constexpr types::geometric_orientation default_geometric_orientation
Definition types.h:342
STL namespace.
static unsigned int child_cell_on_face(const RefinementCase< dim > &ref_case, const unsigned int face, const unsigned int subface, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false, const RefinementCase< dim - 1 > &face_refinement_case=RefinementCase< dim - 1 >::isotropic_refinement)
static std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices()