58 #ifndef __INTREPID2_ORIENTATIONTOOLS_DEF_COEFF_MATRIX_HDIV_HPP__
59 #define __INTREPID2_ORIENTATIONTOOLS_DEF_COEFF_MATRIX_HDIV_HPP__
62 #if defined (__clang__) && !defined (__INTEL_COMPILER)
63 #pragma clang system_header
68 template<
typename ExecSpaceType,
69 typename outputValueType,
70 typename pointValueType>
71 class Basis_HDIV_TET_In_FEM;
75 template<
typename OutputViewType,
76 typename subcellBasisType,
77 typename cellBasisType>
82 const subcellBasisType subcellBasis,
83 const cellBasisType cellBasis,
84 const ordinal_type subcellId,
85 const ordinal_type subcellOrt) {
86 typedef typename OutputViewType::execution_space space_type;
87 typedef typename OutputViewType::value_type value_type;
91 Kokkos::Impl::is_space<space_type>::host_mirror_space::execution_space host_space_type;
93 typedef Kokkos::DynRankView<value_type,host_space_type> DynRankViewHostType;
100 const shards::CellTopology cellTopo = cellBasis.getBaseCellTopology();
101 const shards::CellTopology subcellTopo = subcellBasis.getBaseCellTopology();
103 const ordinal_type cellDim = cellTopo.getDimension();
104 const ordinal_type subcellDim = subcellTopo.getDimension();
106 INTREPID2_TEST_FOR_EXCEPTION( subcellDim >= cellDim,
108 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): " \
109 "cellDim must be greater than subcellDim.");
111 const auto subcellBaseKey = subcellTopo.getBaseKey();
112 const auto cellBaseKey = cellTopo.getBaseKey();
114 INTREPID2_TEST_FOR_EXCEPTION( subcellBaseKey != shards::Line<>::key &&
115 subcellBaseKey != shards::Quadrilateral<>::key &&
116 subcellBaseKey != shards::Triangle<>::key,
118 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): " \
119 "subcellBasis must have line, quad, or triangle topology.");
121 INTREPID2_TEST_FOR_EXCEPTION( cellBaseKey != shards::Quadrilateral<>::key &&
122 cellBaseKey != shards::Triangle<>::key &&
123 cellBaseKey != shards::Hexahedron<>::key &&
124 cellBaseKey != shards::Tetrahedron<>::key,
126 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): " \
127 "cellBasis must have quad, triangle, hexhedron or tetrahedron topology.");
133 const bool isHDIV = cellBasis.getFunctionSpace() == FUNCTION_SPACE_HDIV;
134 INTREPID2_TEST_FOR_EXCEPTION( !isHDIV,
136 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): "
137 "cellBasis is not HDIV.");
139 const bool subcellBasisIsHGRAD = subcellBasis.getFunctionSpace() == FUNCTION_SPACE_HGRAD;
140 const bool subcellBasisIsHVOL = subcellBasis.getFunctionSpace() == FUNCTION_SPACE_HVOL;
141 const bool cellIsTri = cellBaseKey == shards::Triangle<>::key;
142 const bool cellIsTet = cellBaseKey == shards::Tetrahedron<>::key;
143 const bool cellIsHex = cellBaseKey == shards::Hexahedron<>::key;
144 const bool cellIsQuad = cellBaseKey == shards::Quadrilateral<>::key;
146 const std::string subcellBasisName(subcellBasis.getName());
147 switch (subcellDim) {
150 if (cellIsHex || cellIsQuad) {
151 INTREPID2_TEST_FOR_EXCEPTION( !subcellBasisIsHGRAD,
153 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_DIV): "
154 "subcellBasis function space (1d) is not consistent to cellBasis, which should be open line hgrad, order -1.");
155 }
else if (cellIsTet || cellIsTri) {
156 INTREPID2_TEST_FOR_EXCEPTION( !subcellBasisIsHVOL,
158 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_DIV): "
159 "subcellBasis function space (1d) is not consistent to cellBasis, which should be HVOL line, order -1.");
164 if (subcellBaseKey == shards::Quadrilateral<>::key) {
166 INTREPID2_TEST_FOR_EXCEPTION( !subcellBasisIsHGRAD,
168 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): "
169 "subcellBasis function space is not compatible, which should be open line hgrad, order -1.");
170 }
else if (subcellBaseKey == shards::Triangle<>::key) {
172 INTREPID2_TEST_FOR_EXCEPTION( !subcellBasisIsHVOL,
174 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): "
175 "subcellBasis function space is not compatible, which should HVOL, order-1.");
186 const ordinal_type numCellBasis = cellBasis.getCardinality();
187 const ordinal_type numSubcellBasis = subcellBasis.getCardinality();
189 const ordinal_type ordSubcell = cellBasis.getDofOrdinal(subcellDim, subcellId, 0);
190 INTREPID2_TEST_FOR_EXCEPTION( ordSubcell == -1,
192 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): " \
193 "Invalid subcellId returns -1 ordSubcell.");
195 const ordinal_type ndofSubcell = cellBasis.getDofTag(ordSubcell)(3);
198 DynRankViewHostType refPtsSubcell(
"refPtsSubcell", ndofSubcell, subcellDim);
199 DynRankViewHostType subcellDofCoords(
"subcellDofCoords", numSubcellBasis, subcellDim);
200 subcellBasis.getDofCoords(subcellDofCoords);
201 for(ordinal_type i=0; i<ndofSubcell; ++i)
202 for(ordinal_type d=0; d <subcellDim; ++d)
203 refPtsSubcell(i,d) = subcellDofCoords(subcellBasis.getDofOrdinal(subcellDim, 0, i),d);
206 DynRankViewHostType ortPtsSubcell(
"ortPtsSubcell", ndofSubcell, subcellDim);
213 DynRankViewHostType refPtsCell(
"refPtsCell", ndofSubcell, cellDim);
223 DynRankViewHostType refValues(
"refValues", numCellBasis, ndofSubcell, cellDim);
224 cellBasis.getValues(refValues, refPtsCell, OPERATOR_VALUE);
227 DynRankViewHostType ortJacobian(
"ortJacobian", subcellDim, subcellDim);
229 auto ortJacobianDet = (subcellDim == 1) ? ortJacobian(0,0) :
230 ortJacobian(0,0)*ortJacobian(1,1)-ortJacobian(1,0)*ortJacobian(0,1);
235 DynRankViewHostType sideNormal(
"sideNormal", cellDim);
238 if((cellBaseKey == shards::Triangle<>::key))
239 for(ordinal_type i=0; i<cellDim; ++i)
242 Kokkos::View<value_type**,Kokkos::LayoutLeft,host_space_type>
243 refMat(
"refMat", ndofSubcell, ndofSubcell),
244 ortMat(
"ortMat", ndofSubcell, ndofSubcell);
245 DynRankViewHostType tmpValues(
"tmpValues", numCellBasis, ndofSubcell);
246 for (ordinal_type i=0;i<ndofSubcell;++i) {
247 const ordinal_type ii = cellBasis.getDofOrdinal(subcellDim, subcellId, i);
248 for (ordinal_type j=0;j<ndofSubcell;++j)
249 for (ordinal_type k=0;k<cellDim;++k) {
250 refMat(i,j) += refValues(ii,j,k)*sideNormal(k)* ortJacobianDet;
251 ortMat(i,j) = (i==j);
257 Teuchos::LAPACK<ordinal_type,value_type> lapack;
258 ordinal_type info = 0;
259 Kokkos::View<value_type**,Kokkos::LayoutLeft,host_space_type> pivVec(
"pivVec", ndofSubcell, 1);
261 lapack.GESV(ndofSubcell, ndofSubcell,
264 (ordinal_type*)pivVec.data(),
270 std::stringstream ss;
271 ss <<
">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): "
272 <<
"LAPACK return with error code: "
274 INTREPID2_TEST_FOR_EXCEPTION(
true, std::runtime_error, ss.str().c_str() );
279 const double eps = threshold();
280 for (ordinal_type i=0;i<ndofSubcell;++i)
281 for (ordinal_type j=0;j<ndofSubcell;++j) {
282 auto intOrtMat = std::round(ortMat(i,j));
283 ortMat(i,j) = (std::abs(ortMat(i,j) - std::round(ortMat(i,j))) < eps) ? intOrtMat : ortMat(i,j);
290 const Kokkos::pair<ordinal_type,ordinal_type> range(0, ndofSubcell);
291 Kokkos::deep_copy(Kokkos::subview(output, range, range),
292 Kokkos::subview(ortMat, range, range));