Intrepid2
Intrepid2_LagrangianInterpolationDef.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Intrepid2 Package
4 //
5 // Copyright 2007 NTESS and the Intrepid2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
15 #ifndef __INTREPID2_LAGRANGIANINTERPOLATIONDEF_HPP__
16 #define __INTREPID2_LAGRANGIANINTERPOLATIONDEF_HPP__
17 
19 #include "Intrepid2_ArrayTools.hpp"
21 
22 
23 namespace Intrepid2 {
24 
25 
26 namespace FunctorsLagrangianTools {
27 template<typename CoordsViewType,
28 typename ortViewType,
29 typename t2oViewType,
30 typename subcellParamViewType,
31 typename intViewType,
32 typename ScalarViewType>
34  typedef typename ScalarViewType::value_type value_type;
35 
36  CoordsViewType dofCoords_;
37  const ortViewType orts_;
38  const t2oViewType tagToOrdinal_;
39  const subcellParamViewType edgeParam_, faceParam_;
40  const intViewType edgesInternalDofOrdinals_, facesInternalDofOrdinals_;
41  const ScalarViewType edgesInternalDofCoords_;
42  const ScalarViewType facesInternalDofCoords_;
43  ScalarViewType edgeWorkView_, faceWorkView_;
44  const ordinal_type cellDim_, numEdges_, numFaces_;
45  const intViewType edgeTopoKey_, numEdgesInternalDofs_;
46  const intViewType faceTopoKey_, numFacesInternalDofs_;
47 
48  computeDofCoords( CoordsViewType dofCoords,
49  const ortViewType orts,
50  const t2oViewType tagToOrdinal,
51  const subcellParamViewType edgeParam,
52  const subcellParamViewType faceParam,
53  const ScalarViewType edgesInternalDofCoords,
54  const ScalarViewType facesInternalDofCoords,
55  const ordinal_type cellDim,
56  const ordinal_type numEdges,
57  const ordinal_type numFaces,
58  const intViewType edgeTopoKey,
59  const intViewType numEdgesInternalDofs,
60  const intViewType faceTopoKey,
61  const intViewType numFacesInternalDofs
62  )
63  : dofCoords_(dofCoords),
64  orts_(orts),
65  tagToOrdinal_(tagToOrdinal),
66  edgeParam_(edgeParam),
67  faceParam_(faceParam),
68  edgesInternalDofCoords_(edgesInternalDofCoords),
69  facesInternalDofCoords_(facesInternalDofCoords),
70  cellDim_(cellDim),
71  numEdges_(numEdges),
72  numFaces_(numFaces),
73  edgeTopoKey_(edgeTopoKey),
74  numEdgesInternalDofs_(numEdgesInternalDofs),
75  faceTopoKey_(faceTopoKey),
76  numFacesInternalDofs_(numFacesInternalDofs)
77  {
78  if(numEdges > 0)
79  edgeWorkView_ = ScalarViewType("edgeWorkView", dofCoords.extent(0), edgesInternalDofCoords.extent(1), cellDim);
80  if(numFaces > 0)
81  faceWorkView_ = ScalarViewType("faceWorkView", dofCoords.extent(0), facesInternalDofCoords.extent(1), cellDim);
82  }
83 
84  KOKKOS_INLINE_FUNCTION
85  void operator()(const ordinal_type cell) const {
86  typedef Kokkos::pair<ordinal_type,ordinal_type> range_type;
87 
88 
89  if(numEdges_ > 0) {
90  //compute coordinates associated to edge DoFs
91  ordinal_type eOrt[12];
92  orts_(cell).getEdgeOrientation(eOrt, numEdges_);
93  for (ordinal_type iedge=0; iedge < numEdges_; ++iedge) {
94  ordinal_type numInternalDofs = numEdgesInternalDofs_(iedge);
95  auto dofRange = range_type(0, numInternalDofs);
96  auto edgeInternalDofCoords = Kokkos::subview(edgesInternalDofCoords_, iedge, dofRange, Kokkos::ALL());
97  auto cellDofCoordsOriented = Kokkos::subview(edgeWorkView_,cell, dofRange, range_type(0,cellDim_));
98 
99  //map edge DoFs coords into parent element coords
100  Impl::OrientationTools::mapSubcellCoordsToRefCell(cellDofCoordsOriented, edgeInternalDofCoords, edgeParam_, edgeTopoKey_(iedge), iedge, eOrt[iedge]);
101 
102  for (ordinal_type j=0;j<numInternalDofs;++j) {
103  auto idof = tagToOrdinal_(1, iedge, j);
104  for (ordinal_type d=0;d<cellDim_;++d)
105  dofCoords_(cell,idof,d) = cellDofCoordsOriented(j,d);
106  }
107  }
108  }
109 
110  if(numFaces_ > 0) {
111  //compute coordinates associated to face DoFs
112  ordinal_type fOrt[12];
113  orts_(cell).getFaceOrientation(fOrt, numFaces_);
114  //map face dofs coords into parent element coords
115  for (ordinal_type iface=0; iface < numFaces_; ++iface) {
116  ordinal_type ort = fOrt[iface];
117  ordinal_type numInternalDofs = numFacesInternalDofs_(iface);
118  auto dofRange = range_type(0, numInternalDofs);
119  auto faceInternalDofCoords = Kokkos::subview(facesInternalDofCoords_, iface, dofRange, Kokkos::ALL());
120  auto cellDofCoordsOriented = Kokkos::subview(faceWorkView_,cell, dofRange, range_type(0,cellDim_));
121 
122  Impl::OrientationTools::mapSubcellCoordsToRefCell(cellDofCoordsOriented, faceInternalDofCoords, faceParam_, faceTopoKey_(iface), iface, ort);
123  for (ordinal_type j=0;j<numInternalDofs;++j) {
124  auto idof = tagToOrdinal_(2, iface, j);
125  for (ordinal_type d=0;d<cellDim_;++d)
126  dofCoords_(cell,idof,d) = cellDofCoordsOriented(j,d);
127  }
128  }
129  }
130  }
131 };
132 } // FunctorsLagrangianTools namespace
133 
134 
135 template<typename DeviceType>
136 template<typename BasisType,
137 class ...coordsProperties,
138 typename ortValueType, class ...ortProperties>
139 void
141  Kokkos::DynRankView<typename BasisType::scalarType, coordsProperties...> dofCoords,
142  const BasisType* basis,
143  const Kokkos::DynRankView<ortValueType, ortProperties...> orts) {
144 
145  using HostSpaceType = Kokkos::DefaultHostExecutionSpace;
146  using scalarType = typename BasisType::scalarType;
147  using ScalarViewType = Kokkos::DynRankView<scalarType, DeviceType>;
148  using ScalarViewTypeHost = Kokkos::DynRankView<scalarType, HostSpaceType>;
149  using intViewType = Kokkos::DynRankView<ordinal_type, DeviceType>;
150 
151  const auto topo = basis->getBaseCellTopology();
152  const std::string name(basis->getName());
153 
154  ordinal_type numEdges = (basis->getDofCount(1, 0) > 0) ? topo.getEdgeCount() : 0;
155  ordinal_type numFaces = (basis->getDofCount(2, 0) > 0) ? topo.getFaceCount() : 0;
156 
157  std::vector<Teuchos::RCP<Basis<DeviceType,scalarType,scalarType> > > edgeBases, faceBases;
158 
159  for(int i=0;i<numEdges;++i)
160  edgeBases.push_back(basis->getSubCellRefBasis(1,i));
161  for(int i=0;i<numFaces;++i)
162  faceBases.push_back(basis->getSubCellRefBasis(2,i));
163 
164  auto tagToOrdinal = Kokkos::create_mirror_view_and_copy(typename DeviceType::memory_space(), basis->getAllDofOrdinal());
165 
166  const ordinal_type dim = topo.getDimension();
167 
168  ScalarViewType refDofCoords("refDofCoords", dofCoords.extent(1), dofCoords.extent(2));
169  basis->getDofCoords(refDofCoords);
170  RealSpaceTools<DeviceType>::clone(dofCoords,refDofCoords);
171 
172  if((numFaces == 0) && (numEdges == 0))
173  return;
174 
175  //*** Pre-compute needed quantities related to edge DoFs that do not depend on the cell ***
176  intViewType edgeTopoKey("edgeTopoKey",numEdges);
177  intViewType sOrt("eOrt", numEdges);
178  intViewType numEdgesInternalDofs("numEdgesInternalDofs", numEdges);
179  ScalarViewType edgesInternalDofCoords;
180  intViewType edgesInternalDofOrdinals;
181 
182  ordinal_type maxNumEdgesInternalDofs=0;
183  ordinal_type edgeBasisMaxCardinality=0;
184 
185  auto hostNumEdgesInternalDofs = Kokkos::create_mirror_view(numEdgesInternalDofs);
186  for (ordinal_type iedge=0; iedge < numEdges; ++iedge) {
187  ordinal_type numInternalDofs = edgeBases[iedge]->getDofCount(1,0);
188  hostNumEdgesInternalDofs(iedge) = numInternalDofs;
189  maxNumEdgesInternalDofs = std::max(maxNumEdgesInternalDofs,numInternalDofs);
190  ordinal_type edgeBasisCardinality = edgeBases[iedge]->getCardinality();
191  edgeBasisMaxCardinality = std::max(edgeBasisMaxCardinality, edgeBasisCardinality);
192  }
193  Kokkos::deep_copy(numEdgesInternalDofs,hostNumEdgesInternalDofs);
194 
195  edgesInternalDofCoords = ScalarViewType("edgeInternalDofCoords", numEdges, maxNumEdgesInternalDofs,1);
196  edgesInternalDofOrdinals = intViewType("edgeInternalDofCoords", numEdges, maxNumEdgesInternalDofs);
197  auto hostEdgesInternalDofCoords = Kokkos::create_mirror_view(edgesInternalDofCoords);
198  auto hostEdgesInternalDofOrdinals = Kokkos::create_mirror_view(edgesInternalDofOrdinals);
199  auto hostEdgeTopoKey = Kokkos::create_mirror_view(edgeTopoKey);
200  for (ordinal_type iedge=0; iedge < numEdges; ++iedge) {
201  auto hostEdgeBasisPtr = edgeBases[iedge]->getHostBasis();
202  hostEdgeTopoKey(iedge) = hostEdgeBasisPtr->getBaseCellTopology().getBaseKey();
203  ordinal_type edgeBasisCardinality = hostEdgeBasisPtr->getCardinality();
204  ScalarViewTypeHost edgeDofCoords("edgeDofCoords", edgeBasisCardinality, 1);
205  hostEdgeBasisPtr->getDofCoords(edgeDofCoords);
206  for(ordinal_type i=0; i<hostNumEdgesInternalDofs(iedge); ++i) {
207  hostEdgesInternalDofOrdinals(iedge, i) = hostEdgeBasisPtr->getDofOrdinal(1, 0, i);
208  hostEdgesInternalDofCoords(iedge, i,0) = edgeDofCoords(hostEdgesInternalDofOrdinals(iedge, i),0);
209  }
210  }
211  Kokkos::deep_copy(edgesInternalDofCoords,hostEdgesInternalDofCoords);
212  Kokkos::deep_copy(edgeTopoKey,hostEdgeTopoKey);
213 
214  auto edgeParam = RefSubcellParametrization<DeviceType>::get(1, topo.getKey());
215 
216  //*** Pre-compute needed quantities related to face DoFs that do not depend on the cell ***
217  intViewType faceTopoKey("faceTopoKey",numFaces);
218  intViewType fOrt("fOrt", numFaces);
219  intViewType numFacesInternalDofs("numFacesInternalDofs", numFaces);
220  ScalarViewType facesInternalDofCoords;
221  intViewType facesInternalDofOrdinals;
222 
223  ordinal_type maxNumFacesInternalDofs=0;
224  ordinal_type faceBasisMaxCardinality=0;
225 
226  auto hostNumFacesInternalDofs = Kokkos::create_mirror_view(numFacesInternalDofs);
227  for (ordinal_type iface=0; iface < numFaces; ++iface) {
228  ordinal_type numInternalDofs = faceBases[iface]->getDofCount(2,0);
229  hostNumFacesInternalDofs(iface) = numInternalDofs;
230  maxNumFacesInternalDofs = std::max(maxNumFacesInternalDofs,numInternalDofs);
231  ordinal_type faceBasisCardinality = faceBases[iface]->getCardinality();
232  faceBasisMaxCardinality = std::max(faceBasisMaxCardinality, faceBasisCardinality);
233  }
234  Kokkos::deep_copy(numFacesInternalDofs,hostNumFacesInternalDofs);
235 
236  facesInternalDofCoords = ScalarViewType("faceInternalDofCoords", numFaces, maxNumFacesInternalDofs, 2);
237  facesInternalDofOrdinals = intViewType("faceInternalDofCoords", numFaces, maxNumFacesInternalDofs);
238 
239  auto hostFacesInternalDofCoords = Kokkos::create_mirror_view(facesInternalDofCoords);
240  auto hostFacesInternalDofOrdinals = Kokkos::create_mirror_view(facesInternalDofOrdinals);
241  auto hostFaceTopoKey = Kokkos::create_mirror_view(faceTopoKey);
242  for (ordinal_type iface=0; iface < numFaces; ++iface) {
243  auto hostFaceBasisPtr = faceBases[iface]->getHostBasis();
244  hostFaceTopoKey(iface) = hostFaceBasisPtr->getBaseCellTopology().getBaseKey();
245  ordinal_type faceBasisCardinality = hostFaceBasisPtr->getCardinality();
246  ScalarViewTypeHost faceDofCoords("faceDofCoords", faceBasisCardinality, 2);
247  hostFaceBasisPtr->getDofCoords(faceDofCoords);
248  for(ordinal_type i=0; i<hostNumFacesInternalDofs(iface); ++i) {
249  hostFacesInternalDofOrdinals(iface, i) = hostFaceBasisPtr->getDofOrdinal(2, 0, i);
250  for(ordinal_type d=0; d <2; ++d)
251  hostFacesInternalDofCoords(iface, i,d) = faceDofCoords(hostFacesInternalDofOrdinals(iface, i),d);
252  }
253  }
254  Kokkos::deep_copy(facesInternalDofCoords,hostFacesInternalDofCoords);
255  Kokkos::deep_copy(faceTopoKey,hostFaceTopoKey);
256 
257  typename RefSubcellParametrization<DeviceType>::ConstViewType faceParam;
258  if(dim > 2)
259  faceParam = RefSubcellParametrization<DeviceType>::get(2, topo.getKey());
260 
261 
262  //*** Loop over cells ***
263 
264  const Kokkos::RangePolicy<typename DeviceType::execution_space> policy(0, dofCoords.extent(0));
265  using FunctorType = FunctorsLagrangianTools::computeDofCoords<decltype(dofCoords),
266  decltype(orts),
267  decltype(tagToOrdinal),
268  decltype(edgeParam),
269  intViewType,
270  ScalarViewType>;
271  Kokkos::parallel_for(policy,
272  FunctorType(dofCoords,
273  orts, tagToOrdinal, edgeParam, faceParam,
274  edgesInternalDofCoords, facesInternalDofCoords,
275  dim, numEdges, numFaces,
276  edgeTopoKey, numEdgesInternalDofs,
277  faceTopoKey, numFacesInternalDofs));
278 }
279 
280 
281 template<typename DeviceType>
282 template<typename BasisType,
283 class ...coeffsProperties,
284 typename ortValueType, class ...ortProperties>
285 void
287  Kokkos::DynRankView<typename BasisType::scalarType, coeffsProperties...> dofCoeffs,
288  const BasisType* basis,
289  const Kokkos::DynRankView<ortValueType, ortProperties...> orts) {
290 
291  using ScalarViewType = Kokkos::DynRankView<typename BasisType::scalarType, DeviceType>;
292  ScalarViewType refDofCoeffs;
293  if(dofCoeffs.rank() == 3) //vector basis
294  refDofCoeffs = ScalarViewType("refDofCoeffs", dofCoeffs.extent(1), dofCoeffs.extent(2));
295  else //scalar basis
296  refDofCoeffs = ScalarViewType("refDofCoeffs",dofCoeffs.extent(1));
297  basis->getDofCoeffs(refDofCoeffs);
298 
299  OrientationTools<DeviceType>::modifyBasisByOrientationInverse(dofCoeffs, refDofCoeffs, orts, basis, true);
300 }
301 
302 
303 template<typename DeviceType>
304 template<typename basisCoeffsViewType,
305 typename funcViewType,
306 typename BasisType,
307 typename ortViewType>
308 void
310  const funcViewType functionValsAtDofCoords,
311  const BasisType* cellBasis,
312  const ortViewType orts){
313  using scalarType = typename BasisType::scalarType;
314  using ScalarViewType = Kokkos::DynRankView<scalarType, DeviceType>;
315  auto dofCoeffs = (functionValsAtDofCoords.rank() == 3) ?
316  ScalarViewType("dofCoeffs", basisCoeffs.extent(0), cellBasis->getCardinality(), functionValsAtDofCoords.extent(2)) :
317  ScalarViewType("dofCoeffs", basisCoeffs.extent(0), cellBasis->getCardinality());
318  auto dofCoeffs0 = Kokkos::subview(dofCoeffs, 0, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
319  cellBasis->getDofCoeffs(dofCoeffs0);
320  RealSpaceTools<DeviceType>::clone(dofCoeffs,dofCoeffs0);
321  Kokkos::DynRankView<typename basisCoeffsViewType::value_type, DeviceType> basisCoeffsRef("basisCoeffsRef", basisCoeffs.extent(0), basisCoeffs.extent(1));
322  ArrayTools<DeviceType>::dotMultiplyDataData(basisCoeffsRef,functionValsAtDofCoords,dofCoeffs);
323  OrientationTools<DeviceType>::modifyBasisByOrientationInverse(basisCoeffs, basisCoeffsRef, orts, cellBasis, true);
324 }
325 
326 } // Intrepid2 namespace
327 
328 #endif
329 
Header file for the abstract base class Intrepid2::DefaultCubatureFactory.
static void getBasisCoeffs(basisCoeffsViewType basisCoeffs, const funcViewType functionAtDofCoords, const BasisType *cellBasis, const ortViewType orts)
Computes the basis weights of the function interpolation.
static KOKKOS_INLINE_FUNCTION void mapSubcellCoordsToRefCell(coordsViewType cellCoords, const subcellCoordsViewType subCellCoords, const ParamViewType subcellParametrization, const unsigned subcellTopoKey, const ordinal_type subCellOrd, const ordinal_type ort)
Maps points defined on the subCell manifold into the parent Cell accounting for orientation.
static ConstViewType get(const ordinal_type subcellDim, const unsigned parentCellKey)
Returns a Kokkos view with the coefficients of the parametrization maps for the edges or faces of a r...
static void clone(Kokkos::DynRankView< outputValueType, outputProperties...> output, const Kokkos::DynRankView< inputValueType, inputProperties...> input)
Clone input array.
static void dotMultiplyDataData(Kokkos::DynRankView< outputDataValueType, outputDataProperties...> outputData, const Kokkos::DynRankView< inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft, const Kokkos::DynRankView< inputDataRightValueType, inputDataRightProperties...> inputDataRight)
There are two use cases: (1) dot product of a rank-2, 3 or 4 container inputDataRight with dimensions...
static void getOrientedDofCoords(Kokkos::DynRankView< typename BasisType::scalarType, coordsProperties...> dofCoords, const BasisType *cellBasis, const Kokkos::DynRankView< ortValueType, ortProperties...> cellOrientations)
Computes the coordinates associated with the basis DOFs for the reference oriented element...
Header file for the Intrepid2::FunctionSpaceTools class.
static void getOrientedDofCoeffs(Kokkos::DynRankView< typename BasisType::scalarType, coeffsProperties...> dofCoeffs, const BasisType *cellBasis, const Kokkos::DynRankView< ortValueType, ortProperties...> cellOrientations)
Computes the coefficients associated with the basis DOFs for the reference oriented element...
Header file for Intrepid2::ArrayTools class providing utilities for array operations.
static void modifyBasisByOrientationInverse(Kokkos::DynRankView< outputValueType, outputProperties...> output, const Kokkos::DynRankView< inputValueType, inputProperties...> input, const OrientationViewType orts, const BasisType *basis, const bool transpose=false)
Modify basis due to orientation, applying the inverse of the operator applied in modifyBasisByOrienta...