Intrepid2
Intrepid2_DerivedBasis_HCURL_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 
37 #ifndef Intrepid2_DerivedBasis_HCURL_WEDGE_h
38 #define Intrepid2_DerivedBasis_HCURL_WEDGE_h
39 
40 #include <Kokkos_DynRankView.hpp>
41 
43 #include "Intrepid2_Sacado.hpp"
44 
47 
48 namespace Intrepid2
49 {
50  template<class HCURL_TRI, class HGRAD_LINE>
52  : public Basis_TensorBasis<typename HGRAD_LINE::BasisBase>
53  {
54  public:
55  using OutputViewType = typename HGRAD_LINE::OutputViewType;
56  using PointViewType = typename HGRAD_LINE::PointViewType ;
57  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
58 
59  using BasisBase = typename HGRAD_LINE::BasisBase;
60 
61  using DeviceType = typename BasisBase::DeviceType;
62  using ExecutionSpace = typename BasisBase::ExecutionSpace;
63  using OutputValueType = typename BasisBase::OutputValueType;
64  using PointValueType = typename BasisBase::PointValueType;
65 
66  using TriCurlBasis = HCURL_TRI;
67  using LineGradBasis = HGRAD_LINE;
68 
70  public:
76  Basis_Derived_HCURL_Family1_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType = POINTTYPE_DEFAULT)
77  :
78  TensorBasis(Teuchos::rcp( new TriCurlBasis(polyOrder_xy,pointType)),
79  Teuchos::rcp( new LineGradBasis(polyOrder_z,pointType)))
80  {
81  this->functionSpace_ = FUNCTION_SPACE_HCURL;
82  this->setShardsTopologyAndTags();
83  }
84 
86 
89  virtual OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
90  {
91  const EOperator & VALUE = OPERATOR_VALUE;
92  const EOperator & GRAD = OPERATOR_GRAD;
93  const EOperator & CURL = OPERATOR_CURL;
94  if (operatorType == VALUE)
95  {
96  // family 1 goes in x,y components
97  std::vector< std::vector<EOperator> > ops(2);
98  ops[0] = std::vector<EOperator>{VALUE,VALUE}; // occupies x,y
99  ops[1] = std::vector<EOperator>{}; // zero z
100  std::vector<double> weights {1.0, 0.0};
101  return OperatorTensorDecomposition(ops, weights);
102  }
103  else if (operatorType == CURL)
104  {
105  // curl of (f_x(x,y) g(z), f_y(x,y) g(z), 0), where f is in H(curl,tri), g in H(grad,line)
106  // x,y components of curl: rot(f) dg/dz, where rot(f) is a 90-degree rotation of f.
107  // z component of curl: curl(f) g, where curl(f) is the 2D curl, a scalar.
108  std::vector< std::vector<EOperator> > ops(2);
109  ops[0] = std::vector<EOperator>{VALUE,GRAD}; // occupies the x,y components
110  ops[1] = std::vector<EOperator>{CURL,VALUE}; // z component
111  std::vector<double> weights {1.0, 1.0};
112  OperatorTensorDecomposition opDecomposition(ops, weights);
113  opDecomposition.setRotateXYNinetyDegrees(true);
114  return opDecomposition;
115  }
116  else
117  {
118  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported operator type");
119  }
120  }
121 
129  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
130  const PointViewType inputPoints1, const PointViewType inputPoints2,
131  bool tensorPoints) const override
132  {
133  EOperator op1, op2;
134  if (operatorType == OPERATOR_VALUE)
135  {
136  op1 = OPERATOR_VALUE;
137  op2 = OPERATOR_VALUE;
138 
139  // family 1 values go in the x,y components; 0 in the z component
140  auto outputValuesComponent12 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),std::pair<int,int>{0,2});
141  auto outputValuesComponent3 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
142 
143  // place 0 in the z component
144  Kokkos::deep_copy(outputValuesComponent3, 0.0);
145  this->TensorBasis::getValues(outputValuesComponent12,
146  inputPoints1, op1,
147  inputPoints2, op2, tensorPoints);
148 
149  }
150  else if (operatorType == OPERATOR_CURL)
151  {
152  // curl of (f_x(x,y) g(z), f_y(x,y) g(z), 0), where f is in H(curl,tri), g in H(grad,line)
153  // x,y components of curl: rot(f) dg/dz, where rot(f) is a 90-degree rotation of f.
154  // z component of curl: curl(f) g, where curl(f) is the 2D curl, a scalar.
155 
156  auto outputValuesComponent12 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),std::pair<int,int>{0,2});
157  auto outputValuesComponent3 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
158 
159  op1 = OPERATOR_VALUE;
160  op2 = OPERATOR_GRAD;
161 
162  this->TensorBasis::getValues(outputValuesComponent12,
163  inputPoints1, op1,
164  inputPoints2, op2, tensorPoints);
165 
166  auto policy = Kokkos::MDRangePolicy<ExecutionSpace,Kokkos::Rank<2>>({0,0},{outputValuesComponent12.extent_int(0),outputValuesComponent12.extent_int(1)});
167  Kokkos::parallel_for("wedge family 1 curl: rotateXYNinetyDegrees CW", policy,
168  KOKKOS_LAMBDA (const int &fieldOrdinal, const int &pointOrdinal) {
169  const auto f_x = outputValuesComponent12(fieldOrdinal,pointOrdinal,0); // copy
170  const auto &f_y = outputValuesComponent12(fieldOrdinal,pointOrdinal,1); // reference
171  outputValuesComponent12(fieldOrdinal,pointOrdinal,0) = -f_y;
172  outputValuesComponent12(fieldOrdinal,pointOrdinal,1) = f_x;
173  });
174 
175  op1 = OPERATOR_CURL;
176  op2 = OPERATOR_VALUE;
177  this->TensorBasis::getValues(outputValuesComponent3,
178  inputPoints1, op1,
179  inputPoints2, op2, tensorPoints);
180  }
181  else
182  {
183  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
184  }
185  }
186 
198  virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override {
199  auto dofCoeffs1 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),std::make_pair(0,2));
200  auto dofCoeffs2 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),2);
201  this->TensorBasis::getDofCoeffs(dofCoeffs1);
202  Kokkos::deep_copy(dofCoeffs2,0.0);
203  }
204  };
205 
206  template<class HGRAD_TRI, class HVOL_LINE>
208  : public Basis_TensorBasis<typename HVOL_LINE::BasisBase>
209  {
210 
211  public:
212  using OutputViewType = typename HVOL_LINE::OutputViewType;
213  using PointViewType = typename HVOL_LINE::PointViewType ;
214  using ScalarViewType = typename HVOL_LINE::ScalarViewType;
215 
216  using TriGradBasis = HGRAD_TRI;
217  using LineHVolBasis = HVOL_LINE;
218 
219  using BasisBase = typename HVOL_LINE::BasisBase;
221 
222  using DeviceType = typename BasisBase::DeviceType;
223  using ExecutionSpace = typename BasisBase::ExecutionSpace;
224  using OutputValueType = typename BasisBase::OutputValueType;
225  using PointValueType = typename BasisBase::PointValueType;
226 
232  Basis_Derived_HCURL_Family2_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType = POINTTYPE_DEFAULT)
233  :
234  TensorBasis(Teuchos::rcp( new TriGradBasis(polyOrder_xy, pointType) ),
235  Teuchos::rcp( new LineHVolBasis(polyOrder_z-1, pointType) ))
236  {
237  this->functionSpace_ = FUNCTION_SPACE_HCURL;
238  this->setShardsTopologyAndTags();
239  }
240 
243  OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
244  {
245  if (operatorType == OPERATOR_CURL)
246  {
247  // curl of (0,0,f) is (df/dy, -df/dx, 0)
248 
249  // this is a rotation of gradient of the triangle H^1 basis, times the H(vol) line value
250  std::vector< std::vector<EOperator> > ops(2);
251  ops[0] = std::vector<EOperator>{OPERATOR_GRAD,OPERATOR_VALUE}; // occupies the x,y components
252  ops[1] = std::vector<EOperator>{};
253  std::vector<double> weights {-1.0, 0.0}; // -1 because the rotation goes from (df/dx,df/dy) --> (-df/dy,df/dx), and we want (df/dy,-df/dx)
254  OperatorTensorDecomposition opDecomposition(ops, weights);
255  opDecomposition.setRotateXYNinetyDegrees(true);
256  return opDecomposition;
257  }
258  else if (OPERATOR_VALUE == operatorType)
259  {
260  // family 2 goes in z component
261  std::vector< std::vector<EOperator> > ops(2);
262  ops[0] = std::vector<EOperator>{}; // because family 1 identifies this as spanning (x,y), empty op here will also span (x,y)
263  ops[1] = std::vector<EOperator>{OPERATOR_VALUE,OPERATOR_VALUE}; // z component
264  std::vector<double> weights {0.0, 1.0};
265  return OperatorTensorDecomposition(ops, weights);
266  }
267  else
268  {
269  INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unsupported operator type");
270  }
271  }
272 
274 
282  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
283  const PointViewType inputPoints1, const PointViewType inputPoints2,
284  bool tensorPoints) const override
285  {
286  EOperator op1, op2;
287  if (operatorType == OPERATOR_VALUE)
288  {
289  op1 = OPERATOR_VALUE;
290  op2 = OPERATOR_VALUE;
291 
292  // family 2 values go in z component, 0 in (x,y)
293  auto outputValuesComponent12 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),std::pair<int,int>{0,2});
294  auto outputValuesComponent3 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
295 
296  // place 0 in the x,y components
297  Kokkos::deep_copy(outputValuesComponent12, 0.0);
298  this->TensorBasis::getValues(outputValuesComponent3,
299  inputPoints1, op1,
300  inputPoints2, op2, tensorPoints);
301 
302  }
303  else if (operatorType == OPERATOR_CURL)
304  {
305  // curl of (0,0,f) is (df/dy, -df/dx, 0)
306 
307  auto outputValuesComponent12 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),std::pair<int,int>{0,2});
308  auto outputValuesComponent3 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
309 
310  op1 = OPERATOR_GRAD;
311  op2 = OPERATOR_VALUE;
312 
313  this->TensorBasis::getValues(outputValuesComponent12,
314  inputPoints1, op1,
315  inputPoints2, op2, tensorPoints);
316 
317  auto policy = Kokkos::MDRangePolicy<ExecutionSpace,Kokkos::Rank<2>>({0,0},{outputValuesComponent12.extent_int(0),outputValuesComponent12.extent_int(1)});
318  Kokkos::parallel_for("wedge family 2 curl: rotateXYNinetyDegrees CCW", policy,
319  KOKKOS_LAMBDA (const int &fieldOrdinal, const int &pointOrdinal) {
320  const auto f_x = outputValuesComponent12(fieldOrdinal,pointOrdinal,0); // copy
321  const auto &f_y = outputValuesComponent12(fieldOrdinal,pointOrdinal,1); // reference
322  outputValuesComponent12(fieldOrdinal,pointOrdinal,0) = f_y;
323  outputValuesComponent12(fieldOrdinal,pointOrdinal,1) = -f_x;
324  });
325 
326  Kokkos::deep_copy(outputValuesComponent3, 0.0);
327  }
328  else
329  {
330  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
331  }
332  }
333 
345  virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override {
346  auto dofCoeffs1 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),std::make_pair(0,2));
347  auto dofCoeffs2 = Kokkos::subview(dofCoeffs,Kokkos::ALL(),2);
348  Kokkos::deep_copy(dofCoeffs1,0.0);
349  this->TensorBasis::getDofCoeffs(dofCoeffs2);
350  }
351  };
352 
353  template<class HGRAD_TRI, class HCURL_TRI, class HGRAD_LINE, class HVOL_LINE>
355  : public Basis_DirectSumBasis <typename HGRAD_LINE::BasisBase>
356  {
360  public:
361  using BasisBase = typename HGRAD_LINE::BasisBase;
362 
363  protected:
364  std::string name_;
365  ordinal_type order_xy_;
366  ordinal_type order_z_;
367  EPointType pointType_;
368 
369  public:
370  using ExecutionSpace = typename HGRAD_LINE::ExecutionSpace;
371  using OutputValueType = typename HGRAD_LINE::OutputValueType;
372  using PointValueType = typename HGRAD_LINE::PointValueType;
373 
379  Basis_Derived_HCURL_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
380  :
381  DirectSumBasis(Teuchos::rcp( new Family1(polyOrder_xy, polyOrder_z, pointType) ),
382  Teuchos::rcp( new Family2(polyOrder_xy, polyOrder_z, pointType) ))
383  {
384  this->functionSpace_ = FUNCTION_SPACE_HCURL;
385 
386  std::ostringstream basisName;
387  basisName << "HCURL_WEDGE (" << this->DirectSumBasis::getName() << ")";
388  name_ = basisName.str();
389 
390  order_xy_ = polyOrder_xy;
391  order_z_ = polyOrder_z;
392  pointType_ = pointType;
393  }
394 
399  Basis_Derived_HCURL_WEDGE(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT) : Basis_Derived_HCURL_WEDGE(polyOrder, polyOrder, pointType) {}
400 
403  virtual bool requireOrientation() const override
404  {
405  return true;
406  }
407 
412  virtual
413  const char*
414  getName() const override {
415  return name_.c_str();
416  }
417 
427  Teuchos::RCP<BasisBase>
428  getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const override
429  {
430  using LineBasis = HVOL_LINE;
431  using TriCurlBasis = HCURL_TRI;
433  if(subCellDim == 1) {
434  if(subCellOrd < 6) //edges associated to basal and upper triagular faces
435  return Teuchos::rcp( new LineBasis(order_xy_-1, pointType_) );
436  else
437  return Teuchos::rcp( new LineBasis(order_z_-1, pointType_) );
438  }
439  else if(subCellDim == 2) {
440  switch(subCellOrd) {
441  case 0:
442  return Teuchos::rcp( new QuadCurlBasis(order_xy_, order_z_, pointType_) );
443  case 1:
444  return Teuchos::rcp( new QuadCurlBasis(order_xy_, order_z_, pointType_) );
445  case 2:
446  return Teuchos::rcp( new QuadCurlBasis(order_z_, order_xy_, pointType_) );
447  case 3:
448  return Teuchos::rcp( new TriCurlBasis(order_xy_, pointType_) );
449  case 4:
450  return Teuchos::rcp( new TriCurlBasis(order_xy_, pointType_) );
451  default:
452  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"subCellOrd is out of bounds");
453  }
454  }
455  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"subCellDim is out of bounds");
456  }
457 
462  virtual HostBasisPtr<OutputValueType, PointValueType>
463  getHostBasis() const override {
465 
466  auto hostBasis = Teuchos::rcp(new HostBasis(order_xy_, order_z_, pointType_));
467 
468  return hostBasis;
469  }
470  };
471 } // end namespace Intrepid2
472 
473 #endif /* Intrepid2_DerivedBasis_HCURL_WEDGE_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...
Implementation of bases that are tensor products of two or three component bases. ...
virtual HostBasisPtr< OutputValueType, PointValueType > getHostBasis() const override
Creates and returns a Basis object whose DeviceType template argument is Kokkos::HostSpace::device_ty...
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...
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 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)
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...
OperatorTensorDecomposition getSimpleOperatorDecomposition(const EOperator &operatorType) const override
Returns a simple decomposition of the specified operator: what operator(s) should be applied to basis...
A basis that is the direct sum of two other bases.
virtual bool requireOrientation() const override
True if orientation is required.
virtual const char * getName() const override
Returns basis name.
Basis_Derived_HCURL_Family2_WEDGE(int polyOrder_xy, 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...
Teuchos::RCP< BasisBase > getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const override
returns the basis associated to a subCell.
Basis_Derived_HCURL_Family1_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
Basis_Derived_HCURL_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
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_Derived_HCURL_WEDGE(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
Basis defined as the tensor product of two component bases.
virtual const char * getName() const override
Returns basis name.