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
30namespace 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 {
308 using DirectSumBasis = Basis_DirectSumBasis <typename HGRAD_LINE::BasisBase>;
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
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 */
BasisPtr< typename Kokkos::HostSpace::device_type, OutputType, PointType > HostBasisPtr
Pointer to a Basis whose device type is on the host (Kokkos::HostSpace::device_type),...
Implementation of a basis that is the direct sum of two other bases.
Free functions, callable from device code, that implement various polynomials useful in basis definit...
Header file to include all Sacado headers that are required if using Intrepid2 with Sacado types.
Implementation of bases that are tensor products of two or three component bases.
Basis_Derived_HDIV_Family1_QUAD(int polyOrder_x, int polyOrder_y, const EPointType pointType)
Constructor.
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.
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_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 getDofCoeffs(ScalarViewType dofCoeffs) const override
Fills in coefficients of degrees of freedom for Lagrangian basis 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)
virtual bool requireOrientation() const override
True if orientation is required.
Teuchos::RCP< BasisBase > getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const override
returns the basis associated to a subCell.
Basis_Derived_HDIV_QUAD(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
virtual const char * getName() const override
Returns basis name.
Basis_Derived_HDIV_QUAD(int polyOrder_x, int polyOrder_y, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
virtual HostBasisPtr< OutputValueType, PointValueType > getHostBasis() const override
Creates and returns a Basis object whose DeviceType template argument is Kokkos::HostSpace::device_ty...
A basis that is the direct sum of two other bases.
virtual const char * getName() const override
Returns basis name.
Basis defined as the tensor product of two component bases.
virtual void getDofCoeffs(typename BasisBase::ScalarViewType dofCoeffs) const override
Fills in coefficients of degrees of freedom on the reference cell.
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...
For a multi-component tensor basis, specifies the operators to be applied to the components to produc...