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