Flow123d  DF_patch_fe_data_tables-92632e6
patch_point_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_point_values.hh
15  * @brief Store finite element data on the actual patch
16  * such as shape function values, gradients, Jacobian
17  * of the mapping from the reference cell etc.
18  * @author David Flanderka
19  */
20 
21 #ifndef PATCH_POINT_VALUES_HH_
22 #define PATCH_POINT_VALUES_HH_
23 
24 #include <Eigen/Dense>
25 
26 #include "fem/eigen_tools.hh"
27 #include "fem/dh_cell_accessor.hh"
28 #include "fem/element_values.hh"
30 #include "fem/arena_resource.hh"
31 #include "fem/arena_vec.hh"
32 
33 
34 template<unsigned int spacedim> class PatchFEValues;
35 template<unsigned int spacedim> class ElOp;
36 template<unsigned int dim> class BulkValues;
37 template<unsigned int dim> class SideValues;
38 using Scalar = double;
41 
42 
43 
44 
45 /// Type for conciseness
46 using ReinitFunction = std::function<void(std::vector<ElOp<3>> &, IntTableArena &)>;
47 
48 
49 namespace FeBulk {
50  /**
51  * Enumeration of element bulk operations
52  *
53  * Operations are stored in fix order. Order in enum is equal to order
54  * in PatchPointVale::operations_ vector. FE operations are added dynamically
55  * by request of user.
56  */
57  enum BulkOps
58  {
59  /// operations evaluated on elements
60  opElCoords, ///< coordinations of all nodes of element
61  opJac, ///< Jacobian of element
62  opInvJac, ///< inverse Jacobian
63  opJacDet, ///< determinant of Jacobian
64  /// operations evaluated on quadrature points
65  opCoords, ///< coordinations of quadrature point
66  opWeights, ///< weight of quadrature point
67  opJxW ///< JxW value of quadrature point
68  };
69 }
70 
71 
72 namespace FeSide {
73  /**
74  * Enumeration of element side operations
75  *
76  * Operations are stored in fix order. Order in enum is equal to order
77  * in PatchPointVale::operations_ vector. FE operations are added dynamically
78  * by request of user.
79  */
80  enum SideOps
81  {
82  /// operations evaluated on elements
83  opElCoords, ///< coordinations of all nodes of element
84  opElJac, ///< Jacobian of element
85  opElInvJac, ///< inverse Jacobian of element
86  /// operations evaluated on sides
87  opSideCoords, ///< coordinations of all nodes of side
88  opSideJac, ///< Jacobian of element
89  opSideJacDet, ///< determinant of Jacobian of side
90  /// operations evaluated on quadrature points
91  opCoords, ///< coordinations of quadrature point
92  opWeights, ///< weight of quadrature point
93  opJxW, ///< JxW value of quadrature point
94  opNormalVec ///< normal vector of quadrature point
95  };
96 }
97 
98 
99 /// Distinguishes operations by type and size of output rows
101 {
102  elemOp, ///< operation is evaluated on elements or sides
103  pointOp, ///< operation is evaluated on quadrature points
104  fixedSizeOp ///< operation has fixed size and it is filled during initialization
105 };
106 
107 
108 
109 /**
110  * v Class for storing FE data of quadrature points on one patch.
111  *
112  * Store data of bulk or side quadrature points of one dimension.
113  */
114 template<unsigned int spacedim = 3>
116 {
117 public:
118  /**
119  * Constructor
120  *
121  * @param dim Set dimension
122  */
124  : dim_(dim), elements_map_(300, 0), points_map_(300, 0), asm_arena_(asm_arena) {
125  reset();
126  }
127 
128  /**
129  * Initialize object, set number of columns (quantities) in tables.
130  */
131  void initialize() {
132  this->reset();
133  int_table_.resize(int_sizes_.size());
134  }
135 
136  inline void init_finalize(PatchArena *patch_arena) {
137  patch_arena_ = patch_arena;
138  }
139 
140  /// Reset number of columns (points and elements)
141  inline void reset() {
142  n_points_ = 0;
143  n_elems_ = 0;
144  i_elem_ = 0;
145  }
146 
147  /// Getter for dim_
148  inline uint dim() const {
149  return dim_;
150  }
151 
152  /// Getter for n_elems_
153  inline uint n_elems() const {
154  return n_elems_;
155  }
156 
157  /// Getter for n_points_
158  inline uint n_points() const {
159  return n_points_;
160  }
161 
162  /// Getter for quadrature
164  return quad_;
165  }
166 
167  /// Resize data tables. Method is called before reinit of patch.
169  n_elems_ = n_elems;
172  for (uint i=0; i<int_table_.rows(); ++i) {
173  int_table_(i) = ArenaVec<uint>(sizes[ int_sizes_[i] ], *patch_arena_);
174  }
175  for (auto &elOp : operations_)
176  if (elOp.size_type() != fixedSizeOp) {
177  elOp.allocate_result(sizes[elOp.size_type()], *patch_arena_);
178  }
179  std::fill(elements_map_.begin(), elements_map_.end(), (uint)-1);
180  }
181 
182  /**
183  * Register element, add to coords operation
184  *
185  * @param coords Coordinates of element nodes.
186  * @param element_patch_idx Index of element on patch.
187  */
188  uint register_element(arma::mat coords, uint element_patch_idx) {
189  if (elements_map_[element_patch_idx] != (uint)-1) {
190  // Return index of element on patch if it is registered repeatedly
191  return elements_map_[element_patch_idx];
192  }
193 
195  auto &coords_mat = op.result_matrix();
196  std::size_t i_elem = i_elem_;
197  for (uint i_col=0; i_col<coords.n_cols; ++i_col)
198  for (uint i_row=0; i_row<coords.n_rows; ++i_row) {
199  coords_mat(i_row, i_col)(i_elem) = coords(i_row, i_col);
200  }
201 
202  elements_map_[element_patch_idx] = i_elem_;
203  return i_elem_++;
204  }
205 
206  /**
207  * Register side, add to coords operations
208  *
209  * @param coords Coordinates of element nodes.
210  * @param side_coords Coordinates of side nodes.
211  * @param side_idx Index of side on element.
212  */
213  uint register_side(arma::mat elm_coords, arma::mat side_coords, uint side_idx) {
214  {
216  auto &coords_mat = op.result_matrix();
217  std::size_t i_elem = i_elem_;
218  for (uint i_col=0; i_col<elm_coords.n_cols; ++i_col)
219  for (uint i_row=0; i_row<elm_coords.n_rows; ++i_row) {
220  coords_mat(i_row, i_col)(i_elem) = elm_coords(i_row, i_col);
221  }
222  }
223 
224  {
226  auto &coords_mat = op.result_matrix();
227  std::size_t i_elem = i_elem_;
228  for (uint i_col=0; i_col<side_coords.n_cols; ++i_col)
229  for (uint i_row=0; i_row<side_coords.n_rows; ++i_row) {
230  coords_mat(i_row, i_col)(i_elem) = side_coords(i_row, i_col);
231  }
232  }
233 
234  int_table_(3)(i_elem_) = side_idx;
235 
236  return i_elem_++;
237  }
238 
239  /**
240  * Register bulk point, add to int_table_
241  *
242  * @param elem_table_row Index of element in temporary element table.
243  * @param value_patch_idx Index of point in ElementCacheMap.
244  * @param elem_idx Index of element in Mesh.
245  * @param i_point_on_elem Index of point on element
246  */
247  uint register_bulk_point(uint elem_table_row, uint value_patch_idx, uint elem_idx, uint i_point_on_elem) {
248  uint point_pos = i_point_on_elem * n_elems_ + elem_table_row; // index of bulk point on patch
249  int_table_(0)(point_pos) = value_patch_idx;
250  int_table_(1)(point_pos) = elem_table_row;
251  int_table_(2)(point_pos) = elem_idx;
252 
253  points_map_[value_patch_idx] = point_pos;
254  return point_pos;
255  }
256 
257  /**
258  * Register side point, add to int_table_
259  *
260  * @param elem_table_row Index of side in temporary element table.
261  * @param value_patch_idx Index of point in ElementCacheMap.
262  * @param elem_idx Index of element in Mesh.
263  * @param side_idx Index of side on element.
264  * @param i_point_on_side Index of point on side
265  */
266  uint register_side_point(uint elem_table_row, uint value_patch_idx, uint elem_idx, uint side_idx, uint i_point_on_side) {
267  uint point_pos = i_point_on_side * n_elems_ + elem_table_row; // index of side point on patch
268  int_table_(0)(point_pos) = value_patch_idx;
269  int_table_(1)(point_pos) = elem_table_row;
270  int_table_(2)(point_pos) = elem_idx;
271  int_table_(4)(point_pos) = side_idx;
272 
273  points_map_[value_patch_idx] = point_pos;
274  return point_pos;
275  }
276 
277  /**
278  * Adds accessor of new operation to operations_ vector
279  *
280  * @param shape Shape of function output
281  * @param reinit_f Reinitialize function
282  * @param input_ops_vec Indices of input operations in operations_ vector.
283  * @param size_type Type of operation by size of rows
284  */
285  ElOp<spacedim> &make_new_op(std::initializer_list<uint> shape, ReinitFunction reinit_f, std::vector<uint> input_ops_vec, OpSizeType size_type = pointOp) {
286  ElOp<spacedim> op_accessor(this->dim_, shape, reinit_f, size_type, input_ops_vec);
287  row_sizes_.insert(row_sizes_.end(), op_accessor.n_comp(), size_type);
288  operations_.push_back(op_accessor);
289  return operations_[operations_.size()-1];
290  }
291 
292  /**
293  * Adds accessor of new operation with fixed data size (ref data) to operations_ vector
294  *
295  * @param shape Shape of function output
296  * @param reinit_f Reinitialize function
297  */
298  ElOp<spacedim> &make_fixed_op(std::initializer_list<uint> shape, ReinitFunction reinit_f) {
299  return make_new_op(shape, reinit_f, {}, fixedSizeOp);
300  }
301 
302  /**
303  * Adds accessor of FE operation and adds operation dynamically to operations_ vector
304  *
305  * @param shape Shape of function output
306  * @param reinit_f Reinitialize function
307  * @param input_ops_vec Indices of input operations in operations_ vector.
308  * @param n_dofs Number of DOFs
309  * @param size_type Type of operation by size of rows
310  */
311  ElOp<spacedim> &make_fe_op(std::initializer_list<uint> shape, ReinitFunction reinit_f, std::vector<uint> input_ops_vec, uint n_dofs,
312  OpSizeType size_type = pointOp) {
313  ElOp<spacedim> op_accessor(this->dim_, shape, reinit_f, size_type, input_ops_vec, n_dofs);
314  row_sizes_.insert(row_sizes_.end(), op_accessor.n_comp() * n_dofs, size_type);
315  operations_.push_back(op_accessor);
316  return operations_[operations_.size()-1];
317  }
318 
319 
320  /**
321  * Reinitializes patch data.
322  *
323  * Calls reinit functions defined on each operations.
324  */
325  void reinit_patch() {
326  if (n_elems_ == 0) return; // skip if tables are empty
327  for (uint i=0; i<operations_.size(); ++i)
328  operations_[i].reinit_function(operations_, int_table_);
329  }
330 
331  /**
332  * Returns scalar output value.
333  *
334  * @param op_idx Index of operation in operations vector
335  * @param point_idx Index of quadrature point in ElementCacheMap
336  * @param i_dof Index of DOF
337  */
338  inline Scalar scalar_value(uint op_idx, uint point_idx, uint i_dof=0) const {
339  return operations_[op_idx].result_matrix()(0)(points_map_[point_idx] + i_dof*n_points_);
340  }
341 
342  /**
343  * Returns vector output value.
344  *
345  * @param op_idx Index of operation in operations vector
346  * @param point_idx Index of quadrature point in ElementCacheMap
347  * @param i_dof Index of DOF
348  */
349  inline Vector vector_value(uint op_idx, uint point_idx, uint i_dof=0) const {
350  Vector val;
351  const auto &op_matrix = operations_[op_idx].result_matrix();
352  uint op_matrix_idx = points_map_[point_idx] + i_dof*n_points_;
353  for (uint i=0; i<3; ++i)
354  val(i) = op_matrix(i)(op_matrix_idx);
355  return val;
356  }
357 
358  /**
359  * Returns tensor output value.
360  *
361  * @param op_idx Index of operation in operations vector
362  * @param point_idx Index of quadrature point in ElementCacheMap
363  * @param i_dof Index of DOF
364  */
365  inline Tensor tensor_value(uint op_idx, uint point_idx, uint i_dof=0) const {
366  Tensor val;
367  const auto &op_matrix = operations_[op_idx].result_matrix();
368  uint op_matrix_idx = points_map_[point_idx] + i_dof*n_points_;
369  for (uint i=0; i<3; ++i)
370  for (uint j=0; j<3; ++j)
371  val(i,j) = op_matrix(i,j)(op_matrix_idx);
372  return val;
373  }
374 
375  /**
376  * Performs output of data tables to stream.
377  *
378  * Development method.
379  * @param points Allows switched off output of point table,
380  * @param ints Allows switched off output of int (connectivity to elements) table,
381  */
382  void print_data_tables(ostream& stream, bool points, bool ints) const {
383  if (points) {
384  stream << "Point vals: " << std::endl;
385  for (auto &op : operations_) {
386  const auto &mat = op.result_matrix();
387  for (uint i_mat=0; i_mat<mat.rows()*mat.cols(); ++i_mat) {
388  if (mat(i_mat).data_size()==0) stream << "<empty>";
389  else {
390  const double *vals = mat(i_mat).data_ptr();
391  for (size_t i_val=0; i_val<mat(i_mat).data_size(); ++i_val)
392  stream << vals[i_val] << " ";
393  }
394  stream << std::endl;
395  }
396  stream << " --- end of operation ---" << std::endl;
397  }
398  }
399  if (ints) {
400  stream << "Int vals: " << int_table_.rows() << " - " << int_table_.cols() << std::endl;
401  for (uint i_row=0; i_row<int_table_.rows(); ++i_row) {
402  if (int_table_(i_row).data_size()==0) stream << "<empty>";
403  else {
404  const uint *vals = int_table_(i_row).data_ptr();
405  for (size_t i_val=0; i_val<int_table_(i_row).data_size(); ++i_val)
406  stream << vals[i_val] << " ";
407  }
408  stream << std::endl;
409  }
410  stream << std::endl;
411  }
412  }
413 
414  /**
415  * Performs table of fixed operations to stream.
416  *
417  * Development method.
418  * @param bulk_side Needs set 0 (bulk) or 1 (side) for correct output of operation names.
419  */
420  void print_operations(ostream& stream, uint bulk_side) const {
422  {
423  { "el_coords", "jacobian", "inv_jac", "jac_det", "pt_coords", "weights", "JxW", "", "", "", "", "" },
424  { "el_coords", "el_jac", "el_inv_jac", "side_coords", "side_jac", "side_jac_det", "exp_el_coords", "exp_el_jac", "exp_el_inv_jac",
425  "exp_side_coords", "exp_side_jac", "exp_side_jac_det", "pt_coords", "weights", "JxW", "normal_vec", "", "", "", "", "" }
426  };
427  stream << std::setfill(' ') << " Operation" << setw(12) << "" << "Shape" << setw(2) << ""
428  << "n DOFs" << setw(2) << "" << "Input operations" << endl;
429  for (uint i=0; i<operations_.size(); ++i) {
430  stream << " " << std::left << setw(20) << op_names[bulk_side][i] << "" << " " << setw(6) << operations_[i].format_shape() << "" << " "
431  << setw(7) << operations_[i].n_dofs() << "" << " ";
432  auto &input_ops = operations_[i].input_ops();
433  for (auto i_o : input_ops) stream << op_names[bulk_side][i_o] << " ";
434  stream << std::endl;
435  }
436  }
437 
438 protected:
439  /**
440  * Hold integer values of quadrature points of defined operations.
441  *
442  * Table contains following rows:
443  * 0: Index of quadrature point on patch
444  * 1: Row of element/side in ElOp::result_ table in registration step (before expansion)
445  * 2: Element idx in Mesh
446  * - last two rows are allocated only for side point table
447  * 3: Index of side in element - short vector, size of column = number of sides
448  * 4: Index of side in element - long vector, size of column = number of points
449  * Number of used rows is given by n_points_.
450  */
452 
453  /// Set size and type of rows of int_table_, value is set implicitly in constructor of descendants
455 
456 
457  /// Vector of all defined operations
459 
460  uint dim_; ///< Dimension
461  uint n_points_; ///< Number of points in patch
462  uint n_elems_; ///< Number of elements in patch
463  uint i_elem_; ///< Index of registered element in table, helper value used during patch creating.
464  Quadrature *quad_; ///< Quadrature of given dimension and order passed in constructor.
465 
466  std::vector<uint> elements_map_; ///< Map of element patch indices to ElOp::result_ and int_table_ tables
467  std::vector<uint> points_map_; ///< Map of point patch indices to ElOp::result_ and int_table_ tables
468  std::vector<OpSizeType> row_sizes_; ///< hold sizes of rows by type of operation
469  AssemblyArena &asm_arena_; ///< Reference to global assembly arena of PatchFeValues
470  PatchArena *patch_arena_; ///< Pointer to global patch arena of PatchFeValues
471 
472  friend class PatchFEValues<spacedim>;
473  friend class ElOp<spacedim>;
474  template<unsigned int dim>
475  friend class BulkValues;
476  template<unsigned int dim>
477  friend class SideValues;
478  template<unsigned int dim>
479  friend class JoinValues;
480 };
481 
482 /**
483  * @brief Class represents element or FE operations.
484  */
485 template<unsigned int spacedim = 3>
486 class ElOp {
487 public:
488  /**
489  * Constructor
490  *
491  * Set all data members.
492  */
493  ElOp(uint dim, std::initializer_list<uint> shape, ReinitFunction reinit_f, OpSizeType size_type, std::vector<uint> input_ops = {}, uint n_dofs = 1)
495  {}
496 
497  /// Aligns shape_vec to 2 items (equal to matrix number of dimensions)
498  std::vector<uint> set_shape_vec(std::initializer_list<uint> shape) const {
499  std::vector<uint> shape_vec(shape);
500  if (shape_vec.size() == 1) shape_vec.push_back(1);
501  ASSERT_EQ(shape_vec.size(), 2);
502  return shape_vec;
503  }
504 
505  /**
506  * Return number of operation components
507  *
508  * Value is computed from shape_ vector
509  */
510  inline uint n_comp() const {
511  return shape_[0] * shape_[1];
512  }
513 
514  /// Getter for dimension
515  inline uint dim() const {
516  return dim_;
517  }
518 
519  /// Getter for size_type_
521  return size_type_;
522  }
523 
524  /// Getter for n_dofs_
525  inline uint n_dofs() const {
526  return n_dofs_;
527  }
528 
529  /// Getter for input_ops_
530  inline const std::vector<uint> &input_ops() const {
531  return input_ops_;
532  }
533 
534  /// Getter for shape_
535  inline const std::vector<uint> &shape() const {
536  return shape_;
537  }
538 
539  /**
540  * Format shape to string
541  *
542  * Method is used in output development method.
543  */
544  inline std::string format_shape() const {
545  stringstream ss;
546  ss << shape_[0] << "x" << shape_[1];
547  return ss.str();
548  }
549 
550  /// Call reinit function on element table if function is defined
551  inline void reinit_function(std::vector<ElOp<spacedim>> &operations, IntTableArena &int_table) {
552  reinit_func(operations, int_table);
553  }
554 
555  inline void allocate_result(size_t data_size, PatchArena &arena) {
556  result_ = Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic>(shape_[0], shape_[1]);
557  for (uint i=0; i<n_comp(); ++i)
558  result_(i) = ArenaVec<double>(data_size, arena);
559  }
560 
561  /// Return map referenced result as Eigen::Matrix
562  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> &result_matrix() {
563  return result_;
564  }
565 
566  /// Same as previous but return const reference
567  const Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> &result_matrix() const {
568  return result_;
569  }
570 
571 
572 protected:
573  uint dim_; ///< Dimension
574  std::vector<uint> shape_; ///< Shape of stored data (size of vector or number of rows and cols of matrix)
575  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> result_; ///< Result matrix of operation
576  OpSizeType size_type_; ///< Type of operation by size of vector (element, point or fixed size)
577  std::vector<uint> input_ops_; ///< Indices of operations in PatchPointValues::operations_ vector on which ElOp is depended
578  uint n_dofs_; ///< Number of DOFs of FE operations (or 1 in case of element operations)
579 
580  ReinitFunction reinit_func; ///< Pointer to patch reinit function of element data table specialized by operation
581 };
582 
583 
584 /// Defines common functionality of reinit operations.
586  // empty base operation
587  static inline void op_base(FMT_UNUSED std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
588  // empty
589  }
590 
591 };
592 
593 /// Defines reinit operations on bulk points.
594 struct bulk_reinit {
595  // element operations
596  template<unsigned int dim>
597  static inline void elop_jac(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
598  // result matrix(spacedim, dim), input matrix(spacedim, dim+1)
599  auto &op = operations[FeBulk::BulkOps::opJac];
600  auto &jac_value = op.result_matrix();
601  const auto &coords_value = operations[ op.input_ops()[0] ].result_matrix();
602  for (unsigned int i=0; i<3; i++)
603  for (unsigned int j=0; j<dim; j++)
604  jac_value(i,j) = coords_value(i,j+1) - coords_value(i,0);
605  }
606  template<unsigned int dim>
607  static inline void elop_inv_jac(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
608  // result matrix(spacedim, dim), input matrix(spacedim, dim+1)
609  auto &op = operations[FeBulk::BulkOps::opInvJac];
610  auto &inv_jac_value = op.result_matrix();
611  const auto &jac_value = operations[ op.input_ops()[0] ].result_matrix();
612  inv_jac_value = eigen_arena_tools::inverse<3, dim>(jac_value);
613  }
614  template<unsigned int dim>
615  static inline void elop_jac_det(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
616  // result double, input matrix(spacedim, dim)
617  auto &op = operations[FeBulk::BulkOps::opJacDet];
618  auto &jac_det_value = op.result_matrix();
619  const auto &jac_value = operations[ op.input_ops()[0] ].result_matrix();
620  jac_det_value(0,0) = eigen_arena_tools::determinant<3, dim>(jac_value).abs();
621  }
622 
623  // point operations
624  static inline void ptop_coords(FMT_UNUSED std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
625  // Implement
626  }
627  static inline void ptop_weights(std::vector<ElOp<3>> &operations, PatchArena *arena, const std::vector<double> &point_weights) {
628  auto &op = operations[FeBulk::BulkOps::opWeights];
629  op.allocate_result(point_weights.size(), *arena);
630  auto &weights_value = op.result_matrix();
631  for (uint i=0; i<point_weights.size(); ++i)
632  weights_value(0,0)(i) = point_weights[i];
633  }
634  static inline void ptop_JxW(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
635  auto &op = operations[FeBulk::BulkOps::opJxW];
636  auto &weights_value = operations[ op.input_ops()[0] ].result_matrix();
637  auto &jac_det_value = operations[ op.input_ops()[1] ].result_matrix();
638  ArenaOVec<double> weights_ovec( weights_value(0,0) );
639  ArenaOVec<double> jac_det_ovec( jac_det_value(0,0) );
640  ArenaOVec<double> jxw_ovec = jac_det_ovec * weights_ovec;
641  auto &jxw_value = op.result_matrix();
642  jxw_value(0,0) = jxw_ovec.get_vec();
643  }
644  static inline void ptop_scalar_shape(std::vector<ElOp<3>> &operations,
645  std::vector< std::vector<double> > shape_values, uint scalar_shape_op_idx) {
646  auto &op = operations[scalar_shape_op_idx];
647  uint n_dofs = shape_values.size();
648  uint n_points = shape_values[0].size();
649  uint n_elem = op.result_matrix()(0).data_size() / n_points;
650 
651  auto &shape_matrix = op.result_matrix();
652  ArenaVec<double> ref_vec(n_points * n_dofs, op.result_matrix()(0).arena());
653  ArenaVec<double> elem_vec(n_elem, op.result_matrix()(0).arena());
654  for (uint i=0; i<n_elem; ++i) {
655  elem_vec(i) = 1.0;
656  }
657  ArenaOVec<double> ref_ovec(ref_vec);
658  ArenaOVec<double> elem_ovec(elem_vec);
659  for (uint i_dof=0; i_dof<n_dofs; ++i_dof)
660  for (uint i_p=0; i_p<n_points; ++i_p)
661  ref_vec(i_dof * n_points + i_p) = shape_values[i_dof][i_p];
662  ArenaOVec<double> shape_ovec = elem_ovec * ref_ovec;
663  shape_matrix(0) = shape_ovec.get_vec();
664  }
665  template<unsigned int dim>
666  static inline void ptop_scalar_shape_grads(std::vector<ElOp<3>> &operations,
667  std::vector< std::vector<arma::mat> > ref_shape_grads, uint scalar_shape_grads_op_idx) {
668  auto &op = operations[scalar_shape_grads_op_idx];
669  auto &inv_jac_vec = operations[ op.input_ops()[0] ].result_matrix();
670  uint n_points = ref_shape_grads.size();
671  uint n_dofs = ref_shape_grads[0].size();
672 
673  Eigen::Matrix<ArenaVec<double>, dim, 1> ref_grads_vec;
674  Eigen::Matrix<ArenaOVec<double>, dim, 1> ref_grads_ovec;
675  for (uint i=0; i<ref_grads_vec.rows(); ++i) {
676  ref_grads_vec(i) = ArenaVec<double>(n_points * n_dofs, op.result_matrix()(0).arena());
677  for (uint i_dof=0; i_dof<n_dofs; ++i_dof)
678  for (uint i_p=0; i_p<n_points; ++i_p)
679  ref_grads_vec(i)(i_dof * n_points + i_p) = ref_shape_grads[i_p][i_dof](i);
680  ref_grads_ovec(i) = ArenaOVec(ref_grads_vec(i));
681  }
682 
683  Eigen::Matrix<ArenaOVec<double>, dim, 3> inv_jac_ovec;
684  for (uint i=0; i<dim*3; ++i) {
685  inv_jac_ovec(i) = ArenaOVec(inv_jac_vec(i));
686  }
687 
688  auto &result_vec = op.result_matrix();
689  Eigen::Matrix<ArenaOVec<double>, 3, 1> result_ovec = inv_jac_ovec.transpose() * ref_grads_ovec;
690  for (uint i=0; i<3; ++i) {
691  result_vec(i) = result_ovec(i).get_vec();
692  }
693  }
694 };
695 
696 
697 
698 /// Defines reinit operations on side points.
699 struct side_reinit {
700  // element operations
701  template<unsigned int dim>
702  static inline void elop_el_jac(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
703  // result matrix(spacedim, dim), input matrix(spacedim, dim+1)
704  auto &op = operations[FeSide::SideOps::opElJac];
705  auto &jac_value = op.result_matrix();
706  const auto &coords_value = operations[ op.input_ops()[0] ].result_matrix();
707  for (unsigned int i=0; i<3; i++)
708  for (unsigned int j=0; j<dim; j++)
709  jac_value(i,j) = coords_value(i,j+1) - coords_value(i,0);
710  }
711  template<unsigned int dim>
712  static inline void elop_el_inv_jac(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
713  auto &op = operations[FeSide::SideOps::opElInvJac];
714  auto &inv_jac_value = op.result_matrix();
715  const auto &jac_value = operations[ op.input_ops()[0] ].result_matrix();
716  inv_jac_value = eigen_arena_tools::inverse<3, dim>(jac_value);
717  }
718  template<unsigned int dim>
719  static inline void elop_sd_jac(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
720  // result matrix(spacedim, dim), input matrix(spacedim, dim+1)
721  auto &op = operations[FeSide::SideOps::opSideJac];
722  auto &jac_value = op.result_matrix();
723  const auto &coords_value = operations[ op.input_ops()[0] ].result_matrix();
724  for (unsigned int i=0; i<3; i++)
725  for (unsigned int j=0; j<dim-1; j++)
726  jac_value(i,j) = coords_value(i,j+1) - coords_value(i,0);
727  }
728  template<unsigned int dim>
729  static inline void elop_sd_jac_det(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
730  // result double, input matrix(spacedim, dim)
731  auto &op = operations[FeSide::SideOps::opSideJacDet];
732  auto &jac_det_value = op.result_matrix();
733  const auto &jac_value = operations[ op.input_ops()[0] ].result_matrix();
734  jac_det_value(0,0) = eigen_arena_tools::determinant<3, dim-1>(jac_value).abs();
735  }
736 
737  // Point operations
738  static inline void ptop_coords(FMT_UNUSED std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
739  // Implement
740  }
741  static inline void ptop_weights(std::vector<ElOp<3>> &operations, PatchArena *arena, const std::vector<double> &point_weights) {
742  auto &op = operations[FeSide::SideOps::opWeights];
743  op.allocate_result(point_weights.size(), *arena);
744  auto &weights_value = op.result_matrix();
745  for (uint i=0; i<point_weights.size(); ++i)
746  weights_value(0,0)(i) = point_weights[i];
747  }
748  static inline void ptop_JxW(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
749  auto &op = operations[FeSide::SideOps::opJxW];
750  auto &weights_value = operations[ op.input_ops()[0] ].result_matrix();
751  auto &jac_det_value = operations[ op.input_ops()[1] ].result_matrix();
752  ArenaOVec<double> weights_ovec( weights_value(0,0) );
753  ArenaOVec<double> jac_det_ovec( jac_det_value(0,0) );
754  ArenaOVec<double> jxw_ovec = jac_det_ovec * weights_ovec;
755  auto &jxw_value = op.result_matrix();
756  jxw_value(0,0) = jxw_ovec.get_vec();
757  }
758  template<unsigned int dim>
759  static inline void ptop_normal_vec(std::vector<ElOp<3>> &operations, IntTableArena &el_table) {
760  auto &op = operations[FeSide::SideOps::opNormalVec];
761  auto &normal_value = op.result_matrix();
762  auto &inv_jac_mat_value = operations[ op.input_ops()[0] ].result_matrix();
763  normal_value = inv_jac_mat_value.transpose() * RefElement<dim>::normal_vector_array( el_table(3) );
764 
765  ArenaVec<double> norm_vec( normal_value(0).data_size(), normal_value(0).arena() );
766  Eigen::VectorXd A(3);
767  for (uint i=0; i<normal_value(0).data_size(); ++i) {
768  A(0) = normal_value(0)(i);
769  A(1) = normal_value(1)(i);
770  A(2) = normal_value(2)(i);
771  norm_vec(i) = A.norm();
772  }
773 
774  size_t points_per_side = el_table(4).data_size() / el_table(3).data_size();
775  size_t n_points = el_table(3).data_size();
776  for (uint i=0; i<3; ++i) {
777  normal_value(i) = normal_value(i) / norm_vec;
778  ArenaVec<double> expand_vec( normal_value(i).data_size() * points_per_side, normal_value(i).arena() );
779  for (uint j=0; j<expand_vec.data_size(); ++j) {
780  expand_vec(j) = normal_value(i)(j % n_points);
781  }
782  normal_value(i) = expand_vec;
783  }
784  }
785  static inline void ptop_scalar_shape(std::vector<ElOp<3>> &operations, IntTableArena &el_table,
786  std::vector< std::vector< std::vector<double> > > shape_values, uint scalar_shape_op_idx) {
787  uint n_dofs = shape_values[0][0].size();
788  uint n_sides = el_table(3).data_size();
789  uint n_patch_points = el_table(4).data_size();
790 
791  auto &op = operations[scalar_shape_op_idx];
792  auto &scalar_shape_value = op.result_matrix();
793  scalar_shape_value(0) = ArenaVec<double>(n_dofs*n_patch_points, scalar_shape_value(0).arena());
794 
795  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
796  uint dof_shift = i_dof * n_patch_points;
797  for (uint i_pt=0; i_pt<n_patch_points; ++i_pt)
798  scalar_shape_value(0)(i_pt + dof_shift) = shape_values[el_table(4)(i_pt)][i_pt / n_sides][i_dof];
799  }
800  }
801  template<unsigned int dim>
802  static inline void ptop_scalar_shape_grads(std::vector<ElOp<3>> &operations, IntTableArena &el_table,
803  std::vector< std::vector< std::vector<arma::mat> > > ref_shape_grads, uint scalar_shape_grads_op_idx) {
804  uint n_points = ref_shape_grads[0].size();
805  uint n_dofs = ref_shape_grads[0][0].size();
806  uint n_sides = el_table(3).data_size();
807  uint n_patch_points = el_table(4).data_size();
808 
809  // Result vector
810  auto &op = operations[scalar_shape_grads_op_idx];
811  auto &grad_scalar_shape_value = op.result_matrix();
812 
813  // Expands inverse jacobian to inv_jac_expd_value
814  auto &inv_jac_value = operations[ op.input_ops()[0] ].result_matrix();
815  Eigen::Matrix<ArenaVec<double>, dim, 3> inv_jac_expd_value;
816  for (uint i=0; i<dim*3; ++i) {
817  inv_jac_expd_value(i) = ArenaVec<double>( n_dofs*n_patch_points, inv_jac_value(i).arena() );
818  for (uint j=0; j<n_dofs*n_patch_points; ++j)
819  inv_jac_expd_value(i)(j) = inv_jac_value(i)(j%n_sides);
820  }
821 
822  // Fill ref shape gradients by q_point. DOF and side_idx
823  Eigen::Matrix<ArenaVec<double>, dim, 1> ref_shape_grads_expd;
824  for (uint i=0; i<dim; ++i) {
825  ref_shape_grads_expd(i) = ArenaVec<double>( n_dofs*n_patch_points, inv_jac_value(0).arena() );
826  }
827  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
828  for (uint i_pt=0; i_pt<n_points; ++i_pt) {
829  uint i_begin = (i_dof * n_points + i_pt) * n_sides;
830  for (uint i_sd=0; i_sd<n_sides; ++i_sd) {
831  for (uint i_c=0; i_c<dim; ++i_c) {
832  ref_shape_grads_expd(i_c)(i_begin + i_sd) = ref_shape_grads[el_table(3)(i_sd)][i_pt][i_dof][i_c];
833  }
834  }
835  }
836  }
837 
838  // computes operation result
839  grad_scalar_shape_value = inv_jac_expd_value.transpose() * ref_shape_grads_expd;
840  }
841 };
842 
843 
844 // template specialization
845 template<>
846 inline void side_reinit::elop_sd_jac<1>(FMT_UNUSED std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
847 }
848 
849 template<>
850 inline void side_reinit::elop_sd_jac_det<1>(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
851  auto &op = operations[FeSide::SideOps::opSideJacDet];
852  auto &result_vec = op.result_matrix();
853  for (uint i=0;i<result_vec(0,0).data_size(); ++i) {
854  result_vec(0,0)(i) = 1.0;
855  }
856 }
857 
858 
859 
860 namespace FeBulk {
861 
862  /// Bulk data specialization, order of item in operations_ vector corresponds to the BulkOps enum
863  template<unsigned int spacedim = 3>
864  class PatchPointValues : public ::PatchPointValues<spacedim> {
865  public:
866  /// Constructor
867  PatchPointValues(uint dim, uint quad_order, AssemblyArena &asm_arena)
868  : ::PatchPointValues<spacedim>(dim, asm_arena) {
869  this->quad_ = new QGauss(dim, 2*quad_order);
870  this->int_sizes_ = {pointOp, pointOp, pointOp};
871  switch (dim) {
872  case 1:
873  init<1>();
874  break;
875  case 2:
876  init<2>();
877  break;
878  case 3:
879  init<3>();
880  break;
881  }
882  }
883 
884  private:
885  /// Initialize operations vector
886  template<unsigned int dim>
887  void init() {
888  // First step: adds element values operations
889  /*auto &el_coords =*/ this->make_new_op( {spacedim, this->dim_+1}, &common_reinit::op_base, {}, OpSizeType::elemOp );
890 
891  /*auto &el_jac =*/ this->make_new_op( {spacedim, this->dim_}, &bulk_reinit::elop_jac<dim>, {BulkOps::opElCoords}, OpSizeType::elemOp );
892 
893  /*auto &el_inv_jac =*/ this->make_new_op( {this->dim_, spacedim}, &bulk_reinit::elop_inv_jac<dim>, {BulkOps::opJac}, OpSizeType::elemOp );
894 
895  /*auto &el_jac_det =*/ this->make_new_op( {1}, &bulk_reinit::elop_jac_det<dim>, {BulkOps::opJac}, OpSizeType::elemOp );
896 
897  // Second step: adds point values operations
898  /*auto &pt_coords =*/ this->make_new_op( {spacedim}, &bulk_reinit::ptop_coords, {} );
899 
900  // use lambda reinit function
901  const std::vector<double> &point_weights_vec = this->quad_->get_weights();
902  auto lambda_weights = [this, point_weights_vec](std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
903  bulk_reinit::ptop_weights(operations, this->patch_arena_, point_weights_vec);
904  };
905  /*auto &weights =*/ this->make_fixed_op( {1}, lambda_weights );
906 
907  /*auto &JxW =*/ this->make_new_op( {1}, &bulk_reinit::ptop_JxW, {BulkOps::opWeights, BulkOps::opJacDet} );
908  }
909  };
910 
911 } // closing namespace FeBulk
912 
913 
914 
915 namespace FeSide {
916 
917 /// Bulk Side specialization, order of item in operations_ vector corresponds to the SideOps enum
918  template<unsigned int spacedim = 3>
919  class PatchPointValues : public ::PatchPointValues<spacedim> {
920  public:
921  /// Constructor
922  PatchPointValues(uint dim, uint quad_order, AssemblyArena &asm_arena)
923  : ::PatchPointValues<spacedim>(dim, asm_arena) {
924  this->quad_ = new QGauss(dim-1, 2*quad_order);
925  this->int_sizes_ = {pointOp, pointOp, pointOp, elemOp, pointOp};
926  switch (dim) {
927  case 1:
928  init<1>();
929  break;
930  case 2:
931  init<2>();
932  break;
933  case 3:
934  init<3>();
935  break;
936  }
937  }
938 
939  private:
940  /// Initialize operations vector
941  template<unsigned int dim>
942  void init() {
943  // First step: adds element values operations
944  /*auto &el_coords =*/ this->make_new_op( {spacedim, this->dim_+1}, &common_reinit::op_base, {}, OpSizeType::elemOp );
945 
946  /*auto &el_jac =*/ this->make_new_op( {spacedim, this->dim_}, &side_reinit::elop_el_jac<dim>, {SideOps::opElCoords}, OpSizeType::elemOp );
947 
948  /*auto &el_inv_jac =*/ this->make_new_op( {this->dim_, spacedim}, &side_reinit::elop_el_inv_jac<dim>, {SideOps::opElJac}, OpSizeType::elemOp );
949 
950  // Second step: adds side values operations
951  /*auto &sd_coords =*/ this->make_new_op( {spacedim, this->dim_}, &common_reinit::op_base, {}, OpSizeType::elemOp );
952 
953  /*auto &sd_jac =*/ this->make_new_op( {spacedim, this->dim_-1}, &side_reinit::elop_sd_jac<dim>, {SideOps::opSideCoords}, OpSizeType::elemOp );
954 
955  /*auto &sd_jac_det =*/ this->make_new_op( {1}, &side_reinit::elop_sd_jac_det<dim>, {SideOps::opSideJac}, OpSizeType::elemOp );
956 
957  // Third step: adds point values operations
958  /*auto &coords =*/ this->make_new_op( {spacedim}, &side_reinit::ptop_coords, {} );
959 
960  // use lambda reinit function
961  const std::vector<double> &point_weights_vec = this->quad_->get_weights();
962  auto lambda_weights = [this, point_weights_vec](std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
963  side_reinit::ptop_weights(operations, this->patch_arena_, point_weights_vec);
964  };
965  /*auto &weights =*/ this->make_fixed_op( {1}, lambda_weights );
966 
968 
969  /*auto &normal_vec =*/ this->make_new_op( {spacedim}, &side_reinit::ptop_normal_vec<dim>, {SideOps::opElInvJac} );
970  }
971  };
972 
973 } // closing namespace FeSide
974 
975 
976 
977 #endif /* PATCH_POINT_VALUES_HH_ */
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:333
ArenaVec< T > get_vec() const
Convert ArenaOVec to ArenaVec and its.
Definition: arena_vec.hh:284
size_t data_size() const
Getter for data_size_.
Definition: arena_vec.hh:104
Class represents element or FE operations.
ElOp(uint dim, std::initializer_list< uint > shape, ReinitFunction reinit_f, OpSizeType size_type, std::vector< uint > input_ops={}, uint n_dofs=1)
Eigen::Matrix< ArenaVec< double >, Eigen::Dynamic, Eigen::Dynamic > & result_matrix()
Return map referenced result as Eigen::Matrix.
void allocate_result(size_t data_size, PatchArena &arena)
std::string format_shape() const
std::vector< uint > input_ops_
Indices of operations in PatchPointValues::operations_ vector on which ElOp is depended.
std::vector< uint > set_shape_vec(std::initializer_list< uint > shape) const
Aligns shape_vec to 2 items (equal to matrix number of dimensions)
uint dim_
Dimension.
Eigen::Matrix< ArenaVec< double >, Eigen::Dynamic, Eigen::Dynamic > result_
Result matrix of operation.
std::vector< uint > shape_
Shape of stored data (size of vector or number of rows and cols of matrix)
const std::vector< uint > & shape() const
Getter for shape_.
const std::vector< uint > & input_ops() const
Getter for input_ops_.
OpSizeType size_type_
Type of operation by size of vector (element, point or fixed size)
const Eigen::Matrix< ArenaVec< double >, Eigen::Dynamic, Eigen::Dynamic > & result_matrix() const
Same as previous but return const reference.
uint n_dofs() const
Getter for n_dofs_.
ReinitFunction reinit_func
Pointer to patch reinit function of element data table specialized by operation.
void reinit_function(std::vector< ElOp< spacedim >> &operations, IntTableArena &int_table)
Call reinit function on element table if function is defined.
uint n_dofs_
Number of DOFs of FE operations (or 1 in case of element operations)
uint dim() const
Getter for dimension.
uint n_comp() const
OpSizeType size_type() const
Getter for size_type_.
Bulk data specialization, order of item in operations_ vector corresponds to the BulkOps enum.
PatchPointValues(uint dim, uint quad_order, AssemblyArena &asm_arena)
Constructor.
void init()
Initialize operations vector.
Bulk Side specialization, order of item in operations_ vector corresponds to the SideOps enum.
PatchPointValues(uint dim, uint quad_order, AssemblyArena &asm_arena)
Constructor.
void init()
Initialize operations vector.
void print_data_tables(ostream &stream, bool points, bool ints) const
PatchPointValues(uint dim, AssemblyArena &asm_arena)
AssemblyArena & asm_arena_
Reference to global assembly arena of PatchFeValues.
std::vector< OpSizeType > row_sizes_
hold sizes of rows by type of operation
std::vector< uint > points_map_
Map of point patch indices to ElOp::result_ and int_table_ tables.
uint register_bulk_point(uint elem_table_row, uint value_patch_idx, uint elem_idx, uint i_point_on_elem)
uint register_element(arma::mat coords, uint element_patch_idx)
void resize_tables(uint n_elems, uint n_points)
Resize data tables. Method is called before reinit of patch.
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 n_elems() const
Getter for n_elems_.
uint i_elem_
Index of registered element in table, helper value used during patch creating.
void reset()
Reset number of columns (points and elements)
uint n_points() const
Getter for n_points_.
ElOp< spacedim > & make_fixed_op(std::initializer_list< uint > shape, ReinitFunction reinit_f)
std::vector< uint > elements_map_
Map of element patch indices to ElOp::result_ and int_table_ tables.
uint dim() const
Getter for dim_.
Tensor tensor_value(uint op_idx, uint point_idx, uint i_dof=0) const
Scalar scalar_value(uint op_idx, uint point_idx, uint i_dof=0) const
void init_finalize(PatchArena *patch_arena)
uint register_side(arma::mat elm_coords, arma::mat side_coords, uint side_idx)
uint register_side_point(uint elem_table_row, uint value_patch_idx, uint elem_idx, uint side_idx, uint i_point_on_side)
IntTableArena int_table_
uint n_points_
Number of points in patch.
void print_operations(ostream &stream, uint bulk_side) const
Quadrature * quad_
Quadrature of given dimension and order passed in constructor.
ElOp< spacedim > & make_new_op(std::initializer_list< uint > shape, ReinitFunction reinit_f, std::vector< uint > input_ops_vec, OpSizeType size_type=pointOp)
std::vector< OpSizeType > int_sizes_
Set size and type of rows of int_table_, value is set implicitly in constructor of descendants.
Vector vector_value(uint op_idx, uint point_idx, uint i_dof=0) const
PatchArena * patch_arena_
Pointer to global patch arena of PatchFeValues.
uint n_elems_
Number of elements in patch.
Symmetric Gauss-Legendre quadrature formulae on simplices.
Base class for quadrature rules on simplices in arbitrary dimensions.
Definition: quadrature.hh:48
const std::vector< double > & get_weights() const
Return a reference to the whole array of weights.
Definition: quadrature.hh:111
static Eigen::Matrix< ArenaVec< double >, dim, 1 > normal_vector_array(ArenaVec< uint > loc_side_idx_vec)
Definition: ref_element.cc:280
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...
unsigned int uint
ArmaMat< double, N, M > mat
Definition: armor.hh:936
@ opCoords
operations evaluated on quadrature points
@ opInvJac
inverse Jacobian
@ opWeights
weight of quadrature point
@ opJac
Jacobian of element.
@ opElCoords
operations evaluated on elements
@ opJxW
JxW value of quadrature point.
@ opNormalVec
normal vector of quadrature point
@ opSideCoords
operations evaluated on sides
@ opJxW
JxW value of quadrature point.
@ opCoords
operations evaluated on quadrature points
@ opElCoords
operations evaluated on elements
@ opElJac
Jacobian of element.
@ opWeights
weight of quadrature point
@ opSideJac
Jacobian of element.
ArenaVec< double > determinant(const Eigen::Matrix< ArenaVec< double >, m, n > &A)
Calculates determinant of a rectangular matrix.
double Scalar
std::function< void(std::vector< ElOp< 3 > > &, IntTableArena &)> ReinitFunction
Type for conciseness.
OpSizeType
Distinguishes operations by type and size of output rows.
@ pointOp
operation is evaluated on quadrature points
@ elemOp
operation is evaluated on elements or sides
@ fixedSizeOp
operation has fixed size and it is filled during initialization
#define FMT_UNUSED
Definition: posix.h:75
Definitions of particular quadrature rules on simplices.
Defines reinit operations on bulk points.
static void elop_inv_jac(std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)
static void ptop_scalar_shape_grads(std::vector< ElOp< 3 >> &operations, std::vector< std::vector< arma::mat > > ref_shape_grads, uint scalar_shape_grads_op_idx)
static void elop_jac(std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)
static void elop_jac_det(std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)
static void ptop_JxW(std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)
static void ptop_weights(std::vector< ElOp< 3 >> &operations, PatchArena *arena, const std::vector< double > &point_weights)
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_coords(FMT_UNUSED std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)
Defines common functionality of reinit operations.
static void op_base(FMT_UNUSED std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)
Defines reinit operations on side points.
static void elop_el_jac(std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)
static void elop_sd_jac_det(std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)
static void elop_sd_jac(std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)
static void ptop_normal_vec(std::vector< ElOp< 3 >> &operations, IntTableArena &el_table)
static void ptop_weights(std::vector< ElOp< 3 >> &operations, PatchArena *arena, const std::vector< double > &point_weights)
static void ptop_scalar_shape_grads(std::vector< ElOp< 3 >> &operations, IntTableArena &el_table, std::vector< std::vector< std::vector< arma::mat > > > ref_shape_grads, uint scalar_shape_grads_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)
static void elop_el_inv_jac(std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)
static void ptop_JxW(std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)
static void ptop_coords(FMT_UNUSED std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)