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 */
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, bool tensorPoints) const
multi-component getValues() method (required/called by TensorBasis)
void getValues(OutputViewType outputValues, const PointViewType inputPoints, const EOperator operatorType=OPERATOR_VALUE) const override
Evaluation of a FEM basis on a reference cell.
virtual bool requireOrientation() const
True if orientation is required.
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.
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)
A basis that is the direct sum of two other bases.
Basis_Derived_HDIV_Family2_QUAD(int polyOrder_x, int polyOrder_y)
Constructor.
Basis_Derived_HDIV_Family1_QUAD(int polyOrder_x, int polyOrder_y)
Constructor.
Basis defined as the tensor product of two component bases.