Flow123d  DF_patch_fe_data_tables-1a16803
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  /// operation executed expansion to quadrature point (value of element / side > values on quadrature points)
91 // opExpansionElCoords, ///< expands coordinates on element
92 // opExpansionElJac, ///< expands Jacobian on element
93 // opExpansionElInvJac, ///< expands inverse Jacobian on element
94 // opExpansionSideCoords, ///< expands coordinates on side
95 // opExpansionSideJac, ///< expands Jacobian on side
96 // opExpansionSideJacDet, ///< expands Jacobian determinant on side
97  /// operations evaluated on quadrature points
98  opCoords, ///< coordinations of quadrature point
99  opWeights, ///< weight of quadrature point
100  opJxW, ///< JxW value of quadrature point
101  opNormalVec ///< normal vector of quadrature point
102  };
103 }
104 
105 
106 /// Distinguishes operations by type and size of output rows
108 {
109  elemOp, ///< operation is evaluated on elements or sides
110  pointOp, ///< operation is evaluated on quadrature points
111  fixedSizeOp ///< operation has fixed size and it is filled during initialization
112 };
113 
114 
115 
116 /**
117  * v Class for storing FE data of quadrature points on one patch.
118  *
119  * Store data of bulk or side quadrature points of one dimension.
120  */
121 template<unsigned int spacedim = 3>
123 {
124 public:
125  /**
126  * Constructor
127  *
128  * @param dim Set dimension
129  */
131  : dim_(dim), n_rows_(0), elements_map_(300, 0), points_map_(300, 0), asm_arena_(asm_arena) {
132  reset();
133  }
134 
135  /**
136  * Initialize object, set number of columns (quantities) in tables.
137  *
138  * Number of columns point_vals_ is given by n_rows_ value.
139  */
140  void initialize() {
141  this->reset();
142 
143  point_vals_.resize(n_rows_);
144  int_table_.resize(int_sizes_.size());
145  }
146 
147  inline void init_finalize(PatchArena *patch_arena) {
148  patch_arena_ = patch_arena;
149  }
150 
151  /// Reset number of columns (points and elements)
152  inline void reset() {
153  n_points_ = 0;
154  n_elems_ = 0;
155  i_elem_ = 0;
156  }
157 
158  /// Getter for dim_
159  inline uint dim() const {
160  return dim_;
161  }
162 
163  /// Getter for n_rows_
164  inline uint n_rows() const {
165  return n_rows_;
166  }
167 
168  /// Getter for n_elems_
169  inline uint n_elems() const {
170  return n_elems_;
171  }
172 
173  /// Getter for n_points_
174  inline uint n_points() const {
175  return n_points_;
176  }
177 
178  /// Getter for quadrature
180  return quad_;
181  }
182 
183  /// Resize data tables. Method is called before reinit of patch.
185  n_elems_ = n_elems;
188  for (uint i=0; i<int_table_.rows(); ++i) {
189  int_table_(i) = ArenaVec<uint>(sizes[ int_sizes_[i] ], *patch_arena_);
190  }
191  for (auto &elOp : operations_)
192  if (elOp.size_type() != fixedSizeOp) {
193  elOp.allocate_result(sizes[elOp.size_type()], *patch_arena_);
194  }
195  for (uint i=0; i<point_vals_.rows(); ++i) {
196  if (row_sizes_[i] == elemOp) {
197  point_vals_(i).resize(n_elems);
198  point_vals_(i).setZero(n_elems,1);
199  } else if (row_sizes_[i] == pointOp) {
200  point_vals_(i).resize(n_points);
201  point_vals_(i).setZero(n_points,1);
202  }
203  }
204  }
205 
206  /**
207  * Register element, add to point_vals_ table
208  *
209  * @param coords Coordinates of element nodes.
210  * @param element_patch_idx Index of element on patch.
211  */
212  uint register_element(arma::mat coords, uint element_patch_idx) {
214  uint res_column = op.result_row();
215  auto &coords_mat = op.result_matrix();
216  std::size_t i_elem = i_elem_;
217  for (uint i_col=0; i_col<coords.n_cols; ++i_col)
218  for (uint i_row=0; i_row<coords.n_rows; ++i_row) {
219  point_vals_(res_column)(i_elem_) = coords(i_row, i_col);
220  coords_mat(i_row, i_col)(i_elem) = coords(i_row, i_col);
221  ++res_column;
222  }
223 
224  elements_map_[element_patch_idx] = i_elem_;
225  return i_elem_++;
226  }
227 
228  /**
229  * Register side, add to point_vals_ table
230  *
231  * @param coords Coordinates of element nodes.
232  * @param side_coords Coordinates of side nodes.
233  * @param side_idx Index of side on element.
234  */
235  uint register_side(arma::mat elm_coords, arma::mat side_coords, uint side_idx) {
236  {
238  uint res_column = op.result_row();
239  auto &coords_mat = op.result_matrix();
240  std::size_t i_elem = i_elem_;
241  for (uint i_col=0; i_col<elm_coords.n_cols; ++i_col)
242  for (uint i_row=0; i_row<elm_coords.n_rows; ++i_row) {
243  point_vals_(res_column)(i_elem_) = elm_coords(i_row, i_col);
244  coords_mat(i_row, i_col)(i_elem) = elm_coords(i_row, i_col);
245  ++res_column;
246  }
247  }
248 
249  {
251  uint res_column = op.result_row();
252  auto &coords_mat = op.result_matrix();
253  std::size_t i_elem = i_elem_;
254  for (uint i_col=0; i_col<side_coords.n_cols; ++i_col)
255  for (uint i_row=0; i_row<side_coords.n_rows; ++i_row) {
256  point_vals_(res_column)(i_elem_) = side_coords(i_row, i_col);
257  coords_mat(i_row, i_col)(i_elem) = side_coords(i_row, i_col);
258  ++res_column;
259  }
260  }
261 
262  int_table_(3)(i_elem_) = side_idx;
263 
264  return i_elem_++;
265  }
266 
267  /**
268  * Register bulk point, add to int_table_
269  *
270  * @param elem_table_row Index of element in temporary element table.
271  * @param value_patch_idx Index of point in ElementCacheMap.
272  * @param elem_idx Index of element in Mesh.
273  * @param i_point_on_elem Index of point on element
274  */
275  uint register_bulk_point(uint elem_table_row, uint value_patch_idx, uint elem_idx, uint i_point_on_elem) {
276  uint point_pos = i_point_on_elem * n_elems_ + elem_table_row; // index of bulk point on patch
277  int_table_(0)(point_pos) = value_patch_idx;
278  int_table_(1)(point_pos) = elem_table_row;
279  int_table_(2)(point_pos) = elem_idx;
280 
281  points_map_[value_patch_idx] = point_pos;
282  return point_pos;
283  }
284 
285  /**
286  * Register side point, add to int_table_
287  *
288  * @param elem_table_row Index of side in temporary element table.
289  * @param value_patch_idx Index of point in ElementCacheMap.
290  * @param elem_idx Index of element in Mesh.
291  * @param side_idx Index of side on element.
292  * @param i_point_on_side Index of point on side
293  */
294  uint register_side_point(uint elem_table_row, uint value_patch_idx, uint elem_idx, uint side_idx, uint i_point_on_side) {
295  uint point_pos = i_point_on_side * n_elems_ + elem_table_row; // index of side point on patch
296  int_table_(0)(point_pos) = value_patch_idx;
297  int_table_(1)(point_pos) = elem_table_row;
298  int_table_(2)(point_pos) = elem_idx;
299  int_table_(4)(point_pos) = side_idx;
300 
301  points_map_[value_patch_idx] = point_pos;
302  return point_pos;
303  }
304 
305  /**
306  * Adds accessor of new operation to operations_ vector
307  *
308  * @param shape Shape of function output
309  * @param reinit_f Reinitialize function
310  * @param input_ops_vec Indices of input operations in operations_ vector.
311  * @param size_type Type of operation by size of rows
312  */
313  ElOp<spacedim> &make_new_op(std::initializer_list<uint> shape, ReinitFunction reinit_f, std::vector<uint> input_ops_vec, OpSizeType size_type = pointOp) {
314  ElOp<spacedim> op_accessor(this->dim_, shape, this->n_rows_, reinit_f, size_type, input_ops_vec);
315  this->n_rows_ += op_accessor.n_comp();
316  row_sizes_.insert(row_sizes_.end(), op_accessor.n_comp(), size_type);
317  operations_.push_back(op_accessor);
318  return operations_[operations_.size()-1];
319  }
320 
321  /**
322  * Adds accessor of new operation with fixed data size (ref data) to operations_ vector
323  *
324  * @param shape Shape of function output
325  * @param reinit_f Reinitialize function
326  */
327  ElOp<spacedim> &make_fixed_op(std::initializer_list<uint> shape, ReinitFunction reinit_f) {
328  return make_new_op(shape, reinit_f, {}, fixedSizeOp);
329  }
330 
331  /**
332  * Adds accessor of expansion operation to operations_ vector
333  *
334  * @param el_op Source operation of expansion.
335  * @param shape Shape of function output
336  * @param reinit_f Reinitialize function
337  */
338  ElOp<spacedim> &make_expansion(ElOp<spacedim> &el_op, std::initializer_list<uint> shape, ReinitFunction reinit_f) {
339  ElOp<spacedim> op_accessor(this->dim_, shape, el_op.result_row(), reinit_f, OpSizeType::pointOp);
340  // shape passed from el_op throws:
341  // C++ exception with description "std::bad_alloc" thrown in the test body.
342  operations_.push_back(op_accessor);
343  return operations_[operations_.size()-1];
344  }
345 
346  /**
347  * Adds accessor of FE operation and adds operation dynamically to operations_ vector
348  *
349  * @param shape Shape of function output
350  * @param reinit_f Reinitialize function
351  * @param input_ops_vec Indices of input operations in operations_ vector.
352  * @param n_dofs Number of DOFs
353  * @param size_type Type of operation by size of rows
354  */
355  ElOp<spacedim> &make_fe_op(std::initializer_list<uint> shape, ReinitFunction reinit_f, std::vector<uint> input_ops_vec, uint n_dofs,
356  OpSizeType size_type = pointOp) {
357  ElOp<spacedim> op_accessor(this->dim_, shape, this->n_rows_, reinit_f, size_type, input_ops_vec, n_dofs);
358  this->n_rows_ += op_accessor.n_comp() * n_dofs;
359  row_sizes_.insert(row_sizes_.end(), op_accessor.n_comp() * n_dofs, size_type);
360  operations_.push_back(op_accessor);
361  return operations_[operations_.size()-1];
362  }
363 
364 
365  /**
366  * Reinitializes patch data.
367  *
368  * Calls reinit functions defined on each operations.
369  */
370  void reinit_patch() {
371  if (n_elems_ == 0) return; // skip if tables are empty
372  for (uint i=0; i<operations_.size(); ++i)
373  operations_[i].reinit_function(operations_, int_table_);
374  }
375 
376  /**
377  * Returns scalar output value.
378  *
379  * @param op_idx Index of operation in operations vector
380  * @param point_idx Index of quadrature point in ElementCacheMap
381  * @param i_dof Index of DOF
382  */
383  inline Scalar scalar_value(uint op_idx, uint point_idx, uint i_dof=0) const {
384  return operations_[op_idx].result_matrix()(0)(points_map_[point_idx] + i_dof*n_points_);
385  }
386 
387  /**
388  * Returns vector output value.
389  *
390  * @param op_idx Index of operation in operations vector
391  * @param point_idx Index of quadrature point in ElementCacheMap
392  * @param i_dof Index of DOF
393  */
394  inline Vector vector_value(uint op_idx, uint point_idx, uint i_dof=0) const {
395  Vector val;
396  const auto &op_matrix = operations_[op_idx].result_matrix();
397  uint op_matrix_idx = points_map_[point_idx] + i_dof*n_points_;
398  for (uint i=0; i<3; ++i)
399  val(i) = op_matrix(i)(op_matrix_idx);
400  return val;
401  }
402 
403  /**
404  * Returns tensor output value.
405  *
406  * @param op_idx Index of operation in operations vector
407  * @param point_idx Index of quadrature point in ElementCacheMap
408  * @param i_dof Index of DOF
409  */
410  inline Tensor tensor_value(uint op_idx, uint point_idx, uint i_dof=0) const {
411  Tensor val;
412  const auto &op_matrix = operations_[op_idx].result_matrix();
413  uint op_matrix_idx = points_map_[point_idx] + i_dof*n_points_;
414  for (uint i=0; i<3; ++i)
415  for (uint j=0; j<3; ++j)
416  val(i,j) = op_matrix(i,j)(op_matrix_idx);
417  return val;
418  }
419 
420  /**
421  * Performs output of data tables to stream.
422  *
423  * Development method.
424  * @param points Allows switched off output of point table,
425  * @param ints Allows switched off output of int (connectivity to elements) table,
426  */
427  void print_data_tables(ostream& stream, bool points, bool ints) const {
428  if (points) {
429  stream << "Point vals: " << point_vals_.rows() << " - " << point_vals_.cols() << std::endl;
430  for (auto &op : operations_) {
431  const auto &mat = op.result_matrix();
432  for (uint i_mat=0; i_mat<mat.rows()*mat.cols(); ++i_mat) {
433  if (mat(i_mat).data_size()==0) stream << "<empty>";
434  else {
435  const double *vals = mat(i_mat).data_ptr();
436  for (size_t i_val=0; i_val<mat(i_mat).data_size(); ++i_val)
437  stream << vals[i_val] << " ";
438  }
439  stream << std::endl;
440  }
441  }
442  stream << std::endl;
443  }
444  if (ints) {
445  stream << "Int vals: " << int_table_.rows() << " - " << int_table_.cols() << std::endl;
446  for (uint i_row=0; i_row<int_table_.rows(); ++i_row) {
447  if (int_table_(i_row).data_size()==0) stream << "<empty>";
448  else {
449  const uint *vals = int_table_(i_row).data_ptr();
450  for (size_t i_val=0; i_val<int_table_(i_row).data_size(); ++i_val)
451  stream << vals[i_val] << " ";
452  }
453  stream << std::endl;
454  }
455  stream << std::endl;
456  }
457  }
458 
459  /**
460  * Performs table of fixed operations to stream.
461  *
462  * Development method.
463  * @param bulk_side Needs set 0 (bulk) or 1 (side) for correct output of operation names.
464  */
465  void print_operations(ostream& stream, uint bulk_side) const {
467  {
468  { "el_coords", "jacobian", "inv_jac", "jac_det", "pt_coords", "weights", "JxW", "", "", "", "", "" },
469  { "el_coords", "el_jac", "el_inv_jac", "side_coords", "side_jac", "side_jac_det", "exp_el_coords", "exp_el_jac", "exp_el_inv_jac",
470  "exp_side_coords", "exp_side_jac", "exp_side_jac_det", "pt_coords", "weights", "JxW", "normal_vec", "", "", "", "", "" }
471  };
472  stream << std::setfill(' ') << " Operation" << setw(12) << "" << "Shape" << setw(2) << ""
473  << "Result row" << setw(2) << "" << "n DOFs" << setw(2) << "" << "Input operations" << endl;
474  for (uint i=0; i<operations_.size(); ++i) {
475  stream << " " << std::left << setw(20) << op_names[bulk_side][i] << "" << " " << setw(6) << operations_[i].format_shape() << "" << " "
476  << setw(11) << operations_[i].result_row() << "" << " " << setw(7) << operations_[i].n_dofs() << "" << " ";
477  auto &input_ops = operations_[i].input_ops();
478  for (auto i_o : input_ops) stream << op_names[bulk_side][i_o] << " ";
479  stream << std::endl;
480  }
481  }
482 
483 protected:
484  /**
485  * Store data of bulk or side quadrature points of one dimension
486  *
487  * Number of columns is given by n_rows_, number of used rows by n_points_.
488  */
490  /**
491  * Hold integer values of quadrature points of defined operations.
492  *
493  * Table contains following rows:
494  * 0: Index of quadrature point on patch
495  * 1: Row of element/side in point_vals_ table in registration step (before expansion)
496  * 2: Element idx in Mesh
497  * - last two rows are allocated only for side point table
498  * 3: Index of side in element - short vector, size of column = number of sides
499  * 4: Index of side in element - long vector, size of column = number of points
500  * Number of used rows is given by n_points_.
501  */
503 
504  /// Set size and type of rows of int_table_, value is set implicitly in constructor of descendants
506 
507 
508  /// Vector of all defined operations
510 
511  uint dim_; ///< Dimension
512  uint n_rows_; ///< Number of columns of \p point_vals table
513  uint n_points_; ///< Number of points in patch
514  uint n_elems_; ///< Number of elements in patch
515  uint i_elem_; ///< Index of registered element in table, helper value used during patch creating.
516  Quadrature *quad_; ///< Quadrature of given dimension and order passed in constructor.
517 
518  std::vector<uint> elements_map_; ///< Map of element patch indices to el_vals_ table
519  std::vector<uint> points_map_; ///< Map of point patch indices to point_vals_ and int_table_ tables
520  std::vector<OpSizeType> row_sizes_; ///< hold sizes of rows by type of operation
521  AssemblyArena &asm_arena_; ///< Reference to global assembly arena of PatchFeValues
522  PatchArena *patch_arena_; ///< Pointer to global patch arena of PatchFeValues
523 
524  friend class PatchFEValues<spacedim>;
525  friend class ElOp<spacedim>;
526  template<unsigned int dim>
527  friend class BulkValues;
528  template<unsigned int dim>
529  friend class SideValues;
530  template<unsigned int dim>
531  friend class JoinValues;
532 };
533 
534 /**
535  * @brief Class represents element or FE operations.
536  */
537 template<unsigned int spacedim = 3>
538 class ElOp {
539 public:
540  /**
541  * Constructor
542  *
543  * Set all data members.
544  */
547  {}
548 
549  /// Aligns shape_vec to 2 items (equal to matrix number of dimensions)
550  std::vector<uint> set_shape_vec(std::initializer_list<uint> shape) const {
551  std::vector<uint> shape_vec(shape);
552  if (shape_vec.size() == 1) shape_vec.push_back(1);
553  ASSERT_EQ(shape_vec.size(), 2);
554  return shape_vec;
555  }
556 
557  /**
558  * Return number of operation components
559  *
560  * Value is computed from shape_ vector
561  */
562  inline uint n_comp() const {
563  return shape_[0] * shape_[1];
564  }
565 
566  /// Getter for dimension
567  inline uint dim() const {
568  return dim_;
569  }
570 
571  /// Getter for result_row_
572  inline uint result_row() const {
573  return result_row_;
574  }
575 
576  /// Getter for size_type_
578  return size_type_;
579  }
580 
581  /// Getter for n_dofs_
582  inline uint n_dofs() const {
583  return n_dofs_;
584  }
585 
586  /// Getter for input_ops_
587  inline const std::vector<uint> &input_ops() const {
588  return input_ops_;
589  }
590 
591  /// Getter for shape_
592  inline const std::vector<uint> &shape() const {
593  return shape_;
594  }
595 
596  /**
597  * Format shape to string
598  *
599  * Method is used in output development method.
600  */
601  inline std::string format_shape() const {
602  stringstream ss;
603  ss << shape_[0] << "x" << shape_[1];
604  return ss.str();
605  }
606 
607  /// Call reinit function on element table if function is defined
608  inline void reinit_function(std::vector<ElOp<spacedim>> &operations, IntTableArena &int_table) {
609  reinit_func(operations, int_table);
610  }
611 
612  inline void allocate_result(size_t data_size, PatchArena &arena) {
613  result_ = Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic>(shape_[0], shape_[1]);
614  for (uint i=0; i<n_comp(); ++i)
615  result_(i) = ArenaVec<double>(data_size, arena);
616  }
617 
618  /// Return map referenced result as Eigen::Matrix
619  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> &result_matrix() {
620  return result_;
621  }
622 // Eigen::Map<Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic>> result_matrix() {
623 // return Eigen::Map<Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic>>(result_.data(), shape_[0], shape_[1]);
624 // }
625 
626  /// Same as previous but return const reference
627  const Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> &result_matrix() const {
628  return result_;
629  }
630 // const Eigen::Map<Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic>> result_matrix() const {
631 // return Eigen::Map<Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic>>(result_.data(), shape_[0], shape_[1]);
632 // }
633 
634  /// Return map referenced Eigen::Matrix of given dimension
635  template<unsigned int dim1, unsigned int dim2>
636  Eigen::Map<Eigen::Matrix<ArrayDbl, dim1, dim2>> value(TableDbl &op_results, uint i_dof = 0) const {
637  return Eigen::Map<Eigen::Matrix<ArrayDbl, dim1, dim2>>(op_results.data() + result_row_ + i_dof * n_comp(), dim1, dim2);
638  }
639 
640  /// Return map referenced Eigen::Matrix of given dimensions
641  Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>> matrix_value(TableDbl &op_results, uint dim1, uint dim2) const {
642  return Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>>(op_results(result_row_).data(), dim1, dim2);
643  }
644 
645  /// Return map referenced Eigen::Matrix of given dimensions
646  Eigen::Map<Eigen::Vector<double, Eigen::Dynamic>> vector_value(TableDbl &op_results) const {
647  return Eigen::Map<Eigen::Vector<double, Eigen::Dynamic>>(op_results(result_row_).data(), op_results(result_row_).rows());
648  }
649 
650 
651 protected:
652  uint dim_; ///< Dimension
653  std::vector<uint> shape_; ///< Shape of stored data (size of vector or number of rows and cols of matrix)
654  uint result_row_; ///< First row to scalar, vector or matrix result TODO replace
655  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> result_;
656  ///< Result matrix of operation
657  OpSizeType size_type_; ///< Type of operation by size of vector (element, point or fixed size)
658  std::vector<uint> input_ops_; ///< Indices of operations in PatchPointValues::operations_ vector on which ElOp is depended
659  uint n_dofs_; ///< Number of DOFs of FE operations (or 1 in case of element operations)
660 
661  ReinitFunction reinit_func; ///< Pointer to patch reinit function of element data table specialized by operation
662 };
663 
664 
665 /// Defines common functionality of reinit operations.
667  // empty base operation
668  static inline void op_base(FMT_UNUSED std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
669  // empty
670  }
671 
672  // expansion operation
673 // static inline void expand_data(ElOp<3> &op, TableDbl &op_results, TableInt &el_table) {
674 // uint row_begin = op.result_row();
675 // uint row_end = row_begin + op.n_comp();
676 // uint size = op_results(row_begin).rows();
677 // for (int i_pt=size-1; i_pt>=0; --i_pt) {
678 // uint el_table_idx = el_table(1)(i_pt);
679 // for (uint i_q=row_begin; i_q<row_end; ++i_q)
680 // op_results(i_q)(i_pt) = op_results(i_q)(el_table_idx);
681 // }
682 // }
683 };
684 
685 /// Defines reinit operations on bulk points.
686 struct bulk_reinit {
687  // element operations
688  template<unsigned int dim>
689  static inline void elop_jac(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
690  // result matrix(spacedim, dim), input matrix(spacedim, dim+1)
691  auto &op = operations[FeBulk::BulkOps::opJac];
692  auto &jac_value = op.result_matrix();
693  const auto &coords_value = operations[ op.input_ops()[0] ].result_matrix();
694  for (unsigned int i=0; i<3; i++)
695  for (unsigned int j=0; j<dim; j++)
696  jac_value(i,j) = coords_value(i,j+1) - coords_value(i,0);
697  }
698  template<unsigned int dim>
699  static inline void elop_inv_jac(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
700  // result matrix(spacedim, dim), input matrix(spacedim, dim+1)
701  auto &op = operations[FeBulk::BulkOps::opInvJac];
702  auto &inv_jac_value = op.result_matrix();
703  const auto &jac_value = operations[ op.input_ops()[0] ].result_matrix();
704  inv_jac_value = eigen_arena_tools::inverse<3, dim>(jac_value);
705  }
706  template<unsigned int dim>
707  static inline void elop_jac_det(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
708  // result double, input matrix(spacedim, dim)
709  auto &op = operations[FeBulk::BulkOps::opJacDet];
710  auto &jac_det_value = op.result_matrix();
711  const auto &jac_value = operations[ op.input_ops()[0] ].result_matrix();
712  jac_det_value(0,0) = eigen_arena_tools::determinant<3, dim>(jac_value).abs();
713  }
714 
715  // point operations
716  static inline void ptop_coords(FMT_UNUSED std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
717  // Implement
718  }
719  static inline void ptop_weights(std::vector<ElOp<3>> &operations, PatchArena *arena, const std::vector<double> &point_weights) {
720  auto &op = operations[FeBulk::BulkOps::opWeights];
721  op.allocate_result(point_weights.size(), *arena);
722  auto &weights_value = op.result_matrix();
723  for (uint i=0; i<point_weights.size(); ++i)
724  weights_value(0,0)(i) = point_weights[i];
725  }
726  static inline void ptop_JxW(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
727  auto &op = operations[FeBulk::BulkOps::opJxW];
728  auto &weights_value = operations[ op.input_ops()[0] ].result_matrix();
729  auto &jac_det_value = operations[ op.input_ops()[1] ].result_matrix();
730  ArenaOVec<double> weights_ovec( weights_value(0,0), weights_value(0,0).data_size() );
731  ArenaOVec<double> jac_det_ovec( jac_det_value(0,0), jac_det_value(0,0).data_size() );
732  ArenaOVec<double> jxw_ovec = jac_det_ovec * weights_ovec;
733  auto &jxw_value = op.result_matrix();
734  jxw_value(0,0) = jxw_ovec.get_vec();
735  }
736  static inline void ptop_scalar_shape(std::vector<ElOp<3>> &operations,
737  std::vector< std::vector<double> > shape_values, uint scalar_shape_op_idx) {
738  auto &op = operations[scalar_shape_op_idx];
739  uint n_dofs = shape_values.size();
740  uint n_points = shape_values[0].size();
741  uint n_elem = op.result_matrix()(0).data_size() / n_points;
742 
743  auto &shape_matrix = op.result_matrix();
744  ArenaVec<double> ref_vec(n_points * n_dofs, op.result_matrix()(0).arena());
745  ArenaVec<double> elem_vec(n_elem, op.result_matrix()(0).arena());
746  for (uint i=0; i<n_elem; ++i) {
747  elem_vec(i) = 1.0;
748  }
749  ArenaOVec<double> ref_ovec(ref_vec, ref_vec.data_size());
750  ArenaOVec<double> elem_ovec(elem_vec, elem_vec.data_size());
751  for (uint i_dof=0; i_dof<n_dofs; ++i_dof)
752  for (uint i_p=0; i_p<n_points; ++i_p)
753  ref_vec(i_dof * n_points + i_p) = shape_values[i_dof][i_p];
754  ArenaOVec<double> shape_ovec = elem_ovec * ref_ovec;
755  shape_matrix(0) = shape_ovec.get_vec();
756  }
757  template<unsigned int dim>
758  static inline void ptop_scalar_shape_grads(std::vector<ElOp<3>> &operations,
759  std::vector< std::vector<arma::mat> > ref_shape_grads, uint scalar_shape_grads_op_idx) {
760  auto &op = operations[scalar_shape_grads_op_idx];
761  auto &inv_jac_vec = operations[ op.input_ops()[0] ].result_matrix();
762  uint n_points = ref_shape_grads.size();
763  uint n_dofs = ref_shape_grads[0].size();
764 
765  Eigen::Matrix<ArenaVec<double>, dim, 1> ref_grads_vec;
766  Eigen::Matrix<ArenaOVec<double>, dim, 1> ref_grads_ovec;
767  for (uint i=0; i<ref_grads_vec.rows(); ++i) {
768  ref_grads_vec(i) = ArenaVec<double>(n_points * n_dofs, op.result_matrix()(0).arena());
769  for (uint i_dof=0; i_dof<n_dofs; ++i_dof)
770  for (uint i_p=0; i_p<n_points; ++i_p)
771  ref_grads_vec(i)(i_dof * n_points + i_p) = ref_shape_grads[i_dof][i_p](i);
772  ref_grads_ovec(i) = ArenaOVec(ref_grads_vec(i), ref_grads_vec(i).data_size());
773  }
774 
775  Eigen::Matrix<ArenaOVec<double>, dim, 3> inv_jac_ovec;
776  for (uint i=0; i<dim*3; ++i) {
777  inv_jac_ovec(i) = ArenaOVec(inv_jac_vec(i), inv_jac_vec(i).data_size());
778  }
779 
780  auto &result_vec = op.result_matrix();
781  Eigen::Matrix<ArenaOVec<double>, 3, 1> result_ovec = inv_jac_ovec.transpose() * ref_grads_ovec;
782  for (uint i=0; i<3; ++i) {
783  result_vec(i) = result_ovec(i).get_vec();
784  }
785  }
786 };
787 
788 
789 
790 /// Defines reinit operations on side points.
791 struct side_reinit {
792  // element operations
793  template<unsigned int dim>
794  static inline void elop_el_jac(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
795  // result matrix(spacedim, dim), input matrix(spacedim, dim+1)
796  auto &op = operations[FeSide::SideOps::opElJac];
797  auto &jac_value = op.result_matrix();
798  const auto &coords_value = operations[ op.input_ops()[0] ].result_matrix();
799  for (unsigned int i=0; i<3; i++)
800  for (unsigned int j=0; j<dim; j++)
801  jac_value(i,j) = coords_value(i,j+1) - coords_value(i,0);
802  }
803  template<unsigned int dim>
804  static inline void elop_el_inv_jac(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
805  auto &op = operations[FeSide::SideOps::opElInvJac];
806  auto &inv_jac_value = op.result_matrix();
807  const auto &jac_value = operations[ op.input_ops()[0] ].result_matrix();
808  inv_jac_value = eigen_arena_tools::inverse<3, dim>(jac_value);
809  }
810  template<unsigned int dim>
811  static inline void elop_sd_jac(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
812  // result matrix(spacedim, dim), input matrix(spacedim, dim+1)
813  auto &op = operations[FeSide::SideOps::opSideJac];
814  auto &jac_value = op.result_matrix();
815  const auto &coords_value = operations[ op.input_ops()[0] ].result_matrix();
816  for (unsigned int i=0; i<3; i++)
817  for (unsigned int j=0; j<dim-1; j++)
818  jac_value(i,j) = coords_value(i,j+1) - coords_value(i,0);
819  }
820  template<unsigned int dim>
821  static inline void elop_sd_jac_det(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
822  // result double, input matrix(spacedim, dim)
823  auto &op = operations[FeSide::SideOps::opSideJacDet];
824  auto &jac_det_value = op.result_matrix();
825  const auto &jac_value = operations[ op.input_ops()[0] ].result_matrix();
826  jac_det_value(0,0) = eigen_arena_tools::determinant<3, dim-1>(jac_value).abs();
827  }
828 
829  // expansion operations
830 // static inline void expd_el_coords(std::vector<ElOp<3>> &operations, TableDbl &op_results, TableInt &el_table) {
831 // auto &op = operations[FeSide::SideOps::opExpansionElCoords];
832 // common_reinit::expand_data(op, op_results, el_table);
833 // }
834 // static inline void expd_el_jac(std::vector<ElOp<3>> &operations, TableDbl &op_results, TableInt &el_table) {
835 // auto &op = operations[FeSide::SideOps::opExpansionElJac];
836 // common_reinit::expand_data(op, op_results, el_table);
837 // }
838 // static inline void expd_el_inv_jac(std::vector<ElOp<3>> &operations, TableDbl &op_results, TableInt &el_table) {
839 // auto &op = operations[FeSide::SideOps::opExpansionElInvJac];
840 // common_reinit::expand_data(op, op_results, el_table);
841 // }
842 //
843 // static inline void expd_sd_coords(std::vector<ElOp<3>> &operations, TableDbl &op_results, TableInt &el_table) {
844 // auto &op = operations[FeSide::SideOps::opExpansionSideCoords];
845 // common_reinit::expand_data(op, op_results, el_table);
846 // }
847 // template<unsigned int dim>
848 // static inline void expd_sd_jac(std::vector<ElOp<3>> &operations, TableDbl &op_results, TableInt &el_table) {
849 // auto &op = operations[FeSide::SideOps::opExpansionSideJac];
850 // common_reinit::expand_data(op, op_results, el_table);
851 // }
852 // static inline void expd_sd_jac_det(std::vector<ElOp<3>> &operations, TableDbl &op_results, TableInt &el_table) {
853 // auto &op = operations[FeSide::SideOps::opExpansionSideJacDet];
854 // common_reinit::expand_data(op, op_results, el_table);
855 // }
856 
857  // Point operations
858  static inline void ptop_coords(FMT_UNUSED std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
859  // Implement
860  }
861  static inline void ptop_weights(std::vector<ElOp<3>> &operations, PatchArena *arena, const std::vector<double> &point_weights) {
862  auto &op = operations[FeSide::SideOps::opWeights];
863  op.allocate_result(point_weights.size(), *arena);
864  auto &weights_value = op.result_matrix();
865  for (uint i=0; i<point_weights.size(); ++i)
866  weights_value(0,0)(i) = point_weights[i];
867  }
868  static inline void ptop_JxW(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
869  auto &op = operations[FeSide::SideOps::opJxW];
870  auto &weights_value = operations[ op.input_ops()[0] ].result_matrix();
871  auto &jac_det_value = operations[ op.input_ops()[1] ].result_matrix();
872  ArenaOVec<double> weights_ovec( weights_value(0,0), weights_value(0,0).data_size() );
873  ArenaOVec<double> jac_det_ovec( jac_det_value(0,0), jac_det_value(0,0).data_size() );
874  ArenaOVec<double> jxw_ovec = jac_det_ovec * weights_ovec;
875  auto &jxw_value = op.result_matrix();
876  jxw_value(0,0) = jxw_ovec.get_vec();
877  }
878  template<unsigned int dim>
879  static inline void ptop_normal_vec(FMT_UNUSED std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
880 // auto &op = operations[FeSide::SideOps::opNormalVec];
881 // auto normal_value = op.value<3, 1>(op_results);
882 // auto inv_jac_mat_value = operations[ op.input_ops()[0] ].value<dim, 3>(op_results);
883 // normal_value = inv_jac_mat_value.transpose() * RefElement<dim>::normal_vector_array( el_table(3) );
884 //
885 // ArrayDbl norm_vec;
886 // norm_vec.resize(normal_value(0).rows());
887 // Eigen::VectorXd A(3);
888 //
889 // for (uint i=0; i<normal_value(0).rows(); ++i) {
890 // A(0) = normal_value(0)(i);
891 // A(1) = normal_value(1)(i);
892 // A(2) = normal_value(2)(i);
893 // norm_vec(i) = A.norm();
894 // }
895 // for (uint i=0; i<3; ++i) {
896 // normal_value(i) /= norm_vec;
897 // }
898  }
899  static inline void ptop_scalar_shape(FMT_UNUSED std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table,
900  FMT_UNUSED std::vector< std::vector< std::vector<double> > > shape_values, FMT_UNUSED uint scalar_shape_op_idx) {
901 // auto &op = operations[scalar_shape_op_idx];
902 // uint n_points = shape_values[0].size();
903 //
904 // for (uint i_row=0; i_row<shape_values[0][0].size(); ++i_row) {
905 // ArrayDbl &result_row = op_results( op.result_row()+i_row );
906 // for (uint i_pt=0; i_pt<result_row.rows(); ++i_pt)
907 // result_row(i_pt) = shape_values[el_table(3)(i_pt)][i_pt % n_points][i_row];
908 // }
909  }
910  template<unsigned int dim>
911  static inline void ptop_scalar_shape_grads(FMT_UNUSED std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table,
912  FMT_UNUSED std::vector< std::vector< std::vector<arma::mat> > > ref_shape_grads, FMT_UNUSED uint scalar_shape_grads_op_idx) {
913 // auto &op = operations[scalar_shape_grads_op_idx];
914 // uint n_points = ref_shape_grads[0].size();
915 // uint n_dofs = ref_shape_grads[0][0].size();
916 //
917 // Eigen::Vector<ArrayDbl, Eigen::Dynamic> ref_shape_grads_expd;
918 // ref_shape_grads_expd.resize(dim*n_dofs);
919 // for (uint i=0; i<ref_shape_grads_expd.rows(); ++i)
920 // ref_shape_grads_expd(i).resize(op_results(0).rows());
921 //
922 // for (uint i_dof=0; i_dof<n_dofs; ++i_dof)
923 // for (uint i_c=0; i_c<dim; ++i_c) {
924 // ArrayDbl &shape_grad_row = ref_shape_grads_expd(i_dof*dim+i_c);
925 // for (uint i_pt=0; i_pt<shape_grad_row.rows(); ++i_pt)
926 // shape_grad_row(i_pt) = ref_shape_grads[el_table(3)(i_pt)][i_pt % n_points][i_dof][i_c];
927 // }
928 //
929 // auto inv_jac_value = operations[ op.input_ops()[0] ].value<dim, 3>(op_results);
930 // for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
931 // auto shape_grad_value = op.value<3, 1>(op_results, i_dof);
932 // Eigen::Map<Eigen::Matrix<ArrayDbl, dim, 1>> ref_shape_grads_dof_value(ref_shape_grads_expd.data() + dim*i_dof, dim, 1);
933 // shape_grad_value = inv_jac_value.transpose() * ref_shape_grads_dof_value;
934 // }
935  }
936 };
937 
938 
939 // template specialization
940 template<>
941 inline void side_reinit::elop_sd_jac<1>(FMT_UNUSED std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
942 }
943 
944 template<>
945 inline void side_reinit::elop_sd_jac_det<1>(std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
946  auto &op = operations[FeSide::SideOps::opSideJacDet];
947  auto &result_vec = op.result_matrix();
948  for (uint i=0;i<result_vec(0,0).data_size(); ++i) {
949  result_vec(0,0)(i) = 1.0;
950  }
951 }
952 
953 //template<>
954 //inline void side_reinit::expd_sd_jac<1>(FMT_UNUSED std::vector<ElOp<3>> &operations, FMT_UNUSED TableDbl &op_results, FMT_UNUSED TableInt &el_table) {
955 //}
956 
957 
958 
959 namespace FeBulk {
960 
961  /// Bulk data specialization, order of item in operations_ vector corresponds to the BulkOps enum
962  template<unsigned int spacedim = 3>
963  class PatchPointValues : public ::PatchPointValues<spacedim> {
964  public:
965  /// Constructor
966  PatchPointValues(uint dim, uint quad_order, AssemblyArena &asm_arena)
967  : ::PatchPointValues<spacedim>(dim, asm_arena) {
968  this->quad_ = new QGauss(dim, 2*quad_order);
969  this->int_sizes_ = {pointOp, pointOp, pointOp};
970  switch (dim) {
971  case 1:
972  init<1>();
973  break;
974  case 2:
975  init<2>();
976  break;
977  case 3:
978  init<3>();
979  break;
980  }
981  }
982 
983  private:
984  /// Initialize operations vector
985  template<unsigned int dim>
986  void init() {
987  // First step: adds element values operations
988  /*auto &el_coords =*/ this->make_new_op( {spacedim, this->dim_+1}, &common_reinit::op_base, {}, OpSizeType::elemOp );
989 
990  /*auto &el_jac =*/ this->make_new_op( {spacedim, this->dim_}, &bulk_reinit::elop_jac<dim>, {BulkOps::opElCoords}, OpSizeType::elemOp );
991 
992  /*auto &el_inv_jac =*/ this->make_new_op( {this->dim_, spacedim}, &bulk_reinit::elop_inv_jac<dim>, {BulkOps::opJac}, OpSizeType::elemOp );
993 
994  /*auto &el_jac_det =*/ this->make_new_op( {1}, &bulk_reinit::elop_jac_det<dim>, {BulkOps::opJac}, OpSizeType::elemOp );
995 
996  // Second step: adds point values operations
997  /*auto &pt_coords =*/ this->make_new_op( {spacedim}, &bulk_reinit::ptop_coords, {} );
998 
999  // use lambda reinit function
1000  const std::vector<double> &point_weights_vec = this->quad_->get_weights();
1001  auto lambda_weights = [this, point_weights_vec](std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
1002  bulk_reinit::ptop_weights(operations, this->patch_arena_, point_weights_vec);
1003  };
1004  /*auto &weights =*/ this->make_fixed_op( {1}, lambda_weights );
1005 
1006  /*auto &JxW =*/ this->make_new_op( {1}, &bulk_reinit::ptop_JxW, {BulkOps::opWeights, BulkOps::opJacDet} );
1007  }
1008  };
1009 
1010 } // closing namespace FeBulk
1011 
1012 
1013 
1014 namespace FeSide {
1015 
1016 /// Bulk Side specialization, order of item in operations_ vector corresponds to the SideOps enum
1017  template<unsigned int spacedim = 3>
1018  class PatchPointValues : public ::PatchPointValues<spacedim> {
1019  public:
1020  /// Constructor
1021  PatchPointValues(uint dim, uint quad_order, AssemblyArena &asm_arena)
1022  : ::PatchPointValues<spacedim>(dim, asm_arena) {
1023  this->quad_ = new QGauss(dim-1, 2*quad_order);
1024  this->int_sizes_ = {pointOp, pointOp, pointOp, elemOp, pointOp};
1025  switch (dim) {
1026  case 1:
1027  init<1>();
1028  break;
1029  case 2:
1030  init<2>();
1031  break;
1032  case 3:
1033  init<3>();
1034  break;
1035  }
1036  }
1037 
1038  private:
1039  /// Initialize operations vector
1040  template<unsigned int dim>
1041  void init() {
1042  // First step: adds element values operations
1043  /*auto &el_coords =*/ this->make_new_op( {spacedim, this->dim_+1}, &common_reinit::op_base, {}, OpSizeType::elemOp );
1044 
1045  /*auto &el_jac =*/ this->make_new_op( {spacedim, this->dim_}, &side_reinit::elop_el_jac<dim>, {SideOps::opElCoords}, OpSizeType::elemOp );
1046 
1047  /*auto &el_inv_jac =*/ this->make_new_op( {this->dim_, spacedim}, &side_reinit::elop_el_inv_jac<dim>, {SideOps::opElJac}, OpSizeType::elemOp );
1048 
1049  /*auto &sd_coords =*/ this->make_new_op( {spacedim, this->dim_}, &common_reinit::op_base, {}, OpSizeType::elemOp );
1050 
1051  /*auto &sd_jac =*/ this->make_new_op( {spacedim, this->dim_-1}, &side_reinit::elop_sd_jac<dim>, {SideOps::opSideCoords}, OpSizeType::elemOp );
1052 
1053  /*auto &sd_jac_det =*/ this->make_new_op( {1}, &side_reinit::elop_sd_jac_det<dim>, {SideOps::opSideJac}, OpSizeType::elemOp );
1054 
1055  // Second step: adds expand operations (element values to point values)
1056 // this->make_expansion( el_coords, {spacedim, this->dim_+1}, &side_reinit::expd_el_coords );
1057 //
1058 // this->make_expansion( el_jac, {spacedim, this->dim_}, &side_reinit::expd_el_jac );
1059 //
1060 // this->make_expansion( el_inv_jac, {this->dim_, spacedim}, &side_reinit::expd_el_inv_jac );
1061 //
1062 // this->make_expansion( sd_coords, {spacedim, this->dim_}, &side_reinit::expd_sd_coords );
1063 //
1064 // this->make_expansion( sd_jac, {spacedim, this->dim_-1}, &side_reinit::expd_sd_jac<dim> );
1065 //
1066 // this->make_expansion( sd_jac_det, {1}, &side_reinit::expd_sd_jac_det );
1067 
1068  // Third step: adds point values operations
1069  /*auto &coords =*/ this->make_new_op( {spacedim}, &side_reinit::ptop_coords, {} );
1070 
1071  // use lambda reinit function
1072  const std::vector<double> &point_weights_vec = this->quad_->get_weights();
1073  auto lambda_weights = [this, point_weights_vec](std::vector<ElOp<3>> &operations, FMT_UNUSED IntTableArena &el_table) {
1074  side_reinit::ptop_weights(operations, this->patch_arena_, point_weights_vec);
1075  };
1076  /*auto &weights =*/ this->make_fixed_op( {1}, lambda_weights );
1077 
1079 
1080  /*auto &normal_vec =*/ this->make_new_op( {spacedim}, &side_reinit::ptop_normal_vec<dim>, {SideOps::opElInvJac} );
1081  }
1082  };
1083 
1084 } // closing namespace FeSide
1085 
1086 
1087 
1088 #endif /* PATCH_POINT_VALUES_HH_ */
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:333
Outer product - only proposal of multi operator.
Definition: arena_vec.hh:237
ArenaVec< T > get_vec() const
Convert ArenaOVec to ArenaVec and its.
Definition: arena_vec.hh:274
size_t data_size() const
Getter for data_size_.
Definition: arena_vec.hh:104
Class represents element or FE operations.
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)
uint result_row() const
Getter for result_row_.
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)
uint result_row_
First row to scalar, vector or matrix result TODO replace.
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.
Eigen::Map< Eigen::Matrix< ArrayDbl, dim1, dim2 > > value(TableDbl &op_results, uint i_dof=0) const
Return map referenced Eigen::Matrix of given dimension.
Eigen::Map< Eigen::Vector< double, Eigen::Dynamic > > vector_value(TableDbl &op_results) const
Return map referenced Eigen::Matrix of given dimensions.
uint n_comp() const
ElOp(uint dim, std::initializer_list< uint > shape, uint result_row, ReinitFunction reinit_f, OpSizeType size_type, std::vector< uint > input_ops={}, uint n_dofs=1)
Eigen::Map< Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > > matrix_value(TableDbl &op_results, uint dim1, uint dim2) const
Return map referenced Eigen::Matrix of given dimensions.
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)
ElOp< spacedim > & make_expansion(ElOp< spacedim > &el_op, std::initializer_list< uint > shape, ReinitFunction reinit_f)
AssemblyArena & asm_arena_
Reference to global assembly arena of PatchFeValues.
std::vector< OpSizeType > row_sizes_
hold sizes of rows by type of operation
uint n_rows() const
Getter for n_rows_.
std::vector< uint > points_map_
Map of point patch indices to point_vals_ and int_table_ tables.
uint n_rows_
Number of columns of point_vals table.
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 el_vals_ table.
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
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
Eigen::Vector< ArrayDbl, Eigen::Dynamic > TableDbl
Definition: eigen_tools.hh:36
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
operation executed expansion to quadrature point (value of element / side > values on quadrature poin...
@ 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 ptop_normal_vec(FMT_UNUSED std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table)
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 ptop_scalar_shape_grads(FMT_UNUSED std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table, FMT_UNUSED std::vector< std::vector< std::vector< arma::mat > > > ref_shape_grads, FMT_UNUSED uint scalar_shape_grads_op_idx)
static void elop_sd_jac(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 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)
static void ptop_scalar_shape(FMT_UNUSED std::vector< ElOp< 3 >> &operations, FMT_UNUSED IntTableArena &el_table, FMT_UNUSED std::vector< std::vector< std::vector< double > > > shape_values, FMT_UNUSED uint scalar_shape_op_idx)