Flow123d  DF_patch_fe_mechanics-ccea6e4
patch_fe_values.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file patch_fe_values.hh
15  * @brief Class FEValues calculates finite element data on the actual
16  * cells such as shape function values, gradients, Jacobian of
17  * the mapping from the reference cell etc.
18  * @author Jan Stebel, David Flanderka
19  */
20 
21 #ifndef PATCH_FE_VALUES_HH_
22 #define PATCH_FE_VALUES_HH_
23 
24 
25 #include <string.h> // for memcpy
26 #include <algorithm> // for swap
27 #include <new> // for operator new[]
28 #include <string> // for operator<<
29 #include <vector> // for vector
30 #include "fem/fe_system.hh" // for FESystem
31 #include "fem/eigen_tools.hh"
33 #include "fem/mapping_p1.hh"
34 #include "mesh/ref_element.hh" // for RefElement
35 #include "mesh/accessors.hh"
36 #include "fem/update_flags.hh" // for UpdateFlags
38 #include "fields/eval_subset.hh"
39 #include "fem/arena_resource.hh"
40 #include "fem/arena_vec.hh"
41 
42 template<unsigned int spacedim> class PatchFEValues;
43 
44 
45 
46 
47 template <class ValueType>
48 class ElQ {
49 public:
50  /// Forbidden default constructor
51  ElQ() = delete;
52 
53  /// Constructor
54  ElQ(PatchPointValues<3> *patch_point_vals, unsigned int op_idx)
55  : patch_point_vals_(patch_point_vals), op_idx_(op_idx) {}
56 
57  ValueType operator()(const BulkPoint &point) const;
58 
59  ValueType operator()(const SidePoint &point) const;
60 
61 private:
62  PatchPointValues<3> *patch_point_vals_; ///< Reference to PatchPointValues
63  unsigned int op_idx_; ///< Index of operation in patch_point_vals_.operations vector
64 };
65 
66 
67 template <class ValueType>
68 class FeQ {
69 public:
70  /// Forbidden default constructor
71  FeQ() = delete;
72 
73  // Class similar to current FeView
74  FeQ(PatchPointValues<3> *patch_point_vals, bool is_bulk, unsigned int op_idx)
75  : patch_point_vals_bulk_(nullptr), patch_point_vals_side_(nullptr), op_idx_(op_idx), i_shape_fn_idx_(0) {
76  if (is_bulk) patch_point_vals_bulk_ = patch_point_vals;
77  else patch_point_vals_side_ = patch_point_vals;
78  }
79 
80  /// Constructor used only in FeQArray::shape()
81  FeQ(PatchPointValues<3> *patch_point_vals_bulk, PatchPointValues<3> *patch_point_vals_side,
82  unsigned int op_idx, unsigned int i_shape_fn_idx)
83  : patch_point_vals_bulk_(patch_point_vals_bulk), patch_point_vals_side_(patch_point_vals_side),
84  op_idx_(op_idx), i_shape_fn_idx_(i_shape_fn_idx) {}
85 
86 
87  ValueType operator()(const BulkPoint &point) const;
88 
89  ValueType operator()(const SidePoint &point) const;
90 
91  // Implementation for EdgePoint, SidePoint, and JoinPoint shoud have a common implementation
92  // resolving to side values
93 
94 private:
95  PatchPointValues<3> *patch_point_vals_bulk_; ///< Pointer to bulk PatchPointValues
96  PatchPointValues<3> *patch_point_vals_side_; ///< Pointer to side PatchPointValues
97  unsigned int op_idx_; ///< Index of operation in patch_point_vals_.operations vector
98  unsigned int i_shape_fn_idx_; ///< Index of shape function
99 };
100 
101 
102 template <class ValueType>
103 class FeQArray {
104 public:
105  /// Forbidden default constructor
106  FeQArray() = delete;
107 
108  // Class similar to current FeView
109  FeQArray(PatchPointValues<3> *patch_point_vals, bool is_bulk, unsigned int op_idx, unsigned int n_dofs)
110  : patch_point_vals_bulk_(nullptr), patch_point_vals_side_(nullptr), op_idx_(op_idx), n_dofs_(n_dofs) {
111  ASSERT_GT(n_dofs, 0).error("Invalid number of DOFs.\n");
112 
113  if (is_bulk) patch_point_vals_bulk_ = patch_point_vals;
114  else patch_point_vals_side_ = patch_point_vals;
115  }
116 
117 
118  FeQ<ValueType> shape(unsigned int i_shape_fn_idx) const {
119  ASSERT_LT(i_shape_fn_idx, n_dofs_);
121  }
122 
123  /// Return number of DOFs
124  inline unsigned int n_dofs() const {
125  return n_dofs_;
126  }
127 
128 private:
129  PatchPointValues<3> *patch_point_vals_bulk_; ///< Reference to bulk PatchPointValues
130  PatchPointValues<3> *patch_point_vals_side_; ///< Reference to side PatchPointValues
131  unsigned int op_idx_; ///< Index of operation in patch_point_vals_.operations vector
132  unsigned int n_dofs_; ///< Number of DOFs
133 };
134 
135 
136 template <class ValueType>
137 class FeQJoin {
138 public:
139  /// Default constructor
141  : patch_point_vals_bulk_(nullptr), patch_point_vals_side_(nullptr) {}
142 
143  /**
144  * Constructor
145  *
146  * @param patch_point_vals_bulk Pointer to PatchPointValues bulk object.
147  * @param patch_point_vals_side Pointer to PatchPointValues side object.
148  * @param begin Index of the first component of the bulk Quantity.
149  * @param begin_side Index of the first component of the side Quantity.
150  * @param n_dofs_bulk Number of DOFs of bulk (lower-dim) element.
151  * @param n_dofs_side Number of DOFs of side (higher-dim) element.
152  */
153  FeQJoin(PatchPointValues<3> *patch_point_vals_bulk, PatchPointValues<3> *patch_point_vals_side, unsigned int n_dofs_bulk,
154  unsigned int n_dofs_side, unsigned int op_idx_bulk, unsigned int op_idx_side)
155  : patch_point_vals_bulk_(patch_point_vals_bulk), patch_point_vals_side_(patch_point_vals_side),
156  n_dofs_high_(n_dofs_side), n_dofs_low_(n_dofs_bulk), op_idx_bulk_(op_idx_bulk), op_idx_side_(op_idx_side) {}
157 
158 
159  inline unsigned int n_dofs_low() const {
160  return n_dofs_low_;
161  }
162 
163  inline unsigned int n_dofs_high() const {
164  return n_dofs_high_;
165  }
166 
167  inline unsigned int n_dofs_both() const {
168  return n_dofs_high_ + n_dofs_low_;
169  }
170 
171 // /// Return local index of DOF (on low / high-dim) - should be private method
172 // inline unsigned int local_idx(unsigned int i_join_idx) const {
173 // if (this->is_high_dim(i_join_idx)) return (i_join_idx - n_dofs_low());
174 // else return i_join_idx;
175 // }
176 
177  inline bool is_high_dim(unsigned int i_join_idx) const {
178  return (i_join_idx >= n_dofs_low());
179  }
180 
181  FeQ<ValueType> shape(unsigned int i_join_idx) const {
182  ASSERT_LT(i_join_idx, n_dofs_both());
183 
184  /*
185  * Set zero bulk PatchFeValues for side DOFs and zero side PatchFeValues for bulk DOFs
186  *
187  * TODO After implementation of dependencies:
188  * 1) Implement FeQ::vec() getter (experimental method returned entire data vector)
189  * 2) Test difference of vectors
190  */
191  if (this->is_high_dim(i_join_idx))
193  else
195  }
196 
197 
198 private:
199  // attributes:
200  PatchPointValues<3> *patch_point_vals_bulk_; ///< Pointer to bulk PatchPointValues
201  PatchPointValues<3> *patch_point_vals_side_; ///< Pointer to side PatchPointValues
202  unsigned int n_dofs_high_; ///< Number of DOFs on high-dim element
203  unsigned int n_dofs_low_; ///< Number of DOFs on low-dim element
204  unsigned int op_idx_bulk_; ///< Index of operation in patch_point_vals_bulk_.operations vector
205  unsigned int op_idx_side_; ///< Index of operation in patch_point_vals_side_.operations vector
206 };
207 
208 
209 
210 template<unsigned int dim>
212 {
213 protected:
214  // Default constructor
216  {}
217 
218  /// Return FiniteElement of \p component_idx for FESystem or \p fe for other types
219  template<unsigned int FE_dim>
220  std::shared_ptr<FiniteElement<FE_dim>> fe_comp(std::shared_ptr< FiniteElement<FE_dim> > fe, uint component_idx) {
221  if (fe->fe_type() == FEMixedSystem) {
222  FESystem<FE_dim> *fe_sys = dynamic_cast<FESystem<FE_dim>*>( fe.get() );
223  return fe_sys->fe()[component_idx];
224  } else {
225  ASSERT_EQ(component_idx, 0).warning("Non-zero component_idx can only be used for FESystem.");
226  return fe;
227  }
228  }
229 
230  /**
231  * @brief Precomputed values of basis functions at the bulk quadrature points.
232  *
233  * Dimensions: (no. of quadrature points)
234  * x (no. of dofs)
235  * x (no. of components in ref. cell)
236  */
237  template<unsigned int FE_dim>
239  std::vector<std::vector<arma::vec> > ref_shape_vals( q->size(), vector<arma::vec>(fe->n_dofs()) );
240 
241  arma::mat shape_values(fe->n_dofs(), fe->n_components());
242  for (unsigned int i=0; i<q->size(); i++)
243  {
244  for (unsigned int j=0; j<fe->n_dofs(); j++)
245  {
246  for (unsigned int c=0; c<fe->n_components(); c++)
247  shape_values(j,c) = fe->shape_value(j, q->point<FE_dim>(i), c);
248 
249  ref_shape_vals[i][j] = trans(shape_values.row(j));
250  }
251  }
252 
253  return ref_shape_vals;
254  }
255 
256  /**
257  * @brief Precomputed values of basis functions at the side quadrature points.
258  *
259  * Dimensions: (sides)
260  * x (no. of quadrature points)
261  * x (no. of dofs)
262  * x (no. of components in ref. cell)
263  */
264  template<unsigned int FE_dim>
267 
268  arma::mat shape_values(fe->n_dofs(), fe->n_components());
269 
270  for (unsigned int sid=0; sid<FE_dim+1; sid++) {
271  auto quad = q->make_from_side<FE_dim>(sid);
272  for (unsigned int i=0; i<quad.size(); i++)
273  {
274  for (unsigned int j=0; j<fe->n_dofs(); j++)
275  {
276  for (unsigned int c=0; c<fe->n_components(); c++) {
277  shape_values(j,c) = fe->shape_value(j, quad.template point<FE_dim>(i), c);
278  }
279 
280  ref_shape_vals[sid][i][j] = trans(shape_values.row(j));
281  }
282  }
283  }
284 
285  return ref_shape_vals;
286  }
287 
288  /**
289  * @brief Precomputed gradients of basis functions at the bulk quadrature points.
290  *
291  * Dimensions: (no. of quadrature points)
292  * x (no. of dofs)
293  * x ((dim_ of. ref. cell)x(no. of components in ref. cell))
294  */
295  template<unsigned int FE_dim>
297  std::vector<std::vector<arma::mat> > ref_shape_grads( q->size(), vector<arma::mat>(fe->n_dofs()) );
298 
299  arma::mat grad(FE_dim, fe->n_components());
300  for (unsigned int i_pt=0; i_pt<q->size(); i_pt++)
301  {
302  for (unsigned int i_dof=0; i_dof<fe->n_dofs(); i_dof++)
303  {
304  grad.zeros();
305  for (unsigned int c=0; c<fe->n_components(); c++)
306  grad.col(c) += fe->shape_grad(i_dof, q->point<FE_dim>(i_pt), c);
307 
308  ref_shape_grads[i_pt][i_dof] = grad;
309  }
310  }
311 
312  return ref_shape_grads;
313  }
314 
315  /**
316  * @brief Precomputed gradients of basis functions at the side quadrature points.
317  *
318  * Dimensions: (sides)
319  * x (no. of quadrature points)
320  * x (no. of dofs)
321  * x ((dim_ of. ref. cell)x(no. of components in ref. cell))
322  */
323  template<unsigned int FE_dim>
325  std::vector<std::vector<std::vector<arma::mat> > > ref_shape_grads( FE_dim+1, std::vector<std::vector<arma::mat> >(q->size(), vector<arma::mat>(fe->n_dofs())) );
326 
327  arma::mat grad(dim, fe->n_components());
328  for (unsigned int sid=0; sid<FE_dim+1; sid++) {
329  auto quad = q->make_from_side<FE_dim>(sid);
330  for (unsigned int i_pt=0; i_pt<quad.size(); i_pt++)
331  {
332  for (unsigned int i_dof=0; i_dof<fe->n_dofs(); i_dof++)
333  {
334  grad.zeros();
335  for (unsigned int c=0; c<fe->n_components(); c++)
336  grad.col(c) += fe->shape_grad(i_dof, quad.template point<FE_dim>(i_pt), c);
337 
338  ref_shape_grads[sid][i_pt][i_dof] = grad;
339  }
340  }
341  }
342 
343  return ref_shape_grads;
344  }
345 
346 };
347 
348 template<unsigned int dim>
349 class BulkValues : public BaseValues<dim>
350 {
351 public:
352  /// Constructor
354  : BaseValues<dim>(), patch_point_vals_(patch_point_vals) {
355  ASSERT_EQ(patch_point_vals->dim(), dim);
356  fe_ = fe[Dim<dim>{}];
357  }
358 
359  /**
360  * @brief Register the product of Jacobian determinant and the quadrature
361  * weight at bulk quadrature points.
362  *
363  * @param quad Quadrature.
364  */
365  inline FeQ<Scalar> JxW()
366  {
368  }
369 
370  /// Create bulk accessor of coords entity
372  {
374  }
375 
376 // inline ElQ<Tensor> jacobian(std::initializer_list<Quadrature *> quad_list)
377 // {}
378 
379  /// Create bulk accessor of jac determinant entity
381  {
383  }
384 
385  inline FeQArray<Scalar> ref_scalar(uint component_idx = 0)
386  {
387  auto fe_component = this->fe_comp(fe_, component_idx);
388  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
389 
390  uint n_points = patch_point_vals_->get_quadrature()->size();
391  uint n_dofs = fe_component->n_dofs();
392 
394 
395  auto ref_shape_vals = this->ref_shape_values_bulk(patch_point_vals_->get_quadrature(), fe_component);
396  ref_scalar_op->allocate_result(n_points, patch_point_vals_->asm_arena());
397  auto ref_scalar_value = ref_scalar_op->result_matrix();
398  for (unsigned int i_p = 0; i_p < n_points; i_p++)
399  for (unsigned int i_dof = 0; i_dof < n_dofs; i_dof++) {
400  ref_scalar_value(i_dof)(i_p) = ref_shape_vals[i_p][i_dof][0];
401  }
402 
403  return FeQArray<Scalar>(patch_point_vals_, true, FeBulk::BulkOps::opRefScalar, fe_component->n_dofs());
404  }
405 
406  inline FeQArray<Vector> ref_vector(uint component_idx = 0)
407  {
408  auto fe_component = this->fe_comp(fe_, component_idx);
409  ASSERT((fe_component->fe_type() == FEType::FEVector) | (fe_component->fe_type() == FEType::FEVectorPiola) | (fe_component->fe_type() == FEType::FEVectorContravariant))
410  .error("Type of FiniteElement of grad_vector_shape accessor must be FEVector, FEVectorPiola or FEVectorContravariant!\n");
411 
412  uint n_points = patch_point_vals_->get_quadrature()->size();
413  uint n_dofs = fe_component->n_dofs();
414 
415  auto *vector_ref_op = patch_point_vals_->make_fixed_fe_op(FeBulk::BulkOps::opRefVector, {3, n_dofs}, &common_reinit::op_base, n_dofs);
416 
417  vector_ref_op->allocate_result(n_points, patch_point_vals_->asm_arena());
418  auto vector_ref_result = vector_ref_op->result_matrix();
419  auto ref_shape_vals = this->ref_shape_values_bulk(patch_point_vals_->get_quadrature(), fe_component);
420 
421  for (uint i_dof=0; i_dof<n_dofs; ++i_dof)
422  for (uint i_p=0; i_p<n_points; ++i_p)
423  for (uint c=0; c<3; ++c)
424  vector_ref_result(c, i_dof)(i_p) = ref_shape_vals[i_p][i_dof](c);
425 
427  }
428 
429  inline FeQArray<Vector> ref_scalar_grad(uint component_idx = 0)
430  {
431  auto fe_component = this->fe_comp(fe_, component_idx);
432  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
433 
434  uint n_points = patch_point_vals_->get_quadrature()->size();
435  uint n_dofs = fe_component->n_dofs();
436 
437  auto *ref_scalar_op = patch_point_vals_->make_fixed_fe_op(FeBulk::BulkOps::opRefScalarGrad, {dim, n_dofs}, &common_reinit::op_base, n_dofs);
438 
440  ref_scalar_op->allocate_result(n_points, patch_point_vals_->asm_arena());
441  auto ref_scalar_value = ref_scalar_op->result_matrix();
442  for (uint i=0; i<ref_scalar_value.rows(); ++i) {
443  for (uint i_dof=0; i_dof<n_dofs; ++i_dof)
444  for (uint i_p=0; i_p<n_points; ++i_p)
445  ref_scalar_value(i, i_dof)(i_p) = ref_shape_grads[i_p][i_dof](i);
446  }
447 
448  return FeQArray<Vector>(patch_point_vals_, true, FeBulk::BulkOps::opRefScalarGrad, fe_component->n_dofs());
449  }
450 
451  inline FeQArray<Tensor> ref_vector_grad(uint component_idx = 0)
452  {
453  auto fe_component = this->fe_comp(fe_, component_idx);
454  ASSERT((fe_component->fe_type() == FEType::FEVector) | (fe_component->fe_type() == FEType::FEVectorPiola) | (fe_component->fe_type() == FEType::FEVectorContravariant))
455  .error("Type of FiniteElement of grad_vector_shape accessor must be FEVector, FEVectorPiola or FEVectorContravariant!\n");
456 
457  uint n_points = patch_point_vals_->get_quadrature()->size();
458  uint n_dofs = fe_component->n_dofs();
459 
460  auto *ref_vector_op = patch_point_vals_->make_fixed_fe_op(FeBulk::BulkOps::opRefVectorGrad, {dim, 3*n_dofs}, &common_reinit::op_base, n_dofs);
461 
463  ref_vector_op->allocate_result(n_points, patch_point_vals_->asm_arena());
464  auto ref_vector_value = ref_vector_op->result_matrix();
465  for (uint i_c=0; i_c<3; ++i_c) {
466  for (uint i_dim=0; i_dim<dim; ++i_dim)
467  for (uint i_dof=0; i_dof<n_dofs; ++i_dof)
468  for (uint i_p=0; i_p<n_points; ++i_p)
469  ref_vector_value(i_dim,3*i_dof+i_c)(i_p) = ref_shape_grads[i_p][i_dof](i_dim, i_c);
470  }
471 
473  }
474 
475  /**
476  * @brief Return the value of the @p function_no-th shape function at
477  * the @p p bulk quadrature point.
478  *
479  * @param component_idx Number of the shape function.
480  */
481  inline FeQArray<Scalar> scalar_shape(uint component_idx = 0)
482  {
483  auto fe_component = this->fe_comp(fe_, component_idx);
484  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
485 
486  uint n_dofs = fe_component->n_dofs();
488 
490  }
491 
492  inline FeQArray<Vector> vector_shape(uint component_idx = 0)
493  {
494  auto fe_component = this->fe_comp(fe_, component_idx);
495 
496  uint n_dofs = fe_component->n_dofs();
497  uint vector_shape_op_idx = FeBulk::BulkOps::opVectorShape;
498 
499  switch (fe_component->fe_type()) {
500  case FEVector:
501  {
502  patch_point_vals_->make_fe_op(vector_shape_op_idx, {3, n_dofs}, bulk_reinit::ptop_vector_shape, n_dofs);
503  break;
504  }
506  {
507  ASSERT_PERMANENT(false).error("Shape vector for FEVectorContravariant is not implemented yet!\n"); // temporary assert
508  patch_point_vals_->make_fe_op(vector_shape_op_idx, {3, n_dofs}, bulk_reinit::ptop_vector_contravariant_shape, n_dofs);
509  break;
510  }
511  case FEVectorPiola:
512  {
513  ASSERT_PERMANENT(false).error("Shape vector for FEVectorPiola is not implemented yet!\n"); // temporary assert
514  patch_point_vals_->make_fe_op(vector_shape_op_idx, {3, n_dofs}, bulk_reinit::ptop_vector_piola_shape, n_dofs);
515  break;
516  }
517  default:
518  ASSERT(false).error("Type of FiniteElement of grad_vector_shape accessor must be FEVector, FEVectorPiola or FEVectorContravariant!\n");
519  }
520 
521  return FeQArray<Vector>(patch_point_vals_, true, vector_shape_op_idx, fe_component->n_dofs());
522  }
523 
524 // inline FeQArray<Tensor> tensor_shape(uint component_idx = 0)
525 // {}
526 
527  /**
528  * @brief Return the value of the @p function_no-th gradient shape function at
529  * the @p p bulk quadrature point.
530  *
531  * @param component_idx Number of the shape function.
532  */
533  inline FeQArray<Vector> grad_scalar_shape(uint component_idx=0)
534  {
535  auto fe_component = this->fe_comp(fe_, component_idx);
536  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of grad_scalar_shape accessor must be FEScalar!\n");
537 
538  uint n_dofs = fe_component->n_dofs();
539  patch_point_vals_->make_fe_op(FeBulk::BulkOps::opGradScalarShape, {3, n_dofs}, bulk_reinit::ptop_scalar_shape_grads<dim>, n_dofs);
540 
542  }
543 
544  /**
545  * @brief Return the value of the @p function_no-th gradient vector shape function
546  * at the @p p bulk quadrature point.
547  *
548  * @param component_idx Number of the shape function.
549  */
550  inline FeQArray<Tensor> grad_vector_shape(uint component_idx=0)
551  {
552  auto fe_component = this->fe_comp(fe_, component_idx);
553 
554  uint n_dofs = fe_component->n_dofs();
555  uint vector_shape_grads_op_idx = FeBulk::BulkOps::opGradVectorShape;
556 
557  switch (fe_component->fe_type()) {
558  case FEVector:
559  {
560  patch_point_vals_->make_fe_op(vector_shape_grads_op_idx,
561  {3, 3*n_dofs},
562  bulk_reinit::ptop_vector_shape_grads<dim>,
563  n_dofs);
564  break;
565  }
567  {
568  ASSERT_PERMANENT(false).error("Grad vector for FEVectorContravariant is not implemented yet!\n"); // temporary assert
569  patch_point_vals_->make_fe_op(vector_shape_grads_op_idx,
570  {3, 3*n_dofs},
571  bulk_reinit::ptop_vector_contravariant_shape_grads<dim>,
572  n_dofs);
573  break;
574  }
575  case FEVectorPiola:
576  {
577  ASSERT_PERMANENT(false).error("Grad vector for FEVectorPiola is not implemented yet!\n"); // temporary assert
578  patch_point_vals_->make_fe_op(vector_shape_grads_op_idx,
579  {3, 3*n_dofs},
580  bulk_reinit::ptop_vector_piola_shape_grads<dim>,
581  n_dofs);
582  break;
583  }
584  default:
585  ASSERT(false).error("Type of FiniteElement of grad_vector_shape accessor must be FEVector, FEVectorPiola or FEVectorContravariant!\n");
586  }
587 
588  return FeQArray<Tensor>(patch_point_vals_, true, vector_shape_grads_op_idx, n_dofs);
589  }
590 
591  /**
592  * @brief Return the value of the @p function_no-th vector symmetric gradient
593  * at the @p p bulk quadrature point.
594  *
595  * @param component_idx Number of the shape function.
596  */
597  inline FeQArray<Tensor> vector_sym_grad(uint component_idx=0)
598  {
599  auto fe_component = this->fe_comp(fe_, component_idx);
600  uint n_dofs = fe_component->n_dofs();
601  //ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of grad_scalar_shape accessor must be FEScalar!\n");
602 
604 
606  }
607 
608  /**
609  * @brief Return the value of the @p function_no-th vector divergence at
610  * the @p p bulk quadrature point.
611  *
612  * @param component_idx Number of the shape function.
613  */
614  inline FeQArray<Scalar> vector_divergence(uint component_idx=0)
615  {
616  auto fe_component = this->fe_comp(fe_, component_idx);
617  uint n_dofs = fe_component->n_dofs();
618  //ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of grad_scalar_shape accessor must be FEScalar!\n");
619 
621 
623  }
624 
625 private:
627  std::shared_ptr< FiniteElement<dim> > fe_;
628 };
629 
630 
631 template<unsigned int dim>
632 class SideValues : public BaseValues<dim>
633 {
634 public:
635  /// Constructor
637  : BaseValues<dim>(), patch_point_vals_(patch_point_vals) {
638  ASSERT_EQ(patch_point_vals->dim(), dim);
639  fe_ = fe[Dim<dim>{}];
640  }
641 
642  /// Same as BulkValues::JxW but register at side quadrature points.
643  inline FeQ<Scalar> JxW()
644  {
646  }
647 
648  /**
649  * @brief Register the normal vector to a side at side quadrature points.
650  *
651  * @param quad Quadrature.
652  */
654  {
656  }
657 
658  /// Create side accessor of coords entity
660  {
662  }
663 
664  /// Create bulk accessor of jac determinant entity
666  {
668  }
669 
670  inline FeQArray<Scalar> ref_scalar(uint component_idx = 0)
671  {
672  auto fe_component = this->fe_comp(fe_, component_idx);
673  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
674 
675  uint n_points = patch_point_vals_->get_quadrature()->size();
676  uint n_dofs = fe_component->n_dofs();
677 
678  auto *ref_scalar_op = patch_point_vals_->make_fixed_fe_op(FeSide::SideOps::opRefScalar, {dim+1, n_dofs}, &common_reinit::op_base, n_dofs);
679 
680  auto ref_shape_vals = this->ref_shape_values_side(patch_point_vals_->get_quadrature(), fe_component);
681  ref_scalar_op->allocate_result(n_points, patch_point_vals_->asm_arena());
682  auto ref_scalar_value = ref_scalar_op->result_matrix();
683  for (unsigned int s=0; s<dim+1; ++s) {
684  for (unsigned int i_p = 0; i_p < n_points; i_p++)
685  for (unsigned int i_dof = 0; i_dof < n_dofs; i_dof++) {
686  ref_scalar_value(s, i_dof)(i_p) = ref_shape_vals[s][i_p][i_dof][0];
687  }
688  }
689 
690  return FeQArray<Scalar>(patch_point_vals_, true, FeSide::SideOps::opRefScalar, fe_component->n_dofs());
691  }
692 
693  inline FeQArray<Vector> ref_vector(uint component_idx = 0)
694  {
695  auto fe_component = this->fe_comp(fe_, component_idx);
696  ASSERT((fe_component->fe_type() == FEType::FEVector) | (fe_component->fe_type() == FEType::FEVectorPiola) | (fe_component->fe_type() == FEType::FEVectorContravariant))
697  .error("Type of FiniteElement of grad_vector_shape accessor must be FEVector, FEVectorPiola or FEVectorContravariant!\n");
698 
699  uint n_points = patch_point_vals_->get_quadrature()->size();
700  uint n_dofs = fe_component->n_dofs();
701 
702  auto *ref_vector_op = patch_point_vals_->make_fixed_fe_op(FeSide::SideOps::opRefVector, {dim+1,3*n_dofs}, &common_reinit::op_base, n_dofs);
703  ref_vector_op->allocate_result(n_points, patch_point_vals_->asm_arena());
704  auto ref_vector_value = ref_vector_op->result_matrix();
705  auto ref_shape_vals = this->ref_shape_values_side(patch_point_vals_->get_quadrature(), fe_component);
706  for (unsigned int s=0; s<dim+1; ++s)
707  for (unsigned int i_p = 0; i_p < n_points; i_p++)
708  for (unsigned int i_dof = 0; i_dof < n_dofs; i_dof++)
709  for (uint c=0; c<3; ++c)
710  ref_vector_value(s,3*i_dof+c)(i_p) = ref_shape_vals[s][i_p][i_dof][c];
711 
712  return FeQArray<Vector>(patch_point_vals_, true, FeSide::SideOps::opRefVector, fe_component->n_dofs());
713  }
714 
715  inline FeQArray<Vector> ref_scalar_grad(uint component_idx = 0)
716  {
717  auto fe_component = this->fe_comp(fe_, component_idx);
718  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
719 
720  uint n_points = patch_point_vals_->get_quadrature()->size();
721  uint n_dofs = fe_component->n_dofs();
722 
723  auto *ref_scalar_op = patch_point_vals_->make_fixed_fe_op(FeSide::SideOps::opRefScalarGrad, {dim+1,dim*n_dofs}, &common_reinit::op_base, n_dofs);
724 
726  ref_scalar_op->allocate_result(n_points, patch_point_vals_->asm_arena());
727  auto ref_scalar_value = ref_scalar_op->result_matrix();
728  for (unsigned int s=0; s<dim+1; ++s)
729  for (uint i_dof=0; i_dof<n_dofs; ++i_dof)
730  for (uint i_p=0; i_p<n_points; ++i_p)
731  for (uint c=0; c<dim; ++c)
732  ref_scalar_value(s,dim*i_dof+c)(i_p) = ref_shape_grads[s][i_p][i_dof](c);
733 
734  return FeQArray<Vector>(patch_point_vals_, true, FeSide::SideOps::opRefScalarGrad, fe_component->n_dofs());
735  }
736 
737  inline FeQArray<Tensor> ref_vector_grad(uint component_idx = 0)
738  {
739  auto fe_component = this->fe_comp(fe_, component_idx);
740  ASSERT((fe_component->fe_type() == FEType::FEVector) | (fe_component->fe_type() == FEType::FEVectorPiola) | (fe_component->fe_type() == FEType::FEVectorContravariant))
741  .error("Type of FiniteElement of grad_vector_shape accessor must be FEVector, FEVectorPiola or FEVectorContravariant!\n");
742 
743  uint n_points = patch_point_vals_->get_quadrature()->size();
744  uint n_dofs = fe_component->n_dofs();
745  uint n_sides = dim+1;
746 
747  auto *ref_vector_op = patch_point_vals_->make_fixed_fe_op(FeSide::SideOps::opRefVectorGrad, {n_sides*dim, 3*n_dofs}, &common_reinit::op_base, n_dofs);
748 
750  ref_vector_op->allocate_result(n_points, patch_point_vals_->asm_arena());
751  auto ref_vector_value = ref_vector_op->result_matrix();
752  for (uint i_sd=0; i_sd<n_sides; ++i_sd)
753  for (uint i_c=0; i_c<3; ++i_c)
754  for (uint i_dim=0; i_dim<dim; ++i_dim)
755  for (uint i_dof=0; i_dof<n_dofs; ++i_dof)
756  for (uint i_p=0; i_p<n_points; ++i_p) {
757  ref_vector_value(i_sd*dim+i_dim, 3*i_dof+i_c)(i_p) = ref_shape_grads[i_sd][i_p][i_dof](i_dim, i_c);
758  }
759 
760  return FeQArray<Tensor>(patch_point_vals_, true, FeSide::SideOps::opRefVectorGrad, fe_component->n_dofs());
761  }
762 
763  /// Same as BulkValues::scalar_shape but register at side quadrature points.
764  inline FeQArray<Scalar> scalar_shape(uint component_idx = 0)
765  {
766  auto fe_component = this->fe_comp(fe_, component_idx);
767  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
768 
769  uint n_dofs = fe_component->n_dofs();
771 
773  }
774 
775  /// Same as BulkValues::vector_shape but register at side quadrature points.
776  inline FeQArray<Vector> vector_shape(uint component_idx = 0)
777  {
778  auto fe_component = this->fe_comp(fe_, component_idx);
779  //ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
780 
781  uint n_dofs = fe_component->n_dofs();
782  uint vector_shape_op_idx = FeSide::SideOps::opVectorShape;
783 
784  switch (fe_component->fe_type()) {
785  case FEVector:
786  {
787  patch_point_vals_->make_fe_op(vector_shape_op_idx, {3, n_dofs}, side_reinit::ptop_vector_shape, n_dofs);
788  break;
789  }
791  {
792  ASSERT_PERMANENT(false).error("Shape vector for FEVectorContravariant is not implemented yet!\n"); // temporary assert
793  patch_point_vals_->make_fe_op(vector_shape_op_idx, {3, n_dofs}, side_reinit::ptop_vector_contravariant_shape, n_dofs);
794  break;
795  }
796  case FEVectorPiola:
797  {
798  ASSERT_PERMANENT(false).error("Shape vector for FEVectorPiola is not implemented yet!\n"); // temporary assert
799  patch_point_vals_->make_fe_op(vector_shape_op_idx, {3, n_dofs}, side_reinit::ptop_vector_piola_shape, n_dofs);
800  break;
801  }
802  default:
803  ASSERT(false).error("Type of FiniteElement of grad_vector_shape accessor must be FEVector, FEVectorPiola or FEVectorContravariant!\n");
804  }
805  return FeQArray<Vector>(patch_point_vals_, false, vector_shape_op_idx, n_dofs);
806  }
807 
808  /// Same as BulkValues::grad_scalar_shape but register at side quadrature points.
809  inline FeQArray<Vector> grad_scalar_shape(uint component_idx=0)
810  {
811  auto fe_component = this->fe_comp(fe_, component_idx);
812  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of grad_scalar_shape accessor must be FEScalar!\n");
813 
814  uint n_dofs = fe_component->n_dofs();
815  patch_point_vals_->make_fe_op(FeSide::SideOps::opGradScalarShape, {3, n_dofs}, side_reinit::ptop_scalar_shape_grads<dim>, n_dofs);
816 
818  }
819 
820  /**
821  * @brief Return the value of the @p function_no-th gradient vector shape function
822  * at the @p p bulk quadrature point.
823  *
824  * @param component_idx Number of the shape function.
825  */
826  inline FeQArray<Tensor> grad_vector_shape(uint component_idx=0)
827  {
828  auto fe_component = this->fe_comp(fe_, component_idx);
829 
830  uint n_dofs = fe_component->n_dofs();
831  uint vector_shape_grads_op_idx = FeSide::SideOps::opGradVectorShape;
832 
833  switch (fe_component->fe_type()) {
834  case FEVector:
835  {
836  patch_point_vals_->make_fe_op(vector_shape_grads_op_idx,
837  {3, 3*n_dofs},
838  side_reinit::ptop_vector_shape_grads<dim>,
839  n_dofs);
840  break;
841  }
843  {
844  ASSERT_PERMANENT(false).error("Grad vector for FEVectorContravariant is not implemented yet!\n"); // temporary assert
845  patch_point_vals_->make_fe_op(vector_shape_grads_op_idx,
846  {3, 3*n_dofs},
847  side_reinit::ptop_vector_contravariant_shape_grads<dim>,
848  n_dofs);
849  break;
850  }
851  case FEVectorPiola:
852  {
853  ASSERT_PERMANENT(false).error("Grad vector for FEVectorPiola is not implemented yet!\n"); // temporary assert
854  patch_point_vals_->make_fe_op(vector_shape_grads_op_idx,
855  {3, 3*n_dofs},
856  side_reinit::ptop_vector_piola_shape_grads<dim>,
857  n_dofs);
858  break;
859  }
860  default:
861  ASSERT(false).error("Type of FiniteElement of grad_vector_shape accessor must be FEVector, FEVectorPiola or FEVectorContravariant!\n");
862  }
863 
864  return FeQArray<Tensor>(patch_point_vals_, false, vector_shape_grads_op_idx, n_dofs);
865  }
866 
867  /**
868  * @brief Return the value of the @p function_no-th vector symmetric gradient
869  * at the @p p side quadrature point.
870  *
871  * @param component_idx Number of the shape function.
872  */
873  inline FeQArray<Tensor> vector_sym_grad(uint component_idx=0)
874  {
875  auto fe_component = this->fe_comp(fe_, component_idx);
876  uint n_dofs = fe_component->n_dofs();
877  //ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of grad_scalar_shape accessor must be FEScalar!\n");
878 
880 
882  }
883 
884  /**
885  * @brief Return the value of the @p function_no-th vector divergence at
886  * the @p p side quadrature point.
887  *
888  * @param component_idx Number of the shape function.
889  */
890  inline FeQArray<Scalar> vector_divergence(uint component_idx=0)
891  {
892  auto fe_component = this->fe_comp(fe_, component_idx);
893  uint n_dofs = fe_component->n_dofs();
894  //ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of grad_scalar_shape accessor must be FEScalar!\n");
895 
897 
899  }
900 
901 private:
903  std::shared_ptr< FiniteElement<dim> > fe_;
904 };
905 
906 
907 template<unsigned int dim>
908 class JoinValues : public BaseValues<dim>
909 {
910 public:
911  /// Constructor
912  JoinValues(PatchPointValues<3> *patch_point_vals_bulk, PatchPointValues<3> *patch_point_vals_side, MixedPtr<FiniteElement> fe)
913  : BaseValues<dim>(), patch_point_vals_bulk_(patch_point_vals_bulk), patch_point_vals_side_(patch_point_vals_side) {
914  ASSERT_EQ(patch_point_vals_bulk->dim(), dim-1);
915  ASSERT_EQ(patch_point_vals_side->dim(), dim);
916  fe_high_dim_ = fe[Dim<dim>{}];
917  fe_low_dim_ = fe[Dim<dim-1>{}];
918  }
919 
920  inline FeQJoin<Scalar> scalar_join_shape(uint component_idx = 0)
921  {
922  // element of lower dim (bulk points)
923  auto fe_component_low = this->fe_comp(fe_low_dim_, component_idx);
924  ASSERT_EQ(fe_component_low->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
925  uint n_dofs_low = fe_component_low->n_dofs();
928 
929  // element of higher dim (side points)
930  auto fe_component_high = this->fe_comp(fe_high_dim_, component_idx);
931  ASSERT_EQ(fe_component_high->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
932  uint n_dofs_high = fe_component_high->n_dofs();
935 
936  return FeQJoin<Scalar>(patch_point_vals_bulk_, patch_point_vals_side_, n_dofs_low, n_dofs_high,
938  }
939 
940  inline FeQJoin<Vector> vector_join_shape(uint component_idx = 0)
941  {
942  // element of lower dim (bulk points)
943  auto fe_component_low = this->fe_comp(fe_low_dim_, component_idx);
944  uint op_idx_bulk = FeBulk::BulkOps::opVectorShape;
945  uint n_dofs_low = fe_component_low->n_dofs();
946 
947  // element of higher dim (side points)
948  auto fe_component_high = this->fe_comp(fe_high_dim_, component_idx);
949  uint op_idx_side = FeSide::SideOps::opVectorShape;
950  uint n_dofs_high = fe_component_high->n_dofs();
951 
952  ASSERT_EQ(fe_component_high->fe_type(), fe_component_low->fe_type()).error("Type of FiniteElement of low and high element must be same!\n");
953  switch (fe_component_low->fe_type()) {
954  case FEVector:
955  {
956  patch_point_vals_bulk_->make_fe_op(op_idx_bulk, {3, n_dofs_low}, bulk_reinit::ptop_vector_shape, n_dofs_low);
957  patch_point_vals_side_->make_fe_op(op_idx_side, {3, n_dofs_high}, side_reinit::ptop_vector_shape, n_dofs_high);
960  break;
961  }
963  {
964  ASSERT_PERMANENT(false).error("Shape vector for FEVectorContravariant is not implemented yet!\n"); // temporary assert
965  //patch_point_vals_.make_fe_op({3}, bulk_reinit::ptop_vector_contravariant_shape, fe_component->n_dofs());
966  break;
967  }
968  case FEVectorPiola:
969  {
970  ASSERT_PERMANENT(false).error("Shape vector for FEVectorPiola is not implemented yet!\n"); // temporary assert
971  //patch_point_vals_.make_fe_op({3}, bulk_reinit::ptop_vector_piola_shape, fe_component->n_dofs());
972  break;
973  }
974  default:
975  ASSERT(false).error("Type of FiniteElement of grad_vector_shape accessor must be FEVector, FEVectorPiola or FEVectorContravariant!\n");
976  }
977 
978  return FeQJoin<Vector>(patch_point_vals_bulk_, patch_point_vals_side_, n_dofs_low, n_dofs_high, op_idx_bulk, op_idx_side);
979  }
980 
982  {
983  // element of lower dim (bulk points)
984  auto fe_component_low = this->fe_comp(fe_low_dim_, component_idx);
986 
987  // element of higher dim (side points)
988  auto fe_component_high = this->fe_comp(fe_high_dim_, component_idx);
990 
991  ASSERT_EQ(fe_component_high->fe_type(), fe_component_low->fe_type()).error("Type of FiniteElement of low and high element must be same!\n");
992  switch (fe_component_low->fe_type()) {
993  case FEVector:
994  {
995  patch_point_vals_bulk_->make_fe_op(op_idx_bulk,
996  {3, 3-fe_component_low->n_dofs()},
998  fe_component_low->n_dofs());
999 
1000  patch_point_vals_side_->make_fe_op(op_idx_side,
1001  {3, 3*fe_component_high->n_dofs()},
1002  side_reinit::ptop_vector_shape_grads<dim>,
1003  fe_component_high->n_dofs());
1004 
1007  break;
1008  }
1009  case FEVectorContravariant:
1010  {
1011  ASSERT_PERMANENT(false).error("Shape vector for FEVectorContravariant is not implemented yet!\n"); // temporary assert
1012 // patch_point_vals_bulk_->make_fe_op(op_idx_bulk,
1013 // {3, 3},
1014 // bulk_reinit::ptop_vector_contravariant_shape_grads<dim-1>,
1015 // fe_component_low->n_dofs());
1016 //
1017 // patch_point_vals_side_->make_fe_op(op_idx_side,
1018 // {3, 3},
1019 // side_reinit::ptop_vector_contravariant_shape_grads<dim>,
1020 // fe_component_high->n_dofs());
1021  break;
1022  }
1023  case FEVectorPiola:
1024  {
1025  ASSERT_PERMANENT(false).error("Shape vector for FEVectorPiola is not implemented yet!\n"); // temporary assert
1026 // patch_point_vals_bulk_->make_fe_op(op_idx_bulk,
1027 // {3, 3},
1028 // bulk_reinit::ptop_vector_piola_shape_grads<dim-1>,
1029 // fe_component_low->n_dofs());
1030 //
1031 // patch_point_vals_side_->make_fe_op(op_idx_side,
1032 // {3, 3},
1033 // side_reinit::ptop_vector_piola_shape_grads<dim>,
1034 // fe_component_high->n_dofs());
1035  break;
1036  }
1037  default:
1038  ASSERT(false).error("Type of FiniteElement of grad_vector_shape accessor must be FEVector, FEVectorPiola or FEVectorContravariant!\n");
1039  }
1040 
1041  return FeQJoin<Tensor>(patch_point_vals_bulk_, patch_point_vals_side_, fe_component_low->n_dofs(),
1042  fe_component_high->n_dofs(), op_idx_bulk, op_idx_side);
1043  }
1044 
1045 private:
1048  std::shared_ptr< FiniteElement<dim> > fe_high_dim_;
1049  std::shared_ptr< FiniteElement<dim-1> > fe_low_dim_;
1050 };
1051 
1052 /// Template specialization of dim = 1
1053 template <>
1054 class JoinValues<1> : public BaseValues<1>
1055 {
1056 public:
1057  /// Constructor
1059  : BaseValues<1>() {}
1060 
1062  {
1063  return FeQJoin<Scalar>();
1064  }
1065 
1067  {
1068  return FeQJoin<Vector>();
1069  }
1070 
1072  {
1073  return FeQJoin<Tensor>();
1074  }
1075 };
1076 
1077 
1078 template<unsigned int spacedim = 3>
1080 public:
1082 
1083  /// Struct for pre-computing number of elements, sides, bulk points and side points on each dimension.
1084  struct TableSizes {
1085  public:
1086  /// Constructor
1090  }
1091 
1092  /// Set all values to zero
1093  void reset() {
1094  std::fill(elem_sizes_[0].begin(), elem_sizes_[0].end(), 0);
1095  std::fill(elem_sizes_[1].begin(), elem_sizes_[1].end(), 0);
1096  std::fill(point_sizes_[0].begin(), point_sizes_[0].end(), 0);
1097  std::fill(point_sizes_[1].begin(), point_sizes_[1].end(), 0);
1098  }
1099 
1100  /// Copy values of other TableSizes instance
1101  void copy(const TableSizes &other) {
1102  elem_sizes_[0] = other.elem_sizes_[0];
1103  elem_sizes_[1] = other.elem_sizes_[1];
1104  point_sizes_[0] = other.point_sizes_[0];
1105  point_sizes_[1] = other.point_sizes_[1];
1106  }
1107 
1108  /**
1109  * Holds number of elements and sides on each dimension
1110  * Format:
1111  * { {n_elements_1D, n_elements_2D, n_elements_3D },
1112  * {n_sides_1D, n_sides_2D, n_sides_3D } }
1113  */
1115 
1116  /**
1117  * Holds number of bulk and side points on each dimension
1118  * Format:
1119  * { {n_bulk_points_1D, n_bulk_points_2D, n_bulk_points_3D },
1120  * {n_side_points_1D, n_side_points_2D, n_side_points_3D } }
1121  */
1123  };
1124 
1126  : patch_fe_data_(1024 * 1024, 256),
1130  patch_point_vals_side_{ {FeSide::PatchPointValues(1, 0, patch_fe_data_),
1131  FeSide::PatchPointValues(2, 0, patch_fe_data_),
1132  FeSide::PatchPointValues(3, 0, patch_fe_data_)} }
1133  {
1134  used_quads_[0] = false; used_quads_[1] = false;
1135  }
1136 
1137  PatchFEValues(unsigned int quad_order, MixedPtr<FiniteElement> fe)
1138  : patch_fe_data_(1024 * 1024, 256),
1139  patch_point_vals_bulk_{ {FeBulk::PatchPointValues(1, quad_order, patch_fe_data_),
1140  FeBulk::PatchPointValues(2, quad_order, patch_fe_data_),
1141  FeBulk::PatchPointValues(3, quad_order, patch_fe_data_)} },
1142  patch_point_vals_side_{ {FeSide::PatchPointValues(1, quad_order, patch_fe_data_),
1143  FeSide::PatchPointValues(2, quad_order, patch_fe_data_),
1144  FeSide::PatchPointValues(3, quad_order, patch_fe_data_)} },
1145  fe_(fe)
1146  {
1147  used_quads_[0] = false; used_quads_[1] = false;
1148 
1149  // TODO move initialization zero_vec_ to patch_fe_data_ constructor when we will create separate ArenaVec of DOshape functions
1150  uint zero_vec_size = 300;
1151  patch_fe_data_.zero_vec_ = ArenaVec<double>(zero_vec_size, patch_fe_data_.asm_arena_);
1152  for (uint i=0; i<zero_vec_size; ++i) patch_fe_data_.zero_vec_(i) = 0.0;
1153  }
1154 
1155 
1156  /// Destructor
1158  {}
1159 
1160  /// Return bulk or side quadrature of given dimension
1161  Quadrature *get_quadrature(uint dim, bool is_bulk) const {
1162  if (is_bulk) return patch_point_vals_bulk_[dim-1].get_quadrature();
1163  else return patch_point_vals_side_[dim-1].get_quadrature();
1164  }
1165 
1166  /**
1167  * @brief Initialize structures and calculates cell-independent data.
1168  *
1169  * @param _quadrature The quadrature rule for the cell associated
1170  * to given finite element or for the cell side.
1171  * @param _flags The update flags.
1172  */
1173  template<unsigned int DIM>
1174  void initialize(Quadrature &_quadrature)
1175  {
1176  if ( _quadrature.dim() == DIM ) {
1177  used_quads_[0] = true;
1178  patch_point_vals_bulk_[DIM-1].initialize(); // bulk
1179  } else {
1180  used_quads_[1] = true;
1181  patch_point_vals_side_[DIM-1].initialize(); // side
1182  }
1183  }
1184 
1185  /// Finalize initialization, creates child (patch) arena and passes it to PatchPointValue objects
1186  void init_finalize() {
1187  patch_fe_data_.patch_arena_ = patch_fe_data_.asm_arena_.get_child_arena();
1188  }
1189 
1190  /// Reset PatchpointValues structures
1191  void reset()
1192  {
1193  for (unsigned int i=0; i<3; ++i) {
1194  if (used_quads_[0]) patch_point_vals_bulk_[i].reset();
1195  if (used_quads_[1]) patch_point_vals_side_[i].reset();
1196  }
1197  patch_fe_data_.patch_arena_->reset();
1198  }
1199 
1200  /// Reinit data.
1202  {
1203  for (unsigned int i=0; i<3; ++i) {
1204  if (used_quads_[0]) patch_point_vals_bulk_[i].reinit_patch();
1205  if (used_quads_[1]) patch_point_vals_side_[i].reinit_patch();
1206  }
1207  }
1208 
1209  /**
1210  * @brief Returns the number of shape functions.
1211  */
1212  template<unsigned int dim>
1213  inline unsigned int n_dofs() const {
1214  ASSERT((dim>=0) && (dim<=3))(dim).error("Dimension must be 0, 1, 2 or 3.");
1215  return fe_[Dim<dim>{}]->n_dofs();
1216  }
1217 
1218  /// Return BulkValue object of dimension given by template parameter
1219  template<unsigned int dim>
1221  ASSERT((dim>0) && (dim<=3))(dim).error("Dimension must be 1, 2 or 3.");
1222  return BulkValues<dim>(&patch_point_vals_bulk_[dim-1], fe_);
1223  }
1224 
1225  /// Return SideValue object of dimension given by template parameter
1226  template<unsigned int dim>
1228  ASSERT((dim>0) && (dim<=3))(dim).error("Dimension must be 1, 2 or 3.");
1229  return SideValues<dim>(&patch_point_vals_side_[dim-1], fe_);
1230  }
1231 
1232  /// Return JoinValue object of dimension given by template parameter
1233  template<unsigned int dim>
1235  //ASSERT((dim>1) && (dim<=3))(dim).error("Dimension must be 2 or 3.");
1236  return JoinValues<dim>(&patch_point_vals_bulk_[dim-2], &patch_point_vals_side_[dim-1], fe_);
1237  }
1238 
1239  /** Following methods are used during update of patch. **/
1240 
1241  /// Resize tables of patch_point_vals_
1242  void resize_tables(TableSizes table_sizes) {
1243  for (uint i=0; i<3; ++i) {
1244  if (used_quads_[0]) patch_point_vals_bulk_[i].resize_tables(table_sizes.elem_sizes_[0][i], table_sizes.point_sizes_[0][i]);
1245  if (used_quads_[1]) patch_point_vals_side_[i].resize_tables(table_sizes.elem_sizes_[1][i], table_sizes.point_sizes_[1][i]);
1246  }
1247  }
1248 
1249  /// Register element to patch_point_vals_ table by dimension of element
1250  uint register_element(DHCellAccessor cell, uint element_patch_idx) {
1251  arma::mat coords;
1252  switch (cell.dim()) {
1253  case 1:
1254  coords = MappingP1<1,spacedim>::element_map(cell.elm());
1255  return patch_point_vals_bulk_[0].register_element(coords, element_patch_idx);
1256  break;
1257  case 2:
1258  coords = MappingP1<2,spacedim>::element_map(cell.elm());
1259  return patch_point_vals_bulk_[1].register_element(coords, element_patch_idx);
1260  break;
1261  case 3:
1262  coords = MappingP1<3,spacedim>::element_map(cell.elm());
1263  return patch_point_vals_bulk_[2].register_element(coords, element_patch_idx);
1264  break;
1265  default:
1266  ASSERT(false);
1267  return 0;
1268  break;
1269  }
1270  }
1271 
1272  /// Register side to patch_point_vals_ table by dimension of side
1274  arma::mat side_coords(spacedim, cell_side.dim());
1275  for (unsigned int n=0; n<cell_side.dim(); n++)
1276  for (unsigned int c=0; c<spacedim; c++)
1277  side_coords(c,n) = (*cell_side.side().node(n))[c];
1278 
1279  arma::mat elm_coords;
1280  DHCellAccessor cell = cell_side.cell();
1281  switch (cell.dim()) {
1282  case 1:
1283  elm_coords = MappingP1<1,spacedim>::element_map(cell.elm());
1284  return patch_point_vals_side_[0].register_side(elm_coords, side_coords, cell_side.side_idx());
1285  break;
1286  case 2:
1287  elm_coords = MappingP1<2,spacedim>::element_map(cell.elm());
1288  return patch_point_vals_side_[1].register_side(elm_coords, side_coords, cell_side.side_idx());
1289  break;
1290  case 3:
1291  elm_coords = MappingP1<3,spacedim>::element_map(cell.elm());
1292  return patch_point_vals_side_[2].register_side(elm_coords, side_coords, cell_side.side_idx());
1293  break;
1294  default:
1295  ASSERT(false);
1296  return 0;
1297  break;
1298  }
1299  }
1300 
1301  /// Register bulk point to patch_point_vals_ table by dimension of element
1302  uint register_bulk_point(DHCellAccessor cell, uint elem_table_row, uint value_patch_idx, uint i_point_on_elem) {
1303  return patch_point_vals_bulk_[cell.dim()-1].register_bulk_point(elem_table_row, value_patch_idx, cell.elm_idx(), i_point_on_elem);
1304  }
1305 
1306  /// Register side point to patch_point_vals_ table by dimension of side
1307  uint register_side_point(DHCellSide cell_side, uint elem_table_row, uint value_patch_idx, uint i_point_on_side) {
1308  return patch_point_vals_side_[cell_side.dim()-1].register_side_point(elem_table_row, value_patch_idx, cell_side.elem_idx(),
1309  cell_side.side_idx(), i_point_on_side);
1310  }
1311 
1312  /// Temporary development method
1313  void print_data_tables(ostream& stream, bool points, bool ints, bool only_bulk=true) const {
1314  stream << endl << "Table of patch FE data:" << endl;
1315  for (uint i=0; i<3; ++i) {
1316  stream << std::setfill('-') << setw(100) << "" << endl;
1317  stream << "Bulk, dimension " << (i+1) << endl;
1318  patch_point_vals_bulk_[i].print_data_tables(stream, points, ints);
1319  }
1320  if (!only_bulk)
1321  for (uint i=0; i<3; ++i) {
1322  stream << std::setfill('-') << setw(100) << "" << endl;
1323  stream << "Side, dimension " << (i+1) << endl;
1324  patch_point_vals_side_[i].print_data_tables(stream, points, ints);
1325  }
1326  stream << std::setfill('=') << setw(100) << "" << endl;
1327  }
1328 
1329  /// Temporary development method
1330  void print_operations(ostream& stream) const {
1331  stream << endl << "Table of patch FE operations:" << endl;
1332  for (uint i=0; i<3; ++i) {
1333  stream << std::setfill('-') << setw(100) << "" << endl;
1334  stream << "Bulk, dimension " << (i+1) << endl;
1335  patch_point_vals_bulk_[i].print_operations(stream, 0);
1336  }
1337  for (uint i=0; i<3; ++i) {
1338  stream << std::setfill('-') << setw(100) << "" << endl;
1339  stream << "Side, dimension " << (i+1) << endl;
1340  patch_point_vals_side_[i].print_operations(stream, 1);
1341  }
1342  stream << std::setfill('=') << setw(100) << "" << endl;
1343  }
1344 
1345 private:
1347  std::array<FeBulk::PatchPointValues<spacedim>, 3> patch_point_vals_bulk_; ///< Sub objects of bulk data of dimensions 1,2,3
1348  std::array<FeSide::PatchPointValues<spacedim>, 3> patch_point_vals_side_; ///< Sub objects of side data of dimensions 1,2,3
1349 
1350  MixedPtr<FiniteElement> fe_; ///< Mixed of shared pointers of FiniteElement object
1351  bool used_quads_[2]; ///< Pair of flags signs holds info if bulk and side quadratures are used
1352 
1353  template <class ValueType>
1354  friend class ElQ;
1355  template <class ValueType>
1356  friend class FeQ;
1357 };
1358 
1359 
1360 template <class ValueType>
1361 ValueType ElQ<ValueType>::operator()(const BulkPoint &point) const {
1362  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
1363  return patch_point_vals_->scalar_elem_value(op_idx_, value_cache_idx);
1364 }
1365 
1366 template <>
1367 inline Vector ElQ<Vector>::operator()(const BulkPoint &point) const {
1368  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
1369  return patch_point_vals_->vector_elem_value(op_idx_, value_cache_idx);
1370 }
1371 
1372 template <>
1373 inline Tensor ElQ<Tensor>::operator()(const BulkPoint &point) const {
1374  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
1375  return patch_point_vals_->tensor_elem_value(op_idx_, value_cache_idx);
1376 }
1377 
1378 template <class ValueType>
1379 ValueType ElQ<ValueType>::operator()(const SidePoint &point) const {
1380  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
1381  return patch_point_vals_->scalar_elem_value(op_idx_, value_cache_idx);
1382 }
1383 
1384 template <>
1385 inline Vector ElQ<Vector>::operator()(const SidePoint &point) const {
1386  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
1387  return patch_point_vals_->vector_elem_value(op_idx_, value_cache_idx);
1388 }
1389 
1390 template <>
1391 inline Tensor ElQ<Tensor>::operator()(const SidePoint &point) const {
1392  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
1393  return patch_point_vals_->tensor_elem_value(op_idx_, value_cache_idx);
1394 }
1395 
1396 template <class ValueType>
1397 ValueType FeQ<ValueType>::operator()(const BulkPoint &point) const {
1399 
1400  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
1401  return patch_point_vals_bulk_->scalar_value(op_idx_, value_cache_idx, i_shape_fn_idx_);
1402 }
1403 
1404 template <>
1405 inline Vector FeQ<Vector>::operator()(const BulkPoint &point) const {
1407 
1408  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
1409  return patch_point_vals_bulk_->vector_value(op_idx_, value_cache_idx, i_shape_fn_idx_);
1410 }
1411 
1412 template <>
1413 inline Tensor FeQ<Tensor>::operator()(const BulkPoint &point) const {
1415 
1416  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
1417  return patch_point_vals_bulk_->tensor_value(op_idx_, value_cache_idx, i_shape_fn_idx_);
1418 }
1419 
1420 template <class ValueType>
1421 ValueType FeQ<ValueType>::operator()(const SidePoint &point) const {
1423 
1424  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
1425  return patch_point_vals_side_->scalar_value(op_idx_, value_cache_idx, i_shape_fn_idx_);
1426 }
1427 
1428 template <>
1429 inline Vector FeQ<Vector>::operator()(const SidePoint &point) const {
1431 
1432  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
1433  return patch_point_vals_side_->vector_value(op_idx_, value_cache_idx, i_shape_fn_idx_);
1434 }
1435 
1436 template <>
1437 inline Tensor FeQ<Tensor>::operator()(const SidePoint &point) const {
1439 
1440  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
1441  return patch_point_vals_side_->tensor_value(op_idx_, value_cache_idx, i_shape_fn_idx_);
1442 }
1443 
1444 
1445 #endif /* PATCH_FE_VALUES_HH_ */
#define ASSERT(expr)
Definition: asserts.hh:351
#define ASSERT_PERMANENT(expr)
Allow use shorter versions of macro names if these names is not used with external library.
Definition: asserts.hh:348
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:301
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:333
#define ASSERT_GT(a, b)
Definition of comparative assert macro (Greater Than) only for debug mode.
Definition: asserts.hh:317
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
Definition: asserts.hh:341
std::vector< std::vector< std::vector< arma::vec > > > ref_shape_values_side(Quadrature *q, std::shared_ptr< FiniteElement< FE_dim >> fe)
Precomputed values of basis functions at the side quadrature points.
std::shared_ptr< FiniteElement< FE_dim > > fe_comp(std::shared_ptr< FiniteElement< FE_dim > > fe, uint component_idx)
Return FiniteElement of component_idx for FESystem or fe for other types.
std::vector< std::vector< arma::mat > > ref_shape_gradients_bulk(Quadrature *q, std::shared_ptr< FiniteElement< FE_dim >> fe)
Precomputed gradients of basis functions at the bulk quadrature points.
std::vector< std::vector< arma::vec > > ref_shape_values_bulk(Quadrature *q, std::shared_ptr< FiniteElement< FE_dim >> fe)
Precomputed values of basis functions at the bulk quadrature points.
std::vector< std::vector< std::vector< arma::mat > > > ref_shape_gradients_side(Quadrature *q, std::shared_ptr< FiniteElement< FE_dim >> fe)
Precomputed gradients of basis functions at the side quadrature points.
Base point accessor class.
Definition: eval_subset.hh:55
const ElementCacheMap * elm_cache_map() const
Definition: eval_subset.hh:73
unsigned int elem_patch_idx() const
Definition: eval_subset.hh:79
unsigned int eval_point_idx() const
Return index in EvalPoints object.
Definition: eval_subset.hh:84
FeQArray< Vector > ref_vector(uint component_idx=0)
FeQ< Scalar > JxW()
Register the product of Jacobian determinant and the quadrature weight at bulk quadrature points.
FeQArray< Vector > grad_scalar_shape(uint component_idx=0)
Return the value of the function_no-th gradient shape function at the p bulk quadrature point.
ElQ< Vector > coords()
Create bulk accessor of coords entity.
FeQArray< Tensor > ref_vector_grad(uint component_idx=0)
ElQ< Scalar > determinant()
Create bulk accessor of jac determinant entity.
FeQArray< Vector > ref_scalar_grad(uint component_idx=0)
PatchPointValues< 3 > * patch_point_vals_
FeQArray< Tensor > grad_vector_shape(uint component_idx=0)
Return the value of the function_no-th gradient vector shape function at the p bulk quadrature point.
BulkValues(PatchPointValues< 3 > *patch_point_vals, MixedPtr< FiniteElement > fe)
Constructor.
std::shared_ptr< FiniteElement< dim > > fe_
FeQArray< Scalar > ref_scalar(uint component_idx=0)
FeQArray< Vector > vector_shape(uint component_idx=0)
FeQArray< Scalar > scalar_shape(uint component_idx=0)
Return the value of the function_no-th shape function at the p bulk quadrature point.
FeQArray< Scalar > vector_divergence(uint component_idx=0)
Return the value of the function_no-th vector divergence at the p bulk quadrature point.
FeQArray< Tensor > vector_sym_grad(uint component_idx=0)
Return the value of the function_no-th vector symmetric gradient at the p bulk quadrature point.
Cell accessor allow iterate over DOF handler cells.
unsigned int dim() const
Return dimension of element appropriate to cell.
unsigned int elm_idx() const
Return serial idx to element of loc_ele_idx_.
ElementAccessor< 3 > elm() const
Return ElementAccessor to element of loc_ele_idx_.
Side accessor allows to iterate over sides of DOF handler cell.
unsigned int elem_idx() const
Side side() const
Return Side of given cell and side_idx.
const DHCellAccessor & cell() const
Return DHCellAccessor appropriate to the side.
unsigned int dim() const
Return dimension of element appropriate to the side.
unsigned int side_idx() const
ValueType operator()(const SidePoint &point) const
ValueType operator()(const BulkPoint &point) const
ElQ(PatchPointValues< 3 > *patch_point_vals, unsigned int op_idx)
Constructor.
unsigned int op_idx_
Index of operation in patch_point_vals_.operations vector.
ElQ()=delete
Forbidden default constructor.
PatchPointValues< 3 > * patch_point_vals_
Reference to PatchPointValues.
int element_eval_point(unsigned int i_elem_in_cache, unsigned int i_eval_point) const
Compound finite element on dim dimensional simplex.
Definition: fe_system.hh:102
const std::vector< std::shared_ptr< FiniteElement< dim > > > & fe() const
Definition: fe_system.hh:147
FeQArray()=delete
Forbidden default constructor.
unsigned int n_dofs() const
Return number of DOFs.
unsigned int n_dofs_
Number of DOFs.
FeQArray(PatchPointValues< 3 > *patch_point_vals, bool is_bulk, unsigned int op_idx, unsigned int n_dofs)
FeQ< ValueType > shape(unsigned int i_shape_fn_idx) const
unsigned int op_idx_
Index of operation in patch_point_vals_.operations vector.
PatchPointValues< 3 > * patch_point_vals_bulk_
Reference to bulk PatchPointValues.
PatchPointValues< 3 > * patch_point_vals_side_
Reference to side PatchPointValues.
FeQJoin(PatchPointValues< 3 > *patch_point_vals_bulk, PatchPointValues< 3 > *patch_point_vals_side, unsigned int n_dofs_bulk, unsigned int n_dofs_side, unsigned int op_idx_bulk, unsigned int op_idx_side)
bool is_high_dim(unsigned int i_join_idx) const
unsigned int n_dofs_both() const
unsigned int n_dofs_low() const
unsigned int n_dofs_low_
Number of DOFs on low-dim element.
PatchPointValues< 3 > * patch_point_vals_side_
Pointer to side PatchPointValues.
unsigned int op_idx_side_
Index of operation in patch_point_vals_side_.operations vector.
unsigned int op_idx_bulk_
Index of operation in patch_point_vals_bulk_.operations vector.
unsigned int n_dofs_high_
Number of DOFs on high-dim element.
FeQJoin()
Default constructor.
unsigned int n_dofs_high() const
FeQ< ValueType > shape(unsigned int i_join_idx) const
PatchPointValues< 3 > * patch_point_vals_bulk_
Pointer to bulk PatchPointValues.
FeQ(PatchPointValues< 3 > *patch_point_vals_bulk, PatchPointValues< 3 > *patch_point_vals_side, unsigned int op_idx, unsigned int i_shape_fn_idx)
Constructor used only in FeQArray::shape()
FeQ(PatchPointValues< 3 > *patch_point_vals, bool is_bulk, unsigned int op_idx)
ValueType operator()(const BulkPoint &point) const
PatchPointValues< 3 > * patch_point_vals_bulk_
Pointer to bulk PatchPointValues.
ValueType operator()(const SidePoint &point) const
unsigned int i_shape_fn_idx_
Index of shape function.
unsigned int op_idx_
Index of operation in patch_point_vals_.operations vector.
PatchPointValues< 3 > * patch_point_vals_side_
Pointer to side PatchPointValues.
FeQ()=delete
Forbidden default constructor.
Bulk Side specialization, order of item in operations_ vector corresponds to the SideOps enum.
Abstract class for the description of a general finite element on a reference simplex in dim dimensio...
FeQJoin< Tensor > gradient_vector_join_shape(FMT_UNUSED uint component_idx=0)
JoinValues(FMT_UNUSED PatchPointValues< 3 > *patch_point_vals_bulk, FMT_UNUSED PatchPointValues< 3 > *patch_point_vals_side, FMT_UNUSED MixedPtr< FiniteElement > fe)
Constructor.
FeQJoin< Vector > vector_join_shape(FMT_UNUSED uint component_idx=0)
FeQJoin< Scalar > scalar_join_shape(FMT_UNUSED uint component_idx=0)
std::shared_ptr< FiniteElement< dim > > fe_high_dim_
JoinValues(PatchPointValues< 3 > *patch_point_vals_bulk, PatchPointValues< 3 > *patch_point_vals_side, MixedPtr< FiniteElement > fe)
Constructor.
FeQJoin< Vector > vector_join_shape(uint component_idx=0)
PatchPointValues< 3 > * patch_point_vals_bulk_
FeQJoin< Tensor > gradient_vector_join_shape(uint component_idx=0)
std::shared_ptr< FiniteElement< dim-1 > > fe_low_dim_
FeQJoin< Scalar > scalar_join_shape(uint component_idx=0)
PatchPointValues< 3 > * patch_point_vals_side_
static ElementMap element_map(ElementAccessor< 3 > elm)
Definition: mapping_p1.cc:48
uint register_element(DHCellAccessor cell, uint element_patch_idx)
Register element to patch_point_vals_ table by dimension of element.
PatchPointValues< spacedim >::PatchFeData PatchFeData
uint register_bulk_point(DHCellAccessor cell, uint elem_table_row, uint value_patch_idx, uint i_point_on_elem)
Register bulk point to patch_point_vals_ table by dimension of element.
~PatchFEValues()
Destructor.
std::array< FeBulk::PatchPointValues< spacedim >, 3 > patch_point_vals_bulk_
Sub objects of bulk data of dimensions 1,2,3.
uint register_side(DHCellSide cell_side)
Register side to patch_point_vals_ table by dimension of side.
void init_finalize()
Finalize initialization, creates child (patch) arena and passes it to PatchPointValue objects.
void print_data_tables(ostream &stream, bool points, bool ints, bool only_bulk=true) const
Temporary development method.
JoinValues< dim > join_values()
Return JoinValue object of dimension given by template parameter.
Quadrature * get_quadrature(uint dim, bool is_bulk) const
Return bulk or side quadrature of given dimension.
BulkValues< dim > bulk_values()
Return BulkValue object of dimension given by template parameter.
uint register_side_point(DHCellSide cell_side, uint elem_table_row, uint value_patch_idx, uint i_point_on_side)
Register side point to patch_point_vals_ table by dimension of side.
void initialize(Quadrature &_quadrature)
Initialize structures and calculates cell-independent data.
void print_operations(ostream &stream) const
Temporary development method.
PatchFeData patch_fe_data_
std::array< FeSide::PatchPointValues< spacedim >, 3 > patch_point_vals_side_
Sub objects of side data of dimensions 1,2,3.
MixedPtr< FiniteElement > fe_
Mixed of shared pointers of FiniteElement object.
SideValues< dim > side_values()
Return SideValue object of dimension given by template parameter.
void resize_tables(TableSizes table_sizes)
Resize tables of patch_point_vals_.
PatchFEValues(unsigned int quad_order, MixedPtr< FiniteElement > fe)
void reinit_patch()
Reinit data.
unsigned int n_dofs() const
Returns the number of shape functions.
void reset()
Reset PatchpointValues structures.
PatchPointValues * zero_values()
Quadrature * get_quadrature() const
Getter for quadrature.
PatchOp< spacedim > * make_fe_op(uint op_idx, std::initializer_list< uint > shape, ReinitFunction reinit_f, uint n_dofs, OpSizeType size_type=pointOp)
uint dim() const
Getter for dim_.
Tensor tensor_value(uint op_idx, uint point_idx, uint i_dof=0) const
Scalar scalar_value(uint op_idx, uint point_idx, uint i_dof=0) const
void zero_values_needed()
Set flag needs_zero_values_ to true.
PatchOp< spacedim > * make_fixed_fe_op(uint op_idx, std::initializer_list< uint > shape, ReinitFunction reinit_f, uint n_dofs)
AssemblyArena & asm_arena() const
return reference to assembly arena
Vector vector_value(uint op_idx, uint point_idx, uint i_dof=0) const
Base class for quadrature rules on simplices in arbitrary dimensions.
Definition: quadrature.hh:48
Quadrature make_from_side(unsigned int sid) const
Definition: quadrature.cc:47
unsigned int size() const
Returns number of quadrature points.
Definition: quadrature.hh:86
unsigned int dim() const
Definition: quadrature.hh:72
Armor::ArmaVec< double, point_dim > point(unsigned int i) const
Returns the ith quadrature point.
Definition: quadrature.hh:151
General point a+ side_begin_ + ccessor allow iterate over quadrature points of given side defined in ...
Definition: eval_subset.hh:116
unsigned int eval_point_idx() const
Return index in EvalPoints object.
Definition: eval_subset.hh:143
FeQArray< Scalar > ref_scalar(uint component_idx=0)
PatchPointValues< 3 > * patch_point_vals_
ElQ< Vector > normal_vector()
Register the normal vector to a side at side quadrature points.
std::shared_ptr< FiniteElement< dim > > fe_
FeQArray< Scalar > scalar_shape(uint component_idx=0)
Same as BulkValues::scalar_shape but register at side quadrature points.
FeQArray< Tensor > grad_vector_shape(uint component_idx=0)
Return the value of the function_no-th gradient vector shape function at the p bulk quadrature point.
ElQ< Vector > coords()
Create side accessor of coords entity.
FeQArray< Vector > vector_shape(uint component_idx=0)
Same as BulkValues::vector_shape but register at side quadrature points.
FeQArray< Tensor > ref_vector_grad(uint component_idx=0)
FeQArray< Vector > ref_scalar_grad(uint component_idx=0)
FeQArray< Vector > ref_vector(uint component_idx=0)
FeQArray< Tensor > vector_sym_grad(uint component_idx=0)
Return the value of the function_no-th vector symmetric gradient at the p side quadrature point.
FeQArray< Vector > grad_scalar_shape(uint component_idx=0)
Same as BulkValues::grad_scalar_shape but register at side quadrature points.
SideValues(PatchPointValues< 3 > *patch_point_vals, MixedPtr< FiniteElement > fe)
Constructor.
FeQArray< Scalar > vector_divergence(uint component_idx=0)
Return the value of the function_no-th vector divergence at the p side quadrature point.
ElQ< Scalar > determinant()
Create bulk accessor of jac determinant entity.
FeQ< Scalar > JxW()
Same as BulkValues::JxW but register at side quadrature points.
NodeAccessor< 3 > node(unsigned int i) const
Returns node for given local index i on the side.
Store finite element data on the actual patch such as shape function values, gradients,...
Class FESystem for compound finite elements.
@ FEScalar
@ FEMixedSystem
@ FEVectorPiola
@ FEVectorContravariant
@ FEVector
Class MappingP1 implements the affine transformation of the unit cell onto the actual cell.
unsigned int uint
ArmaMat< double, N, M > mat
Definition: armor.hh:936
@ opVectorSymGrad
Vector symmetric gradient.
@ opVectorDivergence
Vector divergence.
@ opScalarShape
FE operations.
@ opCoords
operations evaluated on quadrature points
@ opVectorShape
Vector shape operation.
@ opRefScalarGrad
Gradient scalar reference.
@ opGradVectorShape
Vector shape gradient.
@ opGradScalarShape
Scalar shape gradient.
@ opRefVector
Vector reference.
@ opRefScalar
Scalar reference.
Store finite element data on the actual patch such as shape function values, gradients,...
#define FMT_UNUSED
Definition: posix.h:75
Definitions of particular quadrature rules on simplices.
Class RefElement defines numbering of vertices, sides, calculation of normal vectors etc.
Definition: mixed.hh:25
Struct for pre-computing number of elements, sides, bulk points and side points on each dimension.
std::vector< std::vector< uint > > point_sizes_
void reset()
Set all values to zero.
void copy(const TableSizes &other)
Copy values of other TableSizes instance.
std::vector< std::vector< uint > > elem_sizes_
static void ptop_vector_shape_grads(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_piola_shape(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_scalar_shape(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_contravariant_shape(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_shape(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void op_base(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_sym_grad(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
Common reinit function of vector symmetric gradient on bulk and side points.
static void ptop_vector_divergence(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
Common reinit function of vector divergence on bulk and side points.
static void ptop_vector_contravariant_shape(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_shape(PatchOp< 3 > *result_op, IntTableArena &el_table)
static void ptop_vector_piola_shape(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_scalar_shape(PatchOp< 3 > *result_op, IntTableArena &el_table)
Enum type UpdateFlags indicates which quantities are to be recomputed on each finite element cell.