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