Intrepid2
Intrepid2_DerivedBasis_HDIV_WEDGE.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Intrepid2 Package
4 //
5 // Copyright 2007 NTESS and the Intrepid2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
30 #ifndef Intrepid2_DerivedBasis_HDIV_WEDGE_h
31 #define Intrepid2_DerivedBasis_HDIV_WEDGE_h
32 
33 #include <Kokkos_DynRankView.hpp>
34 
36 #include "Intrepid2_Sacado.hpp"
37 
40 
41 namespace Intrepid2
42 {
43  template<class HDIV_TRI, class HVOL_LINE>
45  : public Basis_TensorBasis<typename HVOL_LINE::BasisBase>
46  {
47 
48  public:
49  using OutputViewType = typename HVOL_LINE::OutputViewType;
50  using PointViewType = typename HVOL_LINE::PointViewType ;
51  using ScalarViewType = typename HVOL_LINE::ScalarViewType;
52 
53  using TriDivBasis = HDIV_TRI;
54  using LineHVolBasis = HVOL_LINE;
55 
56  using BasisBase = typename HVOL_LINE::BasisBase;
58 
59  using DeviceType = typename BasisBase::DeviceType;
60  using ExecutionSpace = typename BasisBase::ExecutionSpace;
61  using OutputValueType = typename BasisBase::OutputValueType;
62  using PointValueType = typename BasisBase::PointValueType;
63 
69  Basis_Derived_HDIV_Family1_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType = POINTTYPE_DEFAULT)
70  :
71  TensorBasis(Teuchos::rcp( new TriDivBasis(polyOrder_xy, pointType) ),
72  Teuchos::rcp( new LineHVolBasis(polyOrder_z-1, pointType) ))
73  {
74  this->functionSpace_ = FUNCTION_SPACE_HDIV;
75  this->setShardsTopologyAndTags();
76  }
77 
80  OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
81  {
82  if (operatorType == OPERATOR_DIV)
83  {
84  // div of (f(x,y)h(z),g(x,y)h(z),0) is (df/dx + dg/dy) * h
85 
86  std::vector< std::vector<EOperator> > ops(1);
87  ops[0] = std::vector<EOperator>{OPERATOR_DIV,OPERATOR_VALUE};
88  std::vector<double> weights {1.0};
89  OperatorTensorDecomposition opDecomposition(ops, weights);
90  return opDecomposition;
91  }
92  else if (OPERATOR_VALUE == operatorType)
93  {
94  // family 1 goes in x,y components
95  std::vector< std::vector<EOperator> > ops(2);
96  ops[0] = std::vector<EOperator>{OPERATOR_VALUE,OPERATOR_VALUE}; // spans (x,y) due to H(div,tri) (first tensorial component)
97  ops[1] = std::vector<EOperator>{}; // empty z component
98  std::vector<double> weights {1.0,0.0};
99  return OperatorTensorDecomposition(ops, weights);
100  }
101  else
102  {
103  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported operator type");
104  }
105  }
106 
108 
116  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
117  const PointViewType inputPoints1, const PointViewType inputPoints2,
118  bool tensorPoints) const override
119  {
120  EOperator op1, op2;
121  if (operatorType == OPERATOR_VALUE)
122  {
123  op1 = OPERATOR_VALUE;
124  op2 = OPERATOR_VALUE;
125 
126  // family 1 values goes in (x,y) components, 0 in z
127  auto outputValuesComponent12 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),std::pair<int,int>{0,2});
128  auto outputValuesComponent3 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
129 
130  // place 0 in the z component
131  Kokkos::deep_copy(outputValuesComponent3, 0.0);
132  this->TensorBasis::getValues(outputValuesComponent12,
133  inputPoints1, op1,
134  inputPoints2, op2, tensorPoints);
135 
136  }
137  else if (operatorType == OPERATOR_DIV)
138  {
139  // div of (f(x,y)h(z),g(x,y)h(z),0) is (df/dx + dg/dy) * h
140 
141  op1 = OPERATOR_DIV;
142  op2 = OPERATOR_VALUE;
143 
144  this->TensorBasis::getValues(outputValues,
145  inputPoints1, op1,
146  inputPoints2, op2, tensorPoints);
147  }
148  else
149  {
150  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
151  }
152  }
153 
165  virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override {
166  auto dofCoeffs1 = Kokkos::subview(dofCoeffs,Kokkos::ALL(), std::make_pair(0,2));
167  auto dofCoeffs2 = Kokkos::subview(dofCoeffs,Kokkos::ALL(), 2);
168  this->TensorBasis::getDofCoeffs(dofCoeffs1);
169  Kokkos::deep_copy(dofCoeffs2,0.0);
170  }
171  };
172 
173  template<class HVOL_TRI, class HGRAD_LINE>
175  : public Basis_TensorBasis<typename HGRAD_LINE::BasisBase>
176  {
177  public:
178  using OutputViewType = typename HGRAD_LINE::OutputViewType;
179  using PointViewType = typename HGRAD_LINE::PointViewType ;
180  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
181 
182  using BasisBase = typename HGRAD_LINE::BasisBase;
183 
184  using DeviceType = typename BasisBase::DeviceType;
185  using ExecutionSpace = typename BasisBase::ExecutionSpace;
186  using OutputValueType = typename BasisBase::OutputValueType;
187  using PointValueType = typename BasisBase::PointValueType;
188 
189  using TriVolBasis = HVOL_TRI;
190  using LineGradBasis = HGRAD_LINE;
191 
193  public:
199  Basis_Derived_HDIV_Family2_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType = POINTTYPE_DEFAULT)
200  :
201  TensorBasis(Teuchos::rcp( new TriVolBasis(polyOrder_xy-1,pointType)),
202  Teuchos::rcp( new LineGradBasis(polyOrder_z,pointType)))
203  {
204  this->functionSpace_ = FUNCTION_SPACE_HDIV;
205  this->setShardsTopologyAndTags();
206  }
207 
209 
212  virtual OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
213  {
214  const EOperator & VALUE = OPERATOR_VALUE;
215  const EOperator & GRAD = OPERATOR_GRAD;
216  const EOperator & DIV = OPERATOR_DIV;
217  if (operatorType == VALUE)
218  {
219  // family 2 goes in z component
220  std::vector< std::vector<EOperator> > ops(2);
221  ops[0] = std::vector<EOperator>{}; // will span x,y because family 1's first component does
222  ops[1] = std::vector<EOperator>{VALUE,VALUE};
223  std::vector<double> weights {0.,1.0};
224  OperatorTensorDecomposition opDecomposition(ops, weights);
225  return opDecomposition;
226  }
227  else if (operatorType == DIV)
228  {
229  // div of (0, 0, f*g, where f=f(x,y), g=g(z), equals f * g'(z).
230  std::vector< std::vector<EOperator> > ops(1);
231  ops[0] = std::vector<EOperator>{VALUE,GRAD};
232  std::vector<double> weights {1.0};
233  OperatorTensorDecomposition opDecomposition(ops, weights);
234  return opDecomposition;
235  }
236  else
237  {
238  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported operator type");
239  }
240  }
241 
249  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
250  const PointViewType inputPoints1, const PointViewType inputPoints2,
251  bool tensorPoints) const override
252  {
253  EOperator op1, op2;
254  if (operatorType == OPERATOR_VALUE)
255  {
256  op1 = OPERATOR_VALUE;
257  op2 = OPERATOR_VALUE;
258 
259  // family 2 values goes in z component
260  auto outputValuesComponent12 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),std::pair<int,int>{0,2});
261  auto outputValuesComponent3 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
262 
263  // place 0 in the x,y components
264  Kokkos::deep_copy(outputValuesComponent12, 0.0);
265  this->TensorBasis::getValues(outputValuesComponent3,
266  inputPoints1, op1,
267  inputPoints2, op2, tensorPoints);
268 
269  }
270  else if (operatorType == OPERATOR_DIV)
271  {
272  // div of (0, 0, f*g, where f=f(x,y), g=g(z), equals f * g'(z).
273  op1 = OPERATOR_VALUE;
274  op2 = OPERATOR_GRAD;
275 
276  this->TensorBasis::getValues(outputValues,
277  inputPoints1, op1,
278  inputPoints2, op2, tensorPoints);
279  }
280  else
281  {
282  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
283  }
284  }
285 
297  virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override {
298  auto dofCoeffs1 = Kokkos::subview(dofCoeffs,Kokkos::ALL(), std::make_pair(0,2));
299  auto dofCoeffs2 = Kokkos::subview(dofCoeffs,Kokkos::ALL(), 2);
300  Kokkos::deep_copy(dofCoeffs1,0.0);
301  this->TensorBasis::getDofCoeffs(dofCoeffs2);
302  }
303  };
304 
305 
306  template<class HDIV_TRI, class HVOL_TRI, class HGRAD_LINE, class HVOL_LINE>
308  : public Basis_DirectSumBasis <typename HGRAD_LINE::BasisBase>
309  {
313  public:
314  using BasisBase = typename HGRAD_LINE::BasisBase;
315 
316  protected:
317  std::string name_;
318  ordinal_type order_xy_;
319  ordinal_type order_z_;
320  EPointType pointType_;
321 
322  public:
323  using ExecutionSpace = typename HGRAD_LINE::ExecutionSpace;
324  using OutputValueType = typename HGRAD_LINE::OutputValueType;
325  using PointValueType = typename HGRAD_LINE::PointValueType;
326 
332  Basis_Derived_HDIV_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
333  :
334  DirectSumBasis(Teuchos::rcp( new Family1(polyOrder_xy, polyOrder_z, pointType) ),
335  Teuchos::rcp( new Family2(polyOrder_xy, polyOrder_z, pointType) ))
336  {
337  this->functionSpace_ = FUNCTION_SPACE_HDIV;
338 
339  std::ostringstream basisName;
340  basisName << "HDIV_WEDGE (" << this->DirectSumBasis::getName() << ")";
341  name_ = basisName.str();
342 
343  order_xy_ = polyOrder_xy;
344  order_z_ = polyOrder_z;
345  pointType_ = pointType;
346  }
347 
352  Basis_Derived_HDIV_WEDGE(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT) : Basis_Derived_HDIV_WEDGE(polyOrder, polyOrder, pointType) {}
353 
356  virtual bool requireOrientation() const override
357  {
358  return true;
359  }
360 
365  virtual
366  const char*
367  getName() const override {
368  return name_.c_str();
369  }
370 
371 
381  Teuchos::RCP<BasisBase>
382  getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const override
383  {
384  using QuadBasis = Basis_Derived_HVOL_QUAD<HVOL_LINE>;
385  using TriBasis = HVOL_TRI;
386 
387  if(subCellDim == 2) {
388  switch(subCellOrd) {
389  case 0:
390  return Teuchos::rcp( new QuadBasis(order_xy_-1, order_z_-1, pointType_) );
391  case 1:
392  return Teuchos::rcp( new QuadBasis(order_xy_-1, order_z_-1, pointType_) );
393  case 2:
394  return Teuchos::rcp( new QuadBasis(order_z_-1, order_xy_-1, pointType_) );
395  case 3:
396  return Teuchos::rcp( new TriBasis(order_xy_-1, pointType_) );
397  case 4:
398  return Teuchos::rcp( new TriBasis(order_xy_-1, pointType_) );
399  default:
400  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"subCellOrd is out of bounds");
401  }
402  }
403  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"subCellDim is out of bounds");
404  }
405 
410  virtual HostBasisPtr<OutputValueType, PointValueType>
411  getHostBasis() const override {
413 
414  auto hostBasis = Teuchos::rcp(new HostBasis(order_xy_, order_z_, pointType_));
415 
416  return hostBasis;
417  }
418  };
419 } // end namespace Intrepid2
420 
421 #endif /* Intrepid2_DerivedBasis_HDIV_WEDGE_h */
virtual HostBasisPtr< OutputValueType, PointValueType > getHostBasis() const override
Creates and returns a Basis object whose DeviceType template argument is Kokkos::HostSpace::device_ty...
virtual bool requireOrientation() const override
True if orientation is required.
Implementation of bases that are tensor products of two or three component bases. ...
virtual void getValues(OutputViewType outputValues, const EOperator operatorType, const PointViewType inputPoints1, const PointViewType inputPoints2, bool tensorPoints) const override
multi-component getValues() method (required/called by TensorBasis)
virtual void getDofCoeffs(ScalarViewType dofCoeffs) const override
Fills in coefficients of degrees of freedom for Lagrangian basis on the reference cell...
Implementation of H(vol) basis on the quadrilateral that is templated on H(vol) on the line...
Teuchos::RCP< BasisBase > getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const override
returns the basis associated to a subCell.
Free functions, callable from device code, that implement various polynomials useful in basis definit...
For a multi-component tensor basis, specifies the operators to be applied to the components to produc...
Basis_Derived_HDIV_Family1_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
virtual void getValues(BasisValues< OutputValueType, DeviceType > outputValues, const TensorPoints< PointValueType, DeviceType > inputPoints, const EOperator operatorType=OPERATOR_VALUE) const override
Evaluation of a FEM basis on a reference cell, using point and output value containers that allow pre...
Implementation of a basis that is the direct sum of two other bases.
OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
Returns a simple decomposition of the specified operator: what operator(s) should be applied to basis...
Basis_Derived_HDIV_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
A basis that is the direct sum of two other bases.
virtual const char * getName() const override
Returns basis name.
virtual void getDofCoeffs(ScalarViewType dofCoeffs) const override
Fills in coefficients of degrees of freedom for Lagrangian basis on the reference cell...
Header file to include all Sacado headers that are required if using Intrepid2 with Sacado types...
virtual OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
Returns a simple decomposition of the specified operator: what operator(s) should be applied to basis...
Basis_Derived_HDIV_Family2_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
virtual const char * getName() const override
Returns basis name.
virtual void getDofCoeffs(typename BasisBase::ScalarViewType dofCoeffs) const override
Fills in coefficients of degrees of freedom on the reference cell.
Basis_Derived_HDIV_WEDGE(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
Basis defined as the tensor product of two component bases.
virtual void getValues(OutputViewType outputValues, const EOperator operatorType, const PointViewType inputPoints1, const PointViewType inputPoints2, bool tensorPoints) const override
multi-component getValues() method (required/called by TensorBasis)