48 #ifndef __INTREPID2_LAGRANGIANINTERPOLATIONDEF_HPP__
49 #define __INTREPID2_LAGRANGIANINTERPOLATIONDEF_HPP__
57 namespace Experimental {
61 template<
typename ScalarViewType,
64 typename subcellParamViewType,
67 typedef typename ScalarViewType::value_type value_type;
69 ScalarViewType dofCoords_, dofCoeffs_;
70 const ortViewType orts_;
71 const t2oViewType tagToOrdinal_;
72 const subcellParamViewType edgeParam_, faceParam_;
73 const intViewType edgeInternalDofOrdinals_, facesInternalDofOrdinals_;
74 const ScalarViewType edgeInternalDofCoords_, edgeDofCoeffs_, ortJacobianEdge_, refEdgesTan_, refEdgesNormal_;
75 const ScalarViewType facesInternalDofCoords_, faceDofCoeffs_, ortJacobianFace_, refFaceTangents_, refFacesNormal_;
76 ScalarViewType edgeWorkView_, faceWorkView_;
77 const ordinal_type cellDim_, numEdges_, numFaces_;
78 const ordinal_type edgeTopoKey_, numEdgeInternalDofs_;
79 const intViewType faceTopoKey_, numFacesInternalDofs_;
80 const value_type edgeScale_, faceScale_;
81 const bool isBasisHCURL_, isBasisHDIV_;
84 ScalarViewType dofCoeffs,
85 const ortViewType orts,
86 const t2oViewType tagToOrdinal,
87 const subcellParamViewType edgeParam,
88 const subcellParamViewType faceParam,
89 const intViewType edgeInternalDofOrdinals,
90 const intViewType facesInternalDofOrdinals,
91 const ScalarViewType edgeInternalDofCoords,
92 const ScalarViewType edgeDofCoeffs,
93 const ScalarViewType refEdgesTan,
94 const ScalarViewType refEdgesNormal,
95 const ScalarViewType facesInternalDofCoords,
96 const ScalarViewType faceDofCoeffs,
97 const ScalarViewType refFaceTangents,
98 const ScalarViewType refFacesNormal,
99 const ordinal_type cellDim,
100 const ordinal_type numEdges,
101 const ordinal_type numFaces,
102 const ordinal_type edgeTopoKey,
103 const ordinal_type numEdgeInternalDofs,
104 const intViewType faceTopoKey,
105 const intViewType numFacesInternalDofs,
106 const value_type edgeScale,
107 const value_type faceScale,
108 const bool isBasisHCURL,
109 const bool isBasisHDIV
111 : dofCoords_(dofCoords),
112 dofCoeffs_(dofCoeffs),
114 tagToOrdinal_(tagToOrdinal),
115 edgeParam_(edgeParam),
116 faceParam_(faceParam),
117 edgeInternalDofOrdinals_(edgeInternalDofOrdinals),
118 facesInternalDofOrdinals_(facesInternalDofOrdinals),
119 edgeInternalDofCoords_(edgeInternalDofCoords),
120 edgeDofCoeffs_(edgeDofCoeffs),
121 refEdgesTan_(refEdgesTan),
122 refEdgesNormal_(refEdgesNormal),
123 facesInternalDofCoords_(facesInternalDofCoords),
124 faceDofCoeffs_(faceDofCoeffs),
125 refFaceTangents_(refFaceTangents),
126 refFacesNormal_(refFacesNormal),
130 edgeTopoKey_(edgeTopoKey),
131 numEdgeInternalDofs_(numEdgeInternalDofs),
132 faceTopoKey_(faceTopoKey),
133 numFacesInternalDofs_(numFacesInternalDofs),
134 edgeScale_(edgeScale),
135 faceScale_(faceScale),
136 isBasisHCURL_(isBasisHCURL),
137 isBasisHDIV_(isBasisHDIV)
140 edgeWorkView_ = ScalarViewType(
"edgeWorkView", dofCoords.extent(0), numEdgeInternalDofs, 1);
142 faceWorkView_ = ScalarViewType(
"faceWorkView", dofCoords.extent(0), facesInternalDofCoords.extent(1), 2);
145 KOKKOS_INLINE_FUNCTION
146 void operator()(
const ordinal_type cell)
const {
147 typedef Kokkos::pair<ordinal_type,ordinal_type> range_type;
152 ordinal_type eOrt[12];
154 ScalarViewType ortJacobianEdge(&ortJac, 1, 1);
155 orts_(cell).getEdgeOrientation(eOrt, numEdges_);
156 auto edgeInternalDofCoordsOriented = Kokkos::subview(edgeWorkView_,cell, Kokkos::ALL(), Kokkos::ALL());
158 for (ordinal_type iedge=0; iedge < numEdges_; ++iedge) {
161 for (ordinal_type j=0;j<numEdgeInternalDofs_;++j) {
162 const auto u = edgeInternalDofCoordsOriented(j, 0);
163 auto idof = tagToOrdinal_(1, iedge, j);
164 for (ordinal_type d=0;d<cellDim_;++d)
165 dofCoords_(cell,idof,d) = edgeParam_(iedge, d, 0) + edgeParam_(iedge, d, 1)*u ;
171 for (ordinal_type iedge=0; iedge < numEdges_; ++iedge) {
173 for(ordinal_type j=0; j<numEdgeInternalDofs_; ++j) {
174 auto idof = tagToOrdinal_(1, iedge, j);
175 auto jdof = edgeInternalDofOrdinals_(j);
176 for(ordinal_type d=0; d <cellDim_; ++d) {
177 dofCoeffs_(cell,idof,d) = 0;
178 for(ordinal_type k=0; k <1; ++k)
179 for(ordinal_type l=0; l <1; ++l)
180 dofCoeffs_(cell,idof,d) += refEdgesTan_(iedge,d)*ortJacobianEdge(0,0)*edgeDofCoeffs_(jdof)*edgeScale_;
184 }
else if(isBasisHDIV_) {
185 for (ordinal_type iedge=0; iedge < numEdges_; ++iedge) {
187 auto ortJacobianDet = ortJacobianEdge(0,0);
188 for(ordinal_type j=0; j<numEdgeInternalDofs_; ++j) {
189 auto idof = tagToOrdinal_(1, iedge, j);
190 auto jdof = edgeInternalDofOrdinals_(j);
191 for(ordinal_type d=0; d <cellDim_; ++d)
192 dofCoeffs_(cell,idof,d) = refEdgesNormal_(iedge, d)*ortJacobianDet*edgeDofCoeffs_(jdof)*edgeScale_;
196 for (ordinal_type iedge=0; iedge < numEdges_; ++iedge) {
197 for(ordinal_type j=0; j<numEdgeInternalDofs_; ++j) {
198 auto idof = tagToOrdinal_(1, iedge, j);
199 auto jdof = edgeInternalDofOrdinals_(j);
200 dofCoeffs_(cell,idof,0) = edgeDofCoeffs_(jdof);
209 ordinal_type fOrt[12];
210 value_type ortJac[4];
211 ScalarViewType ortJacobianFace(ortJac, 2, 2);
212 orts_(cell).getFaceOrientation(fOrt, numFaces_);
214 for (ordinal_type iface=0; iface < numFaces_; ++iface) {
215 ordinal_type ort = fOrt[iface];
216 ordinal_type numInternalDofs = numFacesInternalDofs_(iface);
217 auto dofRange = range_type(0, numInternalDofs);
218 auto faceInternalDofCoords = Kokkos::subview(facesInternalDofCoords_, iface, dofRange, Kokkos::ALL());
219 auto faceInternalDofCoordsOriented = Kokkos::subview(faceWorkView_,cell, dofRange, Kokkos::ALL());
222 for (ordinal_type j=0;j<numInternalDofs;++j) {
223 const auto u = faceInternalDofCoordsOriented(j, 0);
224 const auto v = faceInternalDofCoordsOriented(j, 1);
225 auto idof = tagToOrdinal_(2, iface, j);
226 for (ordinal_type d=0;d<cellDim_;++d)
227 dofCoords_(cell,idof,d) = faceParam_(iface, d, 0) + faceParam_(iface, d, 1)*u + faceParam_(iface, d, 2)*v;
232 for (ordinal_type iface=0; iface < numFaces_; ++iface) {
234 for(ordinal_type j=0; j<numFacesInternalDofs_(iface); ++j) {
235 auto idof = tagToOrdinal_(2, iface, j);
236 auto jdof = facesInternalDofOrdinals_(iface, j);
237 for(ordinal_type d=0; d <cellDim_; ++d) {
238 dofCoeffs_(cell,idof,d) = 0;
239 for(ordinal_type k=0; k <2; ++k)
240 for(ordinal_type l=0; l <2; ++l)
241 dofCoeffs_(cell,idof,d) += refFaceTangents_(iface, d,l)*ortJacobianFace(l,k)*faceDofCoeffs_(iface,jdof,k);
245 }
else if(isBasisHDIV_) {
246 for (ordinal_type iface=0; iface < numFaces_; ++iface) {
248 auto ortJacobianDet = ortJacobianFace(0,0)*ortJacobianFace(1,1)-ortJacobianFace(1,0)*ortJacobianFace(0,1);
249 for(ordinal_type j=0; j<numFacesInternalDofs_(iface); ++j) {
250 auto idof = tagToOrdinal_(2, iface, j);
251 auto jdof = facesInternalDofOrdinals_(iface, j);
252 for(ordinal_type d=0; d <cellDim_; ++d)
253 dofCoeffs_(cell,idof,d) = refFacesNormal_(iface,d)*ortJacobianDet*faceDofCoeffs_(iface,jdof)*faceScale_;
258 for (ordinal_type iface=0; iface < numFaces_; ++iface) {
259 for(ordinal_type j=0; j<numFacesInternalDofs_(iface); ++j) {
260 auto idof = tagToOrdinal_(2, iface, j);
261 auto jdof = facesInternalDofOrdinals_(iface, j);
262 dofCoeffs_(cell,idof,0) = faceDofCoeffs_(iface,jdof);
270 template<
typename SpT>
271 template<
typename BasisType,
272 class ...coordsProperties,
class ...coeffsProperties,
273 typename ortValueType,
class ...ortProperties>
276 Kokkos::DynRankView<typename BasisType::scalarType, coordsProperties...> dofCoords,
277 Kokkos::DynRankView<typename BasisType::scalarType, coeffsProperties...> dofCoeffs,
278 const BasisType* basis,
279 EPointType pointType,
280 const Kokkos::DynRankView<ortValueType, ortProperties...> orts) {
282 typedef typename BasisType::scalarType scalarType;
283 typedef Kokkos::DynRankView<scalarType, SpT> ScalarViewType;
284 typedef Kokkos::DynRankView<ordinal_type, SpT> intViewType;
285 typedef Kokkos::pair<ordinal_type,ordinal_type> range_type;
287 const auto topo = basis->getBaseCellTopology();
288 const std::string name(basis->getName());
289 const ordinal_type degree(basis->getDegree());
291 bool isBasisHCURL = name.find(
"HCURL") != std::string::npos;
292 bool isBasisHDIV = name.find(
"HDIV") != std::string::npos;
293 bool isBasisTriOrTet = (name.find(
"TRI") != std::string::npos) || (name.find(
"TET") != std::string::npos);
294 bool isBasisHEXI1 = (name.find(
"HEX_I1") != std::string::npos);
295 bool isBasisTETI1 = (name.find(
"TET_I1") != std::string::npos);
296 bool isBasisI1 = (name.find(
"I1") != std::string::npos);
298 ordinal_type numEdges = (basis->getDofCount(1, 0) > 0) ? topo.getEdgeCount() : 0;
299 ordinal_type numFaces = (basis->getDofCount(2, 0) > 0) ? topo.getFaceCount() : 0;
301 Teuchos::RCP<Basis<SpT,scalarType,scalarType> > faceBases[6];
302 Teuchos::RCP<Basis<SpT,scalarType,scalarType> > edgeBasis;
305 if ((name ==
"Intrepid2_HGRAD_QUAD_Cn_FEM") || (name ==
"Intrepid2_HGRAD_QUAD_C1_FEM")) {
307 }
else if ((name ==
"Intrepid2_HGRAD_HEX_Cn_FEM") || (name ==
"Intrepid2_HGRAD_HEX_C1_FEM")){
310 for(ordinal_type i=1; i<6; ++i) faceBases[i]=faceBases[0];
311 }
else if ((name ==
"Intrepid2_HGRAD_TRI_Cn_FEM") || (name ==
"Intrepid2_HGRAD_TRI_C1_FEM")) {
313 }
else if ((name ==
"Intrepid2_HGRAD_TET_Cn_FEM") || (name ==
"Intrepid2_HGRAD_TET_C1_FEM")) {
316 for(ordinal_type i=1; i<4; ++i) faceBases[i]=faceBases[0];
317 }
else if ((name ==
"Intrepid2_HCURL_QUAD_In_FEM") || (name ==
"Intrepid2_HCURL_QUAD_I1_FEM")) {
319 }
else if ((name ==
"Intrepid2_HCURL_HEX_In_FEM") || (name ==
"Intrepid2_HCURL_HEX_I1_FEM")) {
322 for(ordinal_type i=1; i<6; ++i) faceBases[i]=faceBases[0];
323 }
else if ((name ==
"Intrepid2_HCURL_TRI_In_FEM") || (name ==
"Intrepid2_HCURL_TRI_I1_FEM")) {
325 }
else if ((name ==
"Intrepid2_HCURL_TET_In_FEM") || (name ==
"Intrepid2_HCURL_TET_I1_FEM")) {
328 for(ordinal_type i=1; i<4; ++i) faceBases[i]=faceBases[0];
329 }
else if ((name ==
"Intrepid2_HDIV_QUAD_In_FEM") || (name ==
"Intrepid2_HDIV_QUAD_I1_FEM")) {
331 }
else if ((name ==
"Intrepid2_HDIV_HEX_In_FEM") || (name ==
"Intrepid2_HDIV_HEX_I1_FEM")) {
332 edgeBasis = Teuchos::null;
334 for(ordinal_type i=1; i<6; ++i) faceBases[i]=faceBases[0];
335 }
else if ((name ==
"Intrepid2_HDIV_TRI_In_FEM") || (name ==
"Intrepid2_HDIV_TRI_I1_FEM")) {
337 }
else if ((name ==
"Intrepid2_HDIV_TET_In_FEM") || (name ==
"Intrepid2_HDIV_TET_I1_FEM")) {
338 edgeBasis = Teuchos::null;
340 for(ordinal_type i=1; i<4; ++i) faceBases[i]=faceBases[0];
343 INTREPID2_TEST_FOR_ABORT(name.find(
"HVOL") == std::string::npos,
344 ">>> ERROR (Intrepid2::Experimental::LagrangianInterpolation<SpT>::getDofCoordsAndCoeffs): " \
345 "method not implemented for this basis function");
348 auto tagToOrdinal = Kokkos::create_mirror_view_and_copy(
typename SpT::memory_space(), basis->getAllDofOrdinal());
350 const ordinal_type dim = topo.getDimension();
352 const ordinal_type numCells = dofCoeffs.extent(0);
354 ScalarViewType refDofCoords(
"refDofCoords", dofCoords.extent(1), dofCoords.extent(2)), refDofCoeffs;
355 basis->getDofCoords(refDofCoords);
358 if(dofCoeffs.rank() == 3)
359 refDofCoeffs = ScalarViewType(
"refDofCoeffs", dofCoeffs.extent(1), dofCoeffs.extent(2));
361 refDofCoeffs = ScalarViewType(
"refDofCoeffs",dofCoeffs.extent(1));
362 basis->getDofCoeffs(refDofCoeffs);
367 ordinal_type edgeTopoKey = Teuchos::nonnull(edgeBasis) ? edgeBasis->getBaseCellTopology().getBaseKey() : 0;
368 intViewType eOrt(
"eOrt", numEdges);
369 ScalarViewType refEdgesTan(
"refEdgesTan", numEdges, dim);
370 ScalarViewType refEdgesNormal(
"refEdgesNormal", numEdges, dim);
371 ScalarViewType edgeParam;
372 ordinal_type edgeBasisCardinality = Teuchos::nonnull(edgeBasis) ? edgeBasis->getCardinality() : ordinal_type(0);
373 ordinal_type numEdgeInternalDofs = Teuchos::nonnull(edgeBasis) ? edgeBasis->getDofCount(1,0) : ordinal_type(0);
374 ScalarViewType edgeDofCoords(
"edgeDofCoords", edgeBasisCardinality, 1);
375 ScalarViewType edgeDofCoeffs(
"edgeDofCoeffs", edgeBasisCardinality);
376 ScalarViewType edgeInternalDofCoords(
"edgeInternalDofCoords", numEdgeInternalDofs, 1);
377 intViewType edgeInternalDofOrdinals(
"edgeInternalDofOrdinals", numEdgeInternalDofs);
379 auto edgeScale = (isBasisTriOrTet||isBasisI1) ? 2.0 :1.0;
381 if(Teuchos::nonnull(edgeBasis)) {
382 edgeBasis->getDofCoords(edgeDofCoords);
383 edgeBasis->getDofCoeffs(edgeDofCoeffs);
386 for (ordinal_type iedge=0; iedge < numEdges; ++iedge) {
388 auto edgeTan = Kokkos::subview(refEdgesTan, iedge, Kokkos::ALL);
389 auto edgeTanHost = Kokkos::create_mirror_view(edgeTan);
391 Kokkos::deep_copy(edgeTan,edgeTanHost);
393 else if(isBasisHDIV) {
394 auto edgeNormal = Kokkos::subview(refEdgesNormal, iedge, Kokkos::ALL);
395 auto edgeNormalHost = Kokkos::create_mirror_view(edgeNormal);
397 Kokkos::deep_copy(edgeNormal,edgeNormalHost);
402 for(ordinal_type i=0; i<numEdgeInternalDofs; ++i) {
403 edgeInternalDofOrdinals(i) = edgeBasis->getDofOrdinal(1, 0, i);
404 edgeInternalDofCoords(i,0) = edgeDofCoords(edgeInternalDofOrdinals(i), 0);
411 intViewType faceTopoKey(
"faceTopoKey",numFaces);
412 intViewType fOrt(
"fOrt", numFaces);
413 ScalarViewType refFaceTangents(
"refFaceTangents", numFaces, dim, 2);
414 ScalarViewType refFacesNormal(
"refFacesNormal", numFaces, dim);
415 ScalarViewType faceParam;
416 intViewType numFacesInternalDofs(
"numFacesInternalDofs", numFaces);
417 ScalarViewType facesInternalDofCoords;
418 intViewType facesInternalDofOrdinals;
419 ScalarViewType faceDofCoeffs;
421 auto faceScale = (isBasisHEXI1) ? 4.0 :
422 (isBasisTETI1) ? 0.5 : 1.0;
425 ordinal_type maxNumFacesInternalDofs=0;
426 ordinal_type faceBasisMaxCardinality=0;
428 for (ordinal_type iface=0; iface < numFaces; ++iface) {
429 ordinal_type numInternalDofs = faceBases[iface]->getDofCount(2,0);
430 numFacesInternalDofs(iface) = numInternalDofs;
431 maxNumFacesInternalDofs = std::max(maxNumFacesInternalDofs,numInternalDofs);
432 ordinal_type faceBasisCardinality = faceBases[iface]->getCardinality();
433 faceBasisMaxCardinality = std::max(faceBasisMaxCardinality, faceBasisCardinality);
436 facesInternalDofCoords = ScalarViewType(
"faceInternalDofCoords", numFaces, maxNumFacesInternalDofs, 2);
437 facesInternalDofOrdinals = intViewType(
"faceInternalDofCoords", numFaces, maxNumFacesInternalDofs);
440 faceDofCoeffs = ScalarViewType(
"faceDofCoeffs", numFaces, faceBasisMaxCardinality,2);
442 faceDofCoeffs = ScalarViewType(
"faceDofCoeffs", numFaces, faceBasisMaxCardinality);
444 for (ordinal_type iface=0; iface < numFaces; ++iface) {
445 auto faceBasis = faceBases[iface];
446 faceTopoKey(iface) = faceBasis->getBaseCellTopology().getBaseKey();
447 ordinal_type faceBasisCardinality = faceBasis->getCardinality();
448 ScalarViewType faceDofCoords(
"faceDofCoords", faceBasisCardinality, 2);
449 faceBasis->getDofCoords(faceDofCoords);
450 for(ordinal_type i=0; i<numFacesInternalDofs(iface); ++i) {
451 facesInternalDofOrdinals(iface, i) = faceBasis->getDofOrdinal(2, 0, i);
452 for(ordinal_type d=0; d <2; ++d)
453 facesInternalDofCoords(iface, i,d) = faceDofCoords(facesInternalDofOrdinals(iface, i),d);
456 auto dofRange = range_type(0, faceBasis->getCardinality());
457 faceBasis->getDofCoeffs(Kokkos::subview(faceDofCoeffs, iface, dofRange, Kokkos::ALL()));
460 auto refFaceTanU = Kokkos::subview(refFaceTangents, iface, Kokkos::ALL, 0);
461 auto refFaceTanV = Kokkos::subview(refFaceTangents, iface, Kokkos::ALL,1);
462 auto refFaceTanUHost = Kokkos::create_mirror_view(refFaceTanU);
463 auto refFaceTanVHost = Kokkos::create_mirror_view(refFaceTanV);
465 Kokkos::deep_copy(refFaceTanU, refFaceTanUHost);
466 Kokkos::deep_copy(refFaceTanV, refFaceTanVHost);
467 }
else if(isBasisHDIV) {
468 auto faceNormal = Kokkos::subview(refFacesNormal,iface,Kokkos::ALL());
469 auto faceNormalHost = Kokkos::create_mirror_view(faceNormal);
471 Kokkos::deep_copy(faceNormal, faceNormalHost);
481 const Kokkos::RangePolicy<SpT> policy(0, numCells);
485 decltype(tagToOrdinal),
487 intViewType> FunctorType;
488 Kokkos::parallel_for(policy,
489 FunctorType(dofCoords, dofCoeffs,
490 orts, tagToOrdinal, edgeParam, faceParam,
491 edgeInternalDofOrdinals, facesInternalDofOrdinals,
492 edgeInternalDofCoords, edgeDofCoeffs, refEdgesTan, refEdgesNormal,
493 facesInternalDofCoords, faceDofCoeffs, refFaceTangents, refFacesNormal,
494 dim, numEdges, numFaces,
495 edgeTopoKey, numEdgeInternalDofs,
496 faceTopoKey, numFacesInternalDofs,
497 edgeScale, faceScale,
498 isBasisHCURL, isBasisHDIV));
502 template<
typename SpT>
503 template<
typename basisCoeffsViewType,
504 typename funcViewType,
505 typename dofCoeffViewType>
508 const funcViewType functionValsAtDofCoords,
509 const dofCoeffViewType dofCoeffs){
Implementation of the default HVOL-compatible Lagrange basis of arbitrary degree on Triangle cell...
Header file for the abstract base class Intrepid2::DefaultCubatureFactory.
Implementation of the default H(curl)-compatible FEM basis on Quadrilateral cell. ...
static void getDofCoordsAndCoeffs(Kokkos::DynRankView< typename BasisType::scalarType, coordsProperties...> dofCoords, Kokkos::DynRankView< typename BasisType::scalarType, coeffsProperties...> dofCoeffs, const BasisType *cellBasis, EPointType basisPointType, const Kokkos::DynRankView< ortValueType, ortProperties...> cellOrientations)
Computes the points and coefficients associated with the basis DOFs for the reference oriented elemen...
Implementation of the locally H(grad)-compatible FEM basis of variable order on the [-1...
Implementation of the locally HVOL-compatible FEM basis of variable order on the [-1,1] reference line cell, using Lagrange polynomials.
Implementation of the default H(curl)-compatible Nedelec (first kind) basis of arbitrary degree on Tr...
Implementation of the default H(grad)-compatible Lagrange basis of arbitrary degree on Triangle cell...
static void getBasisCoeffs(basisCoeffsViewType basisCoeffs, const funcViewType functionAtDofCoords, const dofCoeffViewType dofCoeffs)
Computes the basis weights of the function interpolation.
Implementation of the default H(grad)-compatible FEM basis of degree n on Quadrilateral cell Implemen...