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 std::string cellBasisName(cellBasis.getName());
134 INTREPID2_TEST_FOR_EXCEPTION( cellBasisName.find(
"HDIV") == std::string::npos,
136 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): "
137 "cellBasis is not HDIV.");
139 const std::string subcellBasisName(subcellBasis.getName());
140 switch (subcellDim) {
143 if ((cellBasisName.find(
"HEX") != std::string::npos) || (cellBasisName.find(
"QUAD") != std::string::npos)) {
144 INTREPID2_TEST_FOR_EXCEPTION( subcellBasisName.find(
"HGRAD") == std::string::npos,
146 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_DIV): "
147 "subcellBasis function space (1d) is not consistent to cellBasis, which should be open line hgrad, order -1.");
148 }
else if ((cellBasisName.find(
"TET") != std::string::npos) || (cellBasisName.find(
"TRI") != std::string::npos)) {
149 INTREPID2_TEST_FOR_EXCEPTION( subcellBasisName.find(
"HVOL") == std::string::npos,
151 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_DIV): "
152 "subcellBasis function space (1d) is not consistent to cellBasis, which should be HVOL line, order -1.");
157 if (subcellBaseKey == shards::Quadrilateral<>::key) {
159 INTREPID2_TEST_FOR_EXCEPTION( subcellBasisName.find(
"HGRAD") == std::string::npos,
161 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): "
162 "subcellBasis function space is not compatible, which should be open line hgrad, order -1.");
163 }
else if (subcellBaseKey == shards::Triangle<>::key) {
165 INTREPID2_TEST_FOR_EXCEPTION( subcellBasisName.find(
"HVOL") == std::string::npos,
167 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): "
168 "subcellBasis function space is not compatible, which should HVOL, order-1.");
179 const ordinal_type numCellBasis = cellBasis.getCardinality();
180 const ordinal_type numSubcellBasis = subcellBasis.getCardinality();
182 const ordinal_type ordSubcell = cellBasis.getDofOrdinal(subcellDim, subcellId, 0);
183 INTREPID2_TEST_FOR_EXCEPTION( ordSubcell == -1,
185 ">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): " \
186 "Invalid subcellId returns -1 ordSubcell.");
188 const ordinal_type ndofSubcell = cellBasis.getDofTag(ordSubcell)(3);
191 DynRankViewHostType refPtsSubcell(
"refPtsSubcell", ndofSubcell, subcellDim);
192 DynRankViewHostType subcellDofCoords(
"subcellDofCoords", numSubcellBasis, subcellDim);
193 subcellBasis.getDofCoords(subcellDofCoords);
194 for(ordinal_type i=0; i<ndofSubcell; ++i)
195 for(ordinal_type d=0; d <subcellDim; ++d)
196 refPtsSubcell(i,d) = subcellDofCoords(subcellBasis.getDofOrdinal(subcellDim, 0, i),d);
199 DynRankViewHostType ortPtsSubcell(
"ortPtsSubcell", ndofSubcell, subcellDim);
206 DynRankViewHostType refPtsCell(
"refPtsCell", ndofSubcell, cellDim);
216 DynRankViewHostType refValues(
"refValues", numCellBasis, ndofSubcell, cellDim);
217 cellBasis.getValues(refValues, refPtsCell, OPERATOR_VALUE);
220 DynRankViewHostType ortJacobian(
"ortJacobian", subcellDim, subcellDim);
222 auto ortJacobianDet = (subcellDim == 1) ? ortJacobian(0,0) :
223 ortJacobian(0,0)*ortJacobian(1,1)-ortJacobian(1,0)*ortJacobian(0,1);
228 DynRankViewHostType sideNormal(
"sideNormal", cellDim);
231 if((cellBaseKey == shards::Triangle<>::key))
232 for(ordinal_type i=0; i<cellDim; ++i)
235 Kokkos::View<value_type**,Kokkos::LayoutLeft,host_space_type>
236 refMat(
"refMat", ndofSubcell, ndofSubcell),
237 ortMat(
"ortMat", ndofSubcell, ndofSubcell);
238 DynRankViewHostType tmpValues(
"tmpValues", numCellBasis, ndofSubcell);
239 for (ordinal_type i=0;i<ndofSubcell;++i) {
240 const ordinal_type ii = cellBasis.getDofOrdinal(subcellDim, subcellId, i);
241 for (ordinal_type j=0;j<ndofSubcell;++j)
242 for (ordinal_type k=0;k<cellDim;++k) {
243 refMat(i,j) += refValues(ii,j,k)*sideNormal(k)* ortJacobianDet;
244 ortMat(i,j) = (i==j);
250 Teuchos::LAPACK<ordinal_type,value_type> lapack;
251 ordinal_type info = 0;
252 Kokkos::View<value_type**,Kokkos::LayoutLeft,host_space_type> pivVec(
"pivVec", ndofSubcell, 1);
254 lapack.GESV(ndofSubcell, ndofSubcell,
257 (ordinal_type*)pivVec.data(),
263 std::stringstream ss;
264 ss <<
">>> ERROR (Intrepid::OrientationTools::getCoeffMatrix_HDIV): "
265 <<
"LAPACK return with error code: "
267 INTREPID2_TEST_FOR_EXCEPTION(
true, std::runtime_error, ss.str().c_str() );
272 const double eps = threshold();
273 for (ordinal_type i=0;i<ndofSubcell;++i)
274 for (ordinal_type j=0;j<ndofSubcell;++j) {
275 auto intOrtMat = std::round(ortMat(i,j));
276 ortMat(i,j) = (std::abs(ortMat(i,j) - std::round(ortMat(i,j))) < eps) ? intOrtMat : ortMat(i,j);
283 const Kokkos::pair<ordinal_type,ordinal_type> range(0, ndofSubcell);
284 Kokkos::deep_copy(Kokkos::subview(output, range, range),
285 Kokkos::subview(ortMat, range, range));