Intrepid2
Intrepid2_DerivedBasis_HCURL_HEX.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Intrepid2 Package
5 // Copyright (2007) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Kyungjoo Kim (kyukim@sandia.gov),
38 // Mauro Perego (mperego@sandia.gov), or
39 // Nate Roberts (nvrober@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
54 #ifndef Intrepid2_DerivedBasis_HCURL_HEX_h
55 #define Intrepid2_DerivedBasis_HCURL_HEX_h
56 
57 #include <Kokkos_View.hpp>
58 #include <Kokkos_DynRankView.hpp>
59 
61 
64 
65 namespace Intrepid2
66 {
67  template<class HGRAD_LINE, class HVOL_LINE>
69  : public Basis_TensorBasis3<HVOL_LINE,
70  HGRAD_LINE,
71  HGRAD_LINE>
72  {
73  public:
74  using OutputViewType = typename HGRAD_LINE::OutputViewType;
75  using PointViewType = typename HGRAD_LINE::PointViewType ;
76  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
77 
78  using LineGradBasis = HGRAD_LINE;
79  using LineVolBasis = HVOL_LINE;
80 
82  public:
88  Basis_Derived_HCURL_Family1_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
89  :
90  TensorBasis3(LineVolBasis (polyOrder_x-1),
91  LineGradBasis(polyOrder_y ),
92  LineGradBasis(polyOrder_z ))
93  {
94  this->functionSpace_ = FUNCTION_SPACE_HCURL;
95  }
96 
98 
107  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
108  const PointViewType inputPoints1, const PointViewType inputPoints2, const PointViewType inputPoints3,
109  bool tensorPoints) const
110  {
111  Intrepid2::EOperator op1, op2, op3;
112  if (operatorType == Intrepid2::OPERATOR_VALUE)
113  {
114  op1 = Intrepid2::OPERATOR_VALUE;
115  op2 = Intrepid2::OPERATOR_VALUE;
116  op3 = Intrepid2::OPERATOR_VALUE;
117 
118  // family 1 goes in the x component; 0 in the y and z components
119  auto outputValuesComponent1 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
120  auto outputValuesComponent23 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),std::make_pair(1,3));
121 
122  this->TensorBasis3::getValues(outputValuesComponent1,
123  inputPoints1, op1,
124  inputPoints2, op2,
125  inputPoints3, op3, tensorPoints);
126  // place 0 in the y and z components
127  Kokkos::deep_copy(outputValuesComponent23,0.0);
128  }
129  else if (operatorType == Intrepid2::OPERATOR_CURL)
130  {
131  // family 1 is nonzero in the x component, so the curl is d/dz placed in the y component, and -d/dy placed in the z component.
132  auto outputValuesComponent_x = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
133  auto outputValuesComponent_y = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),1);
134  auto outputValuesComponent_z = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
135 
136  // x component is zero
137  Kokkos::deep_copy(outputValuesComponent_x, 0.0);
138 
139  // y component is d/dz
140  op1 = Intrepid2::OPERATOR_VALUE;
141  op2 = Intrepid2::OPERATOR_VALUE;
142  op3 = Intrepid2::OPERATOR_GRAD; // d/dz
143 
144  double weight = 1.0; // the plus sign in front of d/dz
145  this->TensorBasis3::getValues(outputValuesComponent_y,
146  inputPoints1, op1,
147  inputPoints2, op2,
148  inputPoints3, op3, tensorPoints, weight);
149 
150  // z component is -d/dy
151  op1 = Intrepid2::OPERATOR_VALUE;
152  op2 = Intrepid2::OPERATOR_GRAD; // d/dy
153  op3 = Intrepid2::OPERATOR_VALUE;
154  weight = -1.0; // the -1 weight on d/dy
155  this->TensorBasis3::getValues(outputValuesComponent_z,
156  inputPoints1, op1,
157  inputPoints2, op2,
158  inputPoints3, op3, tensorPoints, weight);
159  }
160  else
161  {
162  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
163  }
164  }
165  };
166 
167  template<class HGRAD_LINE, class HVOL_LINE>
169  : public Basis_TensorBasis3<HGRAD_LINE,
170  HVOL_LINE,
171  HGRAD_LINE>
172  {
173  public:
174  using OutputViewType = typename HGRAD_LINE::OutputViewType;
175  using PointViewType = typename HGRAD_LINE::PointViewType ;
176  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
177 
178  using LineGradBasis = HGRAD_LINE;
179  using LineVolBasis = HVOL_LINE;
180 
182  public:
188  Basis_Derived_HCURL_Family2_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
189  :
190  TensorBasis3(LineGradBasis(polyOrder_x),
191  LineVolBasis (polyOrder_y-1),
192  LineGradBasis(polyOrder_z))
193  {
194  this->functionSpace_ = FUNCTION_SPACE_HCURL;
195  }
196 
198 
207  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
208  const PointViewType inputPoints1, const PointViewType inputPoints2, const PointViewType inputPoints3,
209  bool tensorPoints) const
210  {
211  Intrepid2::EOperator op1, op2, op3;
212  if (operatorType == Intrepid2::OPERATOR_VALUE)
213  {
214  op1 = Intrepid2::OPERATOR_VALUE;
215  op2 = Intrepid2::OPERATOR_VALUE;
216  op3 = Intrepid2::OPERATOR_VALUE;
217 
218  // family 2 goes in the y component; 0 in the x and z components
219  auto outputValuesComponent_x = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
220  auto outputValuesComponent_y = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),1);
221  auto outputValuesComponent_z = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
222 
223  // place 0 in the x component
224  Kokkos::deep_copy(outputValuesComponent_x,0.0);
225  // evaluate y component
226  this->TensorBasis3::getValues(outputValuesComponent_y,
227  inputPoints1, op1,
228  inputPoints2, op2,
229  inputPoints3, op3, tensorPoints);
230  // place 0 in the z component
231  Kokkos::deep_copy(outputValuesComponent_z,0.0);
232  }
233  else if (operatorType == Intrepid2::OPERATOR_CURL)
234  {
235  // family 2 is nonzero in the y component, so the curl is -d/dz placed in the x component, and d/dx placed in the z component.
236  auto outputValuesComponent_x = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
237  auto outputValuesComponent_y = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),1);
238  auto outputValuesComponent_z = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
239 
240  // x component is -d/dz
241  op1 = Intrepid2::OPERATOR_VALUE;
242  op2 = Intrepid2::OPERATOR_VALUE;
243  op3 = Intrepid2::OPERATOR_GRAD; // d/dz
244 
245  double weight = -1.0; // the minus sign in front of d/dz
246  this->TensorBasis3::getValues(outputValuesComponent_x,
247  inputPoints1, op1,
248  inputPoints2, op2,
249  inputPoints3, op3, tensorPoints, weight);
250 
251  // y component is zero
252  Kokkos::deep_copy(outputValuesComponent_y, 0.0);
253 
254  // z component is d/dx
255  op1 = Intrepid2::OPERATOR_GRAD; // d/dx
256  op2 = Intrepid2::OPERATOR_VALUE;
257  op3 = Intrepid2::OPERATOR_VALUE;
258  weight = 1.0; // the weight on d/dx
259  this->TensorBasis3::getValues(outputValuesComponent_z,
260  inputPoints1, op1,
261  inputPoints2, op2,
262  inputPoints3, op3, tensorPoints, weight);
263  }
264  else
265  {
266  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
267  }
268  }
269  };
270 
271  template<class HGRAD_LINE, class HVOL_LINE>
273  : public Basis_TensorBasis3<HGRAD_LINE,
274  HGRAD_LINE,
275  HVOL_LINE>
276  {
277  using OutputViewType = typename HGRAD_LINE::OutputViewType;
278  using PointViewType = typename HGRAD_LINE::PointViewType ;
279  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
280 
281  using LineGradBasis = HGRAD_LINE;
282  using LineVolBasis = HVOL_LINE;
283 
285  public:
291  Basis_Derived_HCURL_Family3_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
292  :
293  TensorBasis3(LineGradBasis(polyOrder_x ),
294  LineGradBasis(polyOrder_y ),
295  LineVolBasis (polyOrder_z-1))
296  {}
297 
299 
308  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
309  const PointViewType inputPoints1, const PointViewType inputPoints2, const PointViewType inputPoints3,
310  bool tensorPoints) const
311  {
312  Intrepid2::EOperator op1, op2, op3;
313  if (operatorType == Intrepid2::OPERATOR_VALUE)
314  {
315  op1 = Intrepid2::OPERATOR_VALUE;
316  op2 = Intrepid2::OPERATOR_VALUE;
317  op3 = Intrepid2::OPERATOR_VALUE;
318 
319  // family 3 goes in the z component; 0 in the x and y components
320  auto outputValuesComponent_xy = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),std::make_pair(0,2));
321  auto outputValuesComponent_z = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
322 
323  // place 0 in the x and y components
324  Kokkos::deep_copy(outputValuesComponent_xy,0.0);
325  // evaluate z component
326  this->TensorBasis3::getValues(outputValuesComponent_z,
327  inputPoints1, op1,
328  inputPoints2, op2,
329  inputPoints3, op3, tensorPoints);
330  }
331  else if (operatorType == Intrepid2::OPERATOR_CURL)
332  {
333  // family 3 is nonzero in the z component, so the curl is d/dy placed in the x component, and -d/dx placed in the y component.
334  auto outputValuesComponent_x = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
335  auto outputValuesComponent_y = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),1);
336  auto outputValuesComponent_z = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
337 
338  // x component is d/dy
339  op1 = Intrepid2::OPERATOR_VALUE;
340  op2 = Intrepid2::OPERATOR_GRAD; // d/dy
341  op3 = Intrepid2::OPERATOR_VALUE;
342 
343  double weight = 1.0; // the sign in front of d/dy
344  this->TensorBasis3::getValues(outputValuesComponent_x,
345  inputPoints1, op1,
346  inputPoints2, op2,
347  inputPoints3, op3, tensorPoints, weight);
348  // y component is -d/dx
349  op1 = Intrepid2::OPERATOR_GRAD; // d/dx
350  op2 = Intrepid2::OPERATOR_VALUE;
351  op3 = Intrepid2::OPERATOR_VALUE;
352  weight = -1.0; // the weight on d/dx
353  this->TensorBasis3::getValues(outputValuesComponent_y,
354  inputPoints1, op1,
355  inputPoints2, op2,
356  inputPoints3, op3, tensorPoints, weight);
357 
358  // z component is zero
359  Kokkos::deep_copy(outputValuesComponent_z, 0.0);
360  }
361  else
362  {
363  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
364  }
365  }
366  };
367 
368  template<class HGRAD_LINE, class HVOL_LINE>
370  : public Basis_DirectSumBasis<Basis_Derived_HCURL_Family1_HEX<HGRAD_LINE, HVOL_LINE>,
371  Basis_Derived_HCURL_Family2_HEX<HGRAD_LINE, HVOL_LINE> >
372  {
376  public:
382  Basis_Derived_HCURL_Family1_Family2_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
383  :
384  DirectSumBasis(Family1(polyOrder_x, polyOrder_y, polyOrder_z),
385  Family2(polyOrder_x, polyOrder_y, polyOrder_z)) {}
386  };
387 
388  template<class HGRAD_LINE, class HVOL_LINE>
390  : public Basis_DirectSumBasis<Basis_Derived_HCURL_Family1_Family2_HEX<HGRAD_LINE, HVOL_LINE>,
391  Basis_Derived_HCURL_Family3_HEX<HGRAD_LINE, HVOL_LINE> >
392  {
396  public:
402  Basis_Derived_HCURL_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
403  :
404  DirectSumBasis(Family12(polyOrder_x, polyOrder_y, polyOrder_z),
405  Family3 (polyOrder_x, polyOrder_y, polyOrder_z)) {
406  this->functionSpace_ = FUNCTION_SPACE_HCURL;
407  }
408 
412  Basis_Derived_HCURL_HEX(int polyOrder) : Basis_Derived_HCURL_HEX(polyOrder, polyOrder, polyOrder) {}
413 
416  virtual bool requireOrientation() const {
417  return (this->getDofCount(1,0) > 0); //if it has edge DOFs, than it needs orientations
418  }
419  };
420 } // end namespace Intrepid2
421 
422 #endif /* Intrepid2_DerivedBasis_HCURL_HEX_h */
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.
Basis_Derived_HCURL_Family3_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
Constructor.
virtual void getValues(OutputViewType outputValues, const EOperator operatorType, const PointViewType inputPoints1, const PointViewType inputPoints2, const PointViewType inputPoints3, bool tensorPoints) const
multi-component getValues() method (required/called by TensorBasis3)
Implementation of bases that are tensor products of two or three component bases. ...
Basis_Derived_HCURL_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
Constructor.
Basis_Derived_HCURL_Family2_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
Constructor.
Basis_Derived_HCURL_Family1_Family2_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
Constructor.
EFunctionSpace functionSpace_
The function space in which the basis is defined.
virtual void getValues(OutputViewType outputValues, const EOperator operatorType, const PointViewType inputPoints1, const PointViewType inputPoints2, const PointViewType inputPoints3, bool tensorPoints) const
multi-component getValues() method (required/called by TensorBasis3)
Free functions, callable from device code, that implement various polynomials useful in basis definit...
Implementation of a basis that is the direct sum of two other bases.
A basis that is the direct sum of two other bases.
Basis_Derived_HCURL_Family1_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
Constructor.
virtual void getValues(OutputViewType outputValues, const EOperator operatorType, const PointViewType inputPoints1, const PointViewType inputPoints2, const PointViewType inputPoints3, bool tensorPoints) const
multi-component getValues() method (required/called by TensorBasis3)
virtual bool requireOrientation() const
True if orientation is required.