Intrepid2
Intrepid2_DerivedBasis_HDIV_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 
57 #ifndef Intrepid2_DerivedBasis_HDIV_HEX_h
58 #define Intrepid2_DerivedBasis_HDIV_HEX_h
59 
60 #include <Kokkos_View.hpp>
61 #include <Kokkos_DynRankView.hpp>
62 
64 
67 
68 namespace Intrepid2
69 {
70  template<class HGRAD_LINE, class HVOL_LINE>
72  :
73  public Basis_TensorBasis3<HGRAD_LINE, HVOL_LINE, HVOL_LINE>
74  {
75  public:
76  using OutputViewType = typename HGRAD_LINE::OutputViewType;
77  using PointViewType = typename HGRAD_LINE::PointViewType ;
78  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
79 
80  using LineGradBasis = HGRAD_LINE;
81  using LineHVolBasis = HVOL_LINE;
82 
84  public:
90  Basis_Derived_HDIV_Family1_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
91  :
92  TensorBasis3(LineGradBasis(polyOrder_x ),
93  LineHVolBasis(polyOrder_y-1),
94  LineHVolBasis(polyOrder_z-1))
95  {
96  this->functionSpace_ = FUNCTION_SPACE_HDIV;
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
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  };
152 
153  template<class HGRAD_LINE, class HVOL_LINE>
155  :
156  public Basis_TensorBasis3<HVOL_LINE, HGRAD_LINE, HVOL_LINE>
157  {
158  public:
159  using OutputViewType = typename HGRAD_LINE::OutputViewType;
160  using PointViewType = typename HGRAD_LINE::PointViewType ;
161  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
162 
163  using LineGradBasis = HGRAD_LINE;
164  using LineHVolBasis = HVOL_LINE;
165 
167  public:
173  Basis_Derived_HDIV_Family2_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
174  :
175  TensorBasis3(LineHVolBasis(polyOrder_x-1),
176  LineGradBasis(polyOrder_y ),
177  LineHVolBasis(polyOrder_z-1))
178  {
179  this->functionSpace_ = FUNCTION_SPACE_HDIV;
180  }
181 
183 
192  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
193  const PointViewType inputPoints1, const PointViewType inputPoints2, const PointViewType inputPoints3,
194  bool tensorPoints) const
195  {
196  Intrepid2::EOperator op1, op2, op3;
197  if (operatorType == Intrepid2::OPERATOR_VALUE)
198  {
199  op1 = Intrepid2::OPERATOR_VALUE;
200  op2 = Intrepid2::OPERATOR_VALUE;
201  op3 = Intrepid2::OPERATOR_VALUE;
202 
203  // family 2 goes in the y component; 0 in the x and z components
204  auto outputValuesComponent_x = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
205  auto outputValuesComponent_y = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),1);
206  auto outputValuesComponent_z = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
207 
208  // 0 in x component
209  Kokkos::deep_copy(outputValuesComponent_x,0.0);
210 
211  double weight = 1.0;
212  this->TensorBasis3::getValues(outputValuesComponent_y,
213  inputPoints1, op1,
214  inputPoints2, op2,
215  inputPoints3, op3, tensorPoints, weight);
216 
217  // 0 in z component
218  Kokkos::deep_copy(outputValuesComponent_z,0.0);
219  }
220  else if (operatorType == Intrepid2::OPERATOR_DIV)
221  {
222  // family 2 is nonzero in the y component, so the div is d/dy of the second component
223  // ESEAS has -1 weight here; we follow that, to simplify verification
224  // outputValues is scalar, so no need to take subviews
225 
226  op1 = Intrepid2::OPERATOR_VALUE;
227  op2 = Intrepid2::OPERATOR_GRAD; // d/dy
228  op3 = Intrepid2::OPERATOR_VALUE;
229 
230  double weight = 1.0;
231  this->TensorBasis3::getValues(outputValues,
232  inputPoints1, op1,
233  inputPoints2, op2,
234  inputPoints3, op3, tensorPoints, weight);
235  }
236  else
237  {
238  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
239  }
240  }
241  };
242 
243  template<class HGRAD_LINE, class HVOL_LINE>
245  : public Basis_TensorBasis3<HVOL_LINE, HVOL_LINE, HGRAD_LINE>
246  {
247  public:
248  using OutputViewType = typename HGRAD_LINE::OutputViewType;
249  using PointViewType = typename HGRAD_LINE::PointViewType ;
250  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
251 
252  using LineGradBasis = HGRAD_LINE;
253  using LineHVolBasis = HVOL_LINE;
254 
256  public:
262  Basis_Derived_HDIV_Family3_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
263  :
264  TensorBasis3(LineHVolBasis(polyOrder_x-1),
265  LineHVolBasis(polyOrder_y-1),
266  LineGradBasis(polyOrder_z ))
267  {
268  this->functionSpace_ = FUNCTION_SPACE_HDIV;
269  }
270 
272 
281  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
282  const PointViewType inputPoints1, const PointViewType inputPoints2, const PointViewType inputPoints3,
283  bool tensorPoints) const
284  {
285  Intrepid2::EOperator op1, op2, op3;
286  if (operatorType == Intrepid2::OPERATOR_VALUE)
287  {
288  op1 = Intrepid2::OPERATOR_VALUE;
289  op2 = Intrepid2::OPERATOR_VALUE;
290  op3 = Intrepid2::OPERATOR_VALUE;
291 
292  // family 3 goes in the z component; 0 in the x and y components
293  auto outputValuesComponent_xy = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),std::make_pair(0,2));
294  auto outputValuesComponent_z = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),2);
295 
296  // 0 in x and y components
297  Kokkos::deep_copy(outputValuesComponent_xy,0.0);
298 
299  // z component
300  this->TensorBasis3::getValues(outputValuesComponent_z,
301  inputPoints1, op1,
302  inputPoints2, op2,
303  inputPoints3, op3, tensorPoints);
304  }
305  else if (operatorType == Intrepid2::OPERATOR_DIV)
306  {
307  // family 3 is nonzero in the z component, so the div is d/dz of the third component
308  // outputValues is scalar, so no need to take subviews
309 
310  op1 = Intrepid2::OPERATOR_VALUE;
311  op2 = Intrepid2::OPERATOR_VALUE;
312  op3 = Intrepid2::OPERATOR_GRAD; // d/dz
313 
314  double weight = 1.0; // the plus sign in front of d/dz
315  this->TensorBasis3::getValues(outputValues,
316  inputPoints1, op1,
317  inputPoints2, op2,
318  inputPoints3, op3, tensorPoints, weight);
319  }
320  else
321  {
322  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
323  }
324  }
325  };
326 
327  // ESEAS numbers its H(div) families differently, with the nonzero going in z, x, y for I,II,III.
328  // To allow our interior orderings to match that of ESEAS, we put the direct sum in the same order as ESEAS,
329  // which is to say that we go 3,1,2.
330  template<class HGRAD_LINE, class HVOL_LINE>
332  : public Basis_DirectSumBasis<Basis_Derived_HDIV_Family3_HEX<HGRAD_LINE, HVOL_LINE>,
333  Basis_Derived_HDIV_Family1_HEX<HGRAD_LINE, HVOL_LINE>>
334  {
338  public:
344  Basis_Derived_HDIV_Family3_Family1_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
345  :
346  DirectSumBasis(Family3(polyOrder_x, polyOrder_y, polyOrder_z),
347  Family1(polyOrder_x, polyOrder_y, polyOrder_z)) {
348  this->functionSpace_ = FUNCTION_SPACE_HDIV;
349  }
350  };
351 
352  template<class HGRAD_LINE, class HVOL_LINE>
354  : public Basis_DirectSumBasis<Basis_Derived_HDIV_Family3_Family1_HEX<HGRAD_LINE, HVOL_LINE>,
355  Basis_Derived_HDIV_Family2_HEX<HGRAD_LINE, HVOL_LINE> >
356  {
360  public:
366  Basis_Derived_HDIV_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
367  :
368  DirectSumBasis(Family31(polyOrder_x, polyOrder_y, polyOrder_z),
369  Family2 (polyOrder_x, polyOrder_y, polyOrder_z)) {
370  this->functionSpace_ = FUNCTION_SPACE_HDIV;
371  }
372 
376  Basis_Derived_HDIV_HEX(int polyOrder) : Basis_Derived_HDIV_HEX(polyOrder, polyOrder, polyOrder) {}
377 
380  virtual bool requireOrientation() const {
381  return (this->getDofCount(2,0) > 0); //if it has side DOFs, than it needs orientations
382  }
383  };
384 } // end namespace Intrepid2
385 
386 #endif /* Intrepid2_DerivedBasis_HDIV_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_HDIV_Family1_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)
EFunctionSpace functionSpace_
The function space in which the basis is defined.
Free functions, callable from device code, that implement various polynomials useful in basis definit...
Basis_Derived_HDIV_Family3_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
Constructor.
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)
Basis_Derived_HDIV_Family2_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
Constructor.
virtual bool requireOrientation() const
True if orientation is required.
Basis_Derived_HDIV_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)
Basis_Derived_HDIV_Family3_Family1_HEX(int polyOrder_x, int polyOrder_y, int polyOrder_z)
Constructor.