Intrepid2
Intrepid2_DerivedBasis_HCURL_QUAD.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 
19 #ifndef Intrepid2_DerivedBasis_HCURL_QUAD_h
20 #define Intrepid2_DerivedBasis_HCURL_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 BasisBase = typename HGRAD_LINE::BasisBase;
46 
47  using LineGradBasis = HGRAD_LINE;
48  using LineHVolBasis = HVOL_LINE;
49 
51  public:
57  Basis_Derived_HCURL_Family1_QUAD(int polyOrder_x, int polyOrder_y, const EPointType pointType = POINTTYPE_DEFAULT)
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_HCURL;
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 CURL = Intrepid2::OPERATOR_CURL;
73  if (operatorType == VALUE)
74  {
75  // family 1 goes in x component
76  std::vector< std::vector<EOperator> > ops(2);
77  ops[0] = std::vector<EOperator>{VALUE,VALUE};
78  ops[1] = std::vector<EOperator>{};
79  std::vector<double> weights {1.0, 0.0};
80  return OperatorTensorDecomposition(ops, weights);
81  }
82  else if (operatorType == CURL)
83  {
84  // family 1 gets a -d/dy applied to the first (nonzero) vector component
85  // since this is H(VOL)(x) * H(GRAD)(y), this amounts to taking the derivative in the second tensorial component
86  return OperatorTensorDecomposition(VALUE,GRAD,-1.0);
87  }
88  else
89  {
90  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported operator type");
91  }
92  }
93 
95 
103  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
104  const PointViewType inputPoints1, const PointViewType inputPoints2,
105  bool tensorPoints) const override
106  {
107  Intrepid2::EOperator op1, op2;
108  if (operatorType == Intrepid2::OPERATOR_VALUE)
109  {
110  op1 = Intrepid2::OPERATOR_VALUE;
111  op2 = Intrepid2::OPERATOR_VALUE;
112 
113  // family 1 goes in the x component; 0 in the y component
114  OutputViewType outputValuesComponent1 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
115  OutputViewType outputValuesComponent2 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),1);
116 
117  this->TensorBasis::getValues(outputValuesComponent1,
118  inputPoints1, op1,
119  inputPoints2, op2, tensorPoints);
120  // place 0 in the y component
121  Kokkos::deep_copy(outputValuesComponent2,0);
122  }
123  else if (operatorType == Intrepid2::OPERATOR_CURL)
124  {
125  // family 1 gets a -d/dy applied to the first (nonzero) vector component
126  // since this is H(VOL)(x) * H(GRAD)(y), this amounts to taking the derivative in the second tensorial component
127  op1 = Intrepid2::OPERATOR_VALUE;
128  op2 = Intrepid2::OPERATOR_GRAD;
129 
130  double weight = -1.0; // the minus sign in front of d/dy
131  this->TensorBasis::getValues(outputValues,
132  inputPoints1, op1,
133  inputPoints2, op2, tensorPoints, weight);
134  }
135  else
136  {
137  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
138  }
139  }
140 
152  virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override {
153  auto dofCoeffs1 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),0);
154  auto dofCoeffs2 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),1);
155  this->TensorBasis::getDofCoeffs(dofCoeffs1);
156  Kokkos::deep_copy(dofCoeffs2,0.0);
157  }
158  };
159 
160  template<class HGRAD_LINE, class HVOL_LINE>
162  : public Basis_TensorBasis<typename HGRAD_LINE::BasisBase>
163  {
164 
165  public:
166  using ExecutionSpace = typename HGRAD_LINE::ExecutionSpace;
167  using OutputValueType = typename HGRAD_LINE::OutputValueType;
168  using PointValueType = typename HGRAD_LINE::PointValueType;
169 
170  using OutputViewType = typename HGRAD_LINE::OutputViewType;
171  using PointViewType = typename HGRAD_LINE::PointViewType ;
172  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
173 
174  using LineGradBasis = HGRAD_LINE;
175  using LineHVolBasis = HVOL_LINE;
176 
177  using BasisBase = typename HGRAD_LINE::BasisBase;
178 
180 
186  Basis_Derived_HCURL_Family2_QUAD(int polyOrder_x, int polyOrder_y, const EPointType pointType = POINTTYPE_DEFAULT)
187  :
188  TensorBasis(Teuchos::rcp( new LineGradBasis(polyOrder_x,pointType) ),
189  Teuchos::rcp( new LineHVolBasis(polyOrder_y-1,pointType) ))
190  {
191  this->functionSpace_ = FUNCTION_SPACE_HCURL;
192  this->setShardsTopologyAndTags();
193  }
194 
197  virtual OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
198  {
199  const EOperator VALUE = Intrepid2::OPERATOR_VALUE;
200  const EOperator GRAD = Intrepid2::OPERATOR_GRAD;
201  const EOperator CURL = Intrepid2::OPERATOR_CURL;
202  if (operatorType == VALUE)
203  {
204  // family 2 goes in y component
205  std::vector< std::vector<EOperator> > ops(2);
206  ops[0] = std::vector<EOperator>{};
207  ops[1] = std::vector<EOperator>{VALUE,VALUE};
208  std::vector<double> weights {0.0, 1.0};
209  return OperatorTensorDecomposition(ops, weights);
210  }
211  else if (operatorType == CURL)
212  {
213  // family 2 gets a d/dx applied to the second (nonzero) vector component
214  // since this is H(GRAD)(x) * H(VOL)(y), this amounts to taking the derivative in the first tensorial component
215  return OperatorTensorDecomposition(GRAD,VALUE,1.0);
216  }
217  else
218  {
219  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported operator type");
220  }
221  }
222 
224 
232  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
233  const PointViewType inputPoints1, const PointViewType inputPoints2,
234  bool tensorPoints) const override
235  {
236  Intrepid2::EOperator op1, op2;
237  if (operatorType == Intrepid2::OPERATOR_VALUE)
238  {
239  op1 = Intrepid2::OPERATOR_VALUE;
240  op2 = Intrepid2::OPERATOR_VALUE;
241 
242  // family 2 goes in the y component; 0 in the x component
243  auto outputValuesComponent1 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
244  auto outputValuesComponent2 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),1);
245 
246  // place 0 in the x component
247  Kokkos::deep_copy(outputValuesComponent1, 0.0);
248  this->TensorBasis::getValues(outputValuesComponent2,
249  inputPoints1, op1,
250  inputPoints2, op2, tensorPoints);
251 
252  }
253  else if (operatorType == Intrepid2::OPERATOR_CURL)
254  {
255  // family 2 gets a d/dx applied to the second (nonzero) vector component
256  // since this is H(GRAD)(x) * H(VOL)(y), this amounts to taking the derivative in the first tensorial component
257  op1 = Intrepid2::OPERATOR_GRAD;
258  op2 = Intrepid2::OPERATOR_VALUE;
259 
260  this->TensorBasis::getValues(outputValues,
261  inputPoints1, op1,
262  inputPoints2, op2, tensorPoints);
263  }
264  else
265  {
266  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
267  }
268  }
269 
281  virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override {
282  auto dofCoeffs1 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),0);
283  auto dofCoeffs2 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),1);
284  Kokkos::deep_copy(dofCoeffs1,0.0);
285  this->TensorBasis::getDofCoeffs(dofCoeffs2);
286  }
287  };
288 
289  template<class HGRAD_LINE, class HVOL_LINE>
291  : public Basis_DirectSumBasis <typename HGRAD_LINE::BasisBase>
292  {
296  public:
297  using BasisBase = typename HGRAD_LINE::BasisBase;
298 
299  protected:
300  std::string name_;
301  ordinal_type order_x_;
302  ordinal_type order_y_;
303  EPointType pointType_;
304 
305  public:
306  using ExecutionSpace = typename HGRAD_LINE::ExecutionSpace;
307  using OutputValueType = typename HGRAD_LINE::OutputValueType;
308  using PointValueType = typename HGRAD_LINE::PointValueType;
309 
315  Basis_Derived_HCURL_QUAD(int polyOrder_x, int polyOrder_y, const EPointType pointType=POINTTYPE_DEFAULT)
316  :
317  DirectSumBasis(Teuchos::rcp( new Family1(polyOrder_x, polyOrder_y, pointType) ),
318  Teuchos::rcp( new Family2(polyOrder_x, polyOrder_y, pointType) ))
319  {
320  this->functionSpace_ = FUNCTION_SPACE_HCURL;
321 
322  std::ostringstream basisName;
323  basisName << "HCURL_QUAD (" << this->DirectSumBasis::getName() << ")";
324  name_ = basisName.str();
325 
326  order_x_ = polyOrder_x;
327  order_y_ = polyOrder_y;
328  pointType_ = pointType;
329  }
330 
335  Basis_Derived_HCURL_QUAD(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT) : Basis_Derived_HCURL_QUAD(polyOrder, polyOrder, pointType) {}
336 
339  virtual bool requireOrientation() const override
340  {
341  return true;
342  }
343 
348  virtual
349  const char*
350  getName() const override {
351  return name_.c_str();
352  }
353 
364  Teuchos::RCP<BasisBase>
365  getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const override{
366  if(subCellDim == 1) {
367  switch(subCellOrd) {
368  case 0:
369  case 2:
370  return Teuchos::rcp( new HVOL_LINE(order_x_-1, pointType_) );
371  case 1:
372  case 3:
373  return Teuchos::rcp( new HVOL_LINE(order_y_-1, pointType_) );
374  }
375  }
376 
377  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"Input parameters out of bounds");
378  }
379 
384  virtual HostBasisPtr<OutputValueType, PointValueType>
385  getHostBasis() const override {
387 
388  auto hostBasis = Teuchos::rcp(new HostBasis(order_x_, order_y_, pointType_));
389 
390  return hostBasis;
391  }
392  };
393 } // end namespace Intrepid2
394 
395 #endif /* Intrepid2_DerivedBasis_HCURL_QUAD_h */
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_HCURL_QUAD(int polyOrder_x, int polyOrder_y, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
Implementation of bases that are tensor products of two or three component bases. ...
Teuchos::RCP< BasisBase > getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const override
returns the basis associated to a subCell.
virtual void getDofCoeffs(ScalarViewType dofCoeffs) const override
Fills in coefficients of degrees of freedom for Lagrangian basis on the reference cell...
virtual void getDofCoeffs(ScalarViewType dofCoeffs) const override
Fills in coefficients of degrees of freedom for Lagrangian basis on the reference cell...
Free functions, callable from device code, that implement various polynomials useful in basis definit...
virtual bool requireOrientation() const override
True if orientation is required.
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...
virtual OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
Returns a simple decomposition of the specified operator: what operator(s) should be applied to basis...
Implementation of a basis that is the direct sum of two other bases.
Basis_Derived_HCURL_Family1_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.
virtual HostBasisPtr< OutputValueType, PointValueType > getHostBasis() const override
Creates and returns a Basis object whose DeviceType template argument is Kokkos::HostSpace::device_ty...
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)
Header file to include all Sacado headers that are required if using Intrepid2 with Sacado types...
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.
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 defined as the tensor product of two component bases.
Basis_Derived_HCURL_Family2_QUAD(int polyOrder_x, int polyOrder_y, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
Basis_Derived_HCURL_QUAD(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.