Intrepid2
Intrepid2_DerivedBasis_HDIV_QUAD.hpp
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 
53 #ifndef Intrepid2_DerivedBasis_HIV_QUAD_h
54 #define Intrepid2_DerivedBasis_HIV_QUAD_h
55 
56 #include <Kokkos_View.hpp>
57 #include <Kokkos_DynRankView.hpp>
58 
60 
63 
64 namespace Intrepid2
65 {
66  template<class HGRAD_LINE, class HVOL_LINE>
68  : public Basis_TensorBasis<HVOL_LINE, HGRAD_LINE>
69  {
70  public:
71  using OutputViewType = typename HGRAD_LINE::OutputViewType;
72  using PointViewType = typename HGRAD_LINE::PointViewType ;
73  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
74 
75  using LineGradBasis = HGRAD_LINE;
76  using LineHVolBasis = HVOL_LINE;
77 
79  public:
84  Basis_Derived_HDIV_Family1_QUAD(int polyOrder_x, int polyOrder_y)
85  :
86  TensorBasis(LineHVolBasis(polyOrder_x-1),
87  LineGradBasis(polyOrder_y))
88  {
89  this->functionSpace_ = FUNCTION_SPACE_HDIV;
90  }
91 
93 
101  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
102  const PointViewType inputPoints1, const PointViewType inputPoints2,
103  bool tensorPoints) const
104  {
105  // ESEAS implements H(div) as rotated H(curl), which involves weighting family1 with -1.
106  // We follow that here to simplify verification tests that involve ESEAS.
107  const double weight = -1.0;
108 
109  Intrepid2::EOperator op1, op2;
110  if (operatorType == Intrepid2::OPERATOR_VALUE)
111  {
112  op1 = Intrepid2::OPERATOR_VALUE;
113  op2 = Intrepid2::OPERATOR_VALUE;
114 
115  // family 1 goes in the y component; 0 in the x component
116  auto outputValuesComponent1 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
117  auto outputValuesComponent2 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),1);
118 
119  this->TensorBasis::getValues(outputValuesComponent2,
120  inputPoints1, op1,
121  inputPoints2, op2, tensorPoints, weight);
122  // place 0 in the y component
123  Kokkos::deep_copy(outputValuesComponent1,0.0);
124  }
125  else if (operatorType == Intrepid2::OPERATOR_DIV)
126  {
127  // family 1 gets a d/dy applied to the second (nonzero) vector component
128  // since this is H(VOL)(x) * H(GRAD)(y), this amounts to taking the derivative in the second tensorial component
129  op1 = Intrepid2::OPERATOR_VALUE;
130  op2 = Intrepid2::OPERATOR_GRAD;
131 
132  this->TensorBasis::getValues(outputValues,
133  inputPoints1, op1,
134  inputPoints2, op2, tensorPoints, weight);
135  }
136  else
137  {
138  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
139  }
140  }
141  };
142 
143  template<class HGRAD_LINE, class HVOL_LINE>
145  : public Basis_TensorBasis<HGRAD_LINE, HVOL_LINE>
146  {
147  using OutputViewType = typename HGRAD_LINE::OutputViewType;
148  using PointViewType = typename HGRAD_LINE::PointViewType ;
149  using ScalarViewType = typename HGRAD_LINE::ScalarViewType;
150 
151  using LineGradBasis = HGRAD_LINE;
152  using LineHVolBasis = HVOL_LINE;
153 
155  public:
160  Basis_Derived_HDIV_Family2_QUAD(int polyOrder_x, int polyOrder_y)
161  :
162  TensorBasis(LineGradBasis(polyOrder_x),
163  LineHVolBasis(polyOrder_y-1))
164  {
165  this->functionSpace_ = FUNCTION_SPACE_HDIV;
166  }
167 
169 
177  virtual void getValues(OutputViewType outputValues, const EOperator operatorType,
178  const PointViewType inputPoints1, const PointViewType inputPoints2,
179  bool tensorPoints) const
180  {
181  Intrepid2::EOperator op1, op2;
182  if (operatorType == Intrepid2::OPERATOR_VALUE)
183  {
184  op1 = Intrepid2::OPERATOR_VALUE;
185  op2 = Intrepid2::OPERATOR_VALUE;
186 
187  // family 2 goes in the x component; 0 in the x component
188  auto outputValuesComponent1 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),0);
189  auto outputValuesComponent2 = Kokkos::subview(outputValues,Kokkos::ALL(),Kokkos::ALL(),1);
190 
191  this->TensorBasis::getValues(outputValuesComponent1,
192  inputPoints1, op1,
193  inputPoints2, op2, tensorPoints);
194  // place 0 in the y component
195  Kokkos::deep_copy(outputValuesComponent2, 0.0);
196  }
197  else if (operatorType == Intrepid2::OPERATOR_DIV)
198  {
199  // family 2 gets a d/dx applied to the first (nonzero) vector component
200  // since this is H(GRAD)(x) * H(VOL)(y), this amounts to taking the derivative in the first tensorial component
201  op1 = Intrepid2::OPERATOR_GRAD;
202  op2 = Intrepid2::OPERATOR_VALUE;
203 
204  this->TensorBasis::getValues(outputValues,
205  inputPoints1, op1,
206  inputPoints2, op2, tensorPoints);
207  }
208  else
209  {
210  INTREPID2_TEST_FOR_EXCEPTION(true,std::invalid_argument,"operator not yet supported");
211  }
212  }
213  };
214 
215  template<class HGRAD_LINE, class HVOL_LINE>
217  : public Basis_DirectSumBasis<Basis_Derived_HDIV_Family1_QUAD<HGRAD_LINE, HVOL_LINE>,
218  Basis_Derived_HDIV_Family2_QUAD<HGRAD_LINE, HVOL_LINE> >
219  {
223  public:
228  Basis_Derived_HDIV_QUAD(int polyOrder_x, int polyOrder_y)
229  :
230  DirectSumBasis(Family1(polyOrder_x, polyOrder_y),
231  Family2(polyOrder_x, polyOrder_y))
232  {
233  this->functionSpace_ = FUNCTION_SPACE_HDIV;
234  }
235 
239  Basis_Derived_HDIV_QUAD(int polyOrder) : Basis_Derived_HDIV_QUAD(polyOrder, polyOrder) {}
240 
243  virtual bool requireOrientation() const {
244  return (this->getDofCount(1,0) > 0); //if it has side DOFs, than it needs orientations
245  }
246  };
247 } // end namespace Intrepid2
248 
249 #endif /* Intrepid2_DerivedBasis_HIV_QUAD_h */
virtual void getValues(OutputViewType outputValues, const EOperator operatorType, const PointViewType inputPoints1, const PointViewType inputPoints2, bool tensorPoints) const
multi-component getValues() method (required/called by TensorBasis)
Implementation of bases that are tensor products of two or three component bases. ...
void getValues(OutputViewType outputValues, const PointViewType inputPoints, const EOperator operatorType=OPERATOR_VALUE) const override
Evaluation of a FEM basis on a reference cell.
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.
Basis_Derived_HDIV_QUAD(int polyOrder_x, int polyOrder_y)
Constructor.
A basis that is the direct sum of two other bases.
EOperator
Enumeration of primitive operators available in Intrepid. Primitive operators act on reconstructed fu...
Basis_Derived_HDIV_Family2_QUAD(int polyOrder_x, int polyOrder_y)
Constructor.
virtual void getValues(OutputViewType outputValues, const EOperator operatorType, const PointViewType inputPoints1, const PointViewType inputPoints2, bool tensorPoints) const
multi-component getValues() method (required/called by TensorBasis)
virtual bool requireOrientation() const
True if orientation is required.
Basis_Derived_HDIV_Family1_QUAD(int polyOrder_x, int polyOrder_y)
Constructor.
Basis defined as the tensor product of two component bases.