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
34namespace 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 {
479 using Family2 = Basis_Derived_HDIV_Family2_HEX <HGRAD_LINE, HVOL_LINE>;
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
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 */
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.
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, const PointViewType inputPoints3, bool tensorPoints) const override
multi-component getValues() method (required/called by TensorBasis3)
Basis_Derived_HDIV_Family1_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.
Basis_Derived_HDIV_Family2_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
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_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.
Basis_Derived_HDIV_Family3_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, 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, const PointViewType inputPoints3, bool tensorPoints) const override
multi-component getValues() method (required/called by TensorBasis3)
Basis_Derived_HDIV_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z, 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...
Teuchos::RCP< BasisBase > getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const override
returns the basis associated to a subCell.
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.
Implementation of H(vol) basis on the quadrilateral that is templated on H(vol) on the line.
A basis that is the direct sum of two other bases.
virtual const char * getName() const override
Returns basis name.
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 void getDofCoeffs(typename BasisBase::ScalarViewType dofCoeffs) const override
Fills in coefficients of degrees of freedom on the reference cell.
For a multi-component tensor basis, specifies the operators to be applied to the components to produc...