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