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(
typename SpT::memory_space(), basis->getAllDofOrdinal());
349 Kokkos::deep_copy(tagToOrdinal, basis->getAllDofOrdinal());
351 const ordinal_type dim = topo.getDimension();
353 const ordinal_type numCells = dofCoeffs.extent(0);
355 ScalarViewType refDofCoords(
"refDofCoords", dofCoords.extent(1), dofCoords.extent(2)), refDofCoeffs;
356 basis->getDofCoords(refDofCoords);
359 if(dofCoeffs.rank() == 3)
360 refDofCoeffs = ScalarViewType(
"refDofCoeffs", dofCoeffs.extent(1), dofCoeffs.extent(2));
362 refDofCoeffs = ScalarViewType(
"refDofCoeffs",dofCoeffs.extent(1));
363 basis->getDofCoeffs(refDofCoeffs);
368 ordinal_type edgeTopoKey = Teuchos::nonnull(edgeBasis) ? edgeBasis->getBaseCellTopology().getBaseKey() : 0;
369 intViewType eOrt(
"eOrt", numEdges);
370 ScalarViewType refEdgesTan(
"refEdgesTan", numEdges, dim);
371 ScalarViewType refEdgesNormal(
"refEdgesNormal", numEdges, dim);
372 ScalarViewType edgeParam;
373 ordinal_type edgeBasisCardinality = Teuchos::nonnull(edgeBasis) ? edgeBasis->getCardinality() : ordinal_type(0);
374 ordinal_type numEdgeInternalDofs = Teuchos::nonnull(edgeBasis) ? edgeBasis->getDofCount(1,0) : ordinal_type(0);
375 ScalarViewType edgeDofCoords(
"edgeDofCoords", edgeBasisCardinality, 1);
376 ScalarViewType edgeDofCoeffs(
"edgeDofCoeffs", edgeBasisCardinality);
377 ScalarViewType edgeInternalDofCoords(
"edgeInternalDofCoords", numEdgeInternalDofs, 1);
378 intViewType edgeInternalDofOrdinals(
"edgeInternalDofOrdinals", numEdgeInternalDofs);
380 auto edgeScale = (isBasisTriOrTet||isBasisI1) ? 2.0 :1.0;
382 if(Teuchos::nonnull(edgeBasis)) {
383 edgeBasis->getDofCoords(edgeDofCoords);
384 edgeBasis->getDofCoeffs(edgeDofCoeffs);
387 for (ordinal_type iedge=0; iedge < numEdges; ++iedge) {
389 auto edgeTan = Kokkos::subview(refEdgesTan, iedge, Kokkos::ALL);
390 auto edgeTanHost = Kokkos::create_mirror_view(edgeTan);
392 Kokkos::deep_copy(edgeTan,edgeTanHost);
394 else if(isBasisHDIV) {
395 auto edgeNormal = Kokkos::subview(refEdgesNormal, iedge, Kokkos::ALL);
396 auto edgeNormalHost = Kokkos::create_mirror_view(edgeNormal);
398 Kokkos::deep_copy(edgeNormal,edgeNormalHost);
403 for(ordinal_type i=0; i<numEdgeInternalDofs; ++i) {
404 edgeInternalDofOrdinals(i) = edgeBasis->getDofOrdinal(1, 0, i);
405 edgeInternalDofCoords(i,0) = edgeDofCoords(edgeInternalDofOrdinals(i), 0);
412 intViewType faceTopoKey(
"faceTopoKey",numFaces);
413 intViewType fOrt(
"fOrt", numFaces);
414 ScalarViewType refFaceTangents(
"refFaceTangents", numFaces, dim, 2);
415 ScalarViewType refFacesNormal(
"refFacesNormal", numFaces, dim);
416 ScalarViewType faceParam;
417 intViewType numFacesInternalDofs(
"numFacesInternalDofs", numFaces);
418 ScalarViewType facesInternalDofCoords;
419 intViewType facesInternalDofOrdinals;
420 ScalarViewType faceDofCoeffs;
422 auto faceScale = (isBasisHEXI1) ? 4.0 :
423 (isBasisTETI1) ? 0.5 : 1.0;
426 ordinal_type maxNumFacesInternalDofs=0;
427 ordinal_type faceBasisMaxCardinality=0;
429 for (ordinal_type iface=0; iface < numFaces; ++iface) {
430 ordinal_type numInternalDofs = faceBases[iface]->getDofCount(2,0);
431 numFacesInternalDofs(iface) = numInternalDofs;
432 maxNumFacesInternalDofs = std::max(maxNumFacesInternalDofs,numInternalDofs);
433 ordinal_type faceBasisCardinality = faceBases[iface]->getCardinality();
434 faceBasisMaxCardinality = std::max(faceBasisMaxCardinality, faceBasisCardinality);
437 facesInternalDofCoords = ScalarViewType(
"faceInternalDofCoords", numFaces, maxNumFacesInternalDofs, 2);
438 facesInternalDofOrdinals = intViewType(
"faceInternalDofCoords", numFaces, maxNumFacesInternalDofs);
441 faceDofCoeffs = ScalarViewType(
"faceDofCoeffs", numFaces, faceBasisMaxCardinality,2);
443 faceDofCoeffs = ScalarViewType(
"faceDofCoeffs", numFaces, faceBasisMaxCardinality);
445 for (ordinal_type iface=0; iface < numFaces; ++iface) {
446 auto faceBasis = faceBases[iface];
447 faceTopoKey(iface) = faceBasis->getBaseCellTopology().getBaseKey();
448 ordinal_type faceBasisCardinality = faceBasis->getCardinality();
449 ScalarViewType faceDofCoords(
"faceDofCoords", faceBasisCardinality, 2);
450 faceBasis->getDofCoords(faceDofCoords);
451 for(ordinal_type i=0; i<numFacesInternalDofs(iface); ++i) {
452 facesInternalDofOrdinals(iface, i) = faceBasis->getDofOrdinal(2, 0, i);
453 for(ordinal_type d=0; d <2; ++d)
454 facesInternalDofCoords(iface, i,d) = faceDofCoords(facesInternalDofOrdinals(iface, i),d);
457 auto dofRange = range_type(0, faceBasis->getCardinality());
458 faceBasis->getDofCoeffs(Kokkos::subview(faceDofCoeffs, iface, dofRange, Kokkos::ALL()));
461 auto refFaceTanU = Kokkos::subview(refFaceTangents, iface, Kokkos::ALL, 0);
462 auto refFaceTanV = Kokkos::subview(refFaceTangents, iface, Kokkos::ALL,1);
463 auto refFaceTanUHost = Kokkos::create_mirror_view(refFaceTanU);
464 auto refFaceTanVHost = Kokkos::create_mirror_view(refFaceTanV);
466 Kokkos::deep_copy(refFaceTanU, refFaceTanUHost);
467 Kokkos::deep_copy(refFaceTanV, refFaceTanVHost);
468 }
else if(isBasisHDIV) {
469 auto faceNormal = Kokkos::subview(refFacesNormal,iface,Kokkos::ALL());
470 auto faceNormalHost = Kokkos::create_mirror_view(faceNormal);
472 Kokkos::deep_copy(faceNormal, faceNormalHost);
482 const Kokkos::RangePolicy<SpT> policy(0, numCells);
486 decltype(tagToOrdinal),
488 intViewType> FunctorType;
489 Kokkos::parallel_for(policy,
490 FunctorType(dofCoords, dofCoeffs,
491 orts, tagToOrdinal, edgeParam, faceParam,
492 edgeInternalDofOrdinals, facesInternalDofOrdinals,
493 edgeInternalDofCoords, edgeDofCoeffs, refEdgesTan, refEdgesNormal,
494 facesInternalDofCoords, faceDofCoeffs, refFaceTangents, refFacesNormal,
495 dim, numEdges, numFaces,
496 edgeTopoKey, numEdgeInternalDofs,
497 faceTopoKey, numFacesInternalDofs,
498 edgeScale, faceScale,
499 isBasisHCURL, isBasisHDIV));
503 template<
typename SpT>
504 template<
typename basisCoeffsViewType,
505 typename funcViewType,
506 typename dofCoeffViewType>
509 const funcViewType functionValsAtDofCoords,
510 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...