Intrepid2
Intrepid2_DerivedBasis_HDIV_QUAD.hpp
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 
19 #ifndef Intrepid2_DerivedBasis_HIV_QUAD_h
20 #define Intrepid2_DerivedBasis_HIV_QUAD_h
21 
22 #include <Kokkos_DynRankView.hpp>
23 
25 #include "Intrepid2_Sacado.hpp"
26 
29 
30 namespace Intrepid2
31 {
32  template<class HGRAD_LINE, class HVOL_LINE>
34  : public Basis_TensorBasis<typename HGRAD_LINE::BasisBase>
35  {
36  public:
37  using ExecutionSpace = typename HGRAD_LINE::ExecutionSpace;
38  using OutputValueType = typename HGRAD_LINE::OutputValueType;
39  using PointValueType = typename HGRAD_LINE::PointValueType;
40 
41  using OutputViewType = typename HGRAD_LINE::OutputViewType;
42  using PointViewType = typename HGRAD_LINE::PointViewType ;
43  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
44 
45  using LineGradBasis = HGRAD_LINE;
46  using LineHVolBasis = HVOL_LINE;
47 
48  using BasisBase = typename HGRAD_LINE::BasisBase;
49 
51  public:
57  Basis_Derived_HDIV_Family1_QUAD(int polyOrder_x, int polyOrder_y, const EPointType pointType)
58  :
59  TensorBasis(Teuchos::rcp(new LineHVolBasis(polyOrder_x-1,pointType)),
60  Teuchos::rcp(new LineGradBasis(polyOrder_y,pointType)))
61  {
62  this->functionSpace_ = FUNCTION_SPACE_HDIV;
63  this->setShardsTopologyAndTags();
64  }
65 
68  virtual OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
69  {
70  const EOperator VALUE = Intrepid2::OPERATOR_VALUE;
71  const EOperator GRAD = Intrepid2::OPERATOR_GRAD;
72  const EOperator DIV = Intrepid2::OPERATOR_DIV;
73 
74  // ESEAS implements H(div) as rotated H(curl), which involves weighting family1 with -1.
75  // We follow that here to simplify verification tests that involve ESEAS.
76  const double weight = -1.0;
77  if (operatorType == VALUE)
78  {
79  std::vector< std::vector<EOperator> > ops(2);
80  ops[0] = std::vector<EOperator>{};
81  ops[1] = std::vector<EOperator>{VALUE,VALUE};
82  std::vector<double> weights {0.0,weight};
83  return OperatorTensorDecomposition(ops, weights);
84  }
85  else if (operatorType == DIV)
86  {
87  // family 1 is nonzero in the y component, so the div is (VALUE,GRAD)
88  std::vector< std::vector<EOperator> > ops(1); // scalar value
89  ops[0] = std::vector<EOperator>{VALUE,GRAD};
90  std::vector<double> weights {weight};
91  return OperatorTensorDecomposition(ops,weights);
92  }
93  else
94  {
95  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported operator type");
96  }
97  }
98 
100 
108  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
109  const PointViewType inputPoints1, const PointViewType inputPoints2,
110  bool tensorPoints) const override
111  {
112  // ESEAS implements H(div) as rotated H(curl), which involves weighting family1 with -1.
113  // We follow that here to simplify verification tests that involve ESEAS.
114  const double weight = -1.0;
115 
116  Intrepid2::EOperator op1, op2;
117  if (operatorType == Intrepid2::OPERATOR_VALUE)
118  {
119  op1 = Intrepid2::OPERATOR_VALUE;
120  op2 = Intrepid2::OPERATOR_VALUE;
121 
122  // family 1 goes in the y component; 0 in the x component
123  auto outputValuesComponent1 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
124  auto outputValuesComponent2 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),1);
125 
126  this->TensorBasis::getValues(outputValuesComponent2,
127  inputPoints1, op1,
128  inputPoints2, op2, tensorPoints, weight);
129  // place 0 in the y component
130  Kokkos::deep_copy(outputValuesComponent1,0.0);
131  }
132  else if (operatorType == Intrepid2::OPERATOR_DIV)
133  {
134  // family 1 gets a d/dy applied to the second (nonzero) vector component
135  // since this is H(VOL)(x) * H(GRAD)(y), this amounts to taking the derivative in the second tensorial component
136  op1 = Intrepid2::OPERATOR_VALUE;
137  op2 = Intrepid2::OPERATOR_GRAD;
138 
139  this->TensorBasis::getValues(outputValues,
140  inputPoints1, op1,
141  inputPoints2, op2, tensorPoints, weight);
142  }
143  else
144  {
145  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
146  }
147  }
148 
160  virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override {
161  auto dofCoeffs1 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),0);
162  auto dofCoeffs2 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),1);
163  Kokkos::deep_copy(dofCoeffs1,0.0);
164  this->TensorBasis::getDofCoeffs(dofCoeffs2);
165  //multiply by weight = -1.0
166  Kokkos::parallel_for( Kokkos::RangePolicy<ExecutionSpace>(0, dofCoeffs2.extent(0)),
167  KOKKOS_LAMBDA (const int i){ dofCoeffs2(i) *= -1.0; });
168  }
169 
170  };
171 
172  template<class HGRAD_LINE, class HVOL_LINE>
174  : public Basis_TensorBasis<typename HGRAD_LINE::BasisBase>
175  {
176  using ExecutionSpace = typename HGRAD_LINE::ExecutionSpace;
177  using OutputValueType = typename HGRAD_LINE::OutputValueType;
178  using PointValueType = typename HGRAD_LINE::PointValueType;
179 
180  using OutputViewType = typename HGRAD_LINE::OutputViewType;
181  using PointViewType = typename HGRAD_LINE::PointViewType ;
182  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
183 
184  using LineGradBasis = HGRAD_LINE;
185  using LineHVolBasis = HVOL_LINE;
186 
187  using BasisBase = typename HGRAD_LINE::BasisBase;
188 
190  public:
196  Basis_Derived_HDIV_Family2_QUAD(int polyOrder_x, int polyOrder_y, const EPointType pointType = POINTTYPE_DEFAULT)
197  :
198  TensorBasis(Teuchos::rcp(new LineGradBasis(polyOrder_x,pointType)),
199  Teuchos::rcp(new LineHVolBasis(polyOrder_y-1,pointType)))
200  {
201  this->functionSpace_ = FUNCTION_SPACE_HDIV;
202  this->setShardsTopologyAndTags();
203  }
204 
207  virtual OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
208  {
209  const EOperator VALUE = Intrepid2::OPERATOR_VALUE;
210  const EOperator GRAD = Intrepid2::OPERATOR_GRAD;
211  const EOperator DIV = Intrepid2::OPERATOR_DIV;
212 
213  const double weight = 1.0; // family 2 (x component nonzero)
214  if (operatorType == VALUE)
215  {
216  std::vector< std::vector<EOperator> > ops(2);
217  ops[0] = std::vector<EOperator>{VALUE,VALUE};
218  ops[1] = std::vector<EOperator>{};
219  std::vector<double> weights {weight, 0.0};
220  return OperatorTensorDecomposition(ops, weights);
221  }
222  else if (operatorType == DIV)
223  {
224  // family 2 is nonzero in the x component, so the div is (GRAD,VALUE)
225  std::vector< std::vector<EOperator> > ops(1); // scalar value
226  ops[0] = std::vector<EOperator>{GRAD,VALUE};
227  std::vector<double> weights {weight};
228  return OperatorTensorDecomposition(ops,weights);
229  }
230  else
231  {
232  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported operator type");
233  }
234  }
235 
237 
245  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
246  const PointViewType inputPoints1, const PointViewType inputPoints2,
247  bool tensorPoints) const override
248  {
249  Intrepid2::EOperator op1, op2;
250  if (operatorType == Intrepid2::OPERATOR_VALUE)
251  {
252  op1 = Intrepid2::OPERATOR_VALUE;
253  op2 = Intrepid2::OPERATOR_VALUE;
254 
255  // family 2 goes in the x component; 0 in the x component
256  auto outputValuesComponent1 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
257  auto outputValuesComponent2 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),1);
258 
259  this->TensorBasis::getValues(outputValuesComponent1,
260  inputPoints1, op1,
261  inputPoints2, op2, tensorPoints);
262  // place 0 in the y component
263  Kokkos::deep_copy(outputValuesComponent2, 0.0);
264  }
265  else if (operatorType == Intrepid2::OPERATOR_DIV)
266  {
267  // family 2 gets a d/dx applied to the first (nonzero) vector component
268  // since this is H(GRAD)(x) * H(VOL)(y), this amounts to taking the derivative in the first tensorial component
269  op1 = Intrepid2::OPERATOR_GRAD;
270  op2 = Intrepid2::OPERATOR_VALUE;
271 
272  this->TensorBasis::getValues(outputValues,
273  inputPoints1, op1,
274  inputPoints2, op2, tensorPoints);
275  }
276  else
277  {
278  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
279  }
280  }
281 
293  virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override {
294  auto dofCoeffs1 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),0);
295  auto dofCoeffs2 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),1);
296  this->TensorBasis::getDofCoeffs(dofCoeffs1);
297  Kokkos::deep_copy(dofCoeffs2,0.0);
298  }
299 
300  };
301 
302  template<class HGRAD_LINE, class HVOL_LINE>
304  : public Basis_DirectSumBasis <typename HGRAD_LINE::BasisBase>
305  {
309 
310  public:
311  using ExecutionSpace = typename HGRAD_LINE::ExecutionSpace;
312  using OutputValueType = typename HGRAD_LINE::OutputValueType;
313  using PointValueType = typename HGRAD_LINE::PointValueType;
314 
315  using BasisBase = typename HGRAD_LINE::BasisBase;
316 
317  protected:
318  std::string name_;
319  ordinal_type order_x_;
320  ordinal_type order_y_;
321  EPointType pointType_;
322  public:
328  Basis_Derived_HDIV_QUAD(int polyOrder_x, int polyOrder_y, const EPointType pointType=POINTTYPE_DEFAULT)
329  :
330  DirectSumBasis(Teuchos::rcp(new Family1(polyOrder_x, polyOrder_y, pointType)),
331  Teuchos::rcp(new Family2(polyOrder_x, polyOrder_y, pointType)))
332  {
333  this->functionSpace_ = FUNCTION_SPACE_HDIV;
334 
335  std::ostringstream basisName;
336  basisName << "HDIV_QUAD (" << this->DirectSumBasis::getName() << ")";
337  name_ = basisName.str();
338 
339  order_x_ = polyOrder_x;
340  order_y_ = polyOrder_y;
341  pointType_ = pointType;
342  }
343 
348  Basis_Derived_HDIV_QUAD(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT) : Basis_Derived_HDIV_QUAD(polyOrder, polyOrder, pointType) {}
349 
352  virtual bool requireOrientation() const override {
353  return true;
354  }
355 
360  virtual
361  const char*
362  getName() const override {
363  return name_.c_str();
364  }
365 
376  Teuchos::RCP<BasisBase>
377  getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const override{
378  if(subCellDim == 1) {
379  switch(subCellOrd) {
380  case 0:
381  case 2:
382  return Teuchos::rcp( new HVOL_LINE(order_x_-1, pointType_) );
383  case 1:
384  case 3:
385  return Teuchos::rcp( new HVOL_LINE(order_y_-1, pointType_) );
386  }
387  }
388 
389  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"Input parameters out of bounds");
390  }
391 
396  virtual HostBasisPtr<OutputValueType, PointValueType>
397  getHostBasis() const override {
399 
400  auto hostBasis = Teuchos::rcp(new HostBasis(order_x_, order_y_, pointType_));
401 
402  return hostBasis;
403  }
404  };
405 } // end namespace Intrepid2
406 
407 #endif /* Intrepid2_DerivedBasis_HIV_QUAD_h */
virtual void getDofCoeffs(ScalarViewType dofCoeffs) const override
Fills in coefficients of degrees of freedom for Lagrangian basis on the reference cell...
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)
Basis_Derived_HDIV_Family1_QUAD(int polyOrder_x, int polyOrder_y, const EPointType pointType)
Constructor.
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...
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.
virtual void getDofCoeffs(ScalarViewType dofCoeffs) const override
Fills in coefficients of degrees of freedom for Lagrangian basis on the reference cell...
Basis_Derived_HDIV_QUAD(int polyOrder_x, int polyOrder_y, 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.
Header file to include all Sacado headers that are required if using Intrepid2 with Sacado types...
virtual bool requireOrientation() const override
True if orientation is required.
virtual const char * getName() const override
Returns basis name.
virtual OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
Returns a simple decomposition of the specified operator: what operator(s) should be applied to basis...
virtual void getDofCoeffs(typename BasisBase::ScalarViewType dofCoeffs) const override
Fills in coefficients of degrees of freedom on the reference cell.
Basis_Derived_HDIV_Family2_QUAD(int polyOrder_x, int polyOrder_y, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
virtual OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
Returns a simple decomposition of the specified operator: what operator(s) should be applied to basis...
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)
Basis_Derived_HDIV_QUAD(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
Basis defined as the tensor product of two component bases.
virtual HostBasisPtr< OutputValueType, PointValueType > getHostBasis() const override
Creates and returns a Basis object whose DeviceType template argument is Kokkos::HostSpace::device_ty...