48 #ifndef __INTREPID2_LAGRANGIANINTERPOLATIONDEF_HPP__
49 #define __INTREPID2_LAGRANGIANINTERPOLATIONDEF_HPP__
57 namespace Experimental {
59 template<
typename SpT>
60 template<
typename BasisType,
61 class ...coordsProperties,
class ...coeffsProperties,
62 typename ortValueType,
class ...ortProperties>
65 Kokkos::DynRankView<typename BasisType::scalarType, coordsProperties...> dofCoords,
66 Kokkos::DynRankView<typename BasisType::scalarType, coeffsProperties...> dofCoeffs,
67 const BasisType* basis,
69 const Kokkos::DynRankView<ortValueType, ortProperties...> orts) {
71 typedef typename BasisType::scalarType scalarType;
72 typedef Kokkos::DynRankView<scalarType, SpT> scalarViewType;
73 typedef Kokkos::DynRankView<ordinal_type, SpT> intViewType;
75 const auto topo = basis->getBaseCellTopology();
76 const std::string name(basis->getName());
77 const ordinal_type degree(basis->getDegree());
79 bool isBasisHCURL = name.find(
"HCURL") != std::string::npos;
80 bool isBasisHDIV = name.find(
"HDIV") != std::string::npos;
81 bool isBasisTriOrTet = (name.find(
"TRI") != std::string::npos) || (name.find(
"TET") != std::string::npos);
82 bool isBasisHEXI1 = (name.find(
"HEX_I1") != std::string::npos);
83 bool isBasisTETI1 = (name.find(
"TET_I1") != std::string::npos);
84 bool isBasisI1 = (name.find(
"I1") != std::string::npos);
86 ordinal_type numEdges = (basis->getDofCount(1, 0) > 0) ? topo.getEdgeCount() : 0;
87 ordinal_type numFaces = (basis->getDofCount(2, 0) > 0) ? topo.getFaceCount() : 0;
89 Teuchos::RCP<Basis<SpT,scalarType,scalarType> > faceBases[6];
90 Teuchos::RCP<Basis<SpT,scalarType,scalarType> > edgeBasis;
93 if ((name ==
"Intrepid2_HGRAD_QUAD_Cn_FEM") || (name ==
"Intrepid2_HGRAD_QUAD_C1_FEM")) {
95 }
else if ((name ==
"Intrepid2_HGRAD_HEX_Cn_FEM") || (name ==
"Intrepid2_HGRAD_HEX_C1_FEM")){
98 for(ordinal_type i=1; i<6; ++i) faceBases[i]=faceBases[0];
99 }
else if ((name ==
"Intrepid2_HGRAD_TRI_Cn_FEM") || (name ==
"Intrepid2_HGRAD_TRI_C1_FEM")) {
101 }
else if ((name ==
"Intrepid2_HGRAD_TET_Cn_FEM") || (name ==
"Intrepid2_HGRAD_TET_C1_FEM")) {
104 for(ordinal_type i=1; i<4; ++i) faceBases[i]=faceBases[0];
105 }
else if ((name ==
"Intrepid2_HCURL_QUAD_In_FEM") || (name ==
"Intrepid2_HCURL_QUAD_I1_FEM")) {
107 }
else if ((name ==
"Intrepid2_HCURL_HEX_In_FEM") || (name ==
"Intrepid2_HCURL_HEX_I1_FEM")) {
110 for(ordinal_type i=1; i<6; ++i) faceBases[i]=faceBases[0];
111 }
else if ((name ==
"Intrepid2_HCURL_TRI_In_FEM") || (name ==
"Intrepid2_HCURL_TRI_I1_FEM")) {
113 }
else if ((name ==
"Intrepid2_HCURL_TET_In_FEM") || (name ==
"Intrepid2_HCURL_TET_I1_FEM")) {
116 for(ordinal_type i=1; i<4; ++i) faceBases[i]=faceBases[0];
117 }
else if ((name ==
"Intrepid2_HDIV_QUAD_In_FEM") || (name ==
"Intrepid2_HDIV_QUAD_I1_FEM")) {
119 }
else if ((name ==
"Intrepid2_HDIV_HEX_In_FEM") || (name ==
"Intrepid2_HDIV_HEX_I1_FEM")) {
120 edgeBasis = Teuchos::null;
122 for(ordinal_type i=1; i<6; ++i) faceBases[i]=faceBases[0];
123 }
else if ((name ==
"Intrepid2_HDIV_TRI_In_FEM") || (name ==
"Intrepid2_HDIV_TRI_I1_FEM")) {
125 }
else if ((name ==
"Intrepid2_HDIV_TET_In_FEM") || (name ==
"Intrepid2_HDIV_TET_I1_FEM")) {
126 edgeBasis = Teuchos::null;
128 for(ordinal_type i=1; i<4; ++i) faceBases[i]=faceBases[0];
131 INTREPID2_TEST_FOR_ABORT(name.find(
"HVOL") == std::string::npos,
132 ">>> ERROR (Intrepid2::Experimental::LagrangianInterpolation<SpT>::getDofCoordsAndCoeffs): " \
133 "method not implemented for this basis function");
137 auto ordinalToTag = basis->getAllDofTags();
138 auto tagToOrdinal = basis->getAllDofOrdinal();
140 const ordinal_type dim = basis->getBaseCellTopology().getDimension();
142 const ordinal_type numCells = dofCoeffs.extent(0);
144 intViewType eOrt(
"eOrt", numEdges);
145 intViewType fOrt(
"fOrt", numFaces);
146 scalarViewType refEdgeTan(
"refEdgeTan", dim);
147 scalarViewType refFaceTangents(
"refFaceTangents", dim, 2);
148 auto refFaceTanU = Kokkos::subview(refFaceTangents, Kokkos::ALL, 0);
149 auto refFaceTanV = Kokkos::subview(refFaceTangents, Kokkos::ALL, 1);
150 scalarViewType refNormal(
"refNormal", dim);
153 scalarViewType refDofCoords(
"refDofCoords", dofCoords.extent(1), dofCoords.extent(2)), refDofCoeffs;
154 basis->getDofCoords(refDofCoords);
157 if(dofCoeffs.rank() == 3)
158 refDofCoeffs = scalarViewType(
"refDofCoeffs", dofCoeffs.extent(1), dofCoeffs.extent(2));
160 refDofCoeffs = scalarViewType(
"refDofCoeffs",dofCoeffs.extent(1));
161 basis->getDofCoeffs(refDofCoeffs);
166 for (ordinal_type iedge=0; iedge < numEdges; ++iedge) {
167 scalarViewType ortJacobian(
"ortJacobian", 1, 1);
168 ordinal_type edgeBasisCardinality = edgeBasis->getCardinality();
169 ordinal_type numInternalDofs = edgeBasis->getDofCount(1,0);
170 scalarViewType edgeDofCoords(
"edgeDofCoords", edgeBasisCardinality, 1);
171 scalarViewType edgeInternalDofCoords(
"edgeInternalDofCoords", numInternalDofs, 1);
172 edgeBasis->getDofCoords(edgeDofCoords);
173 for(ordinal_type i=0; i<numInternalDofs; ++i)
174 edgeInternalDofCoords(i,0) = edgeDofCoords(edgeBasis->getDofOrdinal(1, 0, i),0);
176 scalarViewType edgeInternalDofCoordsOriented(
"edgeInternalDofCoordsOriented", numInternalDofs, 1);
177 scalarViewType edgeDofCoordsOriented3d(
"edgeDofCoordsOriented3d", numInternalDofs, dim);
179 for(ordinal_type i=0; i<numCells; ++i) {
180 orts(i).getEdgeOrientation(eOrt.data(), numEdges);
184 for(ordinal_type j=0; j<numInternalDofs; ++j) {
185 auto idof = basis->getDofOrdinal(1, iedge, j);
186 for(ordinal_type d=0; d <dim; ++d)
187 dofCoords(i,idof,d) = edgeDofCoordsOriented3d(j,d);
192 auto edgeScale = (isBasisTriOrTet||isBasisI1) ? 2.0 :1.0;
195 scalarViewType edgeDofCoeffs(
"edgeDofCoeffs", edgeBasisCardinality);
196 edgeBasis->getDofCoeffs(edgeDofCoeffs);
198 for(ordinal_type i=0; i<numCells; ++i) {
199 orts(i).getEdgeOrientation(eOrt.data(), numEdges);
201 for(ordinal_type j=0; j<numInternalDofs; ++j) {
202 auto idof = basis->getDofOrdinal(1, iedge, j);
203 auto jdof = edgeBasis->getDofOrdinal(1, 0, j);
204 for(ordinal_type d=0; d <dim; ++d) {
205 dofCoeffs(i,idof,d) = 0;
206 for(ordinal_type k=0; k <1; ++k)
207 for(ordinal_type l=0; l <1; ++l)
208 dofCoeffs(i,idof,d) += refEdgeTan(d)*ortJacobian(0,0)*edgeDofCoeffs(jdof)*edgeScale;
212 }
else if(isBasisHDIV) {
214 scalarViewType edgeDofCoeffs(
"edgeDofCoeffs", edgeBasisCardinality);
215 edgeBasis->getDofCoeffs(edgeDofCoeffs);
216 for(ordinal_type i=0; i<numCells; ++i) {
217 orts(i).getEdgeOrientation(eOrt.data(), numEdges);
219 auto ortJacobianDet = ortJacobian(0,0);
220 for(ordinal_type j=0; j<numInternalDofs; ++j) {
221 auto idof = basis->getDofOrdinal(1, iedge, j);
222 auto jdof = edgeBasis->getDofOrdinal(1, 0, j);
223 for(ordinal_type d=0; d <dim; ++d)
224 dofCoeffs(i,idof,d) = refNormal(d)*ortJacobianDet*edgeDofCoeffs(jdof)*edgeScale;
228 scalarViewType edgeDofCoeffs(
"edgeDofCoeffs", edgeBasisCardinality);
229 edgeBasis->getDofCoeffs(edgeDofCoeffs);
230 for(ordinal_type i=0; i<numCells; ++i) {
231 for(ordinal_type j=0; j<numInternalDofs; ++j) {
232 auto idof = basis->getDofOrdinal(1, iedge, j);
233 auto jdof = edgeBasis->getDofOrdinal(1, 0, j);
234 dofCoeffs(i,idof,0) = edgeDofCoeffs(jdof);
240 for (ordinal_type iface=0; iface < numFaces; ++iface) {
241 scalarViewType ortJacobian(
"ortJacobian", 2, 2);
242 auto faceBasis = faceBases[iface];
243 ordinal_type faceBasisCardinality = faceBasis->getCardinality();
244 ordinal_type numInternalDofs = faceBasis->getDofCount(2,0);
245 scalarViewType faceDofCoords(
"faceDofCoords", faceBasisCardinality, 2);
246 scalarViewType faceInternalDofCoords(
"faceInternalDofCoords", numInternalDofs, 2);
247 faceBasis->getDofCoords(faceDofCoords);
248 for(ordinal_type i=0; i<numInternalDofs; ++i)
249 for(ordinal_type d=0; d <2; ++d)
250 faceInternalDofCoords(i,d) = faceDofCoords(faceBasis->getDofOrdinal(2, 0, i),d);
252 scalarViewType faceInternalDofCoordsOriented(
"faceInternalDofCoordsOriented", numInternalDofs, 2);
253 scalarViewType faceDofCoordsOriented3d(
"faceDofCoordsOriented3d", numInternalDofs, dim);
254 for(ordinal_type i=0; i<numCells; ++i) {
255 orts(i).getFaceOrientation(fOrt.data(), numFaces);
256 ordinal_type ort = fOrt(iface);
260 for(ordinal_type j=0; j<numInternalDofs; ++j) {
261 auto idof = basis->getDofOrdinal(2, iface, j);
262 for(ordinal_type d=0; d <dim; ++d)
263 dofCoords(i,idof,d) = faceDofCoordsOriented3d(j,d);
268 scalarViewType faceDofCoeffs(
"faceDofCoeffs", faceBasisCardinality, 2);
269 faceBasis->getDofCoeffs(faceDofCoeffs);
271 for(ordinal_type i=0; i<numCells; ++i) {
272 orts(i).getFaceOrientation(fOrt.data(), numFaces);
274 for(ordinal_type j=0; j<numInternalDofs; ++j) {
275 auto idof = basis->getDofOrdinal(2, iface, j);
276 auto jdof = faceBasis->getDofOrdinal(2, 0, j);
277 for(ordinal_type d=0; d <dim; ++d) {
278 dofCoeffs(i,idof,d) = 0;
279 for(ordinal_type k=0; k <2; ++k)
280 for(ordinal_type l=0; l <2; ++l)
281 dofCoeffs(i,idof,d) += refFaceTangents(d,l)*ortJacobian(l,k)*faceDofCoeffs(jdof,k);
285 }
else if(isBasisHDIV) {
287 auto faceScale = (isBasisHEXI1) ? 4.0 :
288 (isBasisTETI1) ? 0.5 : 1.0;
290 scalarViewType faceDofCoeffs(
"faceDofCoeffs", faceBasisCardinality);
291 faceBasis->getDofCoeffs(faceDofCoeffs);
292 for(ordinal_type i=0; i<numCells; ++i) {
293 orts(i).getFaceOrientation(fOrt.data(), numFaces);
295 auto ortJacobianDet = ortJacobian(0,0)*ortJacobian(1,1)-ortJacobian(1,0)*ortJacobian(0,1);
296 for(ordinal_type j=0; j<numInternalDofs; ++j) {
297 auto idof = basis->getDofOrdinal(2, iface, j);
298 auto jdof = faceBasis->getDofOrdinal(2, 0, j);
299 for(ordinal_type d=0; d <dim; ++d)
300 dofCoeffs(i,idof,d) = refNormal(d)*ortJacobianDet*faceDofCoeffs(jdof)*faceScale;
304 scalarViewType faceDofCoeffs(
"faceDofCoeffs", faceBasisCardinality);
305 faceBasis->getDofCoeffs(faceDofCoeffs);
306 for(ordinal_type i=0; i<numCells; ++i) {
307 for(ordinal_type j=0; j<numInternalDofs; ++j) {
308 auto idof = basis->getDofOrdinal(2, iface, j);
309 auto jdof = faceBasis->getDofOrdinal(2, 0, j);
310 dofCoeffs(i,idof,0) = faceDofCoeffs(jdof);
316 auto numElemDOFs = basis->getDofCount(dim,0);
317 for(ordinal_type j=0; j<numElemDOFs; ++j) {
318 auto idof = basis->getDofOrdinal(dim, 0, j);
319 for(ordinal_type d=0; d <dim; ++d)
320 for(ordinal_type i=1; i <numCells; ++i)
321 dofCoords(i,idof,d) = refDofCoords(idof,d);
322 for(ordinal_type d=0; d <(ordinal_type)dofCoeffs.extent(2); ++d)
323 for(ordinal_type i=1; i <numCells; ++i)
324 dofCoeffs(i,idof,d) = refDofCoeffs(idof,d);
330 template<
typename SpT>
331 template<
typename basisCoeffsViewType,
332 typename funcViewType,
333 typename dofCoeffViewType>
336 const funcViewType functionValsAtDofCoords,
337 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...