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