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.
Implementation of bases that are tensor products of two or three component bases. ...
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)
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.
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.
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 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)
EOperator
Enumeration of primitive operators available in Intrepid. Primitive operators act on reconstructed fu...
Basis_Derived_HCURL_Family1_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
Constructor.
virtual bool requireOrientation() const
True if orientation is required.