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
48namespace 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 {
359 using DirectSumBasis = Basis_DirectSumBasis <typename HGRAD_LINE::BasisBase>;
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
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 */
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_HCURL_Family1_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
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 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.
Basis_Derived_HCURL_Family2_WEDGE(int polyOrder_xy, 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.
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, bool tensorPoints) const override
multi-component getValues() method (required/called by TensorBasis)
Teuchos::RCP< BasisBase > getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const override
returns the basis associated to a subCell.
virtual bool requireOrientation() const override
True if orientation is required.
virtual HostBasisPtr< OutputValueType, PointValueType > getHostBasis() const override
Creates and returns a Basis object whose DeviceType template argument is Kokkos::HostSpace::device_ty...
Basis_Derived_HCURL_WEDGE(int polyOrder_xy, int polyOrder_z, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
virtual const char * getName() const override
Returns basis name.
Basis_Derived_HCURL_WEDGE(int polyOrder, 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.
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...