Flow123d  DF_patch_fe_mechanics-ccea6e4
patch_point_values.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file patch_point_values.hh
15  * @brief Store finite element data on the actual patch
16  * such as shape function values, gradients, Jacobian
17  * of the mapping from the reference cell etc.
18  * @author David Flanderka
19  */
20 
21 #ifndef PATCH_POINT_VALUES_HH_
22 #define PATCH_POINT_VALUES_HH_
23 
24 #include <Eigen/Dense>
25 
26 #include "fem/eigen_tools.hh"
27 #include "fem/dh_cell_accessor.hh"
28 #include "fem/element_values.hh"
30 #include "fem/arena_resource.hh"
31 #include "fem/arena_vec.hh"
32 
33 
34 template<unsigned int spacedim> class PatchFEValues;
35 template<unsigned int spacedim> class PatchOp;
36 template <class ValueType> class ElQ;
37 template <class ValueType> class FeQ;
38 template<unsigned int dim> class BulkValues;
39 template<unsigned int dim> class SideValues;
40 using Scalar = double;
43 
44 
45 
46 
47 /// Type for conciseness
48 using ReinitFunction = std::function<void(PatchOp<3> *, IntTableArena &)>;
49 
50 
51 namespace FeBulk {
52  /**
53  * Enumeration of element bulk operations
54  *
55  * Operations are stored in fix order. Order in enum is equal to order
56  * in PatchPointVale::operations_ vector. FE operations are added dynamically
57  * by request of user.
58  */
59  enum BulkOps
60  {
61  /// fixed operations (reference data filled once during initialization)
62  opWeights, ///< weight of quadrature point
63  opRefScalar, ///< Scalar reference
64  opRefVector, ///< Vector reference
65  opRefScalarGrad, ///< Gradient scalar reference
66  opRefVectorGrad, ///< Gradient vector reference
67  /// operations evaluated on elements
68  opElCoords, ///< coordinations of all nodes of element
69  opJac, ///< Jacobian of element
70  opInvJac, ///< inverse Jacobian
71  opJacDet, ///< determinant of Jacobian
72  /// operations evaluated on quadrature points
73  opCoords, ///< coordinations of quadrature point
74  opJxW, ///< JxW value of quadrature point
75  /// FE operations
76  opScalarShape, ///< Scalar shape operation
77  opVectorShape, ///< Vector shape operation
78  opGradScalarShape, ///< Scalar shape gradient
79  opGradVectorShape, ///< Vector shape gradient
80  opVectorSymGrad, ///< Vector symmetric gradient
81  opVectorDivergence, ///< Vector divergence
82  opNItems ///< Holds number of valid FE operations and value of invalid FE operation
83  };
84 }
85 
86 
87 namespace FeSide {
88  /**
89  * Enumeration of element side operations
90  *
91  * Operations are stored in fix order. Order in enum is equal to order
92  * in PatchPointVale::operations_ vector. FE operations are added dynamically
93  * by request of user.
94  */
95  enum SideOps
96  {
97  /// fixed operations (reference data filled once during initialization)
98  opWeights, ///< weight of quadrature point
99  opRefScalar, ///< Scalar reference
100  opRefVector, ///< Vector reference
101  opRefScalarGrad, ///< Gradient scalar reference
102  opRefVectorGrad, ///< Gradient vector reference
103  /// operations evaluated on elements
104  opElCoords, ///< coordinations of all nodes of element
105  opElJac, ///< Jacobian of element
106  opElInvJac, ///< inverse Jacobian of element
107  /// operations evaluated on sides
108  opSideCoords, ///< coordinations of all nodes of side
109  opSideJac, ///< Jacobian of element
110  opSideJacDet, ///< determinant of Jacobian of side
111  /// operations evaluated on quadrature points
112  opCoords, ///< coordinations of quadrature point
113  opJxW, ///< JxW value of quadrature point
114  opNormalVec, ///< normal vector of quadrature point
115  /// FE operations
116  opScalarShape, ///< Scalar shape operation
117  opVectorShape, ///< Vector shape operation
118  opGradScalarShape, ///< Scalar shape gradient
119  opGradVectorShape, ///< Vector shape gradient
120  opVectorSymGrad, ///< Vector symmetric gradient
121  opVectorDivergence, ///< Vector divergence
122  opNItems ///< Holds number of valid FE operations and value of invalid FE operation
123  };
124 }
125 
126 
127 /// Distinguishes operations by type and size of output rows
129 {
130  elemOp, ///< operation is evaluated on elements or sides
131  pointOp, ///< operation is evaluated on quadrature points
132  fixedSizeOp ///< operation has fixed size and it is filled during initialization
133 };
134 
135 
136 
137 /**
138  * v Class for storing FE data of quadrature points on one patch.
139  *
140  * Store data of bulk or side quadrature points of one dimension.
141  */
142 template<unsigned int spacedim = 3>
144 {
145 public:
146  /**
147  * Stores shared data members between PatchFeValues and PatchPoinValues
148  */
149  struct PatchFeData {
150  public:
151  /// Constructor
152  PatchFeData(size_t buffer_size, size_t simd_alignment)
153  : asm_arena_(buffer_size, simd_alignment), patch_arena_(nullptr) {}
154 
155  /// Destructor
157  if (patch_arena_!=nullptr)
158  delete patch_arena_;
159  }
160 
161  AssemblyArena asm_arena_; ///< Assembly arena, created and filled once during initialization
162  PatchArena *patch_arena_; ///< Patch arena, reseted before patch reinit
163  ArenaVec<double> zero_vec_; ///< ArenaVec of zero values of maximal length using in zero PatchPointValues construction
164  };
165 
166  /**
167  * Constructor
168  *
169  * @param dim Set dimension
170  */
172  : dim_(dim), elements_map_(300, 0), points_map_(300, 0), patch_fe_data_(patch_fe_data), needs_zero_values_(false) {
173  reset();
174  }
175 
176  /**
177  * Destructor.
178  */
179  virtual ~PatchPointValues() {
180  for (uint i=0; i<operations_.size(); ++i)
181  if (operations_[i] != nullptr) delete operations_[i];
182  if (needs_zero_values_)
183  delete zero_values_;
184  }
185 
186  /**
187  * Initialize object, set number of columns (quantities) in tables.
188  */
189  void initialize() {
190  this->reset();
191  int_table_.resize(int_sizes_.size());
192  if (needs_zero_values_)
193  this->create_zero_values();
194  }
195 
196  /// Reset number of columns (points and elements)
197  inline void reset() {
198  n_points_ = 0;
199  n_elems_ = 0;
200  i_elem_ = 0;
201  }
202 
203  /// Getter for dim_
204  inline uint dim() const {
205  return dim_;
206  }
207 
208  /// Getter for n_elems_
209  inline uint n_elems() const {
210  return n_elems_;
211  }
212 
213  /// Getter for n_points_
214  inline uint n_points() const {
215  return n_points_;
216  }
217 
218  /// Getter for quadrature
220  return quad_;
221  }
222 
223  /// Resize data tables. Method is called before reinit of patch.
225  n_elems_ = n_elems;
228  for (uint i=0; i<int_table_.rows(); ++i) {
230  }
231  for (auto *elOp : operations_) {
232  if (elOp == nullptr) continue;
233  if (elOp->size_type() != fixedSizeOp) {
234  elOp->allocate_result(sizes[elOp->size_type()], *patch_fe_data_.patch_arena_);
235  }
236  }
237  std::fill(elements_map_.begin(), elements_map_.end(), (uint)-1);
238  }
239 
240  /**
241  * Register element, add to coords operation
242  *
243  * @param coords Coordinates of element nodes.
244  * @param element_patch_idx Index of element on patch.
245  */
246  uint register_element(arma::mat coords, uint element_patch_idx) {
247  if (elements_map_[element_patch_idx] != (uint)-1) {
248  // Return index of element on patch if it is registered repeatedly
249  return elements_map_[element_patch_idx];
250  }
251 
253  auto coords_mat = op.result_matrix();
254  std::size_t i_elem = i_elem_;
255  for (uint i_col=0; i_col<coords.n_cols; ++i_col)
256  for (uint i_row=0; i_row<coords.n_rows; ++i_row) {
257  coords_mat(i_row, i_col)(i_elem) = coords(i_row, i_col);
258  }
259 
260  elements_map_[element_patch_idx] = i_elem_;
261  return i_elem_++;
262  }
263 
264  /**
265  * Register side, add to coords operations
266  *
267  * @param coords Coordinates of element nodes.
268  * @param side_coords Coordinates of side nodes.
269  * @param side_idx Index of side on element.
270  */
271  uint register_side(arma::mat elm_coords, arma::mat side_coords, uint side_idx) {
272  {
274  auto coords_mat = op.result_matrix();
275  std::size_t i_elem = i_elem_;
276  for (uint i_col=0; i_col<elm_coords.n_cols; ++i_col)
277  for (uint i_row=0; i_row<elm_coords.n_rows; ++i_row) {
278  coords_mat(i_row, i_col)(i_elem) = elm_coords(i_row, i_col);
279  }
280  }
281 
282  {
284  auto coords_mat = op.result_matrix();
285  std::size_t i_elem = i_elem_;
286  for (uint i_col=0; i_col<side_coords.n_cols; ++i_col)
287  for (uint i_row=0; i_row<side_coords.n_rows; ++i_row) {
288  coords_mat(i_row, i_col)(i_elem) = side_coords(i_row, i_col);
289  }
290  }
291 
292  int_table_(3)(i_elem_) = side_idx;
293 
294  return i_elem_++;
295  }
296 
297  /**
298  * Register bulk point, add to int_table_
299  *
300  * @param elem_table_row Index of element in temporary element table.
301  * @param value_patch_idx Index of point in ElementCacheMap.
302  * @param elem_idx Index of element in Mesh.
303  * @param i_point_on_elem Index of point on element
304  */
305  uint register_bulk_point(uint elem_table_row, uint value_patch_idx, uint elem_idx, uint i_point_on_elem) {
306  uint point_pos = i_point_on_elem * n_elems_ + elem_table_row; // index of bulk point on patch
307  int_table_(0)(point_pos) = value_patch_idx;
308  int_table_(1)(point_pos) = elem_table_row;
309  int_table_(2)(point_pos) = elem_idx;
310 
311  points_map_[value_patch_idx] = point_pos;
312  return point_pos;
313  }
314 
315  /**
316  * Register side point, add to int_table_
317  *
318  * @param elem_table_row Index of side in temporary element table.
319  * @param value_patch_idx Index of point in ElementCacheMap.
320  * @param elem_idx Index of element in Mesh.
321  * @param side_idx Index of side on element.
322  * @param i_point_on_side Index of point on side
323  */
324  uint register_side_point(uint elem_table_row, uint value_patch_idx, uint elem_idx, uint side_idx, uint i_point_on_side) {
325  uint point_pos = i_point_on_side * n_elems_ + elem_table_row; // index of side point on patch
326  int_table_(0)(point_pos) = value_patch_idx;
327  int_table_(1)(point_pos) = elem_table_row;
328  int_table_(2)(point_pos) = elem_idx;
329  int_table_(4)(point_pos) = side_idx;
330 
331  points_map_[value_patch_idx] = point_pos;
332  return point_pos;
333  }
334 
335  /**
336  * Adds accessor of new operation to operations_ vector
337  *
338  * @param op_idx Index of operation in operations_ vector
339  * @param shape Shape of function output
340  * @param reinit_f Reinitialize function
341  * @param size_type Type of operation by size of rows
342  */
343  PatchOp<spacedim> *make_new_op(uint op_idx, std::initializer_list<uint> shape, ReinitFunction reinit_f, OpSizeType size_type = pointOp) {
344  return make_fe_op(op_idx, shape, reinit_f, 1, size_type);
345  }
346 
347  /**
348  * Adds accessor of new operation with fixed data size (ref data) to operations_ vector
349  *
350  * @param op_idx Index of operation in operations_ vector
351  * @param shape Shape of function output
352  * @param reinit_f Reinitialize function
353  */
354  PatchOp<spacedim> *make_fixed_op(uint op_idx, std::initializer_list<uint> shape, ReinitFunction reinit_f) {
355  return make_fe_op(op_idx, shape, reinit_f, 1, fixedSizeOp);
356  }
357 
358  /**
359  * Adds accessor of FE operation and adds operation dynamically to operations_ vector
360  *
361  * @param op_idx Index of operation in operations_ vector
362  * @param shape Shape of function output
363  * @param reinit_f Reinitialize function
364  * @param n_dofs Number of DOFs
365  * @param size_type Type of operation by size of rows
366  */
367  PatchOp<spacedim> *make_fe_op(uint op_idx, std::initializer_list<uint> shape, ReinitFunction reinit_f, uint n_dofs,
368  OpSizeType size_type = pointOp) {
369  if (operations_[op_idx] == nullptr) {
370  std::vector<PatchOp<spacedim> *> input_ops_ptr;
371  for (uint i_op : this->op_dependency_[op_idx]) {
372  ASSERT_PTR(operations_[i_op]);
373  input_ops_ptr.push_back(operations_[i_op]);
374  }
375  operations_[op_idx] = new PatchOp<spacedim>(this->dim_, shape, reinit_f, size_type, input_ops_ptr, n_dofs);
376  }
377  return operations_[op_idx];
378  }
379 
380  /**
381  * Adds accessor of new operation with fixed data size (ref data) to operations_ vector
382  *
383  * @param op_idx Index of operation in operations_ vector
384  * @param shape Shape of function output
385  * @param reinit_f Reinitialize function
386  * @param n_dofs Number of DOFs
387  */
388  PatchOp<spacedim> *make_fixed_fe_op(uint op_idx, std::initializer_list<uint> shape, ReinitFunction reinit_f, uint n_dofs) {
389  return make_fe_op(op_idx, shape, reinit_f, n_dofs, fixedSizeOp);
390  }
391 
392 
393  /**
394  * Reinitializes patch data.
395  *
396  * Calls reinit functions defined on each operations.
397  */
398  void reinit_patch() {
399  if (n_elems_ == 0) return; // skip if tables are empty
400  for (uint i=0; i<operations_.size(); ++i) {
401  if (operations_[i] != nullptr) operations_[i]->reinit_function(operations_, int_table_);
402  }
403  }
404 
405  /**
406  * Returns scalar output value of data stored by elements.
407  *
408  * @param op_idx Index of operation in operations vector
409  * @param point_idx Index of quadrature point in ElementCacheMap
410  */
411  inline Scalar scalar_elem_value(uint op_idx, uint point_idx) const {
412  return operations_[op_idx]->raw_result()(0)( int_table_(1)(points_map_[point_idx]) );
413  }
414 
415  /**
416  * Returns vector output value of data stored by elements.
417  *
418  * @param op_idx Index of operation in operations vector
419  * @param point_idx Index of quadrature point in ElementCacheMap
420  */
421  inline Vector vector_elem_value(uint op_idx, uint point_idx) const {
422  Vector val;
423  const auto &op_matrix = operations_[op_idx]->raw_result();
424  uint op_matrix_idx = int_table_(1)(points_map_[point_idx]);
425  for (uint i=0; i<3; ++i)
426  val(i) = op_matrix(i)(op_matrix_idx);
427  return val;
428  }
429 
430  /**
431  * Returns tensor output value of data stored by elements.
432  *
433  * @param op_idx Index of operation in operations vector
434  * @param point_idx Index of quadrature point in ElementCacheMap
435  */
436  inline Tensor tensor_elem_value(uint op_idx, uint point_idx) const {
437  Tensor val;
438  const auto &op_matrix = operations_[op_idx]->raw_result();
439  uint op_matrix_idx = int_table_(1)(points_map_[point_idx]);
440  for (uint i=0; i<3; ++i)
441  for (uint j=0; j<3; ++j)
442  val(i,j) = op_matrix(i+j*spacedim)(op_matrix_idx);
443  return val;
444  }
445 
446  /**
447  * Returns scalar output value on point.
448  *
449  * @param op_idx Index of operation in operations vector
450  * @param point_idx Index of quadrature point in ElementCacheMap
451  * @param i_dof Index of DOF
452  */
453  inline Scalar scalar_value(uint op_idx, uint point_idx, uint i_dof=0) const {
454  return operations_[op_idx]->raw_result()(i_dof)(points_map_[point_idx]);
455  }
456 
457  /**
458  * Returns vector output value on point.
459  *
460  * @param op_idx Index of operation in operations vector
461  * @param point_idx Index of quadrature point in ElementCacheMap
462  * @param i_dof Index of DOF
463  */
464  inline Vector vector_value(uint op_idx, uint point_idx, uint i_dof=0) const {
465  Vector val;
466  auto op_matrix = operations_[op_idx]->raw_result();
467  uint op_matrix_idx = points_map_[point_idx];
468  for (uint i=0; i<3; ++i)
469  val(i) = op_matrix(i + 3*i_dof)(op_matrix_idx);
470  return val;
471  }
472 
473  /**
474  * Returns tensor output value on point.
475  *
476  * @param op_idx Index of operation in operations vector
477  * @param point_idx Index of quadrature point in ElementCacheMap
478  * @param i_dof Index of DOF
479  */
480  inline Tensor tensor_value(uint op_idx, uint point_idx, uint i_dof=0) const {
481  Tensor val;
482  auto op_matrix = operations_[op_idx]->raw_result();
483  uint op_matrix_idx = points_map_[point_idx];
484  for (uint i=0; i<9; ++i)
485  val(i) = op_matrix(i+9*i_dof)(op_matrix_idx);
486  return val;
487  }
488 
489  /// return reference to assembly arena
490  inline AssemblyArena &asm_arena() const {
491  return patch_fe_data_.asm_arena_;
492  }
493 
494  /// return reference to patch arena
495  inline PatchArena &patch_arena() const {
497  }
498 
499  /// Set flag needs_zero_values_ to true
500  inline void zero_values_needed() {
501  needs_zero_values_ = true;
502  }
503 
504 
507  return zero_values_;
508  }
509 
510  /// Create zero_values_ object
511  virtual void create_zero_values() =0;
512 
513  /**
514  * Performs output of data tables to stream.
515  *
516  * Development method.
517  * @param points Allows switched off output of point table,
518  * @param ints Allows switched off output of int (connectivity to elements) table,
519  */
520  void print_data_tables(ostream& stream, bool points, bool ints) const {
521  if (points) {
522  stream << "Point vals: " << std::endl;
523  for (auto *op : operations_) {
524  if (op == nullptr) continue;
525  auto mat = op->raw_result();
526  for (uint i_mat=0; i_mat<mat.rows()*mat.cols(); ++i_mat) {
527  if (mat(i_mat).data_size()==0) stream << "<empty>";
528  else {
529  const double *vals = mat(i_mat).data_ptr();
530  for (size_t i_val=0; i_val<mat(i_mat).data_size(); ++i_val)
531  stream << vals[i_val] << " ";
532  }
533  stream << std::endl;
534  }
535  stream << " --- end of operation ---" << std::endl;
536  }
537  }
538  if (ints) {
539  stream << "Int vals: " << int_table_.rows() << " - " << int_table_.cols() << std::endl;
540  for (uint i_row=0; i_row<int_table_.rows(); ++i_row) {
541  if (int_table_(i_row).data_size()==0) stream << "<empty>";
542  else {
543  const uint *vals = int_table_(i_row).data_ptr();
544  for (size_t i_val=0; i_val<int_table_(i_row).data_size(); ++i_val)
545  stream << vals[i_val] << " ";
546  }
547  stream << std::endl;
548  }
549  stream << std::endl;
550  }
551  }
552 
553  /**
554  * Performs table of fixed operations to stream.
555  *
556  * Development method.
557  * @param bulk_side Needs set 0 (bulk) or 1 (side) for correct output of operation names.
558  */
559  void print_operations(ostream& stream, uint bulk_side) const {
561  {
562  { "weights", "ref_scalar", "ref_vector", "ref_scalar_grad", "ref_vector_grad", "el_coords", "jacobian", "inv_jac", "jac_det",
563  "pt_coords", "JxW", "scalar_shape", "vector_shape", "grad_scalar_shape", "grad_vector_shape", "vector_sym_grad", "vector_divergence" },
564  { "weights", "ref_scalar", "ref_vector", "ref_scalar_grad", "ref_vector_grad", "el_coords", "el_jac", "el_inv_jac", "side_coords",
565  "side_jac", "side_jac_det", "pt_coords", "JxW", "normal_vec", "scalar_shape", "vector_shape", "grad_scalar_shape", "grad_vector_shape",
566  "vector_sym_grad", "vector_divergence" }
567  };
568  stream << std::setfill(' ') << " Operation" << setw(12) << "" << "Shape" << setw(2) << ""
569  << "n DOFs" << setw(2) << "" << "Input operations" << endl;
570  for (uint i=0; i<operations_.size(); ++i) {
571  if (operations_[i] == nullptr) continue;
572  stream << " " << std::left << setw(20) << op_names[bulk_side][i] << "" << " " << setw(6) << operations_[i]->format_shape() << "" << " "
573  << setw(7) << operations_[i]->n_dofs() << "" << " ";
574  //auto &input_ops = operations_[i]->input_ops();
575  for (auto i_o : op_dependency_[i]) stream << op_names[bulk_side][i_o] << " ";
576  stream << std::endl;
577  }
578  }
579 
580 protected:
582 
583  /**
584  * Hold integer values of quadrature points of defined operations.
585  *
586  * Table contains following rows:
587  * 0: Index of quadrature point on patch
588  * 1: Row of element/side in PatchOp::result_ table in registration step (before expansion)
589  * 2: Element idx in Mesh
590  * - last two rows are allocated only for side point table
591  * 3: Index of side in element - short vector, size of column = number of sides
592  * 4: Index of side in element - long vector, size of column = number of points
593  * Number of used rows is given by n_points_.
594  */
596 
597  /// Set size and type of rows of int_table_, value is set implicitly in constructor of descendants
599 
600 
601  /// Vector of all defined operations
603 
604  /// Holds dependency between operations
606 
607  uint dim_; ///< Dimension
608  uint n_points_; ///< Number of points in patch
609  uint n_elems_; ///< Number of elements in patch
610  uint i_elem_; ///< Index of registered element in table, helper value used during patch creating.
611  Quadrature *quad_; ///< Quadrature of given dimension and order passed in constructor.
612 
613  std::vector<uint> elements_map_; ///< Map of element patch indices to PatchOp::result_ and int_table_ tables
614  std::vector<uint> points_map_; ///< Map of point patch indices to PatchOp::result_ and int_table_ tables
615 
616  PatchFeData &patch_fe_data_; ///< Reference to PatchFeData structure shared with PatchFeValues
617 
618  bool needs_zero_values_; ///< Flags hold whether zero_values_ object is needed
619  PatchPointValues *zero_values_; ///< PatchPointValues object returns zero values for all operations
620 
621  friend class PatchFEValues<spacedim>;
622  friend class PatchOp<spacedim>;
623  template <class ValueType>
624  friend class ElQ;
625  template <class ValueType>
626  friend class FeQ;
627  template<unsigned int dim>
628  friend class BulkValues;
629  template<unsigned int dim>
630  friend class SideValues;
631  template<unsigned int dim>
632  friend class JoinValues;
633 };
634 
635 /**
636  * @brief Class represents element or FE operations.
637  */
638 template<unsigned int spacedim = 3>
639 class PatchOp {
640 public:
641  /**
642  * Constructor
643  *
644  * Set all data members.
645  */
646  PatchOp(uint dim, std::initializer_list<uint> shape, ReinitFunction reinit_f, OpSizeType size_type,
649  n_dofs_(n_dofs), reinit_func(reinit_f)
650  {}
651 
652  /// Aligns shape_vec to 2 items (equal to matrix number of dimensions)
653  std::vector<uint> set_shape_vec(std::initializer_list<uint> shape) const {
654  std::vector<uint> shape_vec(shape);
655  if (shape_vec.size() == 1) shape_vec.push_back(1);
656  ASSERT_EQ(shape_vec.size(), 2);
657  return shape_vec;
658  }
659 
660  /**
661  * Return number of operation components
662  *
663  * Value is computed from shape_ vector
664  */
665  inline uint n_comp() const {
666  return shape_[0] * shape_[1];
667  }
668 
669  /// Getter for dimension
670  inline uint dim() const {
671  return dim_;
672  }
673 
674  /// Getter for size_type_
676  return size_type_;
677  }
678 
679  /// Getter for n_dofs_
680  inline uint n_dofs() const {
681  return n_dofs_;
682  }
683 
684  /// Return pointer to operation of i_op index in input operation vector.
685  inline PatchOp<spacedim> *input_ops(uint i_op) const {
686  return input_ops_[i_op];
687  }
688 
689  /// Getter for shape_
690  inline const std::vector<uint> &shape() const {
691  return shape_;
692  }
693 
694  /**
695  * Format shape to string
696  *
697  * Method is used in output development method.
698  */
699  inline std::string format_shape() const {
700  stringstream ss;
701  ss << shape_[0] << "x" << shape_[1];
702  return ss.str();
703  }
704 
705  /// Call reinit function on element table if function is defined
706  inline void reinit_function(FMT_UNUSED std::vector<PatchOp<spacedim> *> &operations, IntTableArena &int_table) {
707  reinit_func(this, int_table);
708  }
709 
710  inline void allocate_result(size_t data_size, PatchArena &arena) {
711  result_ = Eigen::Vector<ArenaVec<double>, Eigen::Dynamic>(shape_[0] * shape_[1]);
712  for (uint i=0; i<n_comp(); ++i)
713  result_(i) = ArenaVec<double>(data_size, arena);
714  }
715 
716  inline void allocate_const_result(ArenaVec<double> &value_vec) {
717  result_ = Eigen::Vector<ArenaVec<double>, Eigen::Dynamic>(shape_[0] * shape_[1]);
718  for (uint i=0; i<n_comp(); ++i)
719  result_(i) = value_vec;
720  }
721 
722  /// Return map referenced result as Eigen::Vector
723  Eigen::Map<Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic>> result_matrix() {
724  return Eigen::Map<Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic>>(result_.data(), shape_[0], shape_[1]);
725  }
726 
727  /// Return map referenced result of DOF values as Eigen::Matrix
728  Eigen::Map<Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic>> result_sub_matrix(uint i_dof) {
729  ASSERT_LT(i_dof, n_dofs_);
730  uint n_dof_comps = shape_[0] * shape_[1] / n_dofs_;
731  return Eigen::Map<Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic>>(result_.data()+i_dof*n_dof_comps, shape_[0], shape_[1] / n_dofs_);
732  }
733 
734  /// Return map referenced result as Eigen::Vector
735  Eigen::Vector<ArenaVec<double>, Eigen::Dynamic> &raw_result() {
736  return result_;
737  }
738 
739  /// Same as previous but return const reference
740  const Eigen::Vector<ArenaVec<double>, Eigen::Dynamic> &raw_result() const {
741  return result_;
742  }
743 
744 
745 protected:
746  uint dim_; ///< Dimension
747  std::vector<uint> shape_; ///< Shape of stored data (size of vector or number of rows and cols of matrix)
748  Eigen::Vector<ArenaVec<double>, Eigen::Dynamic> result_; ///< Result matrix of operation
749  OpSizeType size_type_; ///< Type of operation by size of vector (element, point or fixed size)
750  std::vector<PatchOp<spacedim> *> input_ops_; ///< Indices of operations in PatchPointValues::operations_ vector on which PatchOp is depended
751  uint n_dofs_; ///< Number of DOFs of FE operations (or 1 in case of element operations)
752 
753  ReinitFunction reinit_func; ///< Pointer to patch reinit function of element data table specialized by operation
754 };
755 
756 
757 /// Defines common functionality of reinit operations.
759  // empty base operation
760  static inline void op_base(FMT_UNUSED PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
761  // empty
762  }
763 
764  template<unsigned int dim>
765  static inline void elop_jac(PatchOp<3> * result_op) {
766  // result matrix(spacedim, dim), input matrix(spacedim, dim+1)
767  auto jac_value = result_op->result_matrix();
768  auto coords_value = result_op->input_ops(0)->result_matrix();
769  for (unsigned int i=0; i<3; i++)
770  for (unsigned int j=0; j<dim; j++)
771  jac_value(i,j) = coords_value(i,j+1) - coords_value(i,0);
772  }
773 
774  template<unsigned int dim>
775  static inline void elop_inv_jac(PatchOp<3> * result_op) {
776  // result matrix(spacedim, dim), input matrix(spacedim, dim+1)
777  auto inv_jac_value = result_op->result_matrix();
778  auto jac_value = result_op->input_ops(0)->result_matrix();
779  inv_jac_value = eigen_arena_tools::inverse<3, dim>(jac_value);
780  }
781 
782  template<unsigned int dim>
783  static inline void elop_jac_det(PatchOp<3> * result_op) {
784  // result double, input matrix(spacedim, dim)
785  auto jac_det_value = result_op->result_matrix();
786  auto jac_value = result_op->input_ops(0)->result_matrix();
787  jac_det_value(0) = eigen_arena_tools::determinant<3, dim>(jac_value).abs();
788  }
789 
790  static inline void ptop_JxW(PatchOp<3> * result_op) {
791  auto weights_value = result_op->input_ops(0)->result_matrix();
792  auto jac_det_value = result_op->input_ops(1)->result_matrix();
793  ArenaOVec<double> weights_ovec( weights_value(0,0) );
794  ArenaOVec<double> jac_det_ovec( jac_det_value(0,0) );
795  ArenaOVec<double> jxw_ovec = jac_det_ovec * weights_ovec;
796  auto jxw_value = result_op->result_matrix();
797  jxw_value(0,0) = jxw_ovec.get_vec();
798  }
799 
800  /// Common reinit function of vector symmetric gradient on bulk and side points
801  static inline void ptop_vector_sym_grad(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
802  for (uint i_dof=0; i_dof<result_op->n_dofs(); ++i_dof) {
803  Eigen::Map< Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> > grad_vector_dof = result_op->input_ops(0)->result_sub_matrix(i_dof);
804  Eigen::Map< Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> > sym_grad_dof = result_op->result_sub_matrix(i_dof);
805  sym_grad_dof = 0.5 * (grad_vector_dof.transpose() + grad_vector_dof);
806  }
807  }
808  /// Common reinit function of vector divergence on bulk and side points
809  static inline void ptop_vector_divergence(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
810  auto divergence_value = result_op->result_matrix();
811 
812  for (uint i_dof=0; i_dof<result_op->n_dofs(); ++i_dof) {
813  Eigen::Map< Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> > grad_vector_dof = result_op->input_ops(0)->result_sub_matrix(i_dof);
814  divergence_value(i_dof) = grad_vector_dof(0,0) + grad_vector_dof(1,1) + grad_vector_dof(2,2);
815  }
816  }
817 };
818 
819 /// Defines reinit operations on bulk points.
820 struct bulk_reinit {
821  // element operations
822  template<unsigned int dim>
823  static inline void elop_jac(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
824  common_reinit::elop_jac<dim>(result_op);
825  }
826  template<unsigned int dim>
827  static inline void elop_inv_jac(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
828  common_reinit::elop_inv_jac<dim>(result_op);
829  }
830  template<unsigned int dim>
831  static inline void elop_jac_det(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
832  common_reinit::elop_jac_det<dim>(result_op);
833  }
834 
835  // point operations
836  static inline void ptop_coords(FMT_UNUSED PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
837  // Implement
838  }
839  static inline void ptop_JxW(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
840  common_reinit::ptop_JxW(result_op);
841  }
842  static inline void ptop_scalar_shape(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
843  auto ref_vec = result_op->input_ops(0)->result_matrix();
844  auto result_vec = result_op->result_matrix();
845 
846  uint n_dofs = result_op->n_dofs();
847  uint n_elem = result_vec(0).data_size() / ref_vec(0).data_size();
848 
849  ArenaVec<double> elem_vec(n_elem, result_op->raw_result()(0).arena());
850  for (uint i=0; i<n_elem; ++i) {
851  elem_vec(i) = 1.0;
852  }
853  ArenaOVec<double> elem_ovec(elem_vec);
854 
855  Eigen::Vector<ArenaOVec<double>, Eigen::Dynamic> ref_ovec(n_dofs);
856  for (uint i=0; i<n_dofs; ++i) {
857  ref_ovec(i) = ArenaOVec<double>( ref_vec(i) );
858  }
859 
860  Eigen::Vector<ArenaOVec<double>, Eigen::Dynamic> result_ovec = elem_ovec * ref_ovec;
861  for (uint i=0; i<n_dofs; ++i) {
862  result_vec(i) = result_ovec(i).get_vec();
863  }
864  }
865  static inline void ptop_vector_shape(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
866  auto ref_shape_vec = result_op->input_ops(0)->result_matrix();
867  auto result_vec = result_op->result_matrix(); // result: shape 3x1
868 
869  uint n_dofs = result_op->n_dofs();
870  uint n_elem = result_vec(0).data_size() / ref_shape_vec(0).data_size();
871 
872  ArenaVec<double> elem_vec(n_elem, result_op->raw_result()(0).arena());
873  for (uint i=0; i<n_elem; ++i) {
874  elem_vec(i) = 1.0;
875  }
876  ArenaOVec<double> elem_ovec(elem_vec);
877 
878  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> ref_shape_ovec(3, n_dofs);
879  for (uint c=0; c<3*n_dofs; ++c) {
880  ref_shape_ovec(c) = ArenaOVec(ref_shape_vec(c));
881  }
882 
883  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> result_ovec = elem_ovec * ref_shape_ovec;
884  for (uint c=0; c<3*n_dofs; ++c)
885  result_vec(c) = result_ovec(c).get_vec();
886  }
887  static inline void ptop_vector_contravariant_shape(FMT_UNUSED PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
888 // auto &op = operations[vector_sym_grad_op_idx];
889 // auto grad_vector_value = op.input_ops(0).result_matrix();
890 // auto sym_grad_value = op.result_matrix();
891 // sym_grad_value = 0.5 * (grad_vector_value.transpose() + grad_vector_value);
892  }
893  static inline void ptop_vector_piola_shape(FMT_UNUSED PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
894 // auto &op = operations[vector_sym_grad_op_idx];
895 // auto grad_vector_value = op.input_ops(0).result_matrix();
896 // auto sym_grad_value = op.result_matrix();
897 // sym_grad_value = 0.5 * (grad_vector_value.transpose() + grad_vector_value);
898  }
899  template<unsigned int dim>
900  static inline void ptop_scalar_shape_grads(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
901  auto inv_jac_vec = result_op->input_ops(0)->result_matrix(); // dim x spacedim=3
902  auto ref_grads_vec = result_op->input_ops(1)->result_matrix(); // dim x n_dofs
903 
904  uint n_dofs = result_op->n_dofs();
905 
906  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> ref_grads_ovec(dim, n_dofs);
907  for (uint i=0; i<dim*n_dofs; ++i) {
908  ref_grads_ovec(i) = ArenaOVec(ref_grads_vec(i));
909  }
910 
911  Eigen::Matrix<ArenaOVec<double>, dim, 3> inv_jac_ovec;
912  for (uint i=0; i<dim*3; ++i) {
913  inv_jac_ovec(i) = ArenaOVec(inv_jac_vec(i));
914  }
915 
916  auto result_vec = result_op->result_matrix();
917  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> result_ovec = inv_jac_ovec.transpose() * ref_grads_ovec;
918  for (uint i=0; i<3*n_dofs; ++i) {
919  result_vec(i) = result_ovec(i).get_vec();
920  }
921  }
922  template<unsigned int dim>
923  static inline void ptop_vector_shape_grads(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
924  auto inv_jac_vec = result_op->input_ops(0)->result_matrix(); // dim x 3
925  auto ref_grads_vec = result_op->input_ops(1)->result_matrix(); // dim x 3*n_dofs
926  auto result_vec = result_op->result_matrix(); // 3 x 3*n_dofs
927 
928  uint n_dofs = result_op->n_dofs();
929 
930  Eigen::Matrix<ArenaOVec<double>, dim, 3> inv_jac_ovec;
931  for (uint i=0; i<dim*3; ++i) {
932  inv_jac_ovec(i) = ArenaOVec(inv_jac_vec(i));
933  }
934 
935  Eigen::Matrix<ArenaOVec<double>, dim, 3> ref_grads_ovec;
936  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
937  for (uint i=0; i<3*dim; ++i) {
938  ref_grads_ovec(i) = ArenaOVec(ref_grads_vec(i_dof*3*dim + i));
939  }
940 
941  Eigen::Matrix<ArenaOVec<double>, 3, 3> result_ovec = inv_jac_ovec.transpose() * ref_grads_ovec;
942  for (uint i=0; i<3; ++i) {
943  for (uint j=0; j<3; ++j) {
944  result_vec(j,i+3*i_dof) = result_ovec(i,j).get_vec();
945  }
946  }
947  }
948  }
949  template<unsigned int dim>
951  template<unsigned int dim>
952  static inline void ptop_vector_piola_shape_grads(FMT_UNUSED PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {}
953 };
954 
955 
956 
957 /// Defines reinit operations on side points.
958 struct side_reinit {
959  // element operations
960  template<unsigned int dim>
961  static inline void elop_el_jac(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
962  common_reinit::elop_jac<dim>(result_op);
963  }
964  template<unsigned int dim>
965  static inline void elop_el_inv_jac(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
966  common_reinit::elop_inv_jac<dim>(result_op);
967  }
968  template<unsigned int dim>
969  static inline void elop_sd_jac(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
970  // result matrix(spacedim, dim), input matrix(spacedim, dim+1)
971  common_reinit::elop_jac<dim-1>(result_op);
972  }
973  template<unsigned int dim>
974  static inline void elop_sd_jac_det(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
975  common_reinit::elop_jac_det<dim-1>(result_op);
976  }
977 
978  // Point operations
979  static inline void ptop_coords(FMT_UNUSED PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
980  // Implement
981  }
982  static inline void ptop_JxW(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
983  common_reinit::ptop_JxW(result_op);
984  }
985  template<unsigned int dim>
986  static inline void ptop_normal_vec(PatchOp<3> * result_op, IntTableArena &el_table) {
987  auto normal_value = result_op->result_matrix();
988  auto inv_jac_value = result_op->input_ops(0)->result_matrix();
989  normal_value = inv_jac_value.transpose() * RefElement<dim>::normal_vector_array( el_table(3) );
990 
991  ArenaVec<double> norm_vec( normal_value(0).data_size(), normal_value(0).arena() );
992  Eigen::VectorXd A(3);
993  for (uint i=0; i<normal_value(0).data_size(); ++i) {
994  A(0) = normal_value(0)(i);
995  A(1) = normal_value(1)(i);
996  A(2) = normal_value(2)(i);
997  norm_vec(i) = A.norm();
998  }
999 
1000  for (uint i=0; i<3; ++i) {
1001  normal_value(i) = normal_value(i) / norm_vec;
1002  }
1003  }
1004  static inline void ptop_scalar_shape(PatchOp<3> * result_op, IntTableArena &el_table) {
1005  auto ref_vec = result_op->input_ops(0)->result_matrix();
1006  auto result_vec = result_op->result_matrix();
1007 
1008  uint n_dofs = result_op->n_dofs();
1009  uint n_sides = el_table(3).data_size(); // number of sides on patch
1010  uint n_patch_points = el_table(4).data_size(); // number of points on patch
1011 
1012  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
1013  for (uint i_pt=0; i_pt<n_patch_points; ++i_pt) {
1014  result_vec(i_dof)(i_pt) = ref_vec(el_table(4)(i_pt), i_dof)(i_pt / n_sides);
1015  }
1016  }
1017  }
1018  static inline void ptop_vector_contravariant_shape(FMT_UNUSED PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {}
1019  static inline void ptop_vector_piola_shape(FMT_UNUSED PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {}
1020  static inline void ptop_vector_shape(PatchOp<3> * result_op, IntTableArena &el_table) {
1021  auto ref_shape_vec = result_op->input_ops(0)->result_matrix(); // dim+1 x 3*n_dofs
1022  auto result_vec = result_op->result_matrix(); // 3 x n_dofs
1023 
1024  uint n_dofs = result_op->n_dofs();
1025  uint n_sides = el_table(3).data_size();
1026  uint n_patch_points = el_table(4).data_size();
1027 
1028  for (uint c=0; c<3*n_dofs; c++)
1029  result_vec(c) = ArenaVec<double>(n_patch_points, result_vec(c).arena());
1030 
1031  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
1032  for (uint i_pt=0; i_pt<n_patch_points; ++i_pt)
1033  for (uint c=0; c<3; c++)
1034  result_vec(c,i_dof)(i_pt) = ref_shape_vec(el_table(4)(i_pt),3*i_dof+c)(i_pt / n_sides);
1035  }
1036  }
1037 
1038 template<unsigned int dim>
1039  static inline void ptop_scalar_shape_grads(PatchOp<3> * result_op, IntTableArena &el_table) {
1040  auto ref_shape_grads = result_op->input_ops(1)->result_matrix(); // dim+1 x dim*n_dofs
1041  auto grad_scalar_shape_value = result_op->result_matrix(); // Result vector: 3 x n_dofs
1042 
1043  uint n_dofs = result_op->n_dofs();
1044  uint n_points = ref_shape_grads(0).data_size();
1045  uint n_sides = el_table(3).data_size();
1046  uint n_patch_points = el_table(4).data_size();
1047 
1048  // Expands inverse jacobian to inv_jac_expd_value
1049  auto inv_jac_value = result_op->input_ops(0)->result_matrix();
1050  Eigen::Matrix<ArenaVec<double>, dim, 3> inv_jac_expd_value;
1051  for (uint i=0; i<dim*3; ++i) {
1052  inv_jac_expd_value(i) = ArenaVec<double>( n_patch_points, inv_jac_value(i).arena() );
1053  for (uint j=0; j<n_patch_points; ++j)
1054  inv_jac_expd_value(i)(j) = inv_jac_value(i)(j%n_sides);
1055  }
1056 
1057  // Fill ref shape gradients by q_point. DOF and side_idx
1058  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> ref_shape_grads_expd(dim, n_dofs);
1059  for (uint i=0; i<dim*n_dofs; ++i) {
1060  ref_shape_grads_expd(i) = ArenaVec<double>( n_patch_points, inv_jac_value(0).arena() );
1061  }
1062  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
1063  for (uint i_pt=0; i_pt<n_points; ++i_pt) {
1064  uint i_begin = i_pt * n_sides;
1065  for (uint i_sd=0; i_sd<n_sides; ++i_sd) {
1066  for (uint i_c=0; i_c<dim; ++i_c) {
1067  ref_shape_grads_expd(i_c, i_dof)(i_begin + i_sd) = ref_shape_grads(el_table(3)(i_sd), i_dof*dim+i_c)(i_pt);
1068  }
1069  }
1070  }
1071  }
1072 
1073  // computes operation result
1074  grad_scalar_shape_value = inv_jac_expd_value.transpose() * ref_shape_grads_expd;
1075  }
1076  template<unsigned int dim>
1077  static inline void ptop_vector_shape_grads(PatchOp<3> * result_op, IntTableArena &el_table) {
1078  auto result_vec = result_op->raw_result(); // 3 x 3*n_dofs
1079  auto inv_jac_value = result_op->input_ops(0)->result_matrix(); // dim x 3
1080  auto ref_vector_grad = result_op->input_ops(1)->result_matrix(); // n_sides*dim x 3*n_dofs
1081 
1082  uint n_dofs = result_op->n_dofs();
1083  uint n_points = ref_vector_grad(0).data_size();
1084  uint n_patch_sides = el_table(3).data_size();
1085  uint n_patch_points = el_table(4).data_size();
1086 
1087  // Expands inverse jacobian to inv_jac_expd_value
1088  Eigen::Matrix<ArenaVec<double>, dim, 3> inv_jac_expd_value;
1089  for (uint i=0; i<dim*3; ++i) {
1090  inv_jac_expd_value(i) = ArenaVec<double>( n_patch_points, inv_jac_value(i).arena() );
1091  for (uint j=0; j<n_patch_points; ++j)
1092  inv_jac_expd_value(i)(j) = inv_jac_value(i)(j%n_patch_sides);
1093  }
1094 
1095  // Fill ref shape gradients by q_point. DOF and side_idx
1096  Eigen::Matrix<ArenaVec<double>, dim, 3> ref_shape_grads_expd;
1097  for (uint i=0; i<3*dim; ++i) {
1098  ref_shape_grads_expd(i) = ArenaVec<double>( n_patch_points, inv_jac_value(0).arena() );
1099  }
1100  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
1101 
1102  for (uint i_pt=0; i_pt<n_points; ++i_pt) {
1103  uint i_begin = i_pt * n_patch_sides;
1104  for (uint i_sd=0; i_sd<n_patch_sides; ++i_sd) {
1105  for (uint i_dim=0; i_dim<dim; ++i_dim) {
1106  for (uint i_c=0; i_c<3; ++i_c) {
1107  ref_shape_grads_expd(i_dim, i_c)(i_begin + i_sd) = ref_vector_grad(el_table(3)(i_sd)*dim+i_dim, 3*i_dof+i_c)(i_pt);
1108  }
1109  }
1110  }
1111  }
1112 
1113  // computes operation result
1114  Eigen::Map< Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> > res_submat = result_op->result_sub_matrix(i_dof);
1115  res_submat = (inv_jac_expd_value.transpose() * ref_shape_grads_expd).transpose();
1116  }
1117  }
1118  template<unsigned int dim>
1120  template<unsigned int dim>
1121  static inline void ptop_vector_piola_shape_grads(FMT_UNUSED PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {}
1122 };
1123 
1124 
1125 // template specialization
1126 template<>
1127 inline void side_reinit::elop_sd_jac<1>(FMT_UNUSED PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
1128 }
1129 
1130 template<>
1131 inline void side_reinit::elop_sd_jac_det<1>(PatchOp<3> * result_op, FMT_UNUSED IntTableArena &el_table) {
1132  auto result_vec = result_op->result_matrix();
1133  for (uint i=0;i<result_vec(0).data_size(); ++i) {
1134  result_vec(0,0)(i) = 1.0;
1135  }
1136 }
1137 
1138 
1139 
1140 namespace FeBulk {
1141 
1142  /**
1143  * Bulk data specialization, order of item in operations_ vector corresponds to the BulkOps enum
1144  *
1145  * TODO merge FeBulk::PatchPointValues and FeSide::PatchPointValues to PatchPointValues
1146  * when operation dependencies will be solved by DFS
1147  */
1148  template<unsigned int spacedim = 3>
1149  class PatchPointValues : public ::PatchPointValues<spacedim> {
1150  public:
1151  typedef typename ::PatchPointValues<spacedim>::PatchFeData PatchFeData;
1152 
1153  /// Constructor
1154  PatchPointValues(uint dim, uint quad_order, PatchFeData &patch_fe_data)
1155  : ::PatchPointValues<spacedim>(dim, patch_fe_data) {
1156  // set dependency of operations
1159  this->op_dependency_[BulkOps::opInvJac] = {BulkOps::opJac};
1160  this->op_dependency_[BulkOps::opJacDet] = {BulkOps::opJac};
1161  this->op_dependency_[BulkOps::opJxW] = {BulkOps::opWeights, BulkOps::opJacDet};
1162  this->op_dependency_[BulkOps::opScalarShape] = {BulkOps::opRefScalar};
1163  this->op_dependency_[BulkOps::opVectorShape] = {BulkOps::opRefVector};
1164  // VectorContravariant: {FeBulk::BulkOps::opRefVector, FeBulk::BulkOps::opJac}
1165  // VectorPiola: {FeBulk::BulkOps::opRefVector, FeBulk::BulkOps::opJac, FeBulk::BulkOps::opJacDet}
1168  // VectorContravariant: {FeBulk::BulkOps::opInvJac, FeBulk::BulkOps::opRefVectorGrad, FeBulk::BulkOps::opJac}
1169  // VectorPiola: {FeBulk::BulkOps::opInvJac, FeBulk::BulkOps::opRefVectorGrad, FeBulk::BulkOps::opJac, FeBulk::BulkOps::opJacDet}
1170  this->op_dependency_[BulkOps::opVectorSymGrad] = {BulkOps::opGradVectorShape};
1171  this->op_dependency_[BulkOps::opVectorDivergence] = {BulkOps::opGradVectorShape};
1172 
1173  this->quad_ = new QGauss(dim, 2*quad_order);
1174  this->int_sizes_ = {pointOp, pointOp, pointOp};
1175  this->operations_.resize(BulkOps::opNItems, nullptr);
1176  switch (dim) {
1177  case 1:
1178  init<1>();
1179  break;
1180  case 2:
1181  init<2>();
1182  break;
1183  case 3:
1184  init<3>();
1185  break;
1186  }
1187  }
1188 
1189  /// Destructor
1191 
1192  /// Create zero_values_ object
1193  void create_zero_values() override {
1194  this->zero_values_ = new PatchPointValues(this->dim_, this->operations_, this->patch_fe_data_);
1195  }
1196 
1197  private:
1198  /// Specialized constructor of zero values object. Do not use in other cases!
1200  : ::PatchPointValues<spacedim>(dim, patch_fe_data) {
1202  this->create_zero_operations(operations);
1203  }
1204 
1205  /// Initialize operations vector
1206  template<unsigned int dim>
1207  void init() {
1208  // Fixed operation
1209  auto *weights = this->make_fixed_op( BulkOps::opWeights, {1}, &common_reinit::op_base );
1210  // create result vector of weights operation in assembly arena
1211  const std::vector<double> &point_weights_vec = this->quad_->get_weights();
1212  weights->allocate_result(point_weights_vec.size(), this->patch_fe_data_.asm_arena_);
1213  auto weights_value = weights->result_matrix();
1214  for (uint i=0; i<point_weights_vec.size(); ++i)
1215  weights_value(0)(i) = point_weights_vec[i];
1216 
1217  // First step: adds element values operations
1218  /*auto &el_coords =*/ this->make_new_op( BulkOps::opElCoords, {spacedim, this->dim_+1}, &common_reinit::op_base, OpSizeType::elemOp );
1219 
1220  /*auto &el_jac =*/ this->make_new_op( BulkOps::opJac, {spacedim, this->dim_}, &bulk_reinit::elop_jac<dim>, OpSizeType::elemOp );
1221 
1222  /*auto &el_inv_jac =*/ this->make_new_op( BulkOps::opInvJac, {this->dim_, spacedim}, &bulk_reinit::elop_inv_jac<dim>, OpSizeType::elemOp );
1223 
1224  /*auto &el_jac_det =*/ this->make_new_op( BulkOps::opJacDet, {1}, &bulk_reinit::elop_jac_det<dim>, OpSizeType::elemOp );
1225 
1226  // Second step: adds point values operations
1227  /*auto &pt_coords =*/ this->make_new_op( BulkOps::opCoords, {spacedim}, &bulk_reinit::ptop_coords );
1228 
1229  /*auto &JxW =*/ this->make_new_op( BulkOps::opJxW, {1}, &bulk_reinit::ptop_JxW );
1230  }
1231  };
1232 
1233 } // closing namespace FeBulk
1234 
1235 
1236 
1237 namespace FeSide {
1238 
1239 /// Bulk Side specialization, order of item in operations_ vector corresponds to the SideOps enum
1240  template<unsigned int spacedim = 3>
1241  class PatchPointValues : public ::PatchPointValues<spacedim> {
1242  public:
1243  typedef typename ::PatchPointValues<spacedim>::PatchFeData PatchFeData;
1244 
1245  /// Constructor
1246  PatchPointValues(uint dim, uint quad_order, PatchFeData &patch_fe_data)
1247  : ::PatchPointValues<spacedim>(dim, patch_fe_data) {
1248  // set dependency of operations
1251  this->op_dependency_[SideOps::opElInvJac] = {SideOps::opElJac};
1252  this->op_dependency_[SideOps::opSideJac] = {SideOps::opSideCoords};
1253  this->op_dependency_[SideOps::opSideJacDet] = {SideOps::opSideJac};
1254  this->op_dependency_[SideOps::opJxW] = {SideOps::opWeights, SideOps::opSideJacDet};
1255  this->op_dependency_[SideOps::opNormalVec] = {SideOps::opElInvJac};
1256  this->op_dependency_[SideOps::opScalarShape] = {SideOps::opRefScalar};
1257  this->op_dependency_[SideOps::opVectorShape] = {SideOps::opRefVector};
1258  // VectorContravariant: {FeSide::SideOps::opRefVector, FeSide::SideOps::opSideJac}
1259  // VectorPiola: {FeSide::SideOps::opRefVector, FeSide::SideOps::opSideJac, FeSide::SideOps::opSideJacDet}
1262  // VectorContravariant: {FeSide::SideOps::opElInvJac, FeSide::SideOps::opRefVectorGrad, FeSide::SideOps::opElJac}
1263  // VectorPiola: {FeSide::SideOps::opElInvJac, FeSide::SideOps::opRefVectorGrad, FeSide::SideOps::opElJac, FeSide::SideOps::opSideJacDet}
1264  // TODO ?? define and use opElJacDet
1265  this->op_dependency_[SideOps::opVectorSymGrad] = {SideOps::opGradVectorShape};
1266  this->op_dependency_[SideOps::opVectorDivergence] = {SideOps::opGradVectorShape};
1267 
1268  this->quad_ = new QGauss(dim-1, 2*quad_order);
1269  this->int_sizes_ = {pointOp, pointOp, pointOp, elemOp, pointOp};
1270  this->operations_.resize(SideOps::opNItems, nullptr);
1271  switch (dim) {
1272  case 1:
1273  init<1>();
1274  break;
1275  case 2:
1276  init<2>();
1277  break;
1278  case 3:
1279  init<3>();
1280  break;
1281  }
1282  }
1283 
1284  /// Destructor
1286 
1287  /// Create zero_values_ object
1288  void create_zero_values() override {
1289  this->zero_values_ = new PatchPointValues(this->dim_, this->operations_, this->patch_fe_data_);
1290  }
1291 
1292  private:
1293  /// Specialized constructor of zero values object. Do not use in other cases!
1295  : ::PatchPointValues<spacedim>(dim, patch_fe_data) {
1297  this->create_zero_operations(operations);
1298  }
1299 
1300  /// Initialize operations vector
1301  template<unsigned int dim>
1302  void init() {
1303  // Fixed operation
1304  auto *weights = this->make_fixed_op( SideOps::opWeights, {1}, &common_reinit::op_base ); //lambda_weights );
1305  // create result vector of weights operation in assembly arena
1306  const std::vector<double> &point_weights_vec = this->quad_->get_weights();
1307  weights->allocate_result(point_weights_vec.size(), this->patch_fe_data_.asm_arena_);
1308  auto weights_value = weights->result_matrix();
1309  for (uint i=0; i<point_weights_vec.size(); ++i)
1310  weights_value(0)(i) = point_weights_vec[i];
1311 
1312  // First step: adds element values operations
1313  /*auto &el_coords =*/ this->make_new_op( SideOps::opElCoords, {spacedim, this->dim_+1}, &common_reinit::op_base, OpSizeType::elemOp );
1314 
1315  /*auto &el_jac =*/ this->make_new_op( SideOps::opElJac, {spacedim, this->dim_}, &side_reinit::elop_el_jac<dim>, OpSizeType::elemOp );
1316 
1317  /*auto &el_inv_jac =*/ this->make_new_op( SideOps::opElInvJac, {this->dim_, spacedim}, &side_reinit::elop_el_inv_jac<dim>, OpSizeType::elemOp );
1318 
1319  // Second step: adds side values operations
1320  /*auto &sd_coords =*/ this->make_new_op( SideOps::opSideCoords, {spacedim, this->dim_}, &common_reinit::op_base, OpSizeType::elemOp );
1321 
1322  /*auto &sd_jac =*/ this->make_new_op( SideOps::opSideJac, {spacedim, this->dim_-1}, &side_reinit::elop_sd_jac<dim>, OpSizeType::elemOp );
1323 
1324  /*auto &sd_jac_det =*/ this->make_new_op( SideOps::opSideJacDet, {1}, &side_reinit::elop_sd_jac_det<dim>, OpSizeType::elemOp );
1325 
1326  // Third step: adds point values operations
1327  /*auto &coords =*/ this->make_new_op( SideOps::opCoords, {spacedim}, &side_reinit::ptop_coords );
1328 
1329  /*auto &JxW =*/ this->make_new_op( SideOps::opJxW, {1}, &side_reinit::ptop_JxW );
1330 
1331  /*auto &normal_vec =*/ this->make_new_op( SideOps::opNormalVec, {spacedim}, &side_reinit::ptop_normal_vec<dim>, OpSizeType::elemOp );
1332  }
1333  };
1334 
1335 } // closing namespace FeSide
1336 
1337 
1338 
1339 #endif /* PATCH_POINT_VALUES_HH_ */
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:301
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:333
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
Definition: asserts.hh:341
ArenaVec< T > get_vec() const
Convert ArenaOVec to ArenaVec and its.
Definition: arena_vec.hh:329
void create_zero_values() override
Create zero_values_ object.
PatchPointValues(uint dim, uint quad_order, PatchFeData &patch_fe_data)
Constructor.
PatchPointValues(uint dim, std::vector< PatchOp< spacedim > * > &operations, PatchFeData &patch_fe_data)
Specialized constructor of zero values object. Do not use in other cases!
::PatchPointValues< spacedim >::PatchFeData PatchFeData
void init()
Initialize operations vector.
Bulk Side specialization, order of item in operations_ vector corresponds to the SideOps enum.
void create_zero_values() override
Create zero_values_ object.
PatchPointValues(uint dim, std::vector< PatchOp< spacedim > * > &operations, PatchFeData &patch_fe_data)
Specialized constructor of zero values object. Do not use in other cases!
void init()
Initialize operations vector.
::PatchPointValues< spacedim >::PatchFeData PatchFeData
PatchPointValues(uint dim, uint quad_order, PatchFeData &patch_fe_data)
Constructor.
Class represents element or FE operations.
Eigen::Vector< ArenaVec< double >, Eigen::Dynamic > result_
Result matrix of operation.
Eigen::Map< Eigen::Matrix< ArenaVec< double >, Eigen::Dynamic, Eigen::Dynamic > > result_sub_matrix(uint i_dof)
Return map referenced result of DOF values as Eigen::Matrix.
void reinit_function(FMT_UNUSED std::vector< PatchOp< spacedim > * > &operations, IntTableArena &int_table)
Call reinit function on element table if function is defined.
PatchOp(uint dim, std::initializer_list< uint > shape, ReinitFunction reinit_f, OpSizeType size_type, std::vector< PatchOp< spacedim > * > input_ops={}, uint n_dofs=1)
uint dim() const
Getter for dimension.
uint n_dofs() const
Getter for n_dofs_.
uint n_comp() const
std::vector< PatchOp< spacedim > * > input_ops_
Indices of operations in PatchPointValues::operations_ vector on which PatchOp is depended.
PatchOp< spacedim > * input_ops(uint i_op) const
Return pointer to operation of i_op index in input operation vector.
Eigen::Vector< ArenaVec< double >, Eigen::Dynamic > & raw_result()
Return map referenced result as Eigen::Vector.
uint dim_
Dimension.
OpSizeType size_type_
Type of operation by size of vector (element, point or fixed size)
const std::vector< uint > & shape() const
Getter for shape_.
std::string format_shape() const
std::vector< uint > set_shape_vec(std::initializer_list< uint > shape) const
Aligns shape_vec to 2 items (equal to matrix number of dimensions)
OpSizeType size_type() const
Getter for size_type_.
Eigen::Map< Eigen::Matrix< ArenaVec< double >, Eigen::Dynamic, Eigen::Dynamic > > result_matrix()
Return map referenced result as Eigen::Vector.
std::vector< uint > shape_
Shape of stored data (size of vector or number of rows and cols of matrix)
void allocate_const_result(ArenaVec< double > &value_vec)
void allocate_result(size_t data_size, PatchArena &arena)
ReinitFunction reinit_func
Pointer to patch reinit function of element data table specialized by operation.
const Eigen::Vector< ArenaVec< double >, Eigen::Dynamic > & raw_result() const
Same as previous but return const reference.
uint n_dofs_
Number of DOFs of FE operations (or 1 in case of element operations)
void print_data_tables(ostream &stream, bool points, bool ints) const
PatchPointValues * zero_values()
PatchArena & patch_arena() const
return reference to patch arena
Scalar scalar_elem_value(uint op_idx, uint point_idx) const
PatchPointValues(uint dim, PatchFeData &patch_fe_data)
std::vector< uint > points_map_
Map of point patch indices to PatchOp::result_ and int_table_ tables.
uint register_bulk_point(uint elem_table_row, uint value_patch_idx, uint elem_idx, uint i_point_on_elem)
uint register_element(arma::mat coords, uint element_patch_idx)
void resize_tables(uint n_elems, uint n_points)
Resize data tables. Method is called before reinit of patch.
PatchOp< spacedim > * make_new_op(uint op_idx, std::initializer_list< uint > shape, ReinitFunction reinit_f, OpSizeType size_type=pointOp)
friend class PatchOp< spacedim >
Tensor tensor_elem_value(uint op_idx, uint point_idx) const
Quadrature * get_quadrature() const
Getter for quadrature.
PatchOp< spacedim > * make_fe_op(uint op_idx, std::initializer_list< uint > shape, ReinitFunction reinit_f, uint n_dofs, OpSizeType size_type=pointOp)
uint n_elems() const
Getter for n_elems_.
uint i_elem_
Index of registered element in table, helper value used during patch creating.
PatchFeData & patch_fe_data_
Reference to PatchFeData structure shared with PatchFeValues.
void reset()
Reset number of columns (points and elements)
uint n_points() const
Getter for n_points_.
std::vector< uint > elements_map_
Map of element patch indices to PatchOp::result_ and int_table_ tables.
uint dim() const
Getter for dim_.
Tensor tensor_value(uint op_idx, uint point_idx, uint i_dof=0) const
Scalar scalar_value(uint op_idx, uint point_idx, uint i_dof=0) const
void zero_values_needed()
Set flag needs_zero_values_ to true.
uint register_side(arma::mat elm_coords, arma::mat side_coords, uint side_idx)
PatchOp< spacedim > * make_fixed_fe_op(uint op_idx, std::initializer_list< uint > shape, ReinitFunction reinit_f, uint n_dofs)
AssemblyArena & asm_arena() const
return reference to assembly arena
uint register_side_point(uint elem_table_row, uint value_patch_idx, uint elem_idx, uint side_idx, uint i_point_on_side)
PatchOp< spacedim > * make_fixed_op(uint op_idx, std::initializer_list< uint > shape, ReinitFunction reinit_f)
virtual void create_zero_values()=0
Create zero_values_ object.
IntTableArena int_table_
uint n_points_
Number of points in patch.
void print_operations(ostream &stream, uint bulk_side) const
Quadrature * quad_
Quadrature of given dimension and order passed in constructor.
Vector vector_elem_value(uint op_idx, uint point_idx) const
PatchPointValues * zero_values_
PatchPointValues object returns zero values for all operations.
std::vector< std::vector< unsigned int > > op_dependency_
Holds dependency between operations.
std::vector< OpSizeType > int_sizes_
Set size and type of rows of int_table_, value is set implicitly in constructor of descendants.
Vector vector_value(uint op_idx, uint point_idx, uint i_dof=0) const
uint n_elems_
Number of elements in patch.
std::vector< PatchOp< spacedim > * > operations_
Vector of all defined operations.
bool needs_zero_values_
Flags hold whether zero_values_ object is needed.
void create_zero_operations(std::vector< PatchOp< spacedim > * > &ref_ops)
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::Matrix< ArenaVec< double >, dim, 1 > normal_vector_array(ArenaVec< uint > loc_side_idx_vec)
Definition: ref_element.cc:280
Store finite element data on the actual patch such as shape function values, gradients,...
Eigen::Vector< ArenaVec< uint >, Eigen::Dynamic > IntTableArena
Definition: eigen_tools.hh:39
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
@ opVectorSymGrad
Vector symmetric gradient.
@ opVectorDivergence
Vector divergence.
@ opScalarShape
FE operations.
@ opCoords
operations evaluated on quadrature points
@ opVectorShape
Vector shape operation.
@ opRefScalarGrad
Gradient scalar reference.
@ opGradVectorShape
Vector shape gradient.
@ opInvJac
inverse Jacobian
@ opGradScalarShape
Scalar shape gradient.
@ opWeights
fixed operations (reference data filled once during initialization)
@ opNItems
Holds number of valid FE operations and value of invalid FE operation.
@ opJac
Jacobian of element.
@ opElCoords
operations evaluated on elements
@ opRefVector
Vector reference.
@ opRefScalar
Scalar reference.
@ opGradVectorShape
Vector shape gradient.
@ opRefScalarGrad
Gradient scalar reference.
@ opSideCoords
operations evaluated on sides
@ opVectorDivergence
Vector divergence.
@ opJxW
JxW value of quadrature point.
@ opCoords
operations evaluated on quadrature points
@ opNItems
Holds number of valid FE operations and value of invalid FE operation.
@ opGradScalarShape
Scalar shape gradient.
@ opVectorShape
Vector shape operation.
@ opVectorSymGrad
Vector symmetric gradient.
@ opElCoords
operations evaluated on elements
@ opScalarShape
FE operations.
@ opRefScalar
Scalar reference.
@ opElJac
Jacobian of element.
@ opWeights
fixed operations (reference data filled once during initialization)
@ opSideJac
Jacobian of element.
@ opRefVector
Vector reference.
std::function< void(PatchOp< 3 > *, IntTableArena &)> 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.
AssemblyArena asm_arena_
Assembly arena, created and filled once during initialization.
ArenaVec< double > zero_vec_
ArenaVec of zero values of maximal length using in zero PatchPointValues construction.
PatchFeData(size_t buffer_size, size_t simd_alignment)
Constructor.
PatchArena * patch_arena_
Patch arena, reseted before patch reinit.
Defines reinit operations on bulk points.
static void ptop_vector_shape_grads(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_contravariant_shape_grads(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_scalar_shape_grads(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void elop_jac(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_piola_shape(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_JxW(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_scalar_shape(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void elop_jac_det(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_contravariant_shape(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void elop_inv_jac(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_shape(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_coords(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_piola_shape_grads(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
Defines common functionality of reinit operations.
static void elop_jac(PatchOp< 3 > *result_op)
static void op_base(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_sym_grad(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
Common reinit function of vector symmetric gradient on bulk and side points.
static void ptop_vector_divergence(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
Common reinit function of vector divergence on bulk and side points.
static void ptop_JxW(PatchOp< 3 > *result_op)
static void elop_jac_det(PatchOp< 3 > *result_op)
static void elop_inv_jac(PatchOp< 3 > *result_op)
Defines reinit operations on side points.
static void ptop_vector_contravariant_shape(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_normal_vec(PatchOp< 3 > *result_op, IntTableArena &el_table)
static void ptop_vector_shape(PatchOp< 3 > *result_op, IntTableArena &el_table)
static void ptop_vector_contravariant_shape_grads(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_piola_shape(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_vector_shape_grads(PatchOp< 3 > *result_op, IntTableArena &el_table)
static void ptop_scalar_shape_grads(PatchOp< 3 > *result_op, IntTableArena &el_table)
static void ptop_vector_piola_shape_grads(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_scalar_shape(PatchOp< 3 > *result_op, IntTableArena &el_table)
static void elop_sd_jac_det(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void elop_el_jac(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_JxW(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void ptop_coords(FMT_UNUSED PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void elop_el_inv_jac(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)
static void elop_sd_jac(PatchOp< 3 > *result_op, FMT_UNUSED IntTableArena &el_table)