Intrepid2
Intrepid2_DerivedBasis_HDIV_HEX.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 
23 #ifndef Intrepid2_DerivedBasis_HDIV_HEX_h
24 #define Intrepid2_DerivedBasis_HDIV_HEX_h
25 
26 #include <Kokkos_DynRankView.hpp>
27 
29 
31 #include "Intrepid2_Sacado.hpp"
33 
34 namespace Intrepid2
35 {
36  template<class HGRAD_LINE, class HVOL_LINE>
38  :
39  public Basis_TensorBasis3<typename HGRAD_LINE::BasisBase>
40  {
41  public:
42  using OutputViewType = typename HGRAD_LINE::OutputViewType;
43  using PointViewType = typename HGRAD_LINE::PointViewType ;
44  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
45 
46  using LineGradBasis = HGRAD_LINE;
47  using LineHVolBasis = HVOL_LINE;
48 
50  public:
57  Basis_Derived_HDIV_Family1_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, const EPointType pointType = POINTTYPE_DEFAULT)
58  :
59  TensorBasis3(Teuchos::rcp( new LineGradBasis(polyOrder_x,pointType)),
60  Teuchos::rcp( new LineHVolBasis(polyOrder_y-1,pointType)),
61  Teuchos::rcp( new LineHVolBasis(polyOrder_z-1,pointType)),
62  true) // true: use shards CellTopology and tags
63  {
64  this->functionSpace_ = FUNCTION_SPACE_HDIV;
65  }
66 
69  virtual OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
70  {
71  const EOperator VALUE = Intrepid2::OPERATOR_VALUE;
72  const EOperator GRAD = Intrepid2::OPERATOR_GRAD;
73  const EOperator DIV = Intrepid2::OPERATOR_DIV;
74 
75  const double weight = 1.0;
76  if (operatorType == VALUE)
77  {
78  std::vector< std::vector<EOperator> > ops(3);
79  ops[0] = std::vector<EOperator>{VALUE,VALUE,VALUE};
80  ops[1] = std::vector<EOperator>{};
81  ops[2] = std::vector<EOperator>{};
82  std::vector<double> weights {weight,0.0,0.0};
83  return OperatorTensorDecomposition(ops, weights);
84  }
85  else if (operatorType == DIV)
86  {
87  // family 1 is nonzero in the x component, so the div is (GRAD,VALUE,VALUE)
88  std::vector< std::vector<EOperator> > ops(1); // scalar value
89  ops[0] = std::vector<EOperator>{GRAD,VALUE,VALUE};
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 
109  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
110  const PointViewType inputPoints1, const PointViewType inputPoints2, const PointViewType inputPoints3,
111  bool tensorPoints) const override
112  {
113  Intrepid2::EOperator op1, op2, op3;
114  if (operatorType == Intrepid2::OPERATOR_VALUE)
115  {
116  op1 = Intrepid2::OPERATOR_VALUE;
117  op2 = Intrepid2::OPERATOR_VALUE;
118  op3 = Intrepid2::OPERATOR_VALUE;
119 
120  // family 1 goes in the x component; 0 in the y and z components
121  auto outputValuesComponent1 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
122  auto outputValuesComponent23 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),std::make_pair(1,3));
123 
124  this->TensorBasis3::getValues(outputValuesComponent1,
125  inputPoints1, op1,
126  inputPoints2, op2,
127  inputPoints3, op3, tensorPoints);
128  // place 0 in the y and z components
129  Kokkos::deep_copy(outputValuesComponent23,0.0);
130  }
131  else if (operatorType == Intrepid2::OPERATOR_DIV)
132  {
133  // family 1 is nonzero in the x component, so the div is d/dx of the first component
134  // outputValues is scalar, so no need to take subviews
135 
136  op1 = Intrepid2::OPERATOR_GRAD; // d/dx
137  op2 = Intrepid2::OPERATOR_VALUE;
138  op3 = Intrepid2::OPERATOR_VALUE;
139 
140  double weight = 1.0; // the plus sign in front of d/dx
141  this->TensorBasis3::getValues(outputValues,
142  inputPoints1, op1,
143  inputPoints2, op2,
144  inputPoints3, op3, tensorPoints, weight);
145  }
146  else
147  {
148  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
149  }
150  }
151 
163  virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override {
164  auto dofCoeffs1 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),0);
165  auto dofCoeffs23 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),std::make_pair(1,3));
166  this->TensorBasis3::getDofCoeffs(dofCoeffs1);
167  Kokkos::deep_copy(dofCoeffs23,0.0);
168  }
169  };
170 
171  template<class HGRAD_LINE, class HVOL_LINE>
173  :
174  public Basis_TensorBasis3<typename HGRAD_LINE::BasisBase>
175  {
176  public:
177  using OutputViewType = typename HGRAD_LINE::OutputViewType;
178  using PointViewType = typename HGRAD_LINE::PointViewType ;
179  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
180 
181  using LineGradBasis = HGRAD_LINE;
182  using LineHVolBasis = HVOL_LINE;
183 
185  public:
192  Basis_Derived_HDIV_Family2_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, const EPointType pointType = POINTTYPE_DEFAULT)
193  :
194  TensorBasis3(Teuchos::rcp( new LineHVolBasis(polyOrder_x-1,pointType) ),
195  Teuchos::rcp( new LineGradBasis(polyOrder_y,pointType) ),
196  Teuchos::rcp( new LineHVolBasis(polyOrder_z-1,pointType) ),
197  true) // true: use shards CellTopology and tags
198  {
199  this->functionSpace_ = FUNCTION_SPACE_HDIV;
200  }
201 
204  virtual OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
205  {
206  const EOperator VALUE = Intrepid2::OPERATOR_VALUE;
207  const EOperator GRAD = Intrepid2::OPERATOR_GRAD;
208  const EOperator DIV = Intrepid2::OPERATOR_DIV;
209 
210  const double weight = 1.0;
211  if (operatorType == VALUE)
212  {
213  std::vector< std::vector<EOperator> > ops(3);
214  ops[0] = std::vector<EOperator>{};
215  ops[1] = std::vector<EOperator>{VALUE,VALUE,VALUE};
216  ops[2] = std::vector<EOperator>{};
217  std::vector<double> weights {0.0,weight,0.0};
218  return OperatorTensorDecomposition(ops, weights);
219  }
220  else if (operatorType == DIV)
221  {
222  // family 2 is nonzero in the y component, so the div is (VALUE,GRAD,VALUE)
223  std::vector< std::vector<EOperator> > ops(1); // scalar value
224  ops[0] = std::vector<EOperator>{VALUE,GRAD,VALUE};
225  std::vector<double> weights {weight};
226  return OperatorTensorDecomposition(ops,weights);
227  }
228  else
229  {
230  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported operator type");
231  }
232  }
233 
235 
244  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
245  const PointViewType inputPoints1, const PointViewType inputPoints2, const PointViewType inputPoints3,
246  bool tensorPoints) const override
247  {
248  Intrepid2::EOperator op1, op2, op3;
249  if (operatorType == Intrepid2::OPERATOR_VALUE)
250  {
251  op1 = Intrepid2::OPERATOR_VALUE;
252  op2 = Intrepid2::OPERATOR_VALUE;
253  op3 = Intrepid2::OPERATOR_VALUE;
254 
255  // family 2 goes in the y component; 0 in the x and z components
256  auto outputValuesComponent_x = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
257  auto outputValuesComponent_y = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),1);
258  auto outputValuesComponent_z = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
259 
260  // 0 in x component
261  Kokkos::deep_copy(outputValuesComponent_x,0.0);
262 
263  double weight = 1.0;
264  this->TensorBasis3::getValues(outputValuesComponent_y,
265  inputPoints1, op1,
266  inputPoints2, op2,
267  inputPoints3, op3, tensorPoints, weight);
268 
269  // 0 in z component
270  Kokkos::deep_copy(outputValuesComponent_z,0.0);
271  }
272  else if (operatorType == Intrepid2::OPERATOR_DIV)
273  {
274  // family 2 is nonzero in the y component, so the div is d/dy of the second component
275  op1 = Intrepid2::OPERATOR_VALUE;
276  op2 = Intrepid2::OPERATOR_GRAD; // d/dy
277  op3 = Intrepid2::OPERATOR_VALUE;
278 
279  double weight = 1.0;
280  this->TensorBasis3::getValues(outputValues,
281  inputPoints1, op1,
282  inputPoints2, op2,
283  inputPoints3, op3, tensorPoints, weight);
284  }
285  else
286  {
287  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
288  }
289  }
290 
302  virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override {
303  auto dofCoeffs1 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),0);
304  auto dofCoeffs2 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),1);
305  auto dofCoeffs3 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),2);
306  Kokkos::deep_copy(dofCoeffs1,0.0);
307  this->TensorBasis3::getDofCoeffs(dofCoeffs2);
308  Kokkos::deep_copy(dofCoeffs3,0.0);
309  }
310  };
311 
312  template<class HGRAD_LINE, class HVOL_LINE>
314  : public Basis_TensorBasis3<typename HGRAD_LINE::BasisBase>
315  {
316  public:
317  using OutputViewType = typename HGRAD_LINE::OutputViewType;
318  using PointViewType = typename HGRAD_LINE::PointViewType ;
319  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
320 
321  using LineGradBasis = HGRAD_LINE;
322  using LineHVolBasis = HVOL_LINE;
323 
325  public:
332  Basis_Derived_HDIV_Family3_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, const EPointType pointType = POINTTYPE_DEFAULT)
333  :
334  TensorBasis3(Teuchos::rcp( new LineHVolBasis(polyOrder_x-1,pointType) ),
335  Teuchos::rcp( new LineHVolBasis(polyOrder_y-1,pointType) ),
336  Teuchos::rcp( new LineGradBasis(polyOrder_z,pointType) ),
337  true) // true: use shards CellTopology and tags
338  {
339  this->functionSpace_ = FUNCTION_SPACE_HDIV;
340  }
341 
344  virtual OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
345  {
346  const EOperator VALUE = Intrepid2::OPERATOR_VALUE;
347  const EOperator GRAD = Intrepid2::OPERATOR_GRAD;
348  const EOperator DIV = Intrepid2::OPERATOR_DIV;
349 
350  const double weight = 1.0;
351  if (operatorType == VALUE)
352  {
353  std::vector< std::vector<EOperator> > ops(3);
354  ops[0] = std::vector<EOperator>{};
355  ops[1] = std::vector<EOperator>{};
356  ops[2] = std::vector<EOperator>{VALUE,VALUE,VALUE};
357  std::vector<double> weights {0.0,0.0,weight};
358  return OperatorTensorDecomposition(ops, weights);
359  }
360  else if (operatorType == DIV)
361  {
362  // family 3 is nonzero in the z component, so the div is (VALUE,VALUE,GRAD)
363  std::vector< std::vector<EOperator> > ops(1); // scalar value
364  ops[0] = std::vector<EOperator>{VALUE,VALUE,GRAD};
365  std::vector<double> weights {weight};
366  return OperatorTensorDecomposition(ops,weights);
367  }
368  else
369  {
370  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported operator type");
371  }
372  }
373 
375 
384  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
385  const PointViewType inputPoints1, const PointViewType inputPoints2, const PointViewType inputPoints3,
386  bool tensorPoints) const override
387  {
388  Intrepid2::EOperator op1, op2, op3;
389  if (operatorType == Intrepid2::OPERATOR_VALUE)
390  {
391  op1 = Intrepid2::OPERATOR_VALUE;
392  op2 = Intrepid2::OPERATOR_VALUE;
393  op3 = Intrepid2::OPERATOR_VALUE;
394 
395  // family 3 goes in the z component; 0 in the x and y components
396  auto outputValuesComponent_xy = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),std::make_pair(0,2));
397  auto outputValuesComponent_z = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
398 
399  // 0 in x and y components
400  Kokkos::deep_copy(outputValuesComponent_xy,0.0);
401 
402  // z component
403  this->TensorBasis3::getValues(outputValuesComponent_z,
404  inputPoints1, op1,
405  inputPoints2, op2,
406  inputPoints3, op3, tensorPoints);
407  }
408  else if (operatorType == Intrepid2::OPERATOR_DIV)
409  {
410  // family 3 is nonzero in the z component, so the div is d/dz of the third component
411  // outputValues is scalar, so no need to take subviews
412 
413  op1 = Intrepid2::OPERATOR_VALUE;
414  op2 = Intrepid2::OPERATOR_VALUE;
415  op3 = Intrepid2::OPERATOR_GRAD; // d/dz
416 
417  double weight = 1.0; // the plus sign in front of d/dz
418  this->TensorBasis3::getValues(outputValues,
419  inputPoints1, op1,
420  inputPoints2, op2,
421  inputPoints3, op3, tensorPoints, weight);
422  }
423  else
424  {
425  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
426  }
427  }
428 
440  virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override {
441  auto dofCoeffs12 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),std::make_pair(0,2));
442  auto dofCoeffs3 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),2);
443  Kokkos::deep_copy(dofCoeffs12,0.0);
444  this->TensorBasis3::getDofCoeffs(dofCoeffs3);
445  }
446 
447  };
448 
449  // ESEAS numbers its H(div) families differently, with the nonzero going in z, x, y for I,II,III.
450  // To allow our interior orderings to match that of ESEAS, we put the direct sum in the same order as ESEAS,
451  // which is to say that we go 3,1,2.
452  template<class HGRAD_LINE, class HVOL_LINE>
454  : public Basis_DirectSumBasis <typename HGRAD_LINE::BasisBase>
455  {
459  public:
466  Basis_Derived_HDIV_Family3_Family1_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, const EPointType pointType)
467  :
468  DirectSumBasis(Teuchos::rcp( new Family3(polyOrder_x, polyOrder_y, polyOrder_z, pointType)),
469  Teuchos::rcp( new Family1(polyOrder_x, polyOrder_y, polyOrder_z, pointType))) {
470  this->functionSpace_ = FUNCTION_SPACE_HDIV;
471  }
472  };
473 
474  template<class HGRAD_LINE, class HVOL_LINE>
476  : public Basis_DirectSumBasis <typename HGRAD_LINE::BasisBase>
477  {
481 
482  std::string name_;
483  ordinal_type order_x_;
484  ordinal_type order_y_;
485  ordinal_type order_z_;
486  EPointType pointType_;
487 
488  public:
489  using ExecutionSpace = typename HGRAD_LINE::ExecutionSpace;
490  using OutputValueType = typename HGRAD_LINE::OutputValueType;
491  using PointValueType = typename HGRAD_LINE::PointValueType;
492 
493  using BasisBase = typename HGRAD_LINE::BasisBase;
494 
501  Basis_Derived_HDIV_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
502  :
503  DirectSumBasis(Teuchos::rcp(new Family31(polyOrder_x, polyOrder_y, polyOrder_z, pointType)),
504  Teuchos::rcp(new Family2 (polyOrder_x, polyOrder_y, polyOrder_z, pointType))) {
505  this->functionSpace_ = FUNCTION_SPACE_HDIV;
506 
507  std::ostringstream basisName;
508  basisName << "HDIV_HEX (" << this->DirectSumBasis::getName() << ")";
509  name_ = basisName.str();
510 
511  order_x_ = polyOrder_x;
512  order_y_ = polyOrder_y;
513  order_z_ = polyOrder_z;
514  pointType_ = pointType;
515  }
516 
520  Basis_Derived_HDIV_HEX(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT) : Basis_Derived_HDIV_HEX(polyOrder, polyOrder, polyOrder, pointType) {}
521 
524  virtual bool requireOrientation() const override {
525  return true;
526  }
527 
532  virtual
533  const char*
534  getName() const override {
535  return name_.c_str();
536  }
537 
548  Teuchos::RCP<BasisBase>
549  getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const override {
550 
551  using QuadBasis = Basis_Derived_HVOL_QUAD<HVOL_LINE>;
552 
553  if(subCellDim == 2) {
554  switch(subCellOrd) {
555  case 0:
556  return Teuchos::rcp( new QuadBasis(order_x_-1, order_z_-1, pointType_) );
557  case 1:
558  return Teuchos::rcp( new QuadBasis(order_y_-1,order_z_-1, pointType_) );
559  case 2:
560  return Teuchos::rcp( new QuadBasis(order_x_-1, order_z_-1, pointType_) );
561  case 3:
562  return Teuchos::rcp( new QuadBasis(order_z_-1, order_y_-1, pointType_) );
563  case 4:
564  return Teuchos::rcp( new QuadBasis(order_y_-1, order_x_-1, pointType_) );
565  case 5:
566  return Teuchos::rcp( new QuadBasis(order_x_-1, order_y_-1, pointType_) );
567  }
568  }
569 
570  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"Input parameters out of bounds");
571  }
572 
577  virtual HostBasisPtr<OutputValueType, PointValueType>
578  getHostBasis() const override {
580 
581  auto hostBasis = Teuchos::rcp(new HostBasis(order_x_, order_y_, order_z_, pointType_));
582 
583  return hostBasis;
584  }
585  };
586 } // end namespace Intrepid2
587 
588 #endif /* Intrepid2_DerivedBasis_HDIV_HEX_h */
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, const PointViewType inputPoints3, bool tensorPoints) const override
multi-component getValues() method (required/called by TensorBasis3)
Implementation of H(vol) basis on the quadrilateral that is templated on H(vol) on the line...
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 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_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
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 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 inputPoints12, const PointViewType inputPoints3, bool tensorPoints) const override
Evaluation of a tensor FEM basis on a reference cell.
virtual const char * getName() const override
Returns basis name.
Implementation of a basis that is the direct sum of two other bases.
A basis that is the direct sum of two other bases.
virtual const char * getName() const override
Returns basis name.
virtual bool requireOrientation() const override
True if orientation is required.
Basis_Derived_HDIV_HEX(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
Basis_Derived_HDIV_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
Header file to include all Sacado headers that are required if using Intrepid2 with Sacado types...
Basis_Derived_HDIV_Family3_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
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...
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, const PointViewType inputPoints3, bool tensorPoints) const override
multi-component getValues() method (required/called by TensorBasis3)
virtual void getValues(OutputViewType outputValues, const EOperator operatorType, const PointViewType inputPoints1, const PointViewType inputPoints2, const PointViewType inputPoints3, bool tensorPoints) const override
multi-component getValues() method (required/called by TensorBasis3)
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_Family1_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
Basis_Derived_HDIV_Family3_Family1_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, const EPointType pointType)
Constructor.
virtual void getDofCoeffs(ScalarViewType dofCoeffs) const override
Fills in coefficients of degrees of freedom for Lagrangian basis on the reference cell...
Teuchos::RCP< BasisBase > getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const override
returns the basis associated to a subCell.