Flow123d  DF_patch_fe_mechanics-5faa023
op_factory.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_factory.hh
15  * @brief Declares top level factory classes of FE operations.
16  * @author David Flanderka
17  */
18 
19 #ifndef OP_FACTORY_HH_
20 #define OP_FACTORY_HH_
21 
22 #include "fem/eigen_tools.hh"
23 #include "fem/op_function.hh"
24 #include "fem/op_accessors_impl.hh"
25 
26 template<unsigned int spacedim> class PatchFEValues;
27 
28 
29 template<unsigned int dim>
31 {
32 protected:
33  // Default constructor
35  {}
36 
37  /// Factory method. Creates operation of given OpType.
38  template<class OpType>
40  return patch_fe_values_.get< OpType, dim >();
41  }
42 
43  /// Factory method. Same as previous but creates FE operation.
44  template<class ValueType, template<unsigned int, class, unsigned int> class OpType, class Domain>
45  FeQArray<ValueType> make_qarray(uint component_idx = 0) {
46  std::shared_ptr<FiniteElement<dim>> fe_component = patch_fe_values_.fe_comp(fe_, component_idx);
47  return FeQArray<ValueType>(patch_fe_values_.template get< OpType<dim, Domain, 3>, dim >(fe_component));
48  }
49 
51  std::shared_ptr< FiniteElement<dim> > fe_;
52 };
53 
54 template<unsigned int dim>
55 class BulkValues : public BaseValues<dim>
56 {
57 public:
58  /// Constructor
60  : BaseValues<dim>(pfev) {
61  this->fe_ = fe[Dim<dim>{}];
62  }
63 
64  /**
65  * @brief Register the product of Jacobian determinant and the quadrature
66  * weight at bulk quadrature points.
67  *
68  * @param quad Quadrature.
69  */
70  inline FeQ<Scalar> JxW()
71  {
72  return FeQ<Scalar>(this->template make_patch_op< Op::JxW<dim, Op::BulkDomain, 3> >());
73  }
74 
75  /// Create bulk accessor of coords entity
77  {
79  }
80 
81 // inline ElQ<Tensor> jacobian(std::initializer_list<Quadrature *> quad_list)
82 // {}
83 
84  /// Create bulk accessor of jac determinant entity
86  {
88  }
89 
90  /**
91  * @brief Return the value of the @p function_no-th shape function at
92  * the @p p bulk quadrature point.
93  *
94  * @param component_idx Number of the shape function.
95  */
96  inline FeQArray<Scalar> scalar_shape(uint component_idx = 0)
97  {
98  return this->template make_qarray<Scalar, Op::ScalarShape, Op::BulkDomain>(component_idx);
99  }
100 
101  inline FeQArray<Vector> vector_shape(uint component_idx = 0)
102  {
103  return this->template make_qarray<Vector, Op::DispatchVectorShape, Op::BulkDomain>(component_idx);
104  }
105 
106 // inline FeQArray<Tensor> tensor_shape(uint component_idx = 0)
107 // {}
108 
109  /**
110  * @brief Return the value of the @p function_no-th gradient shape function at
111  * the @p p bulk quadrature point.
112  *
113  * @param component_idx Number of the shape function.
114  */
115  inline FeQArray<Vector> grad_scalar_shape(uint component_idx=0)
116  {
117  return this->template make_qarray<Vector, Op::GradScalarShape, Op::BulkDomain>(component_idx);
118  }
119 
120  /**
121  * @brief Return the value of the @p function_no-th gradient vector shape function
122  * at the @p p bulk quadrature point.
123  *
124  * @param component_idx Number of the shape function.
125  */
126  inline FeQArray<Tensor> grad_vector_shape(uint component_idx=0)
127  {
128  return this->template make_qarray<Tensor, Op::DispatchGradVectorShape, Op::BulkDomain>(component_idx);
129  }
130 
131  /**
132  * @brief Return the value of the @p function_no-th vector symmetric gradient
133  * at the @p p bulk quadrature point.
134  *
135  * @param component_idx Number of the shape function.
136  */
137  inline FeQArray<Tensor> vector_sym_grad(uint component_idx=0)
138  {
139  return this->template make_qarray<Tensor, Op::VectorSymGrad, Op::BulkDomain>(component_idx);
140  }
141 
142  /**
143  * @brief Return the value of the @p function_no-th vector divergence at
144  * the @p p bulk quadrature point.
145  *
146  * @param component_idx Number of the shape function.
147  */
148  inline FeQArray<Scalar> vector_divergence(uint component_idx=0)
149  {
150  return this->template make_qarray<Scalar, Op::VectorDivergence, Op::BulkDomain>(component_idx);
151  }
152 };
153 
154 
155 template<unsigned int dim>
157 {
158 public:
159  /// Constructor
161  : BaseValues<dim>(pfev) {
162  this->fe_ = fe[Dim<dim>{}];
163  }
164 
165  /// Same as BulkValues::JxW but register at side quadrature points.
166  inline FeQ<Scalar> JxW()
167  {
168  return FeQ<Scalar>(this->template make_patch_op< Op::JxW<dim, Op::SideDomain, 3> >());
169  }
170 
171  /**
172  * @brief Register the normal vector to a side at side quadrature points.
173  *
174  * @param quad Quadrature.
175  */
177  {
178  return ElQ<Vector>(this->template make_patch_op< Op::NormalVec<dim, 3> >());
179  }
180 
181  /// Create side accessor of coords entity
183  {
184  return FeQ<Vector>(this->template make_patch_op< Op::PtCoords<dim, Op::SideDomain, 3> >());
185  }
186 
187  /// Create bulk accessor of jac determinant entity
189  {
190  return ElQ<Scalar>(this->template make_patch_op< Op::JacDet<dim, Op::SideDomain, Op::SideDomain, 3> >());
191  }
192 
193  /// Same as BulkValues::scalar_shape but register at side quadrature points.
194  inline FeQArray<Scalar> scalar_shape(uint component_idx = 0)
195  {
196  return this->template make_qarray<Scalar, Op::ScalarShape, Op::SideDomain>(component_idx);
197  }
198 
199  /// Same as BulkValues::vector_shape but register at side quadrature points.
200  inline FeQArray<Vector> vector_shape(uint component_idx = 0)
201  {
202  return this->template make_qarray<Vector, Op::DispatchVectorShape, Op::SideDomain>(component_idx);
203  }
204 
205  /// Same as BulkValues::grad_scalar_shape but register at side quadrature points.
206  inline FeQArray<Vector> grad_scalar_shape(uint component_idx=0)
207  {
208  return this->template make_qarray<Vector, Op::GradScalarShape, Op::SideDomain>(component_idx);
209  }
210 
211  /**
212  * @brief Return the value of the @p function_no-th gradient vector shape function
213  * at the @p p bulk quadrature point.
214  *
215  * @param component_idx Number of the shape function.
216  */
217  inline FeQArray<Tensor> grad_vector_shape(uint component_idx=0)
218  {
219  return this->template make_qarray<Tensor, Op::DispatchGradVectorShape, Op::SideDomain>(component_idx);
220  }
221 
222  /**
223  * @brief Return the value of the @p function_no-th vector symmetric gradient
224  * at the @p p side quadrature point.
225  *
226  * @param component_idx Number of the shape function.
227  */
228  inline FeQArray<Tensor> vector_sym_grad(uint component_idx=0)
229  {
230  return this->template make_qarray<Tensor, Op::VectorSymGrad, Op::SideDomain>(component_idx);
231  }
232 
233  /**
234  * @brief Return the value of the @p function_no-th vector divergence at
235  * the @p p side quadrature point.
236  *
237  * @param component_idx Number of the shape function.
238  */
239  inline FeQArray<Scalar> vector_divergence(uint component_idx=0)
240  {
241  return this->template make_qarray<Scalar, Op::VectorDivergence, Op::SideDomain>(component_idx);
242  }
243 };
244 
245 
246 template<unsigned int dim>
248 {
249 public:
250  /// Constructor
252  : patch_fe_values_(pfev) {
253  fe_high_dim_ = fe[Dim<dim>{}];
254  fe_low_dim_ = fe[Dim<dim-1>{}];
255  }
256 
257  /// Factory method. Same as previous but creates FE operation.
258  template<class ValueType, template<unsigned int, class, unsigned int> class OpType>
259  FeQJoin<ValueType> make_qjoin(uint component_idx = 0) {
260  // element of lower dim (bulk points)
261  auto fe_component_low = patch_fe_values_.fe_comp(fe_low_dim_, component_idx);
262  auto *low_dim_op = patch_fe_values_.template get< OpType<dim-1, Op::BulkDomain, 3>, dim-1 >(fe_component_low);
263  auto *low_dim_zero_op = patch_fe_values_.template get< Op::OpZero<dim-1, Op::BulkDomain, 3>, dim-1 >(fe_component_low);
264 
265  // element of higher dim (side points)
266  auto fe_component_high = patch_fe_values_.fe_comp(fe_high_dim_, component_idx);
267  auto *high_dim_op = patch_fe_values_.template get< OpType<dim, Op::SideDomain, 3>, dim >(fe_component_high);
268  auto *high_dim_zero_op = patch_fe_values_.template get< Op::OpZero<dim, Op::SideDomain, 3>, dim >(fe_component_high);
269 
270  ASSERT_EQ(fe_component_high->fe_type(), fe_component_low->fe_type()).error("Type of FiniteElement of low and high element must be same!\n");
271  return FeQJoin<ValueType>(low_dim_op, high_dim_op, low_dim_zero_op, high_dim_zero_op);
272  }
273 
274  inline FeQJoin<Scalar> scalar_join_shape(uint component_idx = 0)
275  {
276  return this->template make_qjoin<Scalar, Op::ScalarShape>(component_idx);
277  }
278 
279  inline FeQJoin<Vector> vector_join_shape(uint component_idx = 0)
280  {
281  return this->template make_qjoin<Vector, Op::DispatchVectorShape>(component_idx);
282  }
283 
285  {
286  return this->template make_qjoin<Tensor, Op::DispatchGradVectorShape>(component_idx);
287  }
288 
289 private:
291  std::shared_ptr< FiniteElement<dim> > fe_high_dim_;
292  std::shared_ptr< FiniteElement<dim-1> > fe_low_dim_;
293 };
294 
295 /// Template specialization of dim = 1
296 template <>
297 class JoinValues<1> : public BaseValues<1>
298 {
299 public:
300  /// Constructor
302  : BaseValues<1>(pfev) {}
303 
305  {
306  return FeQJoin<Scalar>();
307  }
308 
310  {
311  return FeQJoin<Vector>();
312  }
313 
315  {
316  return FeQJoin<Tensor>();
317  }
318 };
319 
320 
321 #endif /* OP_FACTORY_HH_ */
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:333
std::shared_ptr< FiniteElement< dim > > fe_
Definition: op_factory.hh:51
BaseValues(PatchFEValues< 3 > &pfev)
Definition: op_factory.hh:34
PatchFEValues< 3 > & patch_fe_values_
Definition: op_factory.hh:50
FeQArray< ValueType > make_qarray(uint component_idx=0)
Factory method. Same as previous but creates FE operation.
Definition: op_factory.hh:45
PatchOp< 3 > * make_patch_op()
Factory method. Creates operation of given OpType.
Definition: op_factory.hh:39
FeQ< Scalar > JxW()
Register the product of Jacobian determinant and the quadrature weight at bulk quadrature points.
Definition: op_factory.hh:70
FeQArray< Vector > grad_scalar_shape(uint component_idx=0)
Return the value of the function_no-th gradient shape function at the p bulk quadrature point.
Definition: op_factory.hh:115
ElQ< Scalar > determinant()
Create bulk accessor of jac determinant entity.
Definition: op_factory.hh:85
FeQ< Vector > coords()
Create bulk accessor of coords entity.
Definition: op_factory.hh:76
FeQArray< Tensor > grad_vector_shape(uint component_idx=0)
Return the value of the function_no-th gradient vector shape function at the p bulk quadrature point.
Definition: op_factory.hh:126
FeQArray< Vector > vector_shape(uint component_idx=0)
Definition: op_factory.hh:101
FeQArray< Scalar > scalar_shape(uint component_idx=0)
Return the value of the function_no-th shape function at the p bulk quadrature point.
Definition: op_factory.hh:96
FeQArray< Scalar > vector_divergence(uint component_idx=0)
Return the value of the function_no-th vector divergence at the p bulk quadrature point.
Definition: op_factory.hh:148
BulkValues(PatchFEValues< 3 > &pfev, MixedPtr< FiniteElement > fe)
Constructor.
Definition: op_factory.hh:59
FeQArray< Tensor > vector_sym_grad(uint component_idx=0)
Return the value of the function_no-th vector symmetric gradient at the p bulk quadrature point.
Definition: op_factory.hh:137
Abstract class for the description of a general finite element on a reference simplex in dim dimensio...
JoinValues(PatchFEValues< 3 > &pfev, FMT_UNUSED MixedPtr< FiniteElement > fe)
Constructor.
Definition: op_factory.hh:301
FeQJoin< Tensor > gradient_vector_join_shape(FMT_UNUSED uint component_idx=0)
Definition: op_factory.hh:314
FeQJoin< Vector > vector_join_shape(FMT_UNUSED uint component_idx=0)
Definition: op_factory.hh:309
FeQJoin< Scalar > scalar_join_shape(FMT_UNUSED uint component_idx=0)
Definition: op_factory.hh:304
std::shared_ptr< FiniteElement< dim > > fe_high_dim_
Definition: op_factory.hh:291
FeQJoin< ValueType > make_qjoin(uint component_idx=0)
Factory method. Same as previous but creates FE operation.
Definition: op_factory.hh:259
FeQJoin< Vector > vector_join_shape(uint component_idx=0)
Definition: op_factory.hh:279
JoinValues(PatchFEValues< 3 > &pfev, MixedPtr< FiniteElement > fe)
Constructor.
Definition: op_factory.hh:251
FeQJoin< Tensor > gradient_vector_join_shape(uint component_idx=0)
Definition: op_factory.hh:284
std::shared_ptr< FiniteElement< dim-1 > > fe_low_dim_
Definition: op_factory.hh:292
PatchFEValues< 3 > & patch_fe_values_
Definition: op_factory.hh:290
FeQJoin< Scalar > scalar_join_shape(uint component_idx=0)
Definition: op_factory.hh:274
Class used as template type for type resolution Bulk / Side.
Definition: op_function.hh:30
Evaluates Jacobian determinants on Bulk (Element) / Side.
Definition: op_function.hh:109
Evaluates normal vector on side quadrature points.
Definition: op_function.hh:233
Class represents zero operation of Join quantities.
Definition: op_function.hh:940
Evaluates coordinates of quadrature points - not implemented yet.
Definition: op_function.hh:171
PatchOp< spacedim > * get()
Returns operation of given dim and OpType, creates it if doesn't exist.
std::shared_ptr< FiniteElement< dim > > fe_comp(std::shared_ptr< FiniteElement< dim > > fe, uint component_idx)
Returnd FiniteElement of component_idx for FESystem or fe for other types.
FeQ< Vector > coords()
Create side accessor of coords entity.
Definition: op_factory.hh:182
ElQ< Vector > normal_vector()
Register the normal vector to a side at side quadrature points.
Definition: op_factory.hh:176
FeQArray< Scalar > scalar_shape(uint component_idx=0)
Same as BulkValues::scalar_shape but register at side quadrature points.
Definition: op_factory.hh:194
FeQArray< Tensor > grad_vector_shape(uint component_idx=0)
Return the value of the function_no-th gradient vector shape function at the p bulk quadrature point.
Definition: op_factory.hh:217
FeQArray< Vector > vector_shape(uint component_idx=0)
Same as BulkValues::vector_shape but register at side quadrature points.
Definition: op_factory.hh:200
FeQArray< Tensor > vector_sym_grad(uint component_idx=0)
Return the value of the function_no-th vector symmetric gradient at the p side quadrature point.
Definition: op_factory.hh:228
FeQArray< Vector > grad_scalar_shape(uint component_idx=0)
Same as BulkValues::grad_scalar_shape but register at side quadrature points.
Definition: op_factory.hh:206
SideValues(PatchFEValues< 3 > &pfev, MixedPtr< FiniteElement > fe)
Constructor.
Definition: op_factory.hh:160
FeQArray< Scalar > vector_divergence(uint component_idx=0)
Return the value of the function_no-th vector divergence at the p side quadrature point.
Definition: op_factory.hh:239
ElQ< Scalar > determinant()
Create bulk accessor of jac determinant entity.
Definition: op_factory.hh:188
FeQ< Scalar > JxW()
Same as BulkValues::JxW but register at side quadrature points.
Definition: op_factory.hh:166
Store finite element data on the actual patch such as shape function values, gradients,...
unsigned int uint
Store finite element reinit functions.
#define FMT_UNUSED
Definition: posix.h:75
Definition: mixed.hh:25