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
21
22
23namespace Intrepid2 {
24
25
26namespace FunctorsLagrangianTools {
27template<typename CoordsViewType,
28typename ortViewType,
29typename t2oViewType,
30typename subcellParamViewType,
31typename intViewType,
32typename 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
135template<typename DeviceType>
136template<typename BasisType,
137class ...coordsProperties,
138typename ortValueType, class ...ortProperties>
139void
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
281template<typename DeviceType>
282template<typename BasisType,
283class ...coeffsProperties,
284typename ortValueType, class ...ortProperties>
285void
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
303template<typename DeviceType>
304template<typename basisCoeffsViewType,
305typename funcViewType,
306typename BasisType,
307typename ortViewType>
308void
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 Intrepid2::ArrayTools class providing utilities for array operations.
Header file for the abstract base class Intrepid2::DefaultCubatureFactory.
Header file for the Intrepid2::FunctionSpaceTools class.
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 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 void getBasisCoeffs(basisCoeffsViewType basisCoeffs, const funcViewType functionAtDofCoords, const BasisType *cellBasis, const ortViewType orts)
Computes the basis weights of the function interpolation.
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.
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.
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...
static void clone(Kokkos::DynRankView< outputValueType, outputProperties... > output, const Kokkos::DynRankView< inputValueType, inputProperties... > input)
Clone input array.
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...