Flow123d  DF_patch_fe_data_tables-836d647
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 n_dofs)
81  : patch_point_vals_(patch_point_vals), begin_(begin), 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 n_dofs_; ///< Number of DOFs
95 };
96 
97 
98 template <class ValueType>
100 public:
101  /// Default constructor
103  : patch_point_vals_bulk_(nullptr), patch_point_vals_side_(nullptr), join_idx_(-1) {}
104 
105  /**
106  * Constructor
107  *
108  * @param patch_point_vals_bulk Pointer to PatchPointValues bulk object.
109  * @param patch_point_vals_side Pointer to PatchPointValues side object.
110  * @param begin Index of the first component of the bulk Quantity.
111  * @param begin_side Index of the first component of the side Quantity.
112  * @param n_dofs_bulk Number of DOFs of bulk (lower-dim) element.
113  * @param n_dofs_side Number of DOFs of side (higher-dim) element.
114  * @param join_idx Index function.
115  */
116  JoinShapeAccessor(PatchPointValues<3> *patch_point_vals_bulk, PatchPointValues<3> *patch_point_vals_side,
117  unsigned int begin, unsigned int begin_side, unsigned int n_dofs_bulk, unsigned int n_dofs_side, unsigned int join_idx)
118  : patch_point_vals_bulk_(patch_point_vals_bulk), patch_point_vals_side_(patch_point_vals_side), begin_(begin),
119  begin_side_(begin_side), n_dofs_high_(n_dofs_side), n_dofs_low_(n_dofs_bulk), join_idx_(join_idx) {
120  //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!");
121  }
122 
123  /// Return global index of DOF
124  inline unsigned int join_idx() const {
125  return join_idx_;
126  }
127 
128  /// Return local index of DOF (on low / high-dim) - should be private method
129  inline unsigned int local_idx() const {
130  if (this->is_high_dim()) return (join_idx_ - n_dofs_low_);
131  else return join_idx_;
132  }
133 
134  inline unsigned int n_dofs_low() const {
135  return n_dofs_low_;
136  }
137 
138  inline unsigned int n_dofs_high() const {
139  return n_dofs_high_;
140  }
141 
142  inline unsigned int n_dofs_both() const {
143  return n_dofs_high_ + n_dofs_low_;
144  }
145 
146  inline bool is_high_dim() const {
147  return (join_idx_ >= n_dofs_low_);
148  }
149 
150  /// Iterates to next item.
151  inline void inc() {
152  join_idx_++;
153  }
154 
155  /// Comparison of accessors.
156  bool operator==(const JoinShapeAccessor<ValueType>& other) const {
157  return (join_idx_ == other.join_idx_);
158  }
159 
160 
161  ValueType operator()(const BulkPoint &point);
162 
163  ValueType operator()(const SidePoint &point);
164 
165 private:
166  // attributes:
167  PatchPointValues<3> *patch_point_vals_bulk_; ///< Pointer to bulk PatchPointValues
168  PatchPointValues<3> *patch_point_vals_side_; ///< Pointer to side PatchPointValues
169  unsigned int begin_; ///< Index of the first component of the bulk Quantity. Size is given by ValueType
170  unsigned int begin_side_; ///< Index of the first component of the side Quantity. Size is given by ValueType
171  unsigned int n_dofs_high_; ///< Number of DOFs on high-dim element
172  unsigned int n_dofs_low_; ///< Number of DOFs on low-dim element
173  unsigned int join_idx_; ///< Index of processed DOF
174 };
175 
176 
177 template<unsigned int dim>
179 {
180 protected:
181  // Default constructor
183  {}
184 
185  /// Return FiniteElement of \p component_idx for FESystem or \p fe for other types
186  template<unsigned int FE_dim>
187  std::shared_ptr<FiniteElement<FE_dim>> fe_comp(std::shared_ptr< FiniteElement<FE_dim> > fe, uint component_idx) {
188  FESystem<FE_dim> *fe_sys = dynamic_cast<FESystem<FE_dim>*>( fe.get() );
189  if (fe_sys != nullptr) {
190  return fe_sys->fe()[component_idx];
191  } else {
192  ASSERT_EQ(component_idx, 0).warning("Non-zero component_idx can only be used for FESystem.");
193  return fe;
194  }
195  }
196 
197  /**
198  * @brief Precomputed values of basis functions at the bulk quadrature points.
199  *
200  * Dimensions: (no. of quadrature points)
201  * x (no. of dofs)
202  * x (no. of components in ref. cell)
203  */
204  template<unsigned int FE_dim>
206  std::vector<std::vector<arma::vec> > ref_shape_vals( q->size(), vector<arma::vec>(fe->n_dofs()) );
207 
208  arma::mat shape_values(fe->n_dofs(), fe->n_components());
209  for (unsigned int i=0; i<q->size(); i++)
210  {
211  for (unsigned int j=0; j<fe->n_dofs(); j++)
212  {
213  for (unsigned int c=0; c<fe->n_components(); c++)
214  shape_values(j,c) = fe->shape_value(j, q->point<FE_dim>(i), c);
215 
216  ref_shape_vals[i][j] = trans(shape_values.row(j));
217  }
218  }
219 
220  return ref_shape_vals;
221  }
222 
223  /**
224  * @brief Precomputed values of basis functions at the side quadrature points.
225  *
226  * Dimensions: (sides)
227  * x (no. of quadrature points)
228  * x (no. of dofs)
229  * x (no. of components in ref. cell)
230  */
231  template<unsigned int FE_dim>
234 
235  arma::mat shape_values(fe->n_dofs(), fe->n_components());
236 
237  for (unsigned int sid=0; sid<FE_dim+1; sid++) {
238  auto quad = q->make_from_side<dim>(sid);
239  for (unsigned int i=0; i<quad.size(); i++)
240  {
241  for (unsigned int j=0; j<fe->n_dofs(); j++)
242  {
243  for (unsigned int c=0; c<fe->n_components(); c++) {
244  shape_values(j,c) = fe->shape_value(j, quad.template point<FE_dim>(i), c);
245  }
246 
247  ref_shape_vals[sid][i][j] = trans(shape_values.row(j));
248  }
249  }
250  }
251 
252  return ref_shape_vals;
253  }
254 
255 };
256 
257 template<unsigned int dim>
258 class BulkValues : public BaseValues<dim>
259 {
260 public:
261  /// Constructor
263  : BaseValues<dim>(), patch_point_vals_(patch_point_vals) {
264  ASSERT_EQ(patch_point_vals.dim(), dim);
265  fe_ = fe[Dim<dim>{}];
266  }
267 
268  /**
269  * @brief Register the product of Jacobian determinant and the quadrature
270  * weight at bulk quadrature points.
271  *
272  * @param quad Quadrature.
273  */
274  inline ElQ<Scalar> JxW()
275  {
278  }
279 
280  /// Create bulk accessor of coords entity
282  {
285  }
286 
287 // inline ElQ<Tensor> jacobian(std::initializer_list<Quadrature *> quad_list)
288 // {}
289 
290  /// Create bulk accessor of jac determinant entity
292  {
295  }
296 
297  /**
298  * @brief Return the value of the @p function_no-th shape function at
299  * the @p p bulk quadrature point.
300  *
301  * @param component_idx Number of the shape function.
302  */
303  inline FeQ<Scalar> scalar_shape(uint component_idx = 0)
304  {
305  auto fe_component = this->fe_comp(fe_, component_idx);
306  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
307 
308  // use lambda reinit function
309  std::vector< std::vector<double> > shape_values( patch_point_vals_.get_quadrature()->size(), vector<double>(fe_component->n_dofs()) );
310  auto ref_shape_vals = this->ref_shape_values_bulk(patch_point_vals_.get_quadrature(), fe_component);
311  for (unsigned int i = 0; i < patch_point_vals_.get_quadrature()->size(); i++)
312  for (unsigned int j = 0; j < fe_component->n_dofs(); j++) {
313  shape_values[i][j] = ref_shape_vals[i][j][0];
314  }
315  uint scalar_shape_op_idx = patch_point_vals_.operations_.size(); // index in operations_ vector
316  auto lambda_scalar_shape = [shape_values, scalar_shape_op_idx](std::vector<ElOp<3>> &operations, TableDbl &op_results, FMT_UNUSED TableInt &el_table) {
317  bulk_reinit::ptop_scalar_shape(operations, op_results, shape_values, scalar_shape_op_idx);
318  };
319  auto &scalar_shape_bulk_op = patch_point_vals_.make_fe_op({1}, lambda_scalar_shape, {}, fe_component->n_dofs());
320  uint begin = scalar_shape_bulk_op.result_row();
321 
322  return FeQ<Scalar>(patch_point_vals_, begin, fe_component->n_dofs());
323  }
324 
325 // inline FeQ<Vector> vector_shape(uint component_idx = 0)
326 // {}
327 
328 // inline FeQ<Tensor> tensor_shape(uint component_idx = 0)
329 // {}
330 
331  /**
332  * @brief Return the value of the @p function_no-th gradient shape function at
333  * the @p p bulk quadrature point.
334  *
335  * @param component_idx Number of the shape function.
336  */
337  inline FeQ<Vector> grad_scalar_shape(uint component_idx=0)
338  {
339  auto fe_component = this->fe_comp(fe_, component_idx);
340  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of grad_scalar_shape accessor must be FEScalar!\n");
341 
342  // use lambda reinit function
343  auto ref_shape_grads = this->ref_shape_gradients(fe_component);
344  uint scalar_shape_grads_op_idx = patch_point_vals_.operations_.size(); // index in operations_ vector
345  auto lambda_scalar_shape_grad = [ref_shape_grads, scalar_shape_grads_op_idx](std::vector<ElOp<3>> &operations, TableDbl &op_results, FMT_UNUSED TableInt &el_table) {
346  bulk_reinit::ptop_scalar_shape_grads<dim>(operations, op_results, ref_shape_grads, scalar_shape_grads_op_idx);
347  };
348  auto &grad_scalar_shape_bulk_op = patch_point_vals_.make_fe_op({3}, lambda_scalar_shape_grad, {FeBulk::BulkOps::opInvJac}, fe_component->n_dofs());
349  uint begin = grad_scalar_shape_bulk_op.result_row();
350 
351  return FeQ<Vector>(patch_point_vals_, begin, fe_component->n_dofs());
352  }
353 
354 // inline FeQ<Tensor> grad_vector_shape(std::initializer_list<Quadrature *> quad_list, unsigned int i_comp=0)
355 // {}
356 
357 private:
358  /**
359  * @brief Precomputed gradients of basis functions at the quadrature points.
360  *
361  * Dimensions: (no. of quadrature points)
362  * x (no. of dofs)
363  * x ((dim_ of. ref. cell)x(no. of components in ref. cell))
364  */
367  std::vector<std::vector<arma::mat> > ref_shape_grads( q->size(), vector<arma::mat>(fe->n_dofs()) );
368 
369  arma::mat grad(dim, fe->n_components());
370  for (unsigned int i_pt=0; i_pt<q->size(); i_pt++)
371  {
372  for (unsigned int i_dof=0; i_dof<fe->n_dofs(); i_dof++)
373  {
374  grad.zeros();
375  for (unsigned int c=0; c<fe->n_components(); c++)
376  grad.col(c) += fe->shape_grad(i_dof, q->point<dim>(i_pt), c);
377 
378  ref_shape_grads[i_pt][i_dof] = grad;
379  }
380  }
381 
382  return ref_shape_grads;
383  }
384 
386  std::shared_ptr< FiniteElement<dim> > fe_;
387 };
388 
389 
390 template<unsigned int dim>
391 class SideValues : public BaseValues<dim>
392 {
393 public:
394  /// Constructor
396  : BaseValues<dim>(), patch_point_vals_(patch_point_vals) {
397  ASSERT_EQ(patch_point_vals.dim(), dim);
398  fe_ = fe[Dim<dim>{}];
399  }
400 
401  /// Same as BulkValues::JxW but register at side quadrature points.
402  inline ElQ<Scalar> JxW()
403  {
406  }
407 
408  /**
409  * @brief Register the normal vector to a side at side quadrature points.
410  *
411  * @param quad Quadrature.
412  */
414  {
417  }
418 
419  /// Create side accessor of coords entity
421  {
424  }
425 
426  /// Create bulk accessor of jac determinant entity
428  {
431  }
432 
433  /// Same as BulkValues::scalar_shape but register at side quadrature points.
434  inline FeQ<Scalar> scalar_shape(uint component_idx = 0)
435  {
436  auto fe_component = this->fe_comp(fe_, component_idx);
437  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
438 
439  // use lambda reinit function
441  dim+1,
443  );
444  auto ref_shape_vals = this->ref_shape_values_side(patch_point_vals_.get_quadrature(), fe_component);
445  for (unsigned int s=0; s<dim+1; ++s)
446  for (unsigned int i = 0; i < patch_point_vals_.get_quadrature()->size(); i++)
447  for (unsigned int j = 0; j < fe_component->n_dofs(); j++) {
448  shape_values[s][i][j] = ref_shape_vals[s][i][j][0];
449  }
450  uint scalar_shape_op_idx = patch_point_vals_.operations_.size(); // index in operations_ vector
451  auto lambda_scalar_shape = [shape_values, scalar_shape_op_idx](std::vector<ElOp<3>> &operations, TableDbl &op_results, TableInt &el_table) {
452  side_reinit::ptop_scalar_shape(operations, op_results, el_table, shape_values, scalar_shape_op_idx);
453  };
454  auto &scalar_shape_bulk_op = patch_point_vals_.make_fe_op({1}, lambda_scalar_shape, {}, fe_component->n_dofs());
455  uint begin = scalar_shape_bulk_op.result_row();
456 
457  return FeQ<Scalar>(patch_point_vals_, begin, fe_component->n_dofs());
458  }
459 
460  /// Same as BulkValues::grad_scalar_shape but register at side quadrature points.
461  inline FeQ<Vector> grad_scalar_shape(uint component_idx=0)
462  {
463  auto fe_component = this->fe_comp(fe_, component_idx);
464  ASSERT_EQ(fe_component->fe_type(), FEType::FEScalar).error("Type of FiniteElement of grad_scalar_shape accessor must be FEScalar!\n");
465 
466  // use lambda reinit function
467  auto ref_shape_grads = this->ref_shape_gradients(fe_component);
468  uint scalar_shape_grads_op_idx = patch_point_vals_.operations_.size(); // index in operations_ vector
469  auto lambda_scalar_shape_grad = [ref_shape_grads, scalar_shape_grads_op_idx](std::vector<ElOp<3>> &operations, TableDbl &op_results, TableInt &el_table) {
470  side_reinit::ptop_scalar_shape_grads<dim>(operations, op_results, el_table, ref_shape_grads, scalar_shape_grads_op_idx);
471  };
472  auto &grad_scalar_shape_side_op = patch_point_vals_.make_fe_op({3}, lambda_scalar_shape_grad, {FeSide::SideOps::opElInvJac}, fe_component->n_dofs());
473  uint begin = grad_scalar_shape_side_op.result_row();
474 
475  return FeQ<Vector>(patch_point_vals_, begin, fe_component->n_dofs());
476  }
477 
478 private:
479  /**
480  * @brief Precomputed gradients of basis functions at the quadrature points.
481  *
482  * Dimensions: (sides)
483  * x (no. of quadrature points)
484  * x (no. of dofs)
485  * x ((dim_ of. ref. cell)x(no. of components in ref. cell))
486  */
490 
491  arma::mat grad(dim, fe->n_components());
492  for (unsigned int sid=0; sid<dim+1; sid++) {
493  auto quad = q->make_from_side<dim>(sid);
494  for (unsigned int i_pt=0; i_pt<quad.size(); i_pt++)
495  {
496  for (unsigned int i_dof=0; i_dof<fe->n_dofs(); i_dof++)
497  {
498  grad.zeros();
499  for (unsigned int c=0; c<fe->n_components(); c++)
500  grad.col(c) += fe->shape_grad(i_dof, quad.template point<dim>(i_pt), c);
501 
502  ref_shape_grads[sid][i_pt][i_dof] = grad;
503  }
504  }
505  }
506 
507  return ref_shape_grads;
508  }
509 
511  std::shared_ptr< FiniteElement<dim> > fe_;
512 };
513 
514 
515 template<unsigned int dim>
516 class JoinValues : public BaseValues<dim>
517 {
518 public:
519  /// Constructor
520  JoinValues(PatchPointValues<3> *patch_point_vals_bulk, PatchPointValues<3> *patch_point_vals_side, MixedPtr<FiniteElement> fe)
521  : BaseValues<dim>(), patch_point_vals_bulk_(patch_point_vals_bulk), patch_point_vals_side_(patch_point_vals_side) {
522  ASSERT_EQ(patch_point_vals_bulk->dim(), dim-1);
523  ASSERT_EQ(patch_point_vals_side->dim(), dim);
524  fe_high_dim_ = fe[Dim<dim>{}];
525  fe_low_dim_ = fe[Dim<dim-1>{}];
526  }
527 
529  {
530  // element of lower dim (bulk points)
531  auto fe_component_low = this->fe_comp(fe_low_dim_, component_idx);
532  ASSERT_EQ(fe_component_low->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
533  // use lambda reinit function
534  std::vector< std::vector<double> > shape_values_bulk( patch_point_vals_bulk_->get_quadrature()->size(), vector<double>(fe_component_low->n_dofs()) );
535  auto ref_shape_vals_bulk = this->ref_shape_values_bulk(patch_point_vals_bulk_->get_quadrature(), fe_component_low);
536  for (unsigned int i = 0; i < patch_point_vals_bulk_->get_quadrature()->size(); i++)
537  for (unsigned int j = 0; j < fe_component_low->n_dofs(); j++) {
538  shape_values_bulk[i][j] = ref_shape_vals_bulk[i][j][0];
539  }
540  uint scalar_shape_op_idx_bulk = patch_point_vals_bulk_->operations_.size(); // index in operations_ vector
541  auto lambda_scalar_shape_bulk = [shape_values_bulk, scalar_shape_op_idx_bulk](std::vector<ElOp<3>> &operations, TableDbl &op_results, FMT_UNUSED TableInt &el_table) {
542  bulk_reinit::ptop_scalar_shape(operations, op_results, shape_values_bulk, scalar_shape_op_idx_bulk);
543  };
544  auto &grad_scalar_shape_bulk_op = patch_point_vals_bulk_->make_fe_op({1}, lambda_scalar_shape_bulk, {}, fe_component_low->n_dofs());
545  uint begin_bulk = grad_scalar_shape_bulk_op.result_row();
546 
547  // element of higher dim (side points)
548  auto fe_component_high = this->fe_comp(fe_high_dim_, component_idx);
549  ASSERT_EQ(fe_component_high->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape accessor must be FEScalar!\n");
550  // use lambda reinit function
551  std::vector< std::vector< std::vector<double> > > shape_values_side(
552  dim+1,
554  );
555  auto ref_shape_vals_side = this->ref_shape_values_side(patch_point_vals_side_->get_quadrature(), fe_component_high);
556  for (unsigned int s=0; s<dim+1; ++s)
557  for (unsigned int i = 0; i < patch_point_vals_side_->get_quadrature()->size(); i++)
558  for (unsigned int j = 0; j < fe_component_high->n_dofs(); j++) {
559  shape_values_side[s][i][j] = ref_shape_vals_side[s][i][j][0];
560  }
561  uint scalar_shape_op_idx_side = patch_point_vals_side_->operations_.size(); // index in operations_ vector
562  auto lambda_scalar_shape_side = [shape_values_side, scalar_shape_op_idx_side](std::vector<ElOp<3>> &operations, TableDbl &op_results, TableInt &el_table) {
563  side_reinit::ptop_scalar_shape(operations, op_results, el_table, shape_values_side, scalar_shape_op_idx_side);
564  };
565  auto &grad_scalar_shape_side_op = patch_point_vals_side_->make_fe_op({1}, lambda_scalar_shape_side, {}, fe_component_high->n_dofs());
566  uint begin_side = grad_scalar_shape_side_op.result_row();
567 
568  auto bgn_it = make_iter<JoinShapeAccessor<Scalar>>( JoinShapeAccessor<Scalar>(patch_point_vals_bulk_, patch_point_vals_side_,
569  begin_bulk, begin_side, fe_component_low->n_dofs(), fe_component_high->n_dofs(), 0) );
570  unsigned int end_idx = fe_component_low->n_dofs() + fe_component_high->n_dofs();
571  auto end_it = make_iter<JoinShapeAccessor<Scalar>>( JoinShapeAccessor<Scalar>(patch_point_vals_bulk_, patch_point_vals_side_,
572  begin_bulk, begin_side, fe_component_low->n_dofs(), fe_component_high->n_dofs(), end_idx) );
573  return Range<JoinShapeAccessor<Scalar>>(bgn_it, end_it);
574  }
575 
576 private:
579  std::shared_ptr< FiniteElement<dim> > fe_high_dim_;
580  std::shared_ptr< FiniteElement<dim-1> > fe_low_dim_;
581 };
582 
583 /// Template specialization of dim = 1
584 template <>
585 class JoinValues<1> : public BaseValues<1>
586 {
587 public:
588  /// Constructor
590  : BaseValues<1>() {}
591 
593  {
595  make_iter<JoinShapeAccessor<Scalar>>(JoinShapeAccessor<Scalar>()),
597  }
598 };
599 
600 
601 template<unsigned int spacedim = 3>
603 public:
604  /// Struct for pre-computing number of elements, sides, bulk points and side points on each dimension.
605  struct TableSizes {
606  public:
607  /// Constructor
611  }
612 
613  /// Set all values to zero
614  void reset() {
615  std::fill(elem_sizes_[0].begin(), elem_sizes_[0].end(), 0);
616  std::fill(elem_sizes_[1].begin(), elem_sizes_[1].end(), 0);
617  std::fill(point_sizes_[0].begin(), point_sizes_[0].end(), 0);
618  std::fill(point_sizes_[1].begin(), point_sizes_[1].end(), 0);
619  }
620 
621  /**
622  * Holds number of elements and sides on each dimension
623  * Format:
624  * { {n_elements_1D, n_elements_2D, n_elements_3D },
625  * {n_sides_1D, n_sides_2D, n_sides_3D } }
626  */
628 
629  /**
630  * Holds number of bulk and side points on each dimension
631  * Format:
632  * { {n_bulk_points_1D, n_bulk_points_2D, n_bulk_points_3D },
633  * {n_side_points_1D, n_side_points_2D, n_side_points_3D } }
634  */
636  };
637 
639  : asm_arena_(1024 * 1024, 256),
640  patch_arena_(1024 * 1024, 256),
644  patch_point_vals_side_{ {FeSide::PatchPointValues(1, 0, patch_arena_),
645  FeSide::PatchPointValues(2, 0, patch_arena_),
646  FeSide::PatchPointValues(3, 0, patch_arena_)} }
647  {
648  used_quads_[0] = false; used_quads_[1] = false;
649  }
650 
651  PatchFEValues(unsigned int quad_order, MixedPtr<FiniteElement> fe)
652  : asm_arena_(1024 * 1024, 256),
653  patch_arena_(1024 * 1024, 256),
654  patch_point_vals_bulk_{ {FeBulk::PatchPointValues(1, quad_order, patch_arena_),
655  FeBulk::PatchPointValues(2, quad_order, patch_arena_),
656  FeBulk::PatchPointValues(3, quad_order, patch_arena_)} },
657  patch_point_vals_side_{ {FeSide::PatchPointValues(1, quad_order, patch_arena_),
658  FeSide::PatchPointValues(2, quad_order, patch_arena_),
659  FeSide::PatchPointValues(3, quad_order, patch_arena_)} },
660  fe_(fe)
661  {
662  used_quads_[0] = false; used_quads_[1] = false;
663  }
664 
665 
666  /// Destructor
668  {}
669 
670  /// Return bulk or side quadrature of given dimension
671  Quadrature *get_quadrature(uint dim, bool is_bulk) const {
672  if (is_bulk) return patch_point_vals_bulk_[dim-1].get_quadrature();
673  else return patch_point_vals_side_[dim-1].get_quadrature();
674  }
675 
676  /**
677  * @brief Initialize structures and calculates cell-independent data.
678  *
679  * @param _quadrature The quadrature rule for the cell associated
680  * to given finite element or for the cell side.
681  * @param _flags The update flags.
682  */
683  template<unsigned int DIM>
684  void initialize(Quadrature &_quadrature)
685  {
686  if ( _quadrature.dim() == DIM ) {
687  used_quads_[0] = true;
688  patch_point_vals_bulk_[DIM-1].initialize(3); // bulk
689  } else {
690  used_quads_[1] = true;
691  patch_point_vals_side_[DIM-1].initialize(4); // side
692  }
693  }
694 
695  /// Reset PatchpointValues structures
696  void reset()
697  {
698  for (unsigned int i=0; i<3; ++i) {
699  if (used_quads_[0]) patch_point_vals_bulk_[i].reset();
700  if (used_quads_[1]) patch_point_vals_side_[i].reset();
701  }
702  }
703 
704  /// Reinit data.
706  {
707  for (unsigned int i=0; i<3; ++i) {
708  if (used_quads_[0]) patch_point_vals_bulk_[i].reinit_patch();
709  if (used_quads_[1]) patch_point_vals_side_[i].reinit_patch();
710  }
711  }
712 
713  /**
714  * @brief Returns the number of shape functions.
715  */
716  template<unsigned int dim>
717  inline unsigned int n_dofs() const {
718  ASSERT((dim>=0) && (dim<=3))(dim).error("Dimension must be 0, 1, 2 or 3.");
719  return fe_[Dim<dim>{}]->n_dofs();
720  }
721 
722  /// Return BulkValue object of dimension given by template parameter
723  template<unsigned int dim>
725  ASSERT((dim>0) && (dim<=3))(dim).error("Dimension must be 1, 2 or 3.");
726  return BulkValues<dim>(patch_point_vals_bulk_[dim-1], fe_);
727  }
728 
729  /// Return SideValue object of dimension given by template parameter
730  template<unsigned int dim>
732  ASSERT((dim>0) && (dim<=3))(dim).error("Dimension must be 1, 2 or 3.");
733  return SideValues<dim>(patch_point_vals_side_[dim-1], fe_);
734  }
735 
736  /// Return JoinValue object of dimension given by template parameter
737  template<unsigned int dim>
739  //ASSERT((dim>1) && (dim<=3))(dim).error("Dimension must be 2 or 3.");
740  return JoinValues<dim>(&patch_point_vals_bulk_[dim-2], &patch_point_vals_side_[dim-1], fe_);
741  }
742 
743  /** Following methods are used during update of patch. **/
744 
745  /// Resize tables of patch_point_vals_
746  void resize_tables(TableSizes table_sizes) {
747  for (uint i=0; i<3; ++i) {
748  if (used_quads_[0]) patch_point_vals_bulk_[i].resize_tables(table_sizes.elem_sizes_[0][i], table_sizes.point_sizes_[0][i]);
749  if (used_quads_[1]) patch_point_vals_side_[i].resize_tables(table_sizes.elem_sizes_[1][i], table_sizes.point_sizes_[1][i]);
750  }
751  }
752 
753  /// Register element to patch_point_vals_ table by dimension of element
754  uint register_element(DHCellAccessor cell, uint element_patch_idx) {
755  arma::mat coords;
756  switch (cell.dim()) {
757  case 1:
758  coords = MappingP1<1,spacedim>::element_map(cell.elm());
759  return patch_point_vals_bulk_[0].register_element(coords, element_patch_idx);
760  break;
761  case 2:
762  coords = MappingP1<2,spacedim>::element_map(cell.elm());
763  return patch_point_vals_bulk_[1].register_element(coords, element_patch_idx);
764  break;
765  case 3:
766  coords = MappingP1<3,spacedim>::element_map(cell.elm());
767  return patch_point_vals_bulk_[2].register_element(coords, element_patch_idx);
768  break;
769  default:
770  ASSERT(false);
771  return 0;
772  break;
773  }
774  }
775 
776  /// Register side to patch_point_vals_ table by dimension of side
778  arma::mat side_coords(spacedim, cell_side.dim());
779  for (unsigned int n=0; n<cell_side.dim(); n++)
780  for (unsigned int c=0; c<spacedim; c++)
781  side_coords(c,n) = (*cell_side.side().node(n))[c];
782 
783  arma::mat elm_coords;
784  DHCellAccessor cell = cell_side.cell();
785  switch (cell.dim()) {
786  case 1:
787  elm_coords = MappingP1<1,spacedim>::element_map(cell.elm());
788  return patch_point_vals_side_[0].register_side(elm_coords, side_coords);
789  break;
790  case 2:
791  elm_coords = MappingP1<2,spacedim>::element_map(cell.elm());
792  return patch_point_vals_side_[1].register_side(elm_coords, side_coords);
793  break;
794  case 3:
795  elm_coords = MappingP1<3,spacedim>::element_map(cell.elm());
796  return patch_point_vals_side_[2].register_side(elm_coords, side_coords);
797  break;
798  default:
799  ASSERT(false);
800  return 0;
801  break;
802  }
803  }
804 
805  /// Register bulk point to patch_point_vals_ table by dimension of element
806  uint register_bulk_point(DHCellAccessor cell, uint elem_table_row, uint value_patch_idx) {
807  return patch_point_vals_bulk_[cell.dim()-1].register_bulk_point(elem_table_row, value_patch_idx, cell.elm_idx());
808  }
809 
810  /// Register side point to patch_point_vals_ table by dimension of side
811  uint register_side_point(DHCellSide cell_side, uint elem_table_row, uint value_patch_idx) {
812  return patch_point_vals_side_[cell_side.dim()-1].register_side_point(elem_table_row, value_patch_idx, cell_side.elem_idx(), cell_side.side_idx());
813  }
814 
815  /// Temporary development method
816  void print_data_tables(ostream& stream, bool points, bool ints, bool only_bulk=true) const {
817  stream << endl << "Table of patch FE data:" << endl;
818  for (uint i=0; i<3; ++i) {
819  stream << std::setfill('-') << setw(100) << "" << endl;
820  stream << "Bulk, dimension " << (i+1) << endl;
821  patch_point_vals_bulk_[i].print_data_tables(stream, points, ints);
822  }
823  if (!only_bulk)
824  for (uint i=0; i<3; ++i) {
825  stream << std::setfill('-') << setw(100) << "" << endl;
826  stream << "Side, dimension " << (i+1) << endl;
827  patch_point_vals_side_[i].print_data_tables(stream, points, ints);
828  }
829  stream << std::setfill('=') << setw(100) << "" << endl;
830  }
831 
832  /// Temporary development method
833  void print_operations(ostream& stream) const {
834  stream << endl << "Table of patch FE operations:" << endl;
835  for (uint i=0; i<3; ++i) {
836  stream << std::setfill('-') << setw(100) << "" << endl;
837  stream << "Bulk, dimension " << (i+1) << ", n_rows " << patch_point_vals_bulk_[i].n_rows() << endl;
838  patch_point_vals_bulk_[i].print_operations(stream, 0);
839  }
840  for (uint i=0; i<3; ++i) {
841  stream << std::setfill('-') << setw(100) << "" << endl;
842  stream << "Side, dimension " << (i+1) << ", n_rows " << patch_point_vals_side_[i].n_rows() << endl;
843  patch_point_vals_side_[i].print_operations(stream, 1);
844  }
845  stream << std::setfill('=') << setw(100) << "" << endl;
846  }
847 
848 private:
851  std::array<FeBulk::PatchPointValues<spacedim>, 3> patch_point_vals_bulk_; ///< Sub objects of bulk data of dimensions 1,2,3
852  std::array<FeSide::PatchPointValues<spacedim>, 3> patch_point_vals_side_; ///< Sub objects of side data of dimensions 1,2,3
853 
854  MixedPtr<FiniteElement> fe_; ///< Mixed of shared pointers of FiniteElement object
855  bool used_quads_[2]; ///< Pair of flags signs holds info if bulk and side quadratures are used
856 
857  template <class ValueType>
858  friend class ElQ;
859  template <class ValueType>
860  friend class FeQ;
861  template <class ValueType>
862  friend class JoinShapeAccessor;
863 };
864 
865 
866 template <class ValueType>
867 ValueType ElQ<ValueType>::operator()(const BulkPoint &point) {
868  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
869  return patch_point_vals_.scalar_value(op_idx_, value_cache_idx);
870 }
871 
872 template <>
874  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
875  return patch_point_vals_.vector_value(op_idx_, value_cache_idx);
876 }
877 
878 template <>
880  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
881  return patch_point_vals_.tensor_value(op_idx_, value_cache_idx);
882 }
883 
884 template <class ValueType>
885 ValueType ElQ<ValueType>::operator()(const SidePoint &point) {
886  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
887  return patch_point_vals_.scalar_val(begin_, value_cache_idx);
888 }
889 
890 template <>
892  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
893  return patch_point_vals_.vector_val(begin_, value_cache_idx);
894 }
895 
896 template <>
898  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
899  return patch_point_vals_.tensor_val(begin_, value_cache_idx);
900 }
901 
902 template <class ValueType>
903 ValueType FeQ<ValueType>::operator()(unsigned int shape_idx, const BulkPoint &point) {
904  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
905  return patch_point_vals_.scalar_val(begin_+shape_idx, value_cache_idx);
906 }
907 
908 template <>
909 inline Vector FeQ<Vector>::operator()(unsigned int shape_idx, const BulkPoint &point) {
910  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
911  return patch_point_vals_.vector_val(begin_+3*shape_idx, value_cache_idx);
912 }
913 
914 template <>
915 inline Tensor FeQ<Tensor>::operator()(FMT_UNUSED unsigned int shape_idx, FMT_UNUSED const BulkPoint &point) {
916  Tensor tens; tens.zeros();
917  return tens;
918 }
919 
920 template <class ValueType>
921 ValueType FeQ<ValueType>::operator()(unsigned int shape_idx, const SidePoint &point) {
922  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
923  return patch_point_vals_.scalar_val(begin_+shape_idx, value_cache_idx);
924 }
925 
926 template <>
927 inline Vector FeQ<Vector>::operator()(unsigned int shape_idx, const SidePoint &point) {
928  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
929  return patch_point_vals_.vector_val(begin_+3*shape_idx, value_cache_idx);
930 }
931 
932 template <>
933 inline Tensor FeQ<Tensor>::operator()(FMT_UNUSED unsigned int shape_idx, FMT_UNUSED const SidePoint &point) {
934  Tensor tens; tens.zeros();
935  return tens;
936 }
937 
938 
939 template <class ValueType>
941  if (this->is_high_dim()) {
942  return 0.0;
943  } else {
944  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
945  return patch_point_vals_bulk_->scalar_val(begin_+this->local_idx(), value_cache_idx);
946  }
947 }
948 
949 template <>
951  Vector vect; vect.zeros();
952  return vect;
953 }
954 
955 template <>
957  Tensor tens; tens.zeros();
958  return tens;
959 }
960 
961 template <class ValueType>
963  if (this->is_high_dim()) {
964  unsigned int value_cache_idx = point.elm_cache_map()->element_eval_point(point.elem_patch_idx(), point.eval_point_idx());
965  return patch_point_vals_side_->scalar_val(begin_side_+this->local_idx(), value_cache_idx);
966  } else {
967  return 0.0;
968  }
969 }
970 
971 template <>
973  Vector vect; vect.zeros();
974  return vect;
975 }
976 
977 template <>
979  Tensor tens; tens.zeros();
980  return tens;
981 }
982 
983 
984 #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 the first component of the bulk Quantity. Size is given by ValueType.
ElQ()=delete
Forbidden default constructor.
PatchPointValues< 3 > & patch_point_vals_
Reference to PatchPointValues.
unsigned int begin_
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.
ValueType operator()(FMT_UNUSED unsigned int shape_idx, FMT_UNUSED const BulkPoint &point)
FeQ(PatchPointValues< 3 > &patch_point_vals, unsigned int begin, unsigned int n_dofs)
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.
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 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.
~PatchFEValues()
Destructor.
std::array< FeBulk::PatchPointValues< spacedim >, 3 > patch_point_vals_bulk_
Sub objects of bulk data of dimensions 1,2,3.
uint register_bulk_point(DHCellAccessor cell, uint elem_table_row, uint value_patch_idx)
Register bulk point to patch_point_vals_ table by dimension of element.
uint register_side(DHCellSide cell_side)
Register side to patch_point_vals_ table by dimension of side.
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.
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_
AssemblyArena patch_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.
uint register_side_point(DHCellSide cell_side, uint elem_table_row, uint value_patch_idx)
Register side point to patch_point_vals_ table by dimension of side.
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_val(uint result_row, uint point_idx) 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< ArrayDbl, Eigen::Dynamic > TableDbl
Definition: eigen_tools.hh:36
Eigen::Vector< ArrayInt, Eigen::Dynamic > TableInt
Definition: eigen_tools.hh:37
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, TableDbl &op_results, std::vector< std::vector< double > > shape_values, uint scalar_shape_op_idx)
static void ptop_scalar_shape(std::vector< ElOp< 3 >> &operations, TableDbl &op_results, TableInt &el_table, std::vector< std::vector< std::vector< double > > > shape_values, uint scalar_shape_op_idx)
Enum type UpdateFlags indicates which quantities are to be recomputed on each finite element cell.