15 #ifndef __INTREPID2_ORIENTATIONTOOLS_DEF_MODIFY_POINTS_HPP__ 
   16 #define __INTREPID2_ORIENTATIONTOOLS_DEF_MODIFY_POINTS_HPP__ 
   19 #if defined (__clang__) && !defined (__INTEL_COMPILER) 
   20 #pragma clang system_header 
   32     KOKKOS_INLINE_FUNCTION
 
   37                          const ordinal_type ort) {
 
   38 #ifdef HAVE_INTREPID2_DEBUG 
   39       INTREPID2_TEST_FOR_ABORT( !( -1.0 <= pt && pt <= 1.0 ), 
 
   40                                 ">>> ERROR (Intrepid::OrientationTools::getModifiedLinePoint): " 
   41                                 "Input point is out of range [-1, 1].");
 
   45       case 0: ot =  pt; 
break;
 
   46       case 1: ot = -pt; 
break;
 
   48         INTREPID2_TEST_FOR_ABORT( 
true, 
 
   49                                   ">>> ERROR (Intrepid2::OrientationTools::getModifiedLinePoint): " 
   50                                   "Orientation is invalid (0--1)." );
 
   54     template<
typename JacobianViewType>
 
   55     KOKKOS_INLINE_FUNCTION
 
   59 #ifdef HAVE_INTREPID2_DEBUG 
   60       INTREPID2_TEST_FOR_ABORT( ort <0 || ort >1,
 
   61                                 ">>> ERROR (Intrepid2::OrientationTools::getLineJacobian): " \
 
   62                                 "Orientation is invalid (0--1)." );
 
   65       ordinal_type jac[2] = {  1,  -1 };
 
   67       jacobian(0,0) = jac[ort];
 
   71     KOKKOS_INLINE_FUNCTION
 
   78                              const ordinal_type ort) {
 
   79       const VT lambda[3] = { 1.0 - pt0 - pt1,
 
   83 #ifdef HAVE_INTREPID2_DEBUG 
   86       INTREPID2_TEST_FOR_ABORT( !( -eps <= lambda[0] && lambda[0] <= 1.0+eps ),
 
   87                                 ">>> ERROR (Intrepid::OrientationTools::getModifiedTrianglePoint): " \
 
   88                                 "Computed bicentric coordinate (lamba[0]) is out of range [0, 1].");
 
   90       INTREPID2_TEST_FOR_ABORT( !( -eps <= lambda[1] && lambda[1] <= 1.0+eps ),
 
   91                                 ">>> ERROR (Intrepid::OrientationTools::getModifiedTrianglePoint): " \
 
   92                                 "Computed bicentric coordinate (lamba[1]) is out of range [0, 1].");
 
   94       INTREPID2_TEST_FOR_ABORT( !( -eps <= lambda[2] && lambda[2] <= 1.0+eps ),
 
   95                                 ">>> ERROR (Intrepid::OrientationTools::getModifiedTrianglePoint): " 
   96                                 "Computed bicentric coordinate (lamba[2]) is out of range [0, 1].");
 
  100       case 0: ot0 = lambda[1]; ot1 = lambda[2]; 
break;
 
  101       case 1: ot0 = lambda[0]; ot1 = lambda[1]; 
break;
 
  102       case 2: ot0 = lambda[2]; ot1 = lambda[0]; 
break;
 
  104       case 3: ot0 = lambda[2]; ot1 = lambda[1]; 
break;
 
  105       case 4: ot0 = lambda[0]; ot1 = lambda[2]; 
break;
 
  106       case 5: ot0 = lambda[1]; ot1 = lambda[0]; 
break;
 
  108         INTREPID2_TEST_FOR_ABORT( 
true, 
 
  109                                   ">>> ERROR (Intrepid2::OrientationTools::getModifiedTrianglePoint): " \
 
  110                                   "Orientation is invalid (0--5)." );
 
  114     template<
typename JacobianViewType>
 
  115     KOKKOS_INLINE_FUNCTION
 
  119 #ifdef HAVE_INTREPID2_DEBUG 
  120       INTREPID2_TEST_FOR_ABORT( ort <0 || ort >5,
 
  121                                 ">>> ERROR (Intrepid2::OrientationTools::getTriangleJacobian): " \
 
  122                                 "Orientation is invalid (0--5)." );
 
  125       ordinal_type jac[6][2][2] = { { {  1,  0 },
 
  138       jacobian(0,0) = jac[ort][0][0];
 
  139       jacobian(0,1) = jac[ort][0][1];
 
  140       jacobian(1,0) = jac[ort][1][0];
 
  141       jacobian(1,1) = jac[ort][1][1];
 
  144     template<
typename VT>
 
  145     KOKKOS_INLINE_FUNCTION
 
  152                                   const ordinal_type ort) {
 
  153 #ifdef HAVE_INTREPID2_DEBUG 
  154       INTREPID2_TEST_FOR_ABORT( !( -1.0 <= pt0 && pt0 <= 1.0 ), 
 
  155                                 ">>> ERROR (Intrepid::OrientationTools::getModifiedQuadrilateralPoint): " \
 
  156                                 "Input point(0) is out of range [-1, 1].");
 
  158       INTREPID2_TEST_FOR_ABORT( !( -1.0 <= pt1 && pt1 <= 1.0 ), 
 
  159                                 ">>> ERROR (Intrepid::OrientationTools::getModifiedQuadrilateralPoint): " \
 
  160                                 "Input point(1) is out of range [-1, 1].");
 
  163       const VT lambda[2][2] = { { pt0, -pt0 },
 
  167       case 0: ot0 = lambda[0][0]; ot1 = lambda[1][0]; 
break;
 
  168       case 1: ot0 = lambda[1][1]; ot1 = lambda[0][0]; 
break;
 
  169       case 2: ot0 = lambda[0][1]; ot1 = lambda[1][1]; 
break;
 
  170       case 3: ot0 = lambda[1][0]; ot1 = lambda[0][1]; 
break;
 
  172       case 4: ot0 = lambda[1][0]; ot1 = lambda[0][0]; 
break;
 
  173       case 5: ot0 = lambda[0][1]; ot1 = lambda[1][0]; 
break;
 
  174       case 6: ot0 = lambda[1][1]; ot1 = lambda[0][1]; 
break;
 
  175       case 7: ot0 = lambda[0][0]; ot1 = lambda[1][1]; 
break;
 
  177         INTREPID2_TEST_FOR_ABORT( 
true, 
 
  178                                   ">>> ERROR (Intrepid2::OrientationTools::getModifiedQuadrilateralPoint): " \
 
  179                                   "Orientation is invalid (0--7)." );
 
  183     template<
typename JacobianViewType>
 
  184     KOKKOS_INLINE_FUNCTION
 
  188 #ifdef HAVE_INTREPID2_DEBUG 
  189       INTREPID2_TEST_FOR_ABORT( ort <0 || ort >7,
 
  190                                 ">>> ERROR (Intrepid2::OrientationTools::getQuadrilateralJacobian): " \
 
  191                                 "Orientation is invalid (0--7)." );
 
  194       ordinal_type jac[8][2][2] = { { {  1,  0 },
 
  211       jacobian(0,0) = jac[ort][0][0];
 
  212       jacobian(0,1) = jac[ort][0][1];
 
  213       jacobian(1,0) = jac[ort][1][0];
 
  214       jacobian(1,1) = jac[ort][1][1];
 
  217     template<
typename outPointViewType,
 
  218              typename refPointViewType>
 
  223                            const refPointViewType refPoints,
 
  224                            const shards::CellTopology cellTopo,
 
  225                            const ordinal_type cellOrt) {
 
  226 #ifdef HAVE_INTREPID2_DEBUG 
  228         const auto cellDim = cellTopo.getDimension();
 
  229         INTREPID2_TEST_FOR_EXCEPTION( !( (1 <= cellDim) && (cellDim <= 2 ) ), std::invalid_argument,
 
  230                                       ">>> ERROR (Intrepid::OrientationTools::mapToModifiedReference): " \
 
  231                                       "Method defined only for 1 and 2-dimensional subcells.");
 
  233         INTREPID2_TEST_FOR_EXCEPTION( !( outPoints.extent(0) == refPoints.extent(0) ), std::invalid_argument,
 
  234                                       ">>> ERROR (Intrepid::OrientationTools::mapToModifiedReference): " \
 
  235                                       "Size of input and output point arrays does not match each other.");
 
  243     template<
typename outPointViewType,
 
  244              typename refPointViewType>
 
  245     KOKKOS_INLINE_FUNCTION
 
  249                            const refPointViewType refPoints,
 
  250                            const unsigned cellTopoKey,
 
  251                            const ordinal_type cellOrt) {
 
  253       const ordinal_type numPts = outPoints.extent(0);
 
  254       switch (cellTopoKey) {
 
  255       case shards::Line<>::key : {
 
  256         for (ordinal_type pt=0;pt<numPts;++pt)
 
  262       case shards::Triangle<>::key : {
 
  263         for (ordinal_type pt=0;pt<numPts;++pt)
 
  265                                    refPoints(pt, 0), refPoints(pt, 1),
 
  269       case shards::Quadrilateral<>::key : {
 
  270         for (ordinal_type pt=0;pt<numPts;++pt)
 
  272                                         refPoints(pt, 0), refPoints(pt, 1),
 
  277         INTREPID2_TEST_FOR_ABORT( 
true,
 
  278                                     ">>> ERROR (Intrepid2::OrientationTools::mapToModifiedReference): " \
 
  279                                     "Invalid cell topology key." );
 
  286     template<
typename outPo
intViewType>
 
  291                            const shards::CellTopology cellTopo,
 
  292                            const ordinal_type cellOrt) {
 
  293 #ifdef HAVE_INTREPID2_DEBUG 
  295         const auto cellDim = cellTopo.getDimension();
 
  296         INTREPID2_TEST_FOR_EXCEPTION( !( (1 <= cellDim) && (cellDim <= 2 ) ), std::invalid_argument,
 
  297                                       ">>> ERROR (Intrepid::OrientationTools::getJacobianOfOrientationMap): " \
 
  298                                       "Method defined only for 1 and 2-dimensional subcells.");
 
  300         INTREPID2_TEST_FOR_ABORT( jacobian.rank() != 2,
 
  301                                   ">>> ERROR (Intrepid2::OrientationTools::getJacobianOfOrientationMap): " \
 
  302                                   "Jacobian should have rank 2" );
 
  304         INTREPID2_TEST_FOR_EXCEPTION( ((jacobian.extent(0) != cellDim) || (jacobian.extent(1) != cellDim)), std::invalid_argument,
 
  305                                       ">>> ERROR (Intrepid::OrientationTools::getJacobianOfOrientationMap): " \
 
  306                                       "Size of jacobian is not compatible with cell topology.");
 
  313     template<
typename outPo
intViewType>
 
  314     KOKKOS_INLINE_FUNCTION
 
  318                            const unsigned cellTopoKey,
 
  319                            const ordinal_type cellOrt) {
 
  320       switch (cellTopoKey) {
 
  321       case shards::Line<>::key :
 
  324       case shards::Triangle<>::key :
 
  327       case shards::Quadrilateral<>::key :
 
  331         INTREPID2_TEST_FOR_ABORT( 
true,
 
  332                                     ">>> ERROR (Intrepid2::OrientationTools::mapToModifiedReference): " \
 
  333                                     "Invalid cell topology key." );
 
  340     template<
typename TanViewType, 
typename ParamViewType>
 
  341     KOKKOS_INLINE_FUNCTION
 
  344                                         const ParamViewType subcellParametrization,
 
  345                                         const unsigned subcellTopoKey,
 
  346                                         const ordinal_type subcellOrd,
 
  347                                         const ordinal_type ort){
 
  348       typename ParamViewType::non_const_value_type data[4];
 
  349       typename ParamViewType::non_const_type jac(data, 2, 2);
 
  351       ordinal_type cellDim = subcellParametrization.extent(1);
 
  352       ordinal_type numTans = subcellParametrization.extent(2)-1;
 
  355       for(ordinal_type d=0; d<cellDim; ++d)
 
  356         for(ordinal_type j=0; j<numTans; ++j) {
 
  358           for(ordinal_type k=0; k<numTans; ++k)
 
  359             tangents(j,d) += subcellParametrization(subcellOrd,d,k+1)*jac(k,j);
 
  364     template<
typename TanNormViewType, 
typename ParamViewType>
 
  365     KOKKOS_INLINE_FUNCTION
 
  368                                         const ParamViewType subcellParametrization,
 
  369                                         const unsigned subcellTopoKey,
 
  370                                         const ordinal_type subcellOrd,
 
  371                                         const ordinal_type ort){
 
  372       ordinal_type cellDim = subcellParametrization.extent(1);
 
  373       auto range = Kokkos::pair<ordinal_type, ordinal_type>(0,cellDim-1);
 
  374       auto tangents = Kokkos::subview(tangentsAndNormal,range,Kokkos::ALL());
 
  379         tangentsAndNormal(1,0) = tangents(0,1);
 
  380         tangentsAndNormal(1,1) = -tangents(0,0);
 
  383         tangentsAndNormal(2,0) = tangents(0,1)*tangents(1,2) - tangents(0,2)*tangents(1,1);
 
  384         tangentsAndNormal(2,1) = tangents(0,2)*tangents(1,0) - tangents(0,0)*tangents(1,2);
 
  385         tangentsAndNormal(2,2) = tangents(0,0)*tangents(1,1) - tangents(0,1)*tangents(1,0);
 
  389     template<
typename coordsViewType, 
typename subcellCoordsViewType, 
typename ParamViewType>
 
  390     KOKKOS_INLINE_FUNCTION
 
  393                                         const subcellCoordsViewType subcellCoords,
 
  394                                         const ParamViewType subcellParametrization,
 
  395                                         const unsigned subcellTopoKey,
 
  396                                         const ordinal_type subcellOrd,
 
  397                                         const ordinal_type ort){
 
  399       ordinal_type cellDim = subcellParametrization.extent(1);
 
  400       ordinal_type numCoords = subcellCoords.extent(0);
 
  401       ordinal_type subcellDim = subcellCoords.extent(1);
 
  402       auto range = Kokkos::pair<ordinal_type, ordinal_type>(0,subcellDim);
 
  403       auto modSubcellCoords = Kokkos::subview(cellCoords, Kokkos::ALL(),range);
 
  405       typename coordsViewType::value_type subCoord[2];
 
  407       for(ordinal_type i=0; i<numCoords; ++i) {
 
  408         for(ordinal_type d=0; d<subcellDim; ++d)
 
  409           subCoord[d] = modSubcellCoords(i,d);
 
  411         for(ordinal_type d=0; d<cellDim; ++d) {
 
  412           cellCoords(i,d) = subcellParametrization(subcellOrd, d, 0);
 
  413           for(ordinal_type k=0; k<subcellDim; ++k)
 
  414             cellCoords(i,d) += subcellParametrization(subcellOrd, d, k+1)*subCoord[k];