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