Intrepid2
Intrepid2_OrientationToolsDefMatrixData.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), or
38 // Mauro Perego (mperego@sandia.gov)
39 //
40 // ************************************************************************
41 // @HEADER
42 
43 
48 #ifndef __INTREPID2_ORIENTATIONTOOLS_DEF_MATRIX_DATA_HPP__
49 #define __INTREPID2_ORIENTATIONTOOLS_DEF_MATRIX_DATA_HPP__
50 
51 // disable clang warnings
52 #if defined (__clang__) && !defined (__INTEL_COMPILER)
53 #pragma clang system_header
54 #endif
55 
56 namespace Intrepid2 {
57 
58  template<typename DT>
59  template<typename BasisHostType>
60  typename OrientationTools<DT>::CoeffMatrixDataViewType
61  OrientationTools<DT>::createCoeffMatrixInternal(const BasisHostType* basis, const bool inverse) {
62  const std::string name(basis->getName());
63  CoeffMatrixDataViewType matData;
64 
65  const auto cellTopo = basis->getBaseCellTopology();
66  const ordinal_type numEdges = cellTopo.getSubcellCount(1);
67  const ordinal_type numFaces = cellTopo.getSubcellCount(2);
68  ordinal_type matDim = 0, matDim1 = 0, matDim2 = 0, numOrts = 0, numSubCells;
69  for(ordinal_type i=0; i<numEdges; ++i) {
70  matDim1 = std::max(matDim1, basis->getDofCount(1,i));
71  numOrts = std::max(numOrts,2);
72  }
73  for(ordinal_type i=0; i<numFaces; ++i) {
74  matDim2 = std::max(matDim2, basis->getDofCount(2,i));
75  numOrts = std::max(numOrts,2*ordinal_type(cellTopo.getSideCount(2,i)));
76  }
77  matDim = std::max(matDim1,matDim2);
78  numSubCells = (matDim1>0)*numEdges + (matDim2>0)*numFaces;
79 
80 
81  matData = CoeffMatrixDataViewType("Orientation::CoeffMatrix::"+name,
82  numSubCells,
83  numOrts,
84  matDim,
85  matDim);
86 
87  if(basis->getFunctionSpace() == FUNCTION_SPACE_HGRAD) {
88  init_HGRAD(matData, basis, inverse);
89  } else if (basis->getFunctionSpace() == FUNCTION_SPACE_HCURL) {
90  init_HCURL(matData, basis, inverse);
91  } else if (basis->getFunctionSpace() == FUNCTION_SPACE_HDIV) {
92  init_HDIV(matData, basis, inverse);
93  } else if (basis->getFunctionSpace() == FUNCTION_SPACE_HVOL) {
94  init_HVOL(matData, basis, inverse);
95  }
96  return matData;
97  }
98 
99  //
100  // HGRAD elements
101  //
102  template<typename DT>
103  template<typename BasisHostType>
104  void
106  init_HGRAD(typename OrientationTools<DT>::CoeffMatrixDataViewType matData,
107  BasisHostType const *cellBasis,
108  const bool inverse) {
109 
110  const auto cellTopo = cellBasis->getBaseCellTopology();
111  const ordinal_type numEdges = cellTopo.getSubcellCount(1);
112  const ordinal_type numFaces = cellTopo.getSubcellCount(2);
113  Intrepid2::BasisPtr<typename BasisHostType::DeviceType,
114  typename BasisHostType::OutputValueType,
115  typename BasisHostType::PointValueType>
116  basisPtr;
117  BasisHostType const *subcellBasis;
118 
119  { //edges
120  subcellBasis = cellBasis; // if (dim==1)
121  const ordinal_type numOrt = 2;
122  for (ordinal_type edgeId=0;edgeId<numEdges;++edgeId) {
123  if(cellBasis->getDofCount(1, edgeId) < 2) continue;
124  if(cellTopo.getDimension()!=1) {
125  basisPtr = cellBasis->getSubCellRefBasis(1,edgeId);
126  subcellBasis = basisPtr.get();
127  }
128 
129  for (ordinal_type edgeOrt=0;edgeOrt<numOrt;++edgeOrt) {
130  auto mat = Kokkos::subview(matData,
131  edgeId, edgeOrt,
132  Kokkos::ALL(), Kokkos::ALL());
134  (mat,
135  *subcellBasis, *cellBasis,
136  edgeId, edgeOrt, inverse);
137  }
138  }
139  }
140  { //faces
141  subcellBasis = cellBasis; // if(dim==2)
142  for (ordinal_type faceId=0;faceId<numFaces;++faceId) {
143  // this works for triangles (numOrt=6) and quadrilaterals (numOrt=8)
144  const ordinal_type numOrt = 2*cellTopo.getSideCount(2,faceId);
145  if(cellBasis->getDofCount(2, faceId) < 1) continue;
146  if(cellTopo.getDimension()!=2) {
147  basisPtr = cellBasis->getSubCellRefBasis(2,faceId);
148  subcellBasis = basisPtr.get();
149  }
150  for (ordinal_type faceOrt=0;faceOrt<numOrt;++faceOrt) {
151  auto mat = Kokkos::subview(matData,
152  numEdges+faceId, faceOrt,
153  Kokkos::ALL(), Kokkos::ALL());
155  (mat,
156  *subcellBasis, *cellBasis,
157  faceId, faceOrt, inverse);
158  }
159  }
160  }
161  }
162 
163  //
164  // HCURL elements
165  //
166  template<typename DT>
167  template<typename BasisHostType>
168  void
170  init_HCURL(typename OrientationTools<DT>::CoeffMatrixDataViewType matData,
171  BasisHostType const *cellBasis, const bool inverse) {
172  const auto cellTopo = cellBasis->getBaseCellTopology();
173  const ordinal_type numEdges = cellTopo.getSubcellCount(1);
174  const ordinal_type numFaces = cellTopo.getSubcellCount(2);
175  Intrepid2::BasisPtr<typename BasisHostType::DeviceType,
176  typename BasisHostType::OutputValueType,
177  typename BasisHostType::PointValueType>
178  basisPtr;
179  BasisHostType const* subcellBasis;
180 
181  { // edges
182  subcellBasis = cellBasis; // if (dim==1)
183  const ordinal_type numOrt = 2;
184  for (ordinal_type edgeId=0;edgeId<numEdges;++edgeId) {
185  if(cellBasis->getDofCount(1, edgeId) < 1) continue;
186  if(cellTopo.getDimension()!=1) {
187  basisPtr = cellBasis->getSubCellRefBasis(1,edgeId);
188  subcellBasis = basisPtr.get();
189  }
190  for (ordinal_type edgeOrt=0;edgeOrt<numOrt;++edgeOrt) {
191  auto mat = Kokkos::subview(matData,
192  edgeId, edgeOrt,
193  Kokkos::ALL(), Kokkos::ALL());
195  *subcellBasis, *cellBasis,
196  edgeId, edgeOrt, inverse);
197  }
198  }
199  }
200  { //faces
201  subcellBasis = cellBasis; // if (dim==2)
202  for (ordinal_type faceId=0;faceId<numFaces;++faceId) {
203  // this works for triangles (numOrt=6) and quadratures (numOrt=8)
204  const ordinal_type numOrt = 2*cellTopo.getSideCount(2,faceId);
205  if(cellBasis->getDofCount(2, faceId) < 1) continue;
206  if(cellTopo.getDimension()!=2) {
207  basisPtr = cellBasis->getSubCellRefBasis(2,faceId);
208  subcellBasis = basisPtr.get();
209  }
210  for (ordinal_type faceOrt=0;faceOrt<numOrt;++faceOrt) {
211  auto mat = Kokkos::subview(matData,
212  numEdges+faceId, faceOrt,
213  Kokkos::ALL(), Kokkos::ALL());
215  (mat,
216  *subcellBasis, *cellBasis,
217  faceId, faceOrt, inverse);
218  }
219  }
220  }
221  }
222 
223  //
224  // HDIV elements
225  //
226  template<typename DT>
227  template<typename BasisHostType>
228  void
230  init_HDIV(typename OrientationTools<DT>::CoeffMatrixDataViewType matData,
231  BasisHostType const *cellBasis, const bool inverse) {
232  const auto cellTopo = cellBasis->getBaseCellTopology();
233  const ordinal_type numSides = cellTopo.getSideCount();
234  const ordinal_type sideDim = cellTopo.getDimension()-1;
235  Intrepid2::BasisPtr<typename BasisHostType::DeviceType,
236  typename BasisHostType::OutputValueType,
237  typename BasisHostType::PointValueType>
238  subcellBasisPtr;
239 
240  {
241  for (ordinal_type sideId=0;sideId<numSides;++sideId) {
242  if(cellBasis->getDofCount(sideDim, sideId) < 1) continue;
243  const ordinal_type numOrt = (sideDim == 1) ? 2 : 2*cellTopo.getSideCount(sideDim,sideId);
244  subcellBasisPtr = cellBasis->getSubCellRefBasis(sideDim,sideId);
245  for (ordinal_type faceOrt=0;faceOrt<numOrt;++faceOrt) {
246  auto mat = Kokkos::subview(matData,
247  sideId, faceOrt,
248  Kokkos::ALL(), Kokkos::ALL());
250  *subcellBasisPtr, *cellBasis,
251  sideId, faceOrt, inverse);
252  }
253  }
254  }
255  }
256 
257  //
258  // HVOL elements (used for 2D and 1D side cells)
259  //
260  template<typename DT>
261  template<typename BasisHostType>
262  void
264  init_HVOL(typename OrientationTools<DT>::CoeffMatrixDataViewType matData,
265  BasisHostType const *cellBasis, const bool inverse) {
266 
267  const auto cellTopo = cellBasis->getBaseCellTopology();
268  const ordinal_type numEdges = (cellTopo.getDimension()==1);
269  const ordinal_type numFaces = (cellTopo.getDimension()==2);
270 
271  {
272  const ordinal_type numOrt = 2;
273  for (ordinal_type edgeId=0;edgeId<numEdges;++edgeId) {
274  if(cellBasis->getDofCount(1, edgeId) < 1) continue;
275  for (ordinal_type edgeOrt=0;edgeOrt<numOrt;++edgeOrt) {
276  auto mat = Kokkos::subview(matData,
277  edgeId, edgeOrt,
278  Kokkos::ALL(), Kokkos::ALL());
280  (mat, *cellBasis, edgeOrt, inverse);
281  }
282  }
283  }
284  {
285  for (ordinal_type faceId=0;faceId<numFaces;++faceId) {
286  // this works for triangles (numOrt=6) and quadratures (numOrt=8)
287  const ordinal_type numOrt = 2*cellTopo.getSideCount(2,faceId);
288  if(cellBasis->getDofCount(2, faceId) < 1) continue;
289  for (ordinal_type faceOrt=0;faceOrt<numOrt;++faceOrt) {
290  auto mat = Kokkos::subview(matData,
291  numEdges+faceId, faceOrt,
292  Kokkos::ALL(), Kokkos::ALL());
294  (mat, *cellBasis, faceOrt, inverse);
295  }
296  }
297  }
298  }
299 
300  template<typename DT>
301  template<typename BasisType>
302  typename OrientationTools<DT>::CoeffMatrixDataViewType
303  OrientationTools<DT>::createCoeffMatrix(const BasisType* basis) {
304  Kokkos::push_finalize_hook( [=] {
305  ortCoeffData=std::map<std::pair<std::string,ordinal_type>, typename OrientationTools<DT>::CoeffMatrixDataViewType>();
306  });
307 
308  const std::pair<std::string,ordinal_type> key(basis->getName(), basis->getDegree());
309  const auto found = ortCoeffData.find(key);
310 
311  CoeffMatrixDataViewType matData;
312  if (found == ortCoeffData.end()) {
313  {
314  auto basis_host = basis->getHostBasis();
315  matData = createCoeffMatrixInternal(basis_host.getRawPtr());
316  ortCoeffData.insert(std::make_pair(key, matData));
317  }
318  } else {
319  matData = found->second;
320  }
321 
322  return matData;
323  }
324 
325  template<typename DT>
326  template<typename BasisType>
327  typename OrientationTools<DT>::CoeffMatrixDataViewType
328  OrientationTools<DT>::createInvCoeffMatrix(const BasisType* basis) {
329  Kokkos::push_finalize_hook( [=] {
330  ortInvCoeffData=std::map<std::pair<std::string,ordinal_type>, typename OrientationTools<DT>::CoeffMatrixDataViewType>();
331  });
332 
333  const std::pair<std::string,ordinal_type> key(basis->getName(), basis->getDegree());
334  const auto found = ortInvCoeffData.find(key);
335 
336  CoeffMatrixDataViewType matData;
337  if (found == ortInvCoeffData.end()) {
338  {
339  auto basis_host = basis->getHostBasis();
340  matData = createCoeffMatrixInternal(basis_host.getRawPtr(),true);
341  ortInvCoeffData.insert(std::make_pair(key, matData));
342  }
343  } else {
344  matData = found->second;
345  }
346 
347  return matData;
348  }
349 
350  template<typename DT>
352  ortCoeffData.clear();
353  ortInvCoeffData.clear();
354  }
355 }
356 
357 #endif
static void getCoeffMatrix_HGRAD(OutputViewType &output, const subcellBasisHostType &subcellBasis, const cellBasisHostType &cellBasis, const ordinal_type subcellId, const ordinal_type subcellOrt, const bool inverse=false)
Compute orientation matrix for HGRAD basis for a given subcell and its reference basis.
static void getCoeffMatrix_HCURL(OutputViewType &output, const subcellBasisHostType &subcellBasis, const cellBasisHostType &cellBasis, const ordinal_type subcellId, const ordinal_type subcellOrt, const bool inverse=false)
Compute orientation matrix for HCURL basis for a given subcell and its reference basis.
static void clearCoeffMatrix()
Clear coefficient matrix.
static void init_HDIV(CoeffMatrixDataViewType matData, BasisHostType const *cellBasis, const bool inverse=false)
Compute orientation matrix for HDIV basis.
static void getCoeffMatrix_HVOL(OutputViewType &output, const cellBasisHostType &cellBasis, const ordinal_type cellOrt, const bool inverse=false)
Compute orientation matrix for HVOL basis for a given (2D or 1D) cell and its reference basis...
static void init_HGRAD(CoeffMatrixDataViewType matData, BasisHostType const *cellBasis, const bool inverse=false)
Compute orientation matrix for HGRAD basis.
static void getCoeffMatrix_HDIV(OutputViewType &output, const subcellBasisHostType &subcellBasis, const cellBasisHostType &cellBasis, const ordinal_type subcellId, const ordinal_type subcellOrt, const bool inverse=false)
Compute orientation matrix for HDIV basis for a given subcell and its reference basis.
static CoeffMatrixDataViewType createCoeffMatrix(const BasisType *basis)
Create coefficient matrix.
static void init_HCURL(CoeffMatrixDataViewType matData, BasisHostType const *cellBasis, const bool inverse=false)
Compute orientation matrix for HCURL basis.
static void init_HVOL(CoeffMatrixDataViewType matData, BasisHostType const *cellBasis, const bool inverse=false)
Compute orientation matrix for HVOL basis.
static CoeffMatrixDataViewType createInvCoeffMatrix(const BasisType *basis)
Create inverse of coefficient matrix.