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