Flow123d  DF_patch_fe_darcy_complete-579fe1e
op_function.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 op_function.hh
15  * @brief Store finite element reinit functions.
16  * @author David Flanderka
17  */
18 
19 #ifndef OP_FUNCTION_HH_
20 #define OP_FUNCTION_HH_
21 
22 #include "fem/patch_op.hh"
23 #include "fem/patch_fe_values.hh"
24 
25 
26 
27 namespace Op {
28 
29 /// Class used as template type for type resolution Bulk / Side
30 class BulkDomain {
31 public:
32  static ElemDomain domain() {
34  }
35 
36  static inline constexpr uint n_nodes(uint dim) {
37  return dim+1;
38  }
39 
40  /// Return number of mesh entities (in this case elements) on patch
42  return ppv.elem_dim_list_->size();
43  }
44 
45  /// Return i_n-th node of i_elm-th element stored in PatchPointValues::elem_dim_list_
46  static inline NodeAccessor<3> node(PatchPointValues<3> &ppv, unsigned int i_elm, unsigned int i_n) {
47  return (*ppv.elem_dim_list_)[i_elm].node(i_n);
48  }
49 };
50 
51 /// Class used as template type for type resolution Bulk / Side
52 class SideDomain {
53 public:
54  static ElemDomain domain() {
56  }
57 
58  static inline constexpr uint n_nodes(uint dim) {
59  return dim;
60  }
61 
62  /// Return number of mesh entities (in this case sides) on patch
64  return ppv.side_list_.size();
65  }
66 
67  /// Return i_n-th node of i_elm-th side stored in PatchPointValues::side_list_
68  static inline NodeAccessor<3> node(PatchPointValues<3> &ppv, unsigned int i_elm, unsigned int i_n) {
69  return ppv.side_list_[i_elm].node(i_n);
70  }
71 };
72 
73 
74 /**
75  * Evaluates node coordinates on Bulk (Element) / Side
76  *
77  * Template parameters:
78  * dim Dimension of operation
79  * ElDomain Target domain - data are evaluated on Bulk / Side domain
80  * Domain Source domain - operation is called from Bulk / Side domain
81  * spacedim Dimension of the solved task
82  */
83 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
84 class Coords : public PatchOp<spacedim> {
85 public:
86  /// Constructor
88  : PatchOp<spacedim>(dim, pfev, quad, {spacedim, Domain::n_nodes(dim)}) {
89  this->domain_ = Domain::domain();
90  }
91 
92  void eval() override {
94  uint n_elems = Domain::n_mesh_entities(ppv); // number of elements or sides on patch
95  this->allocate_result( n_elems, this->patch_fe_->patch_arena() );
96  auto result = this->result_matrix();
97 
98  for (uint i_elm=0; i_elm<n_elems; ++i_elm)
99  for (uint i_col=0; i_col<Domain::n_nodes(dim); ++i_col)
100  for (uint i_row=0; i_row<spacedim; ++i_row) {
101  result(i_row, i_col)(i_elm) = ( *Domain::node(ppv, i_elm, i_col) )(i_row);
102  }
103  }
104 
105 };
106 
107 /// Evaluates Jacobians on Bulk (Element) / Side
108 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
109 class Jac : public PatchOp<spacedim> {
110 public:
111  /// Constructor
113  : PatchOp<spacedim>(dim, pfev, quad, {spacedim, Domain::n_nodes(dim)-1})
114  {
115  this->domain_ = Domain::domain();
116  this->input_ops_.push_back( pfev.template get< Op::Coords<dim, Domain, spacedim>, dim >(quad) );
117  }
118 
119  void eval() override {
120  auto jac_value = this->result_matrix();
121  auto coords_value = this->input_ops(0)->result_matrix();
122  for (unsigned int i=0; i<spacedim; i++)
123  for (unsigned int j=0; j<Domain::n_nodes(dim)-1; j++)
124  jac_value(i,j) = coords_value(i,j+1) - coords_value(i,0);
125  }
126 };
127 
128 /// Evaluates Jacobian determinants on Bulk (Element) / Side
129 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
130 class JacDet : public PatchOp<spacedim> {
131 public:
132  /// Constructor
134  : PatchOp<spacedim>(dim, pfev, quad, {1})
135  {
136  this->domain_ = Domain::domain();
137  this->input_ops_.push_back( pfev.template get< Op::Jac<dim, Domain, spacedim>, dim >(quad) );
138  }
139 
140  void eval() override {
141  auto jac_det_value = this->result_matrix();
142  auto jac_value = this->input_ops(0)->result_matrix();
143  jac_det_value(0) = eigen_arena_tools::determinant<spacedim, Domain::n_nodes(dim)-1>(jac_value).abs();
144  }
145 };
146 
147 /// Template specialization of previous: dim=1, domain=Side
148 template<>
149 class JacDet<1, Op::SideDomain, 3> : public PatchOp<3> {
150 public:
151  /// Constructor
152  JacDet(PatchFEValues<3> &pfev, const Quadrature *quad)
153  : PatchOp<3>(1, pfev, quad, {1})
154  {
156  }
157 
158  void eval() override {
159  PatchPointValues<3> &ppv = this->ppv();
160  uint n_sides = ppv.n_mesh_items();
161  this->allocate_result( n_sides, this->patch_fe_->patch_arena() );
162  auto jac_det_value = this->result_matrix();
163  for (uint i=0;i<n_sides; ++i) {
164  jac_det_value(0,0)(i) = 1.0;
165  }
166  }
167 };
168 
169 /**
170  * Evaluates Inverse Jacobians on Bulk (Element) / Side
171  * ElDomain (target) is always Bulk
172  */
173 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
174 class InvJac : public PatchOp<spacedim> {
175 public:
176  /// Constructor
178  : PatchOp<spacedim>(dim, pfev, quad, {dim, spacedim})
179  {
180  this->domain_ = Domain::domain();
181  this->input_ops_.push_back( pfev.template get< Op::Jac<dim, Domain, spacedim>, dim >(quad) );
182  }
183 
184  void eval() override {
185  auto inv_jac_value = this->result_matrix();
186  auto jac_value = this->input_ops(0)->result_matrix();
187  inv_jac_value = eigen_arena_tools::inverse<spacedim, dim>(jac_value);
188  }
189 };
190 
191 
192 /**
193  * Holds common functionality of patch operations.
194  */
195 template<unsigned int spacedim = 3>
196 class FuncHelper {
197 public:
198  /**
199  * Copy reduced data from 'source' to 'target' ArenaVec. Mapping of reduced data is giben by 'ppv' data.
200  */
202  for (uint i_el=0; i_el<ppv.n_mesh_items(); ++i_el) {
203  target( i_el ) = source( ppv.int_table_(patch_elem_on_domain)(i_el) );
204  }
205  }
206 private:
207  /// Forbidden constructor
209 };
210 
211 
212 /// Reference data of PtCoords operation
213 /// TODO need specializations for SideDomain<dim> and SideDomain<1>
214 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
215 class RefBaryCoords : public PatchOp<spacedim> {
216 public:
217  /// Constructor
219  : PatchOp<spacedim>(dim, pfev, quad, {dim+1})
220  {
221  this->domain_ = Domain::domain();
222  double n_points = quad->size();
223  this->allocate_result(n_points, pfev.asm_arena());
224  for (uint i_p=0; i_p<n_points; ++i_p) {
225  auto ref_bar_coords = RefElement<dim>::local_to_bary(quad->point<dim>(i_p));
226  for (uint i_c=0; i_c<dim+1; ++i_c)
227  this->result_(i_c)(i_p) = ref_bar_coords[i_c];
228  }
229  }
230 
231  void eval() override {}
232 };
233 
234 /// Evaluates coordinates of quadrature points - not implemented yet
235 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
236 class PtCoords : public PatchOp<spacedim> {
237 public:
238  /// Constructor
240  : PatchOp<spacedim>(dim, pfev, quad, {spacedim})
241  {
242  this->domain_ = Domain::domain();
243  this->input_ops_.push_back( pfev.template get< Op::Coords<dim, Domain, spacedim>, dim >( pfev.element_quad(dim) ) );
244  this->input_ops_.push_back( pfev.template get< Op::RefBaryCoords<dim, Domain, spacedim>, dim >(quad) );
245  }
246 
247  void eval() override {
248  auto coords_vec_elem = this->input_ops(0)->result_matrix(); // bulk: spacedim x (dim+1), side: spacedim x dim
249  auto ref_bary_vec = this->input_ops(1)->result_matrix(); // bulk: dim+1, side: dim
250 
251  // Copy coords vector of elements registered on patch, convert to ovec
253  uint n_elems = ppv.n_mesh_items();
254  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> coords_vec(spacedim, Domain::n_nodes(dim));
255  Eigen::Matrix<ArenaOVec<double>, spacedim, Domain::n_nodes(dim)> coords_ovec;
256  for (uint i=0; i<spacedim*Domain::n_nodes(dim); ++i) {
257  coords_vec(i) = ArenaVec<double>( n_elems, this->patch_fe_->patch_arena() );
258  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, coords_vec_elem(i), coords_vec(i) );
259  coords_ovec(i) = ArenaOVec<double>( coords_vec(i) );
260  }
261 
262  // Convert ref_bary_vec to ovec
263  Eigen::Vector<ArenaOVec<double>, Eigen::Dynamic> ref_bary_ovec(Domain::n_nodes(dim));
264  for (uint i=0; i<Domain::n_nodes(dim); ++i) {
265  ref_bary_ovec(i) = ArenaOVec<double>( ref_bary_vec(i) );
266  }
267 
268  auto result_vec = this->result_matrix();
269  Eigen::Vector<ArenaOVec<double>, Eigen::Dynamic> result_ovec = coords_ovec * ref_bary_ovec;
270  for (uint i=0; i<spacedim; ++i) {
271  result_vec(i) = result_ovec(i).get_vec();
272  }
273  }
274 };
275 
276 /**
277  * Fixed operation points weights
278  * ElDomain (target) is equivalent with Domain (source)
279  */
280 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
281 class Weights : public PatchOp<spacedim> {
282 public:
283  /// Constructor
285  : PatchOp<spacedim>(dim, pfev, quad, {1})
286  {
287  this->domain_ = Domain::domain();
288  // create result vector of weights operation in assembly arena
289  const std::vector<double> &point_weights_vec = quad->get_weights();
290  this->allocate_result(point_weights_vec.size(), pfev.asm_arena());
291  for (uint i=0; i<point_weights_vec.size(); ++i)
292  this->result_(0)(i) = point_weights_vec[i];
293  }
294 
295  void eval() override {}
296 };
297 
298 
299 /**
300  * Evaluates JxW on quadrature points
301  */
302 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
303 class JxW : public PatchOp<spacedim> {
304 public:
305  /// Constructor
307  : PatchOp<spacedim>(dim, pfev, quad, {1})
308  {
309  this->domain_ = Domain::domain();
310  this->input_ops_.push_back( pfev.template get< Op::Weights<dim, Domain, spacedim>, dim >(quad) );
311  this->input_ops_.push_back( pfev.template get< Op::JacDet<dim, Domain, spacedim>, dim >(pfev.element_quad(dim)) );
312  }
313 
314  void eval() override {
315  auto weights_value = this->input_ops(0)->result_matrix();
316  auto jac_det_value_long = this->input_ops(1)->result_matrix();
317 
318  // Copy InvJac vector of elements registered on patch
320  uint n_elems = ppv.n_mesh_items();
321  ArenaVec<double> jac_det_value( n_elems, this->patch_fe_->patch_arena() );
322  FuncHelper<spacedim>::fill_reduce_element_data_vec(ppv, jac_det_value_long( 0 ), jac_det_value);
323 
324  ArenaOVec<double> weights_ovec( weights_value(0,0) );
325  ArenaOVec<double> jac_det_ovec( jac_det_value );
326  ArenaOVec<double> jxw_ovec = jac_det_ovec * weights_ovec;
327  this->result_(0) = jxw_ovec.get_vec();
328  }
329 };
330 
331 template<unsigned int dim, unsigned int spacedim>
332 class JxW<dim, Op::SideDomain, spacedim> : public PatchOp<spacedim> {
333 public:
334  /// Constructor
336  : PatchOp<spacedim>(dim, pfev, quad, {1})
337  {
339  this->input_ops_.push_back( pfev.template get< Op::Weights<dim, Op::SideDomain, spacedim>, dim >(quad) );
340  this->input_ops_.push_back( pfev.template get< Op::JacDet<dim, Op::SideDomain, spacedim>, dim >(pfev.element_quad(dim)) );
341  }
342 
343  void eval() override {
344  auto weights_value = this->input_ops(0)->result_matrix();
345  auto jac_det_value = this->input_ops(1)->result_matrix();
346  ArenaOVec<double> weights_ovec( weights_value(0,0) );
347  ArenaOVec<double> jac_det_ovec( jac_det_value(0,0) );
348  ArenaOVec<double> jxw_ovec = jac_det_ovec * weights_ovec;
349  this->result_(0) = jxw_ovec.get_vec();
350  }
351 };
352 
353 /// Evaluates normal vector on side quadrature points
354 template<unsigned int dim, unsigned int spacedim = 3>
355 class NormalVec : public PatchOp<spacedim> {
356 public:
357  /// Constructor
359  : PatchOp<spacedim>(dim, pfev, quad, {spacedim})
360  {
362  this->input_ops_.push_back( pfev.template get< Op::InvJac<dim, Op::BulkDomain, spacedim>, dim >(quad) );
363  }
364 
365  void eval() override {
367  auto normal_value = this->result_matrix();
368  auto inv_jac_value_elem = this->input_ops(0)->result_matrix(); // returns vector of inverse jacobians of all elements registered on patch
369 
370  // Copy InvJac vector of sides registered on patch
371  uint n_sides = ppv.n_mesh_items();
372  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> inv_jac_value(dim, spacedim);
373  for (uint i=0; i<dim*spacedim; ++i) {
374  inv_jac_value(i) = ArenaVec<double>( n_sides, this->patch_fe_->patch_arena() );
375  }
376  for (uint i_c=0; i_c<dim*spacedim; ++i_c) {
377  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, inv_jac_value_elem(i_c), inv_jac_value(i_c) );
378  }
379 
380  normal_value = inv_jac_value.transpose() * RefElement<dim>::normal_vector_array( ppv.int_table_(ref_side_on_sides) );
381 
382  ArenaVec<double> norm_vec( n_sides, this->patch_fe_->patch_arena() );
383  Eigen::VectorXd A(3);
384  for (uint i=0; i<normal_value(0).data_size(); ++i) {
385  A(0) = normal_value(0)(i);
386  A(1) = normal_value(1)(i);
387  A(2) = normal_value(2)(i);
388  norm_vec(i) = A.norm();
389  }
390 
391  for (uint i=0; i<spacedim; ++i) {
392  normal_value(i) = normal_value(i) / norm_vec;
393  }
394  }
395 };
396 
397 /// Fixed operation of scalar shape reference values
398 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
399 class RefScalar : public PatchOp<spacedim> {
400 public:
401  /// Constructor
402  RefScalar(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
403  : PatchOp<spacedim>(dim, pfev, quad, {1}, fe->n_dofs())
404  {
405  this->domain_ = Domain::domain();
406  uint n_points = quad->size();
407 
408  this->allocate_result(n_points, pfev.asm_arena());
409  auto ref_scalar_value = this->result_matrix();
410  for (unsigned int i_p = 0; i_p < n_points; i_p++)
411  for (unsigned int i_dof = 0; i_dof < this->n_dofs_; i_dof++)
412  ref_scalar_value(i_dof)(i_p) = fe->shape_value(i_dof, quad->point<dim>(i_p));
413  }
414 
415  void eval() override {}
416 };
417 
418 /// Template specialization of previous: Domain=SideDomain
419 template<unsigned int dim, unsigned int spacedim>
420 class RefScalar<dim, Op::SideDomain, spacedim> : public PatchOp<spacedim> {
421 public:
422  /// Constructor
423  RefScalar(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
424  : PatchOp<spacedim>(dim, pfev, quad, {dim+1}, fe->n_dofs())
425  {
427  uint n_points = quad->size();
428 
429  this->allocate_result(n_points, pfev.asm_arena());
430  auto ref_scalar_value = this->result_matrix();
431  for (unsigned int s=0; s<dim+1; ++s) {
432  Quadrature side_q = quad->make_from_side<dim>(s);
433  for (unsigned int i_p = 0; i_p < n_points; i_p++)
434  for (unsigned int i_dof = 0; i_dof < this->n_dofs_; i_dof++)
435  ref_scalar_value(s, i_dof)(i_p) = fe->shape_value(i_dof, side_q.point<dim>(i_p));
436  }
437  }
438 
439  void eval() override {}
440 };
441 
442 /// Fixed operation of vector shape reference values
443 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
444 class RefVector : public PatchOp<spacedim> {
445 public:
446  /// Constructor
447  RefVector(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
448  : PatchOp<spacedim>(dim, pfev, quad, {fe->n_components()}, fe->n_dofs())
449  {
450  this->domain_ = Domain::domain();
451  uint n_points = quad->size();
452 
453  this->allocate_result(n_points, pfev.asm_arena());
454  auto ref_vector_value = this->result_matrix();
455 
456  for (uint i_dof=0; i_dof<this->n_dofs_; ++i_dof)
457  for (uint i_p=0; i_p<n_points; ++i_p)
458  for (uint c=0; c<fe->n_components(); ++c)
459  ref_vector_value(c, i_dof)(i_p) = fe->shape_value(i_dof, quad->point<dim>(i_p), c);
460  }
461 
462  void eval() override {}
463 };
464 
465 /// Template specialization of previous: Domain=SideDomain
466 template<unsigned int dim, unsigned int spacedim>
467 class RefVector<dim, Op::SideDomain, spacedim> : public PatchOp<spacedim> {
468 public:
469  /// Constructor
470  RefVector(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
471  : PatchOp<spacedim>(dim, pfev, quad, {dim+1, fe->n_components()}, fe->n_dofs())
472  {
474  uint n_points = quad->size();
475 
476  this->allocate_result(n_points, pfev.asm_arena());
477  auto ref_vector_value = this->result_matrix();
478 
479  for (unsigned int s=0; s<dim+1; ++s) {
480  Quadrature side_q = quad->make_from_side<dim>(s);
481  for (unsigned int i_p = 0; i_p < n_points; i_p++)
482  for (unsigned int i_dof = 0; i_dof < this->n_dofs_; i_dof++)
483  for (uint c=0; c<fe->n_components(); ++c)
484  ref_vector_value(s,fe->n_components()*i_dof+c)(i_p) = fe->shape_value(i_dof, side_q.point<dim>(i_p), c);
485  }
486  }
487 
488  void eval() override {}
489 };
490 
491 /// Fixed operation of gradient scalar reference values
492 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
493 class RefGradScalar : public PatchOp<spacedim> {
494 public:
495  /// Constructor
496  RefGradScalar(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
497  : PatchOp<spacedim>(dim, pfev, quad, {dim, 1}, fe->n_dofs())
498  {
499  this->domain_ = Domain::domain();
500  uint n_points = quad->size();
501 
502  this->allocate_result(n_points, pfev.asm_arena());
503  auto ref_scalar_value = this->result_matrix();
504  for (uint i_row=0; i_row<ref_scalar_value.rows(); ++i_row)
505  for (uint i_dof=0; i_dof<this->n_dofs_; ++i_dof)
506  for (uint i_p=0; i_p<n_points; ++i_p)
507  ref_scalar_value(i_row, i_dof)(i_p) = fe->shape_grad(i_dof, quad->point<dim>(i_p))[i_row];
508  }
509 
510  void eval() override {}
511 };
512 
513 /// Template specialization of previous: Domain=SideDomain
514 template<unsigned int dim, unsigned int spacedim>
515 class RefGradScalar<dim, Op::SideDomain, spacedim> : public PatchOp<spacedim> {
516 public:
517  /// Constructor
518  RefGradScalar(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
519  : PatchOp<spacedim>(dim, pfev, quad, {dim+1, dim}, fe->n_dofs())
520  {
522  uint n_points = quad->size();
523 
524  this->allocate_result(n_points, pfev.asm_arena());
525  auto ref_scalar_value = this->result_matrix();
526  for (unsigned int s=0; s<dim+1; ++s) {
527  Quadrature side_q = quad->make_from_side<dim>(s);
528  for (uint i_dof=0; i_dof<this->n_dofs_; ++i_dof)
529  for (uint i_p=0; i_p<n_points; ++i_p)
530  for (uint c=0; c<dim; ++c)
531  ref_scalar_value(s,dim*i_dof+c)(i_p) = fe->shape_grad(i_dof, side_q.point<dim>(i_p))[c];
532  }
533  }
534 
535  void eval() override {}
536 };
537 
538 /// Fixed operation of gradient scalar reference values
539 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
540 class RefGradVector : public PatchOp<spacedim> {
541 public:
542  /// Constructor
543  RefGradVector(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
544  : PatchOp<spacedim>(dim, pfev, quad, {dim, fe->n_components()}, fe->n_dofs())
545  {
546  this->domain_ = Domain::domain();
547  uint n_points = quad->size();
548  uint n_comp = fe->n_components();
549 
550  this->allocate_result(n_points, pfev.asm_arena());
551  auto ref_vector_value = this->result_matrix();
552  for (uint i_c=0; i_c<n_comp; ++i_c) {
553  for (uint i_dim=0; i_dim<dim; ++i_dim)
554  for (uint i_dof=0; i_dof<this->n_dofs_; ++i_dof)
555  for (uint i_p=0; i_p<n_points; ++i_p)
556  ref_vector_value(i_dim,n_comp*i_dof+i_c)(i_p) = fe->shape_grad(i_dof, quad->point<dim>(i_p), i_c)[i_dim];
557  }
558  }
559 
560  void eval() override {}
561 };
562 
563 /// Template specialization of previous: Domain=SideDomain
564 template<unsigned int dim, unsigned int spacedim>
565 class RefGradVector<dim, Op::SideDomain, spacedim> : public PatchOp<spacedim> {
566 public:
567  /// Constructor
568  RefGradVector(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
569  : PatchOp<spacedim>(dim, pfev, quad, {(dim+1)*dim, fe->n_components()}, fe->n_dofs())
570  {
572  uint n_points = quad->size();
573  uint n_sides = dim+1;
574  uint n_comp = fe->n_components();
575 
576  this->allocate_result(n_points, pfev.asm_arena());
577  auto ref_vector_value = this->result_matrix();
578  for (uint i_sd=0; i_sd<n_sides; ++i_sd) {
579  Quadrature side_q = quad->make_from_side<dim>(i_sd);
580  for (uint i_c=0; i_c<n_comp; ++i_c)
581  for (uint i_dim=0; i_dim<dim; ++i_dim)
582  for (uint i_dof=0; i_dof<this->n_dofs_; ++i_dof)
583  for (uint i_p=0; i_p<n_points; ++i_p)
584  ref_vector_value(i_sd*dim+i_dim, n_comp*i_dof+i_c)(i_p) = fe->shape_grad(i_dof, side_q.point<dim>(i_p), i_c)[i_dim];
585  }
586  }
587 
588  void eval() override {}
589 };
590 
591 /// Evaluates scalar shape values
592 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
593 class ScalarShape : public PatchOp<spacedim> {
594 public:
595  /// Constructor
596  ScalarShape(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
597  : PatchOp<spacedim>(dim, pfev, quad, {1}, fe->n_dofs())
598  {
599  ASSERT_EQ(fe->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape must be FEScalar!\n");
600  this->domain_ = Domain::domain();
601  this->input_ops_.push_back( pfev.template get< Op::RefScalar<dim, Domain, spacedim>, dim >(quad, fe) );
602  }
603 
604  void eval() override {
605  auto ref_vec = this->input_ops(0)->result_matrix();
606  auto result_vec = this->result_matrix();
607 
608  uint n_dofs = this->n_dofs();
609  uint n_elem = this->ppv().n_mesh_items();
610 
611  ArenaVec<double> elem_vec(n_elem, this->patch_fe_->patch_arena());
612  for (uint i=0; i<n_elem; ++i) {
613  elem_vec(i) = 1.0;
614  }
615  ArenaOVec<double> elem_ovec(elem_vec);
616 
617  Eigen::Vector<ArenaOVec<double>, Eigen::Dynamic> ref_ovec(n_dofs);
618  for (uint i=0; i<n_dofs; ++i) {
619  ref_ovec(i) = ArenaOVec<double>( ref_vec(i) );
620  }
621 
622  Eigen::Vector<ArenaOVec<double>, Eigen::Dynamic> result_ovec = elem_ovec * ref_ovec;
623  for (uint i=0; i<n_dofs; ++i) {
624  result_vec(i) = result_ovec(i).get_vec();
625  }
626  }
627 };
628 
629 /// Template specialization of previous: Domain=SideDomain
630 template<unsigned int dim, unsigned int spacedim>
631 class ScalarShape<dim, Op::SideDomain, spacedim> : public PatchOp<spacedim> {
632 public:
633  /// Constructor
634  ScalarShape(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
635  : PatchOp<spacedim>(dim, pfev, quad, {1}, fe->n_dofs())
636  {
637  ASSERT_EQ(fe->fe_type(), FEType::FEScalar).error("Type of FiniteElement of scalar_shape must be FEScalar!\n");
639  this->input_ops_.push_back( pfev.template get< Op::RefScalar<dim, Op::SideDomain, spacedim>, dim >(quad, fe) );
640  }
641 
642  void eval() override {
644  uint n_dofs = this->n_dofs();
645  uint n_sides = ppv.n_mesh_items(); // number of sides on patch
646  uint n_patch_points = n_sides * this->quad_->size(); // number of points on patch
647 
648  this->allocate_result(n_patch_points, this->patch_fe_->patch_arena());
649 
650  auto ref_vec = this->input_ops(0)->result_matrix();
651  auto result_vec = this->result_matrix();
652 
653  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
654  for (uint i_pt=0; i_pt<n_patch_points; ++i_pt) {
655  result_vec(i_dof)(i_pt) = ref_vec(ppv.int_table_(ref_side_on_quads)(i_pt), i_dof)(i_pt / n_sides);
656  }
657  }
658  }
659 };
660 
661 /// Evaluates vector values (FEType == FEVector)
662 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
663 class VectorShape : public PatchOp<spacedim> {
664 public:
665  /// Constructor
666  VectorShape(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe, PatchOp<spacedim> &dispatch_op)
667  : PatchOp<spacedim>(dim, pfev, quad, {spacedim}, fe->n_dofs()), dispatch_op_(dispatch_op)
668  {
669  this->domain_ = Domain::domain();
670  this->input_ops_.push_back( pfev.template get< Op::RefVector<dim, Domain, spacedim>, dim >(quad, fe) );
671  }
672 
673  void eval() override {
674  auto ref_shape_vec = this->input_ops(0)->result_matrix();
675  auto result_vec = dispatch_op_.result_matrix();
676 
677  uint n_dofs = this->n_dofs();
678  uint n_elem = this->ppv().n_mesh_items();
679 
680  ArenaVec<double> elem_vec(n_elem, this->patch_fe_->patch_arena());
681  for (uint i=0; i<n_elem; ++i) {
682  elem_vec(i) = 1.0;
683  }
684  ArenaOVec<double> elem_ovec(elem_vec);
685 
686  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> ref_shape_ovec(spacedim, n_dofs);
687  for (uint c=0; c<spacedim*n_dofs; ++c) {
688  ref_shape_ovec(c) = ArenaOVec(ref_shape_vec(c));
689  }
690 
691  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> result_ovec = elem_ovec * ref_shape_ovec;
692  for (uint c=0; c<spacedim*n_dofs; ++c)
693  result_vec(c) = result_ovec(c).get_vec();
694  }
695 
696 private:
698 };
699 
700 /// Template specialization of previous: Domain=SideDomain)
701 template<unsigned int dim, unsigned int spacedim>
702 class VectorShape<dim, Op::SideDomain, spacedim> : public PatchOp<spacedim> {
703 public:
704  /// Constructor
705  VectorShape(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe, PatchOp<spacedim> &dispatch_op)
706  : PatchOp<spacedim>(dim, pfev, quad, {spacedim}, fe->n_dofs()), dispatch_op_(dispatch_op)
707  {
709  this->input_ops_.push_back( pfev.template get< Op::RefVector<dim, Op::SideDomain, spacedim>, dim >(quad, fe) );
710  }
711 
712  void eval() override {
714  uint n_dofs = this->n_dofs();
715  uint n_sides = ppv.n_mesh_items();
716  uint n_patch_points = n_sides * this->quad_->size();
717 
718  dispatch_op_.allocate_result(n_patch_points, this->patch_fe_->patch_arena());
719 
720  auto ref_shape_vec = this->input_ops(0)->result_matrix(); // dim+1 x spacedim
721  auto result_vec = dispatch_op_.result_matrix(); // spacdim x 1
722 
723  for (uint c=0; c<spacedim*n_dofs; c++)
724  result_vec(c) = ArenaVec<double>(n_patch_points, this->patch_fe_->patch_arena());
725 
726  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
727  for (uint i_pt=0; i_pt<n_patch_points; ++i_pt)
728  for (uint c=0; c<spacedim; c++)
729  result_vec(c,i_dof)(i_pt) = ref_shape_vec(ppv.int_table_(ref_side_on_quads)(i_pt),3*i_dof+c)(i_pt / n_sides);
730  }
731  }
732 
733 private:
735 };
736 
737 /// Evaluates vector values (FEType == FEVectorPiola)
738 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
739 class VectorPiolaShape : public PatchOp<spacedim> {
740 public:
741  /// Constructor
742  VectorPiolaShape(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe, PatchOp<spacedim> &dispatch_op)
743  : PatchOp<spacedim>(dim, pfev, quad, {spacedim}, fe->n_dofs()), dispatch_op_(dispatch_op)
744  {
745  this->domain_ = Domain::domain();
746  this->input_ops_.push_back( pfev.template get< Op::RefVector<dim, Domain, spacedim>, dim >(quad, fe) ); // input_ops_[0] ... RefVector dim x n_dofs
747  this->input_ops_.push_back( pfev.template get< Op::Jac<dim, Domain, spacedim>, dim >(pfev.element_quad(dim)) ); // input_ops_[1] ... Jac spacedim x dim
748  this->input_ops_.push_back( pfev.template get< Op::JacDet<dim, Domain, spacedim>, dim >(pfev.element_quad(dim)) ); // input_ops_[2] ... JacDet 1
749  }
750 
751  void eval() override {
752  auto ref_shape_vec = this->input_ops(0)->result_matrix();
753  auto jac_vec_elem = this->input_ops(1)->result_matrix();
754  auto jac_det_vec_elem = this->input_ops(2)->result_matrix();
755  auto result_vec = dispatch_op_.result_matrix();
756 
757  uint n_dofs = this->n_dofs();
758 
759  // Copy Jac and JacDet vector of elements registered on patch
761  uint n_elems = ppv.n_mesh_items();
762  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> jac_vec(spacedim, dim);
763  for (uint i=0; i<spacedim*dim; ++i) {
764  jac_vec(i) = ArenaVec<double>( n_elems, this->patch_fe_->patch_arena() );
765  }
766  for (uint i_c=0; i_c<spacedim*dim; ++i_c) {
767  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, jac_vec_elem(i_c), jac_vec(i_c) );
768  }
769  ArenaVec<double> jac_det_vec( n_elems, this->patch_fe_->patch_arena() );
770  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, jac_det_vec_elem(0), jac_det_vec );
771 
772  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> jac_div_det_vec = jac_vec / jac_det_vec;
773  Eigen::Matrix<ArenaOVec<double>, spacedim, dim> jac_div_det_ovec;
774  for (uint c=0; c<spacedim*dim; ++c) {
775  jac_div_det_ovec(c) = ArenaOVec<double>(jac_div_det_vec(c));
776  }
777 
778  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> ref_shape_ovec(dim, n_dofs);
779  for (uint c=0; c<dim*n_dofs; ++c) {
780  ref_shape_ovec(c) = ArenaOVec<double>(ref_shape_vec(c));
781  }
782 
783  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> result_ovec = jac_div_det_ovec * ref_shape_ovec;
784  for (uint c=0; c<spacedim*n_dofs; ++c) {
785  result_vec(c) = result_ovec(c).get_vec();
786  }
787  }
788 
789 private:
791 };
792 
793 /// Template specialization of previous: Domain=SideDomain)
794 template<unsigned int dim, unsigned int spacedim>
795 class VectorPiolaShape<dim, Op::SideDomain, spacedim> : public PatchOp<spacedim> {
796 public:
797  /// Constructor
798  VectorPiolaShape(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe, PatchOp<spacedim> &dispatch_op)
799  : PatchOp<spacedim>(dim, pfev, quad, {spacedim}, fe->n_dofs()), dispatch_op_(dispatch_op)
800  {
802  this->input_ops_.push_back( pfev.template get< Op::RefVector<dim, Op::SideDomain, spacedim>, dim >(quad, fe) ); // input_ops_[0] ... dim x n_dofs
803  this->input_ops_.push_back( pfev.template get< Op::Jac<dim, Op::BulkDomain, spacedim>, dim >(pfev.element_quad(dim)) ); // input_ops_[1] ... spacedim x dim
804  this->input_ops_.push_back( pfev.template get< Op::JacDet<dim, Op::BulkDomain, spacedim>, dim >(pfev.element_quad(dim)) ); // input_ops_[2] ... 1
805  }
806 
807  void eval() override {
809  uint n_dofs = this->n_dofs();
810  uint n_sides = ppv.n_mesh_items();
811  uint n_patch_points = n_sides * this->quad_->size();
812  uint n_points_per_side = this->quad_->size();
813  dispatch_op_.allocate_result(n_patch_points, this->patch_fe_->patch_arena());
814 
815  auto ref_shape_vec = this->input_ops(0)->result_matrix(); // dim+1 x n_dofs
816  auto jac_vec_elem = this->input_ops(1)->result_matrix();
817  auto jac_det_vec_elem = this->input_ops(2)->result_matrix();
818  auto result_vec = dispatch_op_.result_matrix(); // spacdim x 1
819 
820  // Copy Jac and JacDet vector of elements registered on patch
821  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> jac_vec(spacedim, dim);
822  for (uint i=0; i<spacedim*dim; ++i) {
823  jac_vec(i) = ArenaVec<double>( n_sides, this->patch_fe_->patch_arena() );
824  }
825  for (uint i_c=0; i_c<spacedim*dim; ++i_c) {
826  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, jac_vec_elem(i_c), jac_vec(i_c) );
827  }
828  ArenaVec<double> jac_det_vec( n_sides, this->patch_fe_->patch_arena() );
829  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, jac_det_vec_elem(0), jac_det_vec );
830 
831  // Computes jacobian / determinant and converts result to ArenaOVec
832  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> jac_div_det_vec = jac_vec / jac_det_vec;
833  Eigen::Matrix<ArenaOVec<double>, spacedim, dim> jac_div_det_ovec;
834  for (uint c=0; c<spacedim*dim; ++c) {
835  jac_div_det_ovec(c) = ArenaOVec(jac_div_det_vec(c));
836  }
837 
838  // Computes expand vector of previous result (jacobian / determinant)
839  ArenaVec<double> side_points_vec(n_points_per_side, this->patch_fe_->patch_arena());
840  for (uint i=0; i<n_points_per_side; ++i) {
841  side_points_vec(i) = 1.0;
842  }
843  ArenaOVec<double> side_points_ovec(side_points_vec);
844  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> expand_jac_div_det_ovec = jac_div_det_ovec * side_points_ovec;
845  Eigen::Matrix<ArenaVec<double>, spacedim, dim> expand_jac_div_det_vec;
846  for (uint c=0; c<spacedim*this->dim_; ++c) {
847  expand_jac_div_det_vec(c) = expand_jac_div_det_ovec(c).get_vec();
848  }
849 
850  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> expand_ref_vec(dim, n_dofs);
851  for (uint c=0; c<dim*n_dofs; c++)
852  expand_ref_vec(c) = ArenaVec<double>(n_patch_points, this->patch_fe_->patch_arena());
853 
854  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
855  for (uint i_pt=0; i_pt<n_points_per_side; ++i_pt) {
856  uint i_begin = i_pt * n_sides;
857  for (uint i_sd=0; i_sd<n_sides; ++i_sd) {
858  for (uint i_c=0; i_c<dim; ++i_c) {
859  expand_ref_vec(i_c, i_dof)(i_begin + i_sd) = ref_shape_vec(ppv.int_table_(ref_side_on_sides)(i_sd), i_dof*dim+i_c)(i_pt);
860  }
861  }
862  }
863  }
864 
865  // computes operation result
866  result_vec = expand_jac_div_det_vec * expand_ref_vec;
867  }
868 
869 private:
871 };
872 
873 // class OpVectorCovariantShape
874 // class OpVectorPiolaShape
875 
876 /// Dispatch class of vector values
877 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
878 class DispatchVectorShape : public PatchOp<spacedim> {
879 public:
880  /// Constructor
882  : PatchOp<spacedim>(dim, pfev, quad, {spacedim}, fe->n_dofs()), in_op_(nullptr)
883  {
884  this->domain_ = Domain::domain();
885  switch (fe->fe_type()) {
886  case FEVector:
887  {
888  in_op_ = new VectorShape<dim, Domain, spacedim>(pfev, quad, fe, *this);
889  break;
890  }
892  {
893  ASSERT_PERMANENT(false).error("Shape vector for FEVectorContravariant is not implemented yet!\n"); // temporary assert
894  //in_op_ = new VectorCovariantShape<dim, Domain, spacedim>(pfev, quad, fe, *this);
895  break;
896  }
897  case FEVectorPiola:
898  {
899  in_op_ = new VectorPiolaShape<dim, Domain, spacedim>(pfev, quad, fe, *this);
900  break;
901  }
902  default:
903  ASSERT(false).error("Type of FiniteElement of grad_vector_shape accessor must be FEVector, FEVectorPiola or FEVectorContravariant!\n");
904  }
905 
906  }
907 
908  void eval() override {
909  in_op_->eval();
910  }
911 
912 private:
914 };
915 
916 /// Evaluates gradient scalar values
917 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
918 class GradScalarShape : public PatchOp<spacedim> {
919 public:
920  /// Constructor
921  GradScalarShape(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
922  : PatchOp<spacedim>(dim, pfev, quad, {spacedim, 1}, fe->n_dofs())
923  {
924  ASSERT_EQ(fe->fe_type(), FEType::FEScalar).error("Type of FiniteElement of grad_scalar_shape must be FEScalar!\n");
925  this->domain_ = Domain::domain();
926  this->input_ops_.push_back( pfev.template get< Op::InvJac<dim, Op::BulkDomain, spacedim>, dim >(pfev.element_quad(dim)) );
927  this->input_ops_.push_back( pfev.template get< Op::RefGradScalar<dim, Domain, spacedim>, dim >(quad, fe) );
928  }
929 
930  void eval() override {
931  auto inv_jac_vec_elem = this->input_ops(0)->result_matrix(); // dim x spacedim=3
932  auto ref_grads_vec = this->input_ops(1)->result_matrix(); // dim x n_dofs
933 
934  uint n_dofs = this->n_dofs();
935 
936  // Copy InvJac vector of elements registered on patch
938  uint n_elems = ppv.n_mesh_items();
939  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> inv_jac_vec(dim, spacedim);
940  for (uint i=0; i<dim*spacedim; ++i) {
941  inv_jac_vec(i) = ArenaVec<double>( n_elems, this->patch_fe_->patch_arena() );
942  }
943  for (uint i_c=0; i_c<dim*spacedim; ++i_c) {
944  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, inv_jac_vec_elem(i_c), inv_jac_vec(i_c) );
945  }
946 
947  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> ref_grads_ovec(this->dim_, n_dofs);
948  for (uint i=0; i<this->dim_*n_dofs; ++i) {
949  ref_grads_ovec(i) = ArenaOVec(ref_grads_vec(i));
950  }
951 
952  Eigen::Matrix<ArenaOVec<double>, dim, 3> inv_jac_ovec;
953  for (uint i=0; i<this->dim_*spacedim; ++i) {
954  inv_jac_ovec(i) = ArenaOVec(inv_jac_vec(i));
955  }
956 
957  auto result_vec = this->result_matrix();
958  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> result_ovec = inv_jac_ovec.transpose() * ref_grads_ovec;
959  for (uint i=0; i<spacedim*n_dofs; ++i) {
960  result_vec(i) = result_ovec(i).get_vec();
961  }
962  }
963 };
964 
965 /// Template specialization of previous: Domain=SideDomain
966 template<unsigned int dim, unsigned int spacedim>
967 class GradScalarShape<dim, Op::SideDomain, spacedim> : public PatchOp<spacedim> {
968 public:
969  /// Constructor
970  GradScalarShape(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
971  : PatchOp<spacedim>(dim, pfev, quad, {spacedim, 1}, fe->n_dofs())
972  {
973  ASSERT_EQ(fe->fe_type(), FEType::FEScalar).error("Type of FiniteElement of grad_scalar_shape must be FEScalar!\n");
975  this->input_ops_.push_back( pfev.template get< Op::InvJac<dim, Op::BulkDomain, spacedim>, dim >(pfev.element_quad(dim)) );
976  this->input_ops_.push_back( pfev.template get< Op::RefGradScalar<dim, Op::SideDomain, spacedim>, dim >(quad, fe) );
977  }
978 
979  void eval() override {
981  auto ref_shape_grads = this->input_ops(1)->result_matrix();
982  auto grad_scalar_shape_value = this->result_matrix();
983 
984  uint n_dofs = this->n_dofs();
985  uint n_points = ref_shape_grads(0).data_size();
986  uint n_sides = ppv.n_mesh_items();
987  uint n_patch_points = n_sides * this->quad_->size();
988 
989  this->allocate_result(n_patch_points, this->patch_fe_->patch_arena());
990 
991  // Expands inverse jacobian to inv_jac_expd_value
992  auto inv_jac_value = this->input_ops(0)->result_matrix();
993  Eigen::Matrix<ArenaVec<double>, dim, 3> inv_jac_expd_value;
994  for (uint i=0; i<dim*3; ++i) {
995  inv_jac_expd_value(i) = ArenaVec<double>( n_patch_points, this->patch_fe_->patch_arena() );
996  for (uint j=0; j<n_patch_points; ++j)
997  inv_jac_expd_value(i)(j) = inv_jac_value( i )( ppv.int_table_(patch_elem_on_domain)(j%n_sides) );
998  }
999 
1000  // Fill ref shape gradients by q_point. DOF and side_idx
1001  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> ref_shape_grads_expd(dim, n_dofs);
1002  for (uint i=0; i<dim*n_dofs; ++i) {
1003  ref_shape_grads_expd(i) = ArenaVec<double>( n_patch_points, this->patch_fe_->patch_arena() );
1004  }
1005  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
1006  for (uint i_pt=0; i_pt<n_points; ++i_pt) {
1007  uint i_begin = i_pt * n_sides;
1008  for (uint i_sd=0; i_sd<n_sides; ++i_sd) {
1009  for (uint i_c=0; i_c<dim; ++i_c) {
1010  ref_shape_grads_expd(i_c, i_dof)(i_begin + i_sd) = ref_shape_grads(ppv.int_table_(ref_side_on_sides)(i_sd), i_dof*dim+i_c)(i_pt);
1011  }
1012  }
1013  }
1014  }
1015 
1016  // computes operation result
1017  grad_scalar_shape_value = inv_jac_expd_value.transpose() * ref_shape_grads_expd;
1018  }
1019 };
1020 
1021 /// Evaluates vector values (FEType == FEVector)
1022 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
1023 class GradVectorShape : public PatchOp<spacedim> {
1024 public:
1025  /// Constructor
1026  GradVectorShape(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe, PatchOp<spacedim> &dispatch_op)
1027  : PatchOp<spacedim>(dim, pfev, quad, {spacedim, spacedim}, fe->n_dofs()), dispatch_op_(dispatch_op)
1028  {
1029  this->domain_ = Domain::domain();
1030  this->input_ops_.push_back( pfev.template get< Op::InvJac<dim, Op::BulkDomain, spacedim>, dim >(pfev.element_quad(dim)) );
1031  this->input_ops_.push_back( pfev.template get< Op::RefGradVector<dim, Domain, spacedim>, dim >(quad, fe) );
1032  }
1033 
1034  void eval() override {
1035  auto inv_jac_vec_elem = this->input_ops(0)->result_matrix(); // dim x spacedim
1036  auto ref_grads_vec = this->input_ops(1)->result_matrix(); // dim x spacedim
1037  auto result_vec = dispatch_op_.result_matrix(); // spacedim x spacedim
1038 
1039  uint n_dofs = this->n_dofs();
1040 
1041  // Copy InvJac vector of elements registered on patch
1042  PatchPointValues<spacedim> &ppv = this->ppv();
1043  uint n_elems = ppv.n_mesh_items();
1044  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> inv_jac_vec(dim, spacedim);
1045  for (uint i=0; i<dim*spacedim; ++i) {
1046  inv_jac_vec(i) = ArenaVec<double>( n_elems, this->patch_fe_->patch_arena() );
1047  }
1048  for (uint i_c=0; i_c<dim*spacedim; ++i_c) {
1049  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, inv_jac_vec_elem(i_c), inv_jac_vec(i_c) );
1050  }
1051 
1052  Eigen::Matrix<ArenaOVec<double>, dim, 3> inv_jac_ovec;
1053  for (uint i=0; i<dim*spacedim; ++i) {
1054  inv_jac_ovec(i) = ArenaOVec(inv_jac_vec(i));
1055  }
1056 
1057  Eigen::Matrix<ArenaOVec<double>, dim, spacedim> ref_grads_ovec;
1058  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
1059  for (uint i=0; i<spacedim*dim; ++i) {
1060  ref_grads_ovec(i) = ArenaOVec(ref_grads_vec(i_dof*3*dim + i));
1061  }
1062 
1063  Eigen::Matrix<ArenaOVec<double>, spacedim, spacedim> result_ovec = inv_jac_ovec.transpose() * ref_grads_ovec;
1064  for (uint i=0; i<spacedim; ++i) {
1065  for (uint j=0; j<spacedim; ++j) {
1066  result_vec(j,i+spacedim*i_dof) = result_ovec(i,j).get_vec();
1067  }
1068  }
1069  }
1070  }
1071 
1072 private:
1074 };
1075 
1076 /// Template specialization of previous: Domain=SideDomain)
1077 template<unsigned int dim, unsigned int spacedim>
1078 class GradVectorShape<dim, Op::SideDomain, spacedim> : public PatchOp<spacedim> {
1079 public:
1080  /// Constructor
1081  GradVectorShape(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe, PatchOp<spacedim> &dispatch_op)
1082  : PatchOp<spacedim>(dim, pfev, quad, {spacedim, spacedim}, fe->n_dofs()), dispatch_op_(dispatch_op)
1083  {
1084  this->domain_ = Op::SideDomain::domain();
1085  this->input_ops_.push_back( pfev.template get< Op::InvJac<dim, Op::BulkDomain, spacedim>, dim >(pfev.element_quad(dim)) );
1086  this->input_ops_.push_back( pfev.template get< Op::RefGradVector<dim, Op::SideDomain, spacedim>, dim >(quad, fe) );
1087  }
1088 
1089  void eval() override {
1090  PatchPointValues<spacedim> &ppv = this->ppv();
1091  auto inv_jac_value = this->input_ops(0)->result_matrix(); // dim x spacedim
1092  auto ref_vector_grad = this->input_ops(1)->result_matrix(); // n_sides*dim x spacedim
1093 
1094  uint n_dofs = this->n_dofs();
1095  uint n_points = ref_vector_grad(0).data_size(); // number of ref points
1096  uint n_patch_sides = ppv.n_mesh_items();
1097  uint n_patch_points = n_patch_sides * this->quad_->size();
1098 
1099  // Expands inverse jacobian to inv_jac_expd_value
1100  Eigen::Matrix<ArenaVec<double>, dim, 3> inv_jac_expd_value;
1101  for (uint i=0; i<dim*3; ++i) {
1102  inv_jac_expd_value(i) = ArenaVec<double>( n_patch_points, this->patch_fe_->patch_arena() );
1103  for (uint j=0; j<n_patch_points; ++j)
1104  inv_jac_expd_value( i )( j ) = inv_jac_value( i )( ppv.int_table_(patch_elem_on_domain)(j%n_patch_sides) );
1105  }
1106 
1107  // Fill ref shape gradients by q_point. DOF and side_idx
1108  Eigen::Matrix<ArenaVec<double>, dim, 3> ref_shape_grads_expd;
1109  for (uint i=0; i<spacedim*dim; ++i) {
1110  ref_shape_grads_expd(i) = ArenaVec<double>( n_patch_points, this->patch_fe_->patch_arena() );
1111  }
1112  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
1113 
1114  for (uint i_pt=0; i_pt<n_points; ++i_pt) {
1115  uint i_begin = i_pt * n_patch_sides;
1116  for (uint i_sd=0; i_sd<n_patch_sides; ++i_sd) {
1117  for (uint i_dim=0; i_dim<dim; ++i_dim) {
1118  for (uint i_c=0; i_c<spacedim; ++i_c) {
1119  ref_shape_grads_expd(i_dim, i_c)(i_begin + i_sd) = ref_vector_grad(ppv.int_table_(ref_side_on_sides)(i_sd)*dim+i_dim, 3*i_dof+i_c)(i_pt);
1120  }
1121  }
1122  }
1123  }
1124 
1125  // computes operation result
1126  Eigen::Map< Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> > res_submat = dispatch_op_.result_sub_matrix(i_dof);
1127  res_submat = (inv_jac_expd_value.transpose() * ref_shape_grads_expd).transpose();
1128  }
1129  }
1130 
1131 private:
1133 };
1134 
1135 /// Evaluates vector values (FEType == FEVectorPiola)
1136 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
1137 class GradVectorPiolaShape : public PatchOp<spacedim> {
1138 public:
1139  /// Constructor
1140  GradVectorPiolaShape(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe, PatchOp<spacedim> &dispatch_op)
1141  : PatchOp<spacedim>(dim, pfev, quad, {spacedim, spacedim}, fe->n_dofs()), dispatch_op_(dispatch_op)
1142  {
1143  this->domain_ = Domain::domain();
1144  this->input_ops_.push_back( pfev.template get< Op::InvJac<dim, Op::BulkDomain, spacedim>, dim >(pfev.element_quad(dim)) );
1145  this->input_ops_.push_back( pfev.template get< Op::RefGradVector<dim, Domain, spacedim>, dim >(quad, fe) );
1146  this->input_ops_.push_back( pfev.template get< Op::Jac<dim, Op::BulkDomain, spacedim>, dim >(pfev.element_quad(dim)) );
1147  this->input_ops_.push_back( pfev.template get< Op::JacDet<dim, Op::BulkDomain, spacedim>, dim >(pfev.element_quad(dim)) );
1148  }
1149 
1150  void eval() override {
1151  auto inv_jac_vec_elem = this->input_ops(0)->result_matrix(); // dim x spacedim
1152  auto ref_grads_vec = this->input_ops(1)->result_matrix(); // dim x dim
1153  auto jac_vec_elem = this->input_ops(2)->result_matrix(); // spacedim x dim
1154  auto jac_det_vec_elem = this->input_ops(3)->result_matrix(); // 1
1155  auto result_vec = dispatch_op_.result_matrix(); // spacedim x spacedim
1156 
1157  PatchPointValues<spacedim> &ppv = this->ppv();
1158  uint n_elems = ppv.n_mesh_items();
1159  uint n_dofs = this->n_dofs();
1160  uint n_ref_points = this->quad_->size();
1161 
1162  // Copy InvJac and JacDet vector of elements registered on patch
1163  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> inv_jac_vec(dim, spacedim);
1164  for (uint i=0; i<dim*spacedim; ++i) {
1165  inv_jac_vec(i) = ArenaVec<double>( n_elems, this->patch_fe_->patch_arena() );
1166  }
1167  for (uint i_c=0; i_c<spacedim*dim; ++i_c) {
1168  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, inv_jac_vec_elem(i_c), inv_jac_vec(i_c) );
1169  }
1170  ArenaVec<double> jac_det_vec( n_elems, this->patch_fe_->patch_arena() );
1171  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, jac_det_vec_elem(0), jac_det_vec );
1172 
1173  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> inv_jac_div_det_vec = inv_jac_vec / jac_det_vec;
1174  Eigen::Matrix<ArenaOVec<double>, dim, spacedim> inv_jac_div_det_ovec;
1175  for (uint c=0; c<dim*spacedim; ++c) {
1176  inv_jac_div_det_ovec(c) = ArenaOVec<double>(inv_jac_div_det_vec(c));
1177  }
1178 
1179  Eigen::Matrix<ArenaVec<double>, spacedim, dim> jac_vec;
1180  for (uint i_c=0; i_c<spacedim*dim; ++i_c) {
1181  jac_vec(i_c) = ArenaVec<double>( n_elems*n_ref_points, this->patch_fe_->patch_arena() );
1182  for (uint i_el=0; i_el<n_elems; ++i_el)
1183  for (uint i_pt=0; i_pt<n_ref_points; ++i_pt) {
1184  jac_vec(i_c)( i_pt*n_elems + i_el ) = jac_vec_elem(i_c)( ppv.int_table_(patch_elem_on_domain)(i_el) );
1185  }
1186  }
1187 
1188  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> ref_grads_ovec(dim, dim);
1189  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
1190  for (uint i=0; i<dim*dim; ++i) {
1191  ref_grads_ovec(i) = ArenaOVec(ref_grads_vec(i_dof*dim*dim + i));
1192  }
1193 
1194  Eigen::Matrix<ArenaOVec<double>, spacedim, dim> inv_jac_multi_ref_ovec = inv_jac_div_det_ovec.transpose() * ref_grads_ovec;
1195  Eigen::Matrix<ArenaVec<double>, spacedim, dim> inv_jac_multi_ref_vec; // converts components ArenaOVec to ArenaVec
1196  for (uint i=0; i<spacedim*dim; ++i) {
1197  inv_jac_multi_ref_vec(i) = inv_jac_multi_ref_ovec(i);
1198  }
1199 
1200  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> sub_result_vec = inv_jac_multi_ref_vec * jac_vec.transpose();
1201  for (uint i=0; i<spacedim; ++i) {
1202  for (uint j=0; j<spacedim; ++j) {
1203  result_vec(j,i+spacedim*i_dof) = sub_result_vec(i,j);
1204  }
1205  }
1206  }
1207  }
1208 
1209 private:
1211 };
1212 
1213 /// Template specialization of previous: Domain=SideDomain)
1214 template<unsigned int dim, unsigned int spacedim>
1215 class GradVectorPiolaShape<dim, Op::SideDomain, spacedim> : public PatchOp<spacedim> {
1216 public:
1217  /// Constructor
1218  GradVectorPiolaShape(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe, PatchOp<spacedim> &dispatch_op)
1219  : PatchOp<spacedim>(dim, pfev, quad, {spacedim, spacedim}, fe->n_dofs()), dispatch_op_(dispatch_op)
1220  {
1221  this->domain_ = Op::SideDomain::domain();
1222  this->input_ops_.push_back( pfev.template get< Op::InvJac<dim, Op::BulkDomain, spacedim>, dim >(pfev.element_quad(dim)) );
1223  this->input_ops_.push_back( pfev.template get< Op::RefGradVector<dim, Op::SideDomain, spacedim>, dim >(quad, fe) );
1224  this->input_ops_.push_back( pfev.template get< Op::Jac<dim, Op::BulkDomain, spacedim>, dim >(pfev.element_quad(dim)) );
1225  this->input_ops_.push_back( pfev.template get< Op::JacDet<dim, Op::BulkDomain, spacedim>, dim >(pfev.element_quad(dim)) );
1226  }
1227 
1228  void eval() override {
1229  auto inv_jac_vec_elem = this->input_ops(0)->result_matrix(); // dim x spacedim
1230  auto ref_grads_vec = this->input_ops(1)->result_matrix(); // dim x dim
1231  auto jac_vec_elem = this->input_ops(2)->result_matrix(); // spacedim x dim
1232  auto jac_det_vec_elem = this->input_ops(3)->result_matrix(); // 1
1233 
1234  PatchPointValues<spacedim> &ppv = this->ppv();
1235  uint n_sides = ppv.n_mesh_items();
1236  uint n_dofs = this->n_dofs();
1237  uint n_points = ref_grads_vec(0).data_size();
1238  uint n_patch_points = n_sides * this->quad_->size();
1239  uint n_points_per_side = this->quad_->size();
1240 
1241  // Copy InvJac, Jac and JacDet vector of elements registered on patch
1242  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> inv_jac_vec(dim, spacedim);
1243  for (uint i_c=0; i_c<dim*spacedim; ++i_c) {
1244  inv_jac_vec(i_c) = ArenaVec<double>( n_sides, this->patch_fe_->patch_arena() );
1245  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, inv_jac_vec_elem(i_c), inv_jac_vec(i_c) );
1246  }
1247  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> jac_vec(spacedim, dim);
1248  Eigen::Matrix<ArenaOVec<double>, spacedim, dim> jac_ovec;
1249  for (uint i_c=0; i_c<spacedim*dim; ++i_c) {
1250  jac_vec(i_c) = ArenaVec<double>( n_sides, this->patch_fe_->patch_arena() );
1251  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, jac_vec_elem(i_c), jac_vec(i_c) );
1252  jac_ovec(i_c) = ArenaOVec<double>(jac_vec(i_c));
1253  }
1254  ArenaVec<double> jac_det_vec( n_sides, this->patch_fe_->patch_arena() );
1255  FuncHelper<spacedim>::fill_reduce_element_data_vec( ppv, jac_det_vec_elem(0), jac_det_vec );
1256 
1257  // Compute InvJac / Determinant, convert to ArenaOvec
1258  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> inv_jac_div_det_vec = inv_jac_vec / jac_det_vec;
1259  Eigen::Matrix<ArenaOVec<double>, dim, spacedim> inv_jac_div_det_ovec;
1260  for (uint c=0; c<dim*spacedim; ++c) {
1261  inv_jac_div_det_ovec(c) = ArenaOVec<double>(inv_jac_div_det_vec(c));
1262  }
1263 
1264  // Computes expand vector of previous result (inv_jac / determinant) and expand vector of Jacobian
1265  ArenaVec<double> side_points_vec(n_points_per_side, this->patch_fe_->patch_arena());
1266  for (uint i=0; i<n_points_per_side; ++i) {
1267  side_points_vec(i) = 1.0;
1268  }
1269  ArenaOVec<double> side_points_ovec(side_points_vec);
1270  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> expand_inv_jac_div_det_ovec = inv_jac_div_det_ovec * side_points_ovec;
1271  Eigen::Matrix<ArenaVec<double>, dim, spacedim> expand_inv_jac_div_det_vec;
1272  for (uint c=0; c<spacedim*dim; ++c) {
1273  expand_inv_jac_div_det_vec(c) = expand_inv_jac_div_det_ovec(c).get_vec();
1274  }
1275  Eigen::Matrix<ArenaOVec<double>, Eigen::Dynamic, Eigen::Dynamic> expand_jac_ovec = jac_ovec * side_points_ovec;
1276  Eigen::Matrix<ArenaVec<double>, spacedim, dim> expand_jac_vec;
1277  for (uint c=0; c<spacedim*dim; ++c) {
1278  expand_jac_vec(c) = expand_jac_ovec(c).get_vec();
1279  }
1280 
1281  Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> expand_ref_vec(dim, dim);
1282  for (uint c=0; c<dim*dim; c++)
1283  expand_ref_vec(c) = ArenaVec<double>(n_patch_points, this->patch_fe_->patch_arena());
1284 
1285  for (uint i_dof=0; i_dof<n_dofs; ++i_dof) {
1286 
1287  for (uint i_pt=0; i_pt<n_points; ++i_pt) {
1288  uint i_begin = i_pt * n_sides;
1289  for (uint i_sd=0; i_sd<n_sides; ++i_sd) {
1290  for (uint i_dim=0; i_dim<dim; ++i_dim) {
1291  for (uint i_c=0; i_c<dim; ++i_c) {
1292  expand_ref_vec(i_dim, i_c)(i_begin + i_sd) = ref_grads_vec(ppv.int_table_(ref_side_on_sides)(i_sd)*dim+i_dim, dim*i_dof+i_c)(i_pt);
1293  }
1294  }
1295  }
1296  }
1297 
1298  // computes operation result
1299  Eigen::Map< Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> > res_submat = dispatch_op_.result_sub_matrix(i_dof);
1300  res_submat = expand_inv_jac_div_det_vec.transpose() * expand_ref_vec * expand_jac_vec.transpose();
1301  }
1302  }
1303 
1304 private:
1306 };
1307 
1308 // class OpGradVectorCovariantShape
1309 
1310 /// Dispatch class of vector values
1311 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
1312 class DispatchGradVectorShape : public PatchOp<spacedim> {
1313 public:
1314  /// Constructor
1316  : PatchOp<spacedim>(dim, pfev, quad, {spacedim, spacedim}, fe->n_dofs()), in_op_(nullptr)
1317  {
1318  this->domain_ = Domain::domain();
1319  switch (fe->fe_type()) {
1320  case FEVector:
1321  {
1322  in_op_ = new GradVectorShape<dim, Domain, spacedim>(pfev, quad, fe, *this);
1323  break;
1324  }
1325  case FEVectorContravariant:
1326  {
1327  ASSERT_PERMANENT(false).error("Shape vector for FEVectorContravariant is not implemented yet!\n"); // temporary assert
1328  //in_op_ = new GradVectorCovariantShape<dim, Domain, spacedim>(pfev, quad, fe, *this);
1329  break;
1330  }
1331  case FEVectorPiola:
1332  {
1333  in_op_ = new GradVectorPiolaShape<dim, Domain, spacedim>(pfev, quad, fe, *this);
1334  break;
1335  }
1336  default:
1337  ASSERT(false).error("Type of FiniteElement of grad_vector_shape accessor must be FEVector, FEVectorPiola or FEVectorContravariant!\n");
1338  }
1339 
1340  }
1341 
1342  void eval() override {
1343  in_op_->eval();
1344  }
1345 
1346 private:
1348 };
1349 
1350 /// Evaluates vector symmetric gradients
1351 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
1352 class VectorSymGrad : public PatchOp<spacedim> {
1353 public:
1354  /// Constructor
1355  VectorSymGrad(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
1356  : PatchOp<spacedim>(dim, pfev, quad, {spacedim, spacedim}, fe->n_dofs())
1357  {
1358  this->domain_ = Domain::domain();
1359  this->input_ops_.push_back( pfev.template get< DispatchGradVectorShape<dim, Domain, spacedim>, dim >(quad, fe) );
1360  }
1361 
1362  void eval() override {
1363  for (uint i_dof=0; i_dof<this->n_dofs(); ++i_dof) {
1364  Eigen::Map< Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> > grad_vector_dof = this->input_ops(0)->result_sub_matrix(i_dof);
1365  Eigen::Map< Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> > sym_grad_dof = this->result_sub_matrix(i_dof);
1366  sym_grad_dof = 0.5 * (grad_vector_dof.transpose() + grad_vector_dof);
1367  }
1368  }
1369 };
1370 
1371 /// Evaluates vector vector divergence
1372 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
1373 class VectorDivergence : public PatchOp<spacedim> {
1374 public:
1375  /// Constructor
1377  : PatchOp<spacedim>(dim, pfev, quad, {1}, fe->n_dofs())
1378  {
1379  this->domain_ = Domain::domain();
1380  this->input_ops_.push_back( pfev.template get< DispatchGradVectorShape<dim, Domain, spacedim>, dim >(quad, fe) );
1381  }
1382 
1383  void eval() override {
1384  auto divergence_value = this->result_matrix();
1385 
1386  for (uint i_dof=0; i_dof<this->n_dofs(); ++i_dof) {
1387  Eigen::Map< Eigen::Matrix<ArenaVec<double>, Eigen::Dynamic, Eigen::Dynamic> > grad_vector_dof = this->input_ops(0)->result_sub_matrix(i_dof);
1388  divergence_value(i_dof) = grad_vector_dof(0,0) + grad_vector_dof(1,1) + grad_vector_dof(2,2);
1389  }
1390  }
1391 };
1392 
1393 /// Class represents zero operation of Join quantities.
1394 template<unsigned int dim, class Domain, unsigned int spacedim = 3>
1395 class OpZero : public PatchOp<spacedim> {
1396 public:
1397  /// Constructor
1398  OpZero(PatchFEValues<spacedim> &pfev, const Quadrature *quad, std::shared_ptr<FiniteElement<dim>> fe)
1399  : PatchOp<spacedim>(dim, pfev, quad, {spacedim, spacedim}, fe->n_dofs())
1400  {
1401  this->domain_ = Domain::domain();
1402  this->allocate_const_result( this->patch_fe_->patch_fe_data().zero_vec_ );
1403  }
1404 
1405  void eval() override {}
1406 };
1407 
1408 } // end of namespace Op
1409 
1410 
1411 #endif /* OP_FUNCTION_HH_ */
#define ASSERT(expr)
Definition: asserts.hh:351
#define ASSERT_PERMANENT(expr)
Allow use shorter versions of macro names if these names is not used with external library.
Definition: asserts.hh:348
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:333
ArenaVec< T > get_vec() const
Convert ArenaOVec to ArenaVec and its.
Definition: arena_vec.hh:329
Abstract class for the description of a general finite element on a reference simplex in dim dimensio...
Class used as template type for type resolution Bulk / Side.
Definition: op_function.hh:30
static ElemDomain domain()
Definition: op_function.hh:32
static constexpr uint n_nodes(uint dim)
Definition: op_function.hh:36
static NodeAccessor< 3 > node(PatchPointValues< 3 > &ppv, unsigned int i_elm, unsigned int i_n)
Return i_n-th node of i_elm-th element stored in PatchPointValues::elem_dim_list_.
Definition: op_function.hh:46
static uint n_mesh_entities(PatchPointValues< 3 > &ppv)
Return number of mesh entities (in this case elements) on patch.
Definition: op_function.hh:41
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:92
Coords(PatchFEValues< spacedim > &pfev, const Quadrature *quad)
Constructor.
Definition: op_function.hh:87
Dispatch class of vector values.
PatchOp< spacedim > * in_op_
void eval() override
Reinit function of operation. Implementation in descendants.
DispatchGradVectorShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Dispatch class of vector values.
Definition: op_function.hh:878
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:908
PatchOp< spacedim > * in_op_
Definition: op_function.hh:913
DispatchVectorShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:881
FuncHelper()
Forbidden constructor.
Definition: op_function.hh:208
static void fill_reduce_element_data_vec(PatchPointValues< spacedim > &ppv, ArenaVec< double > &source, ArenaVec< double > &target)
Definition: op_function.hh:201
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:979
GradScalarShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:970
Evaluates gradient scalar values.
Definition: op_function.hh:918
GradScalarShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:921
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:930
void eval() override
Reinit function of operation. Implementation in descendants.
GradVectorPiolaShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe, PatchOp< spacedim > &dispatch_op)
Constructor.
Evaluates vector values (FEType == FEVectorPiola)
void eval() override
Reinit function of operation. Implementation in descendants.
GradVectorPiolaShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe, PatchOp< spacedim > &dispatch_op)
Constructor.
PatchOp< spacedim > & dispatch_op_
void eval() override
Reinit function of operation. Implementation in descendants.
GradVectorShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe, PatchOp< spacedim > &dispatch_op)
Constructor.
Evaluates vector values (FEType == FEVector)
GradVectorShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe, PatchOp< spacedim > &dispatch_op)
Constructor.
PatchOp< spacedim > & dispatch_op_
void eval() override
Reinit function of operation. Implementation in descendants.
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:184
InvJac(PatchFEValues< spacedim > &pfev, const Quadrature *quad)
Constructor.
Definition: op_function.hh:177
JacDet(PatchFEValues< 3 > &pfev, const Quadrature *quad)
Constructor.
Definition: op_function.hh:152
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:158
Evaluates Jacobian determinants on Bulk (Element) / Side.
Definition: op_function.hh:130
JacDet(PatchFEValues< spacedim > &pfev, const Quadrature *quad)
Constructor.
Definition: op_function.hh:133
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:140
Evaluates Jacobians on Bulk (Element) / Side.
Definition: op_function.hh:109
Jac(PatchFEValues< spacedim > &pfev, const Quadrature *quad)
Constructor.
Definition: op_function.hh:112
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:119
JxW(PatchFEValues< spacedim > &pfev, const Quadrature *quad)
Constructor.
Definition: op_function.hh:335
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:343
JxW(PatchFEValues< spacedim > &pfev, const Quadrature *quad)
Constructor.
Definition: op_function.hh:306
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:314
Evaluates normal vector on side quadrature points.
Definition: op_function.hh:355
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:365
NormalVec(PatchFEValues< spacedim > &pfev, const Quadrature *quad)
Constructor.
Definition: op_function.hh:358
Class represents zero operation of Join quantities.
void eval() override
Reinit function of operation. Implementation in descendants.
OpZero(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Evaluates coordinates of quadrature points - not implemented yet.
Definition: op_function.hh:236
PtCoords(PatchFEValues< spacedim > &pfev, const Quadrature *quad)
Constructor.
Definition: op_function.hh:239
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:247
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:231
RefBaryCoords(PatchFEValues< spacedim > &pfev, const Quadrature *quad)
Constructor.
Definition: op_function.hh:218
Template specialization of previous: Domain=SideDomain.
Definition: op_function.hh:515
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:535
RefGradScalar(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:518
Fixed operation of gradient scalar reference values.
Definition: op_function.hh:493
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:510
RefGradScalar(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:496
Template specialization of previous: Domain=SideDomain.
Definition: op_function.hh:565
RefGradVector(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:568
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:588
Fixed operation of gradient scalar reference values.
Definition: op_function.hh:540
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:560
RefGradVector(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:543
Template specialization of previous: Domain=SideDomain.
Definition: op_function.hh:420
RefScalar(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:423
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:439
Fixed operation of scalar shape reference values.
Definition: op_function.hh:399
RefScalar(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:402
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:415
Template specialization of previous: Domain=SideDomain.
Definition: op_function.hh:467
RefVector(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:470
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:488
Fixed operation of vector shape reference values.
Definition: op_function.hh:444
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:462
RefVector(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:447
ScalarShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:634
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:642
Evaluates scalar shape values.
Definition: op_function.hh:593
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:604
ScalarShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Definition: op_function.hh:596
Class used as template type for type resolution Bulk / Side.
Definition: op_function.hh:52
static constexpr uint n_nodes(uint dim)
Definition: op_function.hh:58
static uint n_mesh_entities(PatchPointValues< 3 > &ppv)
Return number of mesh entities (in this case sides) on patch.
Definition: op_function.hh:63
static ElemDomain domain()
Definition: op_function.hh:54
static NodeAccessor< 3 > node(PatchPointValues< 3 > &ppv, unsigned int i_elm, unsigned int i_n)
Return i_n-th node of i_elm-th side stored in PatchPointValues::side_list_.
Definition: op_function.hh:68
Evaluates vector vector divergence.
void eval() override
Reinit function of operation. Implementation in descendants.
VectorDivergence(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:807
VectorPiolaShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe, PatchOp< spacedim > &dispatch_op)
Constructor.
Definition: op_function.hh:798
Evaluates vector values (FEType == FEVectorPiola)
Definition: op_function.hh:739
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:751
VectorPiolaShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe, PatchOp< spacedim > &dispatch_op)
Constructor.
Definition: op_function.hh:742
PatchOp< spacedim > & dispatch_op_
Definition: op_function.hh:790
VectorShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe, PatchOp< spacedim > &dispatch_op)
Constructor.
Definition: op_function.hh:705
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:712
Evaluates vector values (FEType == FEVector)
Definition: op_function.hh:663
PatchOp< spacedim > & dispatch_op_
Definition: op_function.hh:697
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:673
VectorShape(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe, PatchOp< spacedim > &dispatch_op)
Constructor.
Definition: op_function.hh:666
Evaluates vector symmetric gradients.
void eval() override
Reinit function of operation. Implementation in descendants.
VectorSymGrad(PatchFEValues< spacedim > &pfev, const Quadrature *quad, std::shared_ptr< FiniteElement< dim >> fe)
Constructor.
Weights(PatchFEValues< spacedim > &pfev, const Quadrature *quad)
Constructor.
Definition: op_function.hh:284
void eval() override
Reinit function of operation. Implementation in descendants.
Definition: op_function.hh:295
Class represents element or FE operations.
Definition: patch_op.hh:45
Eigen::Vector< ArenaVec< double >, Eigen::Dynamic > result_
Result matrix of operation.
Definition: patch_op.hh:179
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.
Definition: patch_op.hh:133
const Quadrature * quad_
Pointer to Quadrature.
Definition: patch_op.hh:183
uint n_dofs() const
Getter for n_dofs_.
Definition: patch_op.hh:92
uint n_comp() const
Definition: patch_op.hh:77
std::vector< PatchOp< spacedim > * > input_ops_
Indices of operations in PatchPointValues::operations_ vector on which PatchOp is depended.
Definition: patch_op.hh:180
PatchOp< spacedim > * input_ops(uint i_op) const
Return pointer to operation of i_op index in input operation vector.
Definition: patch_op.hh:97
uint dim_
Dimension.
Definition: patch_op.hh:176
Eigen::Map< Eigen::Matrix< ArenaVec< double >, Eigen::Dynamic, Eigen::Dynamic > > result_matrix()
Return map referenced result as Eigen::Vector.
Definition: patch_op.hh:128
void allocate_const_result(ArenaVec< double > &value_vec)
Definition: patch_op.hh:122
ElemDomain domain_
Flag: BulkOp = 0, SideOp = 1.
Definition: patch_op.hh:177
void allocate_result(size_t data_size, PatchArena &arena)
Definition: patch_op.hh:117
PatchPointValues< spacedim > & ppv() const
Return reference of PatchPointValues.
Definition: patch_op.hh:150
virtual void eval()=0
Reinit function of operation. Implementation in descendants.
uint n_dofs_
Number of DOFs of FE operations (or 1 in case of element operations)
Definition: patch_op.hh:181
PatchFEValues< spacedim > * patch_fe_
Pointer to PatchFEValues object.
Definition: patch_op.hh:182
uint n_mesh_items() const
Getter for n_mesh_items__.
ElemDimList< spacedim > * elem_dim_list_
Number and list of elements on patch.
IntTableArena int_table_
std::vector< Side > side_list_
List of sides on patch.
Base class for quadrature rules on simplices in arbitrary dimensions.
Definition: quadrature.hh:48
Quadrature make_from_side(unsigned int sid) const
Definition: quadrature.cc:47
unsigned int size() const
Returns number of quadrature points.
Definition: quadrature.hh:86
Armor::ArmaVec< double, point_dim > point(unsigned int i) const
Returns the ith quadrature point.
Definition: quadrature.hh:151
static BaryPoint local_to_bary(const LocalPoint &lp)
Converts from local to barycentric coordinates.
Definition: ref_element.cc:188
static Eigen::Matrix< ArenaVec< double >, dim, 1 > normal_vector_array(ArenaVec< uint > loc_side_idx_vec)
Definition: ref_element.cc:280
@ FEScalar
@ FEVectorPiola
@ FEVectorContravariant
@ FEVector
unsigned int uint
ArenaVec< double > determinant(const Eigen::Matrix< ArenaVec< double >, m, n > &A)
Calculates determinant of a rectangular matrix.
Class FEValues calculates finite element data on the actual cells such as shape function values,...
Base class of FE operations.
ElemDomain
Distinguishes bulk and side domain.
Definition: patch_op.hh:35
@ domain_side
Definition: patch_op.hh:37
@ domain_bulk
Definition: patch_op.hh:36
@ patch_elem_on_domain
Index of patch element for each bulk element or side.
@ ref_side_on_sides
Ref index of side in element for each side in patch.
@ ref_side_on_quads
Ref index of side in element for each quadrature point in patch.