Flow123d  DF_patch_fe_data_tables-1a16803
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/element_values.hh" // for ElementValues
31 #include "fem/fe_values.hh" // for FEValuesBase
32 #include "fem/fe_values_views.hh" // for FEValuesViews
33 #include "fem/fe_system.hh" // for FESystem
34 #include "fem/eigen_tools.hh"
36 #include "fem/mapping_p1.hh"
37 #include "mesh/ref_element.hh" // for RefElement
38 #include "mesh/accessors.hh"
39 #include "fem/update_flags.hh" // for UpdateFlags
41 #include "fields/eval_subset.hh"
42 #include "fem/arena_resource.hh"
43 #include "fem/arena_vec.hh"
44 
45 template<unsigned int spacedim> class PatchFEValues;
46 
47 
48 
49 typedef typename std::vector< std::array<uint, 3> > DimPointTable; ///< Holds triplet (dim; bulk/side; idx of point in subtable)
50 
51 
52 template <class ValueType>
53 class ElQ {
54 public:
55  /// Forbidden default constructor
56  ElQ() = delete;
57 
58  /// Constructor
59  ElQ(PatchPointValues<3> &patch_point_vals, unsigned int begin, unsigned int op_idx)
60  : patch_point_vals_(patch_point_vals), begin_(begin), op_idx_(op_idx) {}
61 
62  ValueType operator()(FMT_UNUSED const BulkPoint &point);
63 
64  ValueType operator()(FMT_UNUSED const SidePoint &point);
65 
66 private:
67  PatchPointValues<3> &patch_point_vals_; ///< Reference to PatchPointValues
68  unsigned int begin_; ///< Index of the first component of the bulk Quantity. Size is given by ValueType
69  unsigned int op_idx_; ///< Index of operation in patch_point_vals_.operations vector
70 };
71 
72 
73 template <class ValueType>
74 class FeQ {
75 public:
76  /// Forbidden default constructor
77  FeQ() = delete;
78 
79  // Class similar to current FeView
80  FeQ(PatchPointValues<3> &patch_point_vals, unsigned int begin, unsigned int op_idx, unsigned int n_dofs)
81  : patch_point_vals_(patch_point_vals), begin_(begin), op_idx_(op_idx), n_dofs_(n_dofs) {}
82 
83 
84  ValueType operator()(FMT_UNUSED unsigned int shape_idx, FMT_UNUSED const BulkPoint &point);
85 
86  ValueType operator()(FMT_UNUSED unsigned int shape_idx, FMT_UNUSED const SidePoint &point);
87 
88  // Implementation for EdgePoint, SidePoint, and JoinPoint shoud have a common implementation
89  // resolving to side values
90 
91 private:
92  PatchPointValues<3> &patch_point_vals_; ///< Reference to PatchPointValues
93  unsigned int begin_; ///< Index of the first component of the Quantity. Size is given by ValueType
94  unsigned int op_idx_; ///< Index of operation in patch_point_vals_.operations vector
95  unsigned int n_dofs_; ///< Number of DOFs
96 };
97 
98 
99 template <class ValueType>
101 public:
102  /// Default constructor
104  : patch_point_vals_bulk_(nullptr), patch_point_vals_side_(nullptr), join_idx_(-1) {}
105 
106  /**
107  * Constructor
108  *
109  * @param patch_point_vals_bulk Pointer to PatchPointValues bulk object.
110  * @param patch_point_vals_side Pointer to PatchPointValues side object.
111  * @param begin Index of the first component of the bulk Quantity.
112  * @param begin_side Index of the first component of the side Quantity.
113  * @param n_dofs_bulk Number of DOFs of bulk (lower-dim) element.
114  * @param n_dofs_side Number of DOFs of side (higher-dim) element.
115  * @param join_idx Index function.
116  */
117  JoinShapeAccessor(PatchPointValues<3> *patch_point_vals_bulk, PatchPointValues<3> *patch_point_vals_side,
118  unsigned int begin, unsigned int begin_side, unsigned int n_dofs_bulk, unsigned int n_dofs_side,
119  unsigned int op_idx_bulk, unsigned int op_idx_side, unsigned int join_idx)
120  : patch_point_vals_bulk_(patch_point_vals_bulk), patch_point_vals_side_(patch_point_vals_side), begin_(begin),
121  begin_side_(begin_side), n_dofs_high_(n_dofs_side), n_dofs_low_(n_dofs_bulk), op_idx_bulk_(op_idx_bulk), op_idx_side_(op_idx_side), join_idx_(join_idx) {
122  //ASSERT( (patch_point_vals_bulk->dim()==2) || (patch_point_vals_bulk->dim()==3) )(patch_point_vals_bulk->dim() ).error("Invalid dimension, must be 2 or 3!");
123  }
124 
125  /// Return global index of DOF
126  inline unsigned int join_idx() const {
127  return join_idx_;
128  }
129 
130  /// Return local index of DOF (on low / high-dim) - should be private method
131  inline unsigned int local_idx() const {
132  if (this->is_high_dim()) return (join_idx_ - n_dofs_low_);
133  else return join_idx_;
134  }
135 
136  inline unsigned int n_dofs_low() const {
137  return n_dofs_low_;
138  }
139 
140  inline unsigned int n_dofs_high() const {
141  return n_dofs_high_;
142  }
143 
144  inline unsigned int n_dofs_both() const {
145  return n_dofs_high_ + n_dofs_low_;
146  }
147 
148  inline bool is_high_dim() const {
149  return (join_idx_ >= n_dofs_low_);
150  }
151 
152  /// Iterates to next item.
153  inline void inc() {
154  join_idx_++;
155  }
156 
157  /// Comparison of accessors.
158  bool operator==(const JoinShapeAccessor<ValueType>& other) const {
159  return (join_idx_ == other.join_idx_);
160  }
161 
162 
163  ValueType operator()(const BulkPoint &point);
164 
165  ValueType operator()(const SidePoint &point);
166 
167 private:
168  // attributes:
169  PatchPointValues<3> *patch_point_vals_bulk_; ///< Pointer to bulk PatchPointValues
170  PatchPointValues<3> *patch_point_vals_side_; ///< Pointer to side PatchPointValues
171  unsigned int begin_; ///< Index of the first component of the bulk Quantity. Size is given by ValueType
172  unsigned int begin_side_; ///< Index of the first component of the side Quantity. Size is given by ValueType
173  unsigned int n_dofs_high_; ///< Number of DOFs on high-dim element
174  unsigned int n_dofs_low_; ///< Number of DOFs on low-dim element
175  unsigned int op_idx_bulk_; ///< Index of operation in patch_point_vals_bulk_.operations vector
176  unsigned int op_idx_side_; ///< Index of operation in patch_point_vals_side_.operations vector
177  unsigned int join_idx_; ///< Index of processed DOF
178 };
179 
180 
181 template<unsigned int dim>
183 {
184 protected:
185  // Default constructor
187  {}
188 
189  /// Return FiniteElement of \p component_idx for FESystem or \p fe for other types
190  template<unsigned int FE_dim>
191  std::shared_ptr<FiniteElement<FE_dim>> fe_comp(std::shared_ptr< FiniteElement<FE_dim> > fe, uint component_idx) {
192  FESystem<FE_dim> *fe_sys = dynamic_cast<FESystem<FE_dim>*>( fe.get() );
193  if (fe_sys != nullptr) {
194  return fe_sys->fe()[component_idx];
195  } else {
196  ASSERT_EQ(component_idx, 0).warning("Non-zero component_idx can only be used for FESystem.");
197  return fe;
198  }
199  }
200 
201  /**
202  * @brief Precomputed values of basis functions at the bulk quadrature points.
203  *
204  * Dimensions: (no. of quadrature points)
205  * x (no. of dofs)
206  * x (no. of components in ref. cell)
207  */
208  template<unsigned int FE_dim>
210  std::vector<std::vector<arma::vec> > ref_shape_vals( q->size(), vector<arma::vec>(fe->n_dofs()) );
211 
212  arma::mat shape_values(fe->n_dofs(), fe->n_components());
213  for (unsigned int i=0; i<q->size(); i++)
214  {
215  for (unsigned int j=0; j<fe->n_dofs(); j++)
216  {
217  for (unsigned int c=0; c<fe->n_components(); c++)
218  shape_values(j,c) = fe->shape_value(j, q->point<FE_dim>(i), c);
219 
220  ref_shape_vals[i][j] = trans(shape_values.row(j));
221  }
222  }
223 
224  return ref_shape_vals;
225  }
226 
227  /**
228  * @brief Precomputed values of basis functions at the side quadrature points.
229  *
230  * Dimensions: (sides)
231  * x (no. of quadrature points)
232  * x (no. of dofs)
233  * x (no. of components in ref. cell)
234  */
235  template<unsigned int FE_dim>
238 
239  arma::mat shape_values(fe->n_dofs(), fe->n_components());
240 
241  for (unsigned int sid=0; sid<FE_dim+1; sid++) {
242  auto quad = q->make_from_side<dim>(sid);
243  for (unsigned int i=0; i<quad.size(); i++)
244  {
245  for (unsigned int j=0; j<fe->n_dofs(); j++)
246  {
247  for (unsigned int c=0; c<fe->n_components(); c++) {
248  shape_values(j,c) = fe->shape_value(j, quad.template point<FE_dim>(i), c);
249  }
250 
251  ref_shape_vals[sid][i][j] = trans(shape_values.row(j));
252  }
253  }
254  }
255 
256  return ref_shape_vals;
257  }
258 
259 };
260 
261 template<unsigned int dim>
262 class BulkValues : public BaseValues<dim>
263 {
264 public:
265  /// Constructor
267  : BaseValues<dim>(), patch_point_vals_(patch_point_vals) {
268  ASSERT_EQ(patch_point_vals.dim(), dim);
269  fe_ = fe[Dim<dim>{}];
270  }
271 
272  /**
273  * @brief Register the product of Jacobian determinant and the quadrature
274  * weight at bulk quadrature points.
275  *
276  * @param quad Quadrature.
277  */
278  inline ElQ<Scalar> JxW()
279  {
282  }
283 
284  /// Create bulk accessor of coords entity
286  {
289  }
290 
291 // inline ElQ<Tensor> jacobian(std::initializer_list<Quadrature *> quad_list)
292 // {}
293 
294  /// Create bulk accessor of jac determinant entity
296  {
299  }
300 
301  /**
302  * @brief Return the value of the @p function_no-th shape function at
303  * the @p p bulk quadrature point.
304  *
305  * @param component_idx Number of the shape function.
306  */
307  inline FeQ<Scalar> scalar_shape(uint component_idx = 0)
308  {
309  auto fe_component = this->fe_comp(fe_, component_idx);
310  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
311 
312  // use lambda reinit function
313  std::vector< std::vector<double> > shape_values( fe_component->n_dofs(), vector<double>(patch_point_vals_.get_quadrature()->size()) );
314  auto ref_shape_vals = this->ref_shape_values_bulk(patch_point_vals_.get_quadrature(), fe_component);
315  for (unsigned int i = 0; i < patch_point_vals_.get_quadrature()->size(); i++)
316  for (unsigned int j = 0; j < fe_component->n_dofs(); j++) {
317  shape_values[j][i] = ref_shape_vals[i][j][0];
318  }
319  uint scalar_shape_op_idx = patch_point_vals_.operations_.size(); // index in operations_ vector
320  auto lambda_scalar_shape = [shape_values, scalar_shape_op_idx](std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
321  bulk_reinit::ptop_scalar_shape(operations, shape_values, scalar_shape_op_idx);
322  };
323  auto &scalar_shape_bulk_op = patch_point_vals_.make_fe_op({1}, lambda_scalar_shape, {}, fe_component->n_dofs());
324  // lambda_scalar_shape
325  uint begin = scalar_shape_bulk_op.result_row();
326  uint op_idx = patch_point_vals_.operations_.size()-1;
327 
328  return FeQ<Scalar>(patch_point_vals_, begin, op_idx, fe_component->n_dofs());
329  }
330 
331 // inline FeQ<Vector> vector_shape(uint component_idx = 0)
332 // {}
333 
334 // inline FeQ<Tensor> tensor_shape(uint component_idx = 0)
335 // {}
336 
337  /**
338  * @brief Return the value of the @p function_no-th gradient shape function at
339  * the @p p bulk quadrature point.
340  *
341  * @param component_idx Number of the shape function.
342  */
343  inline FeQ<Vector> grad_scalar_shape(uint component_idx=0)
344  {
345  auto fe_component = this->fe_comp(fe_, component_idx);
346  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of grad_scalar_shape accessor must be FEScalar!\n");
347 
348  // use lambda reinit function
349  auto ref_shape_grads = this->ref_shape_gradients(fe_component);
350  uint scalar_shape_grads_op_idx = patch_point_vals_.operations_.size(); // index in operations_ vector
351  auto lambda_scalar_shape_grad = [ref_shape_grads, scalar_shape_grads_op_idx](std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
352  bulk_reinit::ptop_scalar_shape_grads<dim>(operations, ref_shape_grads, scalar_shape_grads_op_idx);
353  };
354  auto &grad_scalar_shape_bulk_op = patch_point_vals_.make_fe_op({3}, lambda_scalar_shape_grad, {FeBulk::BulkOps::opInvJac}, fe_component->n_dofs());
355  uint begin = grad_scalar_shape_bulk_op.result_row();
356  uint op_idx = patch_point_vals_.operations_.size()-1;
357 
358  return FeQ<Vector>(patch_point_vals_, begin, op_idx, fe_component->n_dofs());
359  }
360 
361 // inline FeQ<Tensor> grad_vector_shape(std::initializer_list<Quadrature *> quad_list, unsigned int i_comp=0)
362 // {}
363 
364 private:
365  /**
366  * @brief Precomputed gradients of basis functions at the quadrature points.
367  *
368  * Dimensions: (no. of quadrature points)
369  * x (no. of dofs)
370  * x ((dim_ of. ref. cell)x(no. of components in ref. cell))
371  */
374  std::vector<std::vector<arma::mat> > ref_shape_grads( q->size(), vector<arma::mat>(fe->n_dofs()) );
375 
376  arma::mat grad(dim, fe->n_components());
377  for (unsigned int i_pt=0; i_pt<q->size(); i_pt++)
378  {
379  for (unsigned int i_dof=0; i_dof<fe->n_dofs(); i_dof++)
380  {
381  grad.zeros();
382  for (unsigned int c=0; c<fe->n_components(); c++)
383  grad.col(c) += fe->shape_grad(i_dof, q->point<dim>(i_pt), c);
384 
385  ref_shape_grads[i_pt][i_dof] = grad;
386  }
387  }
388 
389  return ref_shape_grads;
390  }
391 
393  std::shared_ptr< FiniteElement<dim> > fe_;
394 };
395 
396 
397 template<unsigned int dim>
398 class SideValues : public BaseValues<dim>
399 {
400 public:
401  /// Constructor
403  : BaseValues<dim>(), patch_point_vals_(patch_point_vals) {
404  ASSERT_EQ(patch_point_vals.dim(), dim);
405  fe_ = fe[Dim<dim>{}];
406  }
407 
408  /// Same as BulkValues::JxW but register at side quadrature points.
409  inline ElQ<Scalar> JxW()
410  {
413  }
414 
415  /**
416  * @brief Register the normal vector to a side at side quadrature points.
417  *
418  * @param quad Quadrature.
419  */
421  {
424  }
425 
426  /// Create side accessor of coords entity
428  {
431  }
432 
433  /// Create bulk accessor of jac determinant entity
435  {
438  }
439 
440  /// Same as BulkValues::scalar_shape but register at side quadrature points.
441  inline FeQ<Scalar> scalar_shape(uint component_idx = 0)
442  {
443  auto fe_component = this->fe_comp(fe_, component_idx);
444  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
445 
446  // use lambda reinit function
448  dim+1,
450  );
451  auto ref_shape_vals = this->ref_shape_values_side(patch_point_vals_.get_quadrature(), fe_component);
452  for (unsigned int s=0; s<dim+1; ++s)
453  for (unsigned int i = 0; i < patch_point_vals_.get_quadrature()->size(); i++)
454  for (unsigned int j = 0; j < fe_component->n_dofs(); j++) {
455  shape_values[s][i][j] = ref_shape_vals[s][i][j][0];
456  }
457  uint scalar_shape_op_idx = patch_point_vals_.operations_.size(); // index in operations_ vector
458  auto lambda_scalar_shape = [shape_values, scalar_shape_op_idx](std::vector<ElOp<3>> &operations, IntTableArena &el_table) {
459  side_reinit::ptop_scalar_shape(operations, el_table, shape_values, scalar_shape_op_idx);
460  };
461  auto &scalar_shape_bulk_op = patch_point_vals_.make_fe_op({1}, lambda_scalar_shape, {}, fe_component->n_dofs());
462  uint begin = scalar_shape_bulk_op.result_row();
463  uint op_idx = patch_point_vals_.operations_.size()-1;
464 
465  return FeQ<Scalar>(patch_point_vals_, begin, op_idx, fe_component->n_dofs());
466  }
467 
468  /// Same as BulkValues::grad_scalar_shape but register at side quadrature points.
469  inline FeQ<Vector> grad_scalar_shape(uint component_idx=0)
470  {
471  auto fe_component = this->fe_comp(fe_, component_idx);
472  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of grad_scalar_shape accessor must be FEScalar!\n");
473 
474  // use lambda reinit function
475  auto ref_shape_grads = this->ref_shape_gradients(fe_component);
476  uint scalar_shape_grads_op_idx = patch_point_vals_.operations_.size(); // index in operations_ vector
477  auto lambda_scalar_shape_grad = [ref_shape_grads, scalar_shape_grads_op_idx](std::vector<ElOp<3>> &operations, IntTableArena &el_table) {
478  side_reinit::ptop_scalar_shape_grads<dim>(operations, el_table, ref_shape_grads, scalar_shape_grads_op_idx);
479  };
480  auto &grad_scalar_shape_side_op = patch_point_vals_.make_fe_op({3}, lambda_scalar_shape_grad, {FeSide::SideOps::opElInvJac}, fe_component->n_dofs());
481  uint begin = grad_scalar_shape_side_op.result_row();
482  uint op_idx = patch_point_vals_.operations_.size()-1;
483 
484  return FeQ<Vector>(patch_point_vals_, begin, op_idx, fe_component->n_dofs());
485  }
486 
487 private:
488  /**
489  * @brief Precomputed gradients of basis functions at the quadrature points.
490  *
491  * Dimensions: (sides)
492  * x (no. of quadrature points)
493  * x (no. of dofs)
494  * x ((dim_ of. ref. cell)x(no. of components in ref. cell))
495  */
499 
500  arma::mat grad(dim, fe->n_components());
501  for (unsigned int sid=0; sid<dim+1; sid++) {
502  auto quad = q->make_from_side<dim>(sid);
503  for (unsigned int i_pt=0; i_pt<quad.size(); i_pt++)
504  {
505  for (unsigned int i_dof=0; i_dof<fe->n_dofs(); i_dof++)
506  {
507  grad.zeros();
508  for (unsigned int c=0; c<fe->n_components(); c++)
509  grad.col(c) += fe->shape_grad(i_dof, quad.template point<dim>(i_pt), c);
510 
511  ref_shape_grads[sid][i_pt][i_dof] = grad;
512  }
513  }
514  }
515 
516  return ref_shape_grads;
517  }
518 
520  std::shared_ptr< FiniteElement<dim> > fe_;
521 };
522 
523 
524 template<unsigned int dim>
525 class JoinValues : public BaseValues<dim>
526 {
527 public:
528  /// Constructor
529  JoinValues(PatchPointValues<3> *patch_point_vals_bulk, PatchPointValues<3> *patch_point_vals_side, MixedPtr<FiniteElement> fe)
530  : BaseValues<dim>(), patch_point_vals_bulk_(patch_point_vals_bulk), patch_point_vals_side_(patch_point_vals_side) {
531  ASSERT_EQ(patch_point_vals_bulk->dim(), dim-1);
532  ASSERT_EQ(patch_point_vals_side->dim(), dim);
533  fe_high_dim_ = fe[Dim<dim>{}];
534  fe_low_dim_ = fe[Dim<dim-1>{}];
535  }
536 
538  {
539  // element of lower dim (bulk points)
540  auto fe_component_low = this->fe_comp(fe_low_dim_, component_idx);
541  ASSERT_EQ(fe_component_low->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
542  // use lambda reinit function
543  std::vector< std::vector<double> > shape_values_bulk( patch_point_vals_bulk_->get_quadrature()->size(), vector<double>(fe_component_low->n_dofs()) );
544  auto ref_shape_vals_bulk = this->ref_shape_values_bulk(patch_point_vals_bulk_->get_quadrature(), fe_component_low);
545  for (unsigned int i = 0; i < patch_point_vals_bulk_->get_quadrature()->size(); i++)
546  for (unsigned int j = 0; j < fe_component_low->n_dofs(); j++) {
547  shape_values_bulk[i][j] = ref_shape_vals_bulk[i][j][0];
548  }
549  uint scalar_shape_op_idx_bulk = patch_point_vals_bulk_->operations_.size(); // index in operations_ vector
550  auto lambda_scalar_shape_bulk = [shape_values_bulk, scalar_shape_op_idx_bulk](std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
551  bulk_reinit::ptop_scalar_shape(operations, shape_values_bulk, scalar_shape_op_idx_bulk);
552  };
553  auto &grad_scalar_shape_bulk_op = patch_point_vals_bulk_->make_fe_op({1}, lambda_scalar_shape_bulk, {}, fe_component_low->n_dofs());
554  uint begin_bulk = grad_scalar_shape_bulk_op.result_row();
555  uint op_idx_bulk = patch_point_vals_bulk_->operations_.size()-1;
556 
557  // element of higher dim (side points)
558  auto fe_component_high = this->fe_comp(fe_high_dim_, component_idx);
559  ASSERT_EQ(fe_component_high->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
560  // use lambda reinit function
561  std::vector< std::vector< std::vector<double> > > shape_values_side(
562  dim+1,
564  );
565  auto ref_shape_vals_side = this->ref_shape_values_side(patch_point_vals_side_->get_quadrature(), fe_component_high);
566  for (unsigned int s=0; s<dim+1; ++s)
567  for (unsigned int i = 0; i < patch_point_vals_side_->get_quadrature()->size(); i++)
568  for (unsigned int j = 0; j < fe_component_high->n_dofs(); j++) {
569  shape_values_side[s][i][j] = ref_shape_vals_side[s][i][j][0];
570  }
571  uint scalar_shape_op_idx_side = patch_point_vals_side_->operations_.size(); // index in operations_ vector
572  auto lambda_scalar_shape_side = [shape_values_side, scalar_shape_op_idx_side](std::vector<ElOp<3>> &operations, IntTableArena &el_table) {
573  side_reinit::ptop_scalar_shape(operations, el_table, shape_values_side, scalar_shape_op_idx_side);
574  };
575  auto &grad_scalar_shape_side_op = patch_point_vals_side_->make_fe_op({1}, lambda_scalar_shape_side, {}, fe_component_high->n_dofs());
576  uint begin_side = grad_scalar_shape_side_op.result_row();
577  uint op_idx_side = patch_point_vals_side_->operations_.size()-1;
578 
579  auto bgn_it = make_iter<JoinShapeAccessor<Scalar>>( JoinShapeAccessor<Scalar>(patch_point_vals_bulk_, patch_point_vals_side_,
580  begin_bulk, begin_side, fe_component_low->n_dofs(), fe_component_high->n_dofs(), op_idx_bulk, op_idx_side, 0) );
581  unsigned int end_idx = fe_component_low->n_dofs() + fe_component_high->n_dofs();
582  auto end_it = make_iter<JoinShapeAccessor<Scalar>>( JoinShapeAccessor<Scalar>(patch_point_vals_bulk_, patch_point_vals_side_,
583  begin_bulk, begin_side, fe_component_low->n_dofs(), fe_component_high->n_dofs(), op_idx_bulk, op_idx_side, end_idx) );
584  return Range<JoinShapeAccessor<Scalar>>(bgn_it, end_it);
585  }
586 
587 private:
590  std::shared_ptr< FiniteElement<dim> > fe_high_dim_;
591  std::shared_ptr< FiniteElement<dim-1> > fe_low_dim_;
592 };
593 
594 /// Template specialization of dim = 1
595 template <>
596 class JoinValues<1> : public BaseValues<1>
597 {
598 public:
599  /// Constructor
601  : BaseValues<1>() {}
602 
604  {
606  make_iter<JoinShapeAccessor<Scalar>>(JoinShapeAccessor<Scalar>()),
608  }
609 };
610 
611 
612 template<unsigned int spacedim = 3>
614 public:
615  /// Struct for pre-computing number of elements, sides, bulk points and side points on each dimension.
616  struct TableSizes {
617  public:
618  /// Constructor
622  }
623 
624  /// Set all values to zero
625  void reset() {
626  std::fill(elem_sizes_[0].begin(), elem_sizes_[0].end(), 0);
627  std::fill(elem_sizes_[1].begin(), elem_sizes_[1].end(), 0);
628  std::fill(point_sizes_[0].begin(), point_sizes_[0].end(), 0);
629  std::fill(point_sizes_[1].begin(), point_sizes_[1].end(), 0);
630  }
631 
632  /**
633  * Holds number of elements and sides on each dimension
634  * Format:
635  * { {n_elements_1D, n_elements_2D, n_elements_3D },
636  * {n_sides_1D, n_sides_2D, n_sides_3D } }
637  */
639 
640  /**
641  * Holds number of bulk and side points on each dimension
642  * Format:
643  * { {n_bulk_points_1D, n_bulk_points_2D, n_bulk_points_3D },
644  * {n_side_points_1D, n_side_points_2D, n_side_points_3D } }
645  */
647  };
648 
650  : asm_arena_(1024 * 1024, 256),
651  patch_arena_(nullptr),
655  patch_point_vals_side_{ {FeSide::PatchPointValues(1, 0, asm_arena_),
656  FeSide::PatchPointValues(2, 0, asm_arena_),
657  FeSide::PatchPointValues(3, 0, asm_arena_)} }
658  {
659  used_quads_[0] = false; used_quads_[1] = false;
660  }
661 
662  PatchFEValues(unsigned int quad_order, MixedPtr<FiniteElement> fe)
663  : asm_arena_(1024 * 1024, 256),
664  patch_arena_(nullptr),
665  patch_point_vals_bulk_{ {FeBulk::PatchPointValues(1, quad_order, asm_arena_),
666  FeBulk::PatchPointValues(2, quad_order, asm_arena_),
667  FeBulk::PatchPointValues(3, quad_order, asm_arena_)} },
668  patch_point_vals_side_{ {FeSide::PatchPointValues(1, quad_order, asm_arena_),
669  FeSide::PatchPointValues(2, quad_order, asm_arena_),
670  FeSide::PatchPointValues(3, quad_order, asm_arena_)} },
671  fe_(fe)
672  {
673  used_quads_[0] = false; used_quads_[1] = false;
674  }
675 
676 
677  /// Destructor
679  {
680  if (patch_arena_!=nullptr)
681  delete patch_arena_;
682  }
683 
684  /// Return bulk or side quadrature of given dimension
685  Quadrature *get_quadrature(uint dim, bool is_bulk) const {
686  if (is_bulk) return patch_point_vals_bulk_[dim-1].get_quadrature();
687  else return patch_point_vals_side_[dim-1].get_quadrature();
688  }
689 
690  /**
691  * @brief Initialize structures and calculates cell-independent data.
692  *
693  * @param _quadrature The quadrature rule for the cell associated
694  * to given finite element or for the cell side.
695  * @param _flags The update flags.
696  */
697  template<unsigned int DIM>
698  void initialize(Quadrature &_quadrature)
699  {
700  if ( _quadrature.dim() == DIM ) {
701  used_quads_[0] = true;
702  patch_point_vals_bulk_[DIM-1].initialize(); // bulk
703  } else {
704  used_quads_[1] = true;
705  patch_point_vals_side_[DIM-1].initialize(); // side
706  }
707  }
708 
709  /// Finalize initialization, creates child (patch) arena and passes it to PatchPointValue objects
710  void init_finalize() {
711  patch_arena_ = asm_arena_.get_child_arena();
712  for (unsigned int i=0; i<3; ++i) {
713  if (used_quads_[0]) patch_point_vals_bulk_[i].init_finalize(patch_arena_);
714  if (used_quads_[1]) patch_point_vals_side_[i].init_finalize(patch_arena_);
715  }
716  }
717 
718  /// Reset PatchpointValues structures
719  void reset()
720  {
721  for (unsigned int i=0; i<3; ++i) {
722  if (used_quads_[0]) patch_point_vals_bulk_[i].reset();
723  if (used_quads_[1]) patch_point_vals_side_[i].reset();
724  }
725  patch_arena_->reset();
726  }
727 
728  /// Reinit data.
730  {
731  for (unsigned int i=0; i<3; ++i) {
732  if (used_quads_[0]) patch_point_vals_bulk_[i].reinit_patch();
733  if (used_quads_[1]) patch_point_vals_side_[i].reinit_patch();
734  }
735  }
736 
737  /**
738  * @brief Returns the number of shape functions.
739  */
740  template<unsigned int dim>
741  inline unsigned int n_dofs() const {
742  ASSERT((dim>=0) && (dim<=3))(dim).error("Dimension must be 0, 1, 2 or 3.");
743  return fe_[Dim<dim>{}]->n_dofs();
744  }
745 
746  /// Return BulkValue object of dimension given by template parameter
747  template<unsigned int dim>
749  ASSERT((dim>0) && (dim<=3))(dim).error("Dimension must be 1, 2 or 3.");
750  return BulkValues<dim>(patch_point_vals_bulk_[dim-1], fe_);
751  }
752 
753  /// Return SideValue object of dimension given by template parameter
754  template<unsigned int dim>
756  ASSERT((dim>0) && (dim<=3))(dim).error("Dimension must be 1, 2 or 3.");
757  return SideValues<dim>(patch_point_vals_side_[dim-1], fe_);
758  }
759 
760  /// Return JoinValue object of dimension given by template parameter
761  template<unsigned int dim>
763  //ASSERT((dim>1) && (dim<=3))(dim).error("Dimension must be 2 or 3.");
764  return JoinValues<dim>(&patch_point_vals_bulk_[dim-2], &patch_point_vals_side_[dim-1], fe_);
765  }
766 
767  /** Following methods are used during update of patch. **/
768 
769  /// Resize tables of patch_point_vals_
770  void resize_tables(TableSizes table_sizes) {
771  for (uint i=0; i<3; ++i) {
772  if (used_quads_[0]) patch_point_vals_bulk_[i].resize_tables(table_sizes.elem_sizes_[0][i], table_sizes.point_sizes_[0][i]);
773  if (used_quads_[1]) patch_point_vals_side_[i].resize_tables(table_sizes.elem_sizes_[1][i], table_sizes.point_sizes_[1][i]);
774  }
775  }
776 
777  /// Register element to patch_point_vals_ table by dimension of element
778  uint register_element(DHCellAccessor cell, uint element_patch_idx) {
779  arma::mat coords;
780  switch (cell.dim()) {
781  case 1:
782  coords = MappingP1<1,spacedim>::element_map(cell.elm());
783  return patch_point_vals_bulk_[0].register_element(coords, element_patch_idx);
784  break;
785  case 2:
786  coords = MappingP1<2,spacedim>::element_map(cell.elm());
787  return patch_point_vals_bulk_[1].register_element(coords, element_patch_idx);
788  break;
789  case 3:
790  coords = MappingP1<3,spacedim>::element_map(cell.elm());
791  return patch_point_vals_bulk_[2].register_element(coords, element_patch_idx);
792  break;
793  default:
794  ASSERT(false);
795  return 0;
796  break;
797  }
798  }
799 
800  /// Register side to patch_point_vals_ table by dimension of side
802  arma::mat side_coords(spacedim, cell_side.dim());
803  for (unsigned int n=0; n<cell_side.dim(); n++)
804  for (unsigned int c=0; c<spacedim; c++)
805  side_coords(c,n) = (*cell_side.side().node(n))[c];
806 
807  arma::mat elm_coords;
808  DHCellAccessor cell = cell_side.cell();
809  switch (cell.dim()) {
810  case 1:
811  elm_coords = MappingP1<1,spacedim>::element_map(cell.elm());
812  return patch_point_vals_side_[0].register_side(elm_coords, side_coords, cell_side.side_idx());
813  break;
814  case 2:
815  elm_coords = MappingP1<2,spacedim>::element_map(cell.elm());
816  return patch_point_vals_side_[1].register_side(elm_coords, side_coords, cell_side.side_idx());
817  break;
818  case 3:
819  elm_coords = MappingP1<3,spacedim>::element_map(cell.elm());
820  return patch_point_vals_side_[2].register_side(elm_coords, side_coords, cell_side.side_idx());
821  break;
822  default:
823  ASSERT(false);
824  return 0;
825  break;
826  }
827  }
828 
829  /// Register bulk point to patch_point_vals_ table by dimension of element
830  uint register_bulk_point(DHCellAccessor cell, uint elem_table_row, uint value_patch_idx, uint i_point_on_elem) {
831  return patch_point_vals_bulk_[cell.dim()-1].register_bulk_point(elem_table_row, value_patch_idx, cell.elm_idx(), i_point_on_elem);
832  }
833 
834  /// Register side point to patch_point_vals_ table by dimension of side
835  uint register_side_point(DHCellSide cell_side, uint elem_table_row, uint value_patch_idx, uint i_point_on_side) {
836  return patch_point_vals_side_[cell_side.dim()-1].register_side_point(elem_table_row, value_patch_idx, cell_side.elem_idx(),
837  cell_side.side_idx(), i_point_on_side);
838  }
839 
840  /// Temporary development method
841  void print_data_tables(ostream& stream, bool points, bool ints, bool only_bulk=true) const {
842  stream << endl << "Table of patch FE data:" << endl;
843  for (uint i=0; i<3; ++i) {
844  stream << std::setfill('-') << setw(100) << "" << endl;
845  stream << "Bulk, dimension " << (i+1) << endl;
846  patch_point_vals_bulk_[i].print_data_tables(stream, points, ints);
847  }
848  if (!only_bulk)
849  for (uint i=0; i<3; ++i) {
850  stream << std::setfill('-') << setw(100) << "" << endl;
851  stream << "Side, dimension " << (i+1) << endl;
852  patch_point_vals_side_[i].print_data_tables(stream, points, ints);
853  }
854  stream << std::setfill('=') << setw(100) << "" << endl;
855  }
856 
857  /// Temporary development method
858  void print_operations(ostream& stream) const {
859  stream << endl << "Table of patch FE operations:" << endl;
860  for (uint i=0; i<3; ++i) {
861  stream << std::setfill('-') << setw(100) << "" << endl;
862  stream << "Bulk, dimension " << (i+1) << ", n_rows " << patch_point_vals_bulk_[i].n_rows() << endl;
863  patch_point_vals_bulk_[i].print_operations(stream, 0);
864  }
865  for (uint i=0; i<3; ++i) {
866  stream << std::setfill('-') << setw(100) << "" << endl;
867  stream << "Side, dimension " << (i+1) << ", n_rows " << patch_point_vals_side_[i].n_rows() << endl;
868  patch_point_vals_side_[i].print_operations(stream, 1);
869  }
870  stream << std::setfill('=') << setw(100) << "" << endl;
871  }
872 
873 private:
876  std::array<FeBulk::PatchPointValues<spacedim>, 3> patch_point_vals_bulk_; ///< Sub objects of bulk data of dimensions 1,2,3
877  std::array<FeSide::PatchPointValues<spacedim>, 3> patch_point_vals_side_; ///< Sub objects of side data of dimensions 1,2,3
878 
879  MixedPtr<FiniteElement> fe_; ///< Mixed of shared pointers of FiniteElement object
880  bool used_quads_[2]; ///< Pair of flags signs holds info if bulk and side quadratures are used
881 
882  template <class ValueType>
883  friend class ElQ;
884  template <class ValueType>
885  friend class FeQ;
886  template <class ValueType>
887  friend class JoinShapeAccessor;
888 };
889 
890 
891 template <class ValueType>
892 ValueType ElQ<ValueType>::operator()(const BulkPoint &point) {
893  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
894  return patch_point_vals_.scalar_value(op_idx_, value_cache_idx);
895 }
896 
897 template <>
899  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
900  return patch_point_vals_.vector_value(op_idx_, value_cache_idx);
901 }
902 
903 template <>
905  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
906  return patch_point_vals_.tensor_value(op_idx_, value_cache_idx);
907 }
908 
909 template <class ValueType>
910 ValueType ElQ<ValueType>::operator()(const SidePoint &point) {
911  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
912  return patch_point_vals_.scalar_value(op_idx_, value_cache_idx);
913 }
914 
915 template <>
917  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
918  return patch_point_vals_.vector_value(op_idx_, value_cache_idx);
919 }
920 
921 template <>
923  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
924  return patch_point_vals_.tensor_value(op_idx_, value_cache_idx);
925 }
926 
927 template <class ValueType>
928 ValueType FeQ<ValueType>::operator()(unsigned int shape_idx, const BulkPoint &point) {
929  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
930  return patch_point_vals_.scalar_value(op_idx_, value_cache_idx, shape_idx);
931 }
932 
933 template <>
934 inline Vector FeQ<Vector>::operator()(unsigned int shape_idx, const BulkPoint &point) {
935  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
936  return patch_point_vals_.vector_value(op_idx_, value_cache_idx, shape_idx);
937 }
938 
939 template <>
940 inline Tensor FeQ<Tensor>::operator()(unsigned int shape_idx, const BulkPoint &point) {
941  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
942  return patch_point_vals_.tensor_value(op_idx_, value_cache_idx, shape_idx);
943 }
944 
945 template <class ValueType>
946 ValueType FeQ<ValueType>::operator()(unsigned int shape_idx, const SidePoint &point) {
947  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
948  return patch_point_vals_.scalar_value(op_idx_, value_cache_idx, shape_idx);
949 }
950 
951 template <>
952 inline Vector FeQ<Vector>::operator()(unsigned int shape_idx, const SidePoint &point) {
953  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
954  return patch_point_vals_.vector_value(op_idx_, value_cache_idx, shape_idx);
955 }
956 
957 template <>
958 inline Tensor FeQ<Tensor>::operator()(FMT_UNUSED unsigned int shape_idx, FMT_UNUSED const SidePoint &point) {
959  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
960  return patch_point_vals_.tensor_value(op_idx_, value_cache_idx, shape_idx);
961 }
962 
963 
964 template <class ValueType>
966  if (this->is_high_dim()) {
967  return 0.0;
968  } else {
969  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
970  return patch_point_vals_bulk_->scalar_value(op_idx_bulk_, value_cache_idx, this->local_idx());
971  }
972 }
973 
974 template <>
976  Vector vect; vect.zeros();
977  return vect;
978 }
979 
980 template <>
982  Tensor tens; tens.zeros();
983  return tens;
984 }
985 
986 template <class ValueType>
988  if (this->is_high_dim()) {
989  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
990  return patch_point_vals_side_->scalar_value(op_idx_side_, value_cache_idx, this->local_idx());
991  } else {
992  return 0.0;
993  }
994 }
995 
996 template <>
998  Vector vect; vect.zeros();
999  return vect;
1000 }
1001 
1002 template <>
1004  Tensor tens; tens.zeros();
1005  return tens;
1006 }
1007 
1008 
1009 #endif /* PATCH_FE_VALUES_HH_ */
#define ASSERT(expr)
Definition: asserts.hh:351
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:333
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::vec > > ref_shape_values_bulk(Quadrature *q, std::shared_ptr< FiniteElement< FE_dim >> fe)
Precomputed values of basis functions at the bulk 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
ElQ< Scalar > JxW()
Register the product of Jacobian determinant and the quadrature weight at bulk quadrature points.
PatchPointValues< 3 > & patch_point_vals_
ElQ< Vector > coords()
Create bulk accessor of coords entity.
std::vector< std::vector< arma::mat > > ref_shape_gradients(std::shared_ptr< FiniteElement< dim >> fe)
Precomputed gradients of basis functions at the quadrature points.
ElQ< Scalar > determinant()
Create bulk accessor of jac determinant entity.
std::shared_ptr< FiniteElement< dim > > fe_
FeQ< 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.
FeQ< Scalar > scalar_shape(uint component_idx=0)
Return the value of the function_no-th shape function at the p bulk quadrature point.
BulkValues(PatchPointValues< 3 > &patch_point_vals, MixedPtr< FiniteElement > fe)
Constructor.
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
ElQ(PatchPointValues< 3 > &patch_point_vals, unsigned int begin, 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.
unsigned int begin_
Index of the first component of the bulk Quantity. Size is given by ValueType.
ValueType operator()(FMT_UNUSED const SidePoint &point)
ValueType operator()(FMT_UNUSED const BulkPoint &point)
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
Bulk data specialization, order of item in operations_ vector corresponds to the BulkOps enum.
unsigned int begin_
Index of the first component of the Quantity. Size is given by ValueType.
PatchPointValues< 3 > & patch_point_vals_
Reference to PatchPointValues.
unsigned int n_dofs_
Number of DOFs.
FeQ(PatchPointValues< 3 > &patch_point_vals, unsigned int begin, unsigned int op_idx, unsigned int n_dofs)
ValueType operator()(FMT_UNUSED unsigned int shape_idx, FMT_UNUSED const BulkPoint &point)
unsigned int op_idx_
Index of operation in patch_point_vals_.operations vector.
FeQ()=delete
Forbidden default constructor.
ValueType operator()(FMT_UNUSED unsigned int shape_idx, FMT_UNUSED const SidePoint &point)
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...
unsigned int n_dofs_both() const
unsigned int begin_side_
Index of the first component of the side Quantity. Size is given by ValueType.
unsigned int local_idx() const
Return local index of DOF (on low / high-dim) - should be private method.
bool operator==(const JoinShapeAccessor< ValueType > &other) const
Comparison of accessors.
bool is_high_dim() const
unsigned int begin_
Index of the first component of the bulk Quantity. Size is given by ValueType.
PatchPointValues< 3 > * patch_point_vals_bulk_
Pointer to bulk 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.
JoinShapeAccessor(PatchPointValues< 3 > *patch_point_vals_bulk, PatchPointValues< 3 > *patch_point_vals_side, unsigned int begin, unsigned int begin_side, unsigned int n_dofs_bulk, unsigned int n_dofs_side, unsigned int op_idx_bulk, unsigned int op_idx_side, unsigned int join_idx)
unsigned int n_dofs_high() const
JoinShapeAccessor()
Default constructor.
void inc()
Iterates to next item.
unsigned int join_idx_
Index of processed DOF.
unsigned int n_dofs_high_
Number of DOFs on high-dim element.
unsigned int join_idx() const
Return global index of DOF.
unsigned int n_dofs_low() const
ValueType operator()(const BulkPoint &point)
unsigned int n_dofs_low_
Number of DOFs on low-dim element.
PatchPointValues< 3 > * patch_point_vals_side_
Pointer to side PatchPointValues.
JoinValues(FMT_UNUSED PatchPointValues< 3 > *patch_point_vals_bulk, FMT_UNUSED PatchPointValues< 3 > *patch_point_vals_side, FMT_UNUSED MixedPtr< FiniteElement > fe)
Constructor.
Range< JoinShapeAccessor< 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.
PatchPointValues< 3 > * patch_point_vals_bulk_
Range< JoinShapeAccessor< Scalar > > scalar_join_shape(uint component_idx=0)
std::shared_ptr< FiniteElement< dim-1 > > fe_low_dim_
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.
PatchArena * patch_arena_
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.
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.
AssemblyArena asm_arena_
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.
ElOp< spacedim > & make_fe_op(std::initializer_list< uint > shape, ReinitFunction reinit_f, std::vector< uint > input_ops_vec, uint n_dofs, OpSizeType size_type=pointOp)
std::vector< ElOp< spacedim > > operations_
Vector of all defined operations.
Quadrature * get_quadrature() const
Getter for quadrature.
uint dim() const
Getter for dim_.
Scalar scalar_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
Range helper class.
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
SideValues(PatchPointValues< 3 > &patch_point_vals, MixedPtr< FiniteElement > fe)
Constructor.
ElQ< Vector > normal_vector()
Register the normal vector to a side at side quadrature points.
std::shared_ptr< FiniteElement< dim > > fe_
ElQ< Scalar > JxW()
Same as BulkValues::JxW but register at side quadrature points.
ElQ< Vector > coords()
Create side accessor of coords entity.
FeQ< Scalar > scalar_shape(uint component_idx=0)
Same as BulkValues::scalar_shape but register at side quadrature points.
FeQ< Vector > grad_scalar_shape(uint component_idx=0)
Same as BulkValues::grad_scalar_shape but register at side quadrature points.
std::vector< std::vector< std::vector< arma::mat > > > ref_shape_gradients(std::shared_ptr< FiniteElement< dim >> fe)
Precomputed gradients of basis functions at the quadrature points.
PatchPointValues< 3 > & patch_point_vals_
ElQ< Scalar > determinant()
Create bulk accessor of jac determinant entity.
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,...
Eigen::Vector< ArenaVec< uint >, Eigen::Dynamic > IntTableArena
Definition: eigen_tools.hh:39
Class ElementValues calculates data related to transformation of reference cell to actual cell (Jacob...
Class FESystem for compound finite elements.
Class FEValues calculates finite element data on the actual cells such as shape function values,...
@ FEScalar
Iter< Object > make_iter(Object obj)
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
@ opCoords
operations evaluated on quadrature points
@ opInvJac
inverse Jacobian
@ opJxW
JxW value of quadrature point.
@ opNormalVec
normal vector of quadrature point
std::vector< std::array< uint, 3 > > DimPointTable
Holds triplet (dim; bulk/side; idx of point in subtable)
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.
std::vector< std::vector< uint > > elem_sizes_
static void ptop_scalar_shape(std::vector< ElOp< 3 >> &operations, std::vector< std::vector< double > > shape_values, uint scalar_shape_op_idx)
static void ptop_scalar_shape(FMT_UNUSED std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table, FMT_UNUSED std::vector< std::vector< std::vector< double > > > shape_values, FMT_UNUSED uint scalar_shape_op_idx)
Enum type UpdateFlags indicates which quantities are to be recomputed on each finite element cell.