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