49 #ifndef __INTREPID2_CELLTOOLS_DEF_CONTROL_VOLUME_HPP__ 
   50 #define __INTREPID2_CELLTOOLS_DEF_CONTROL_VOLUME_HPP__ 
   53 #if defined (__clang__) && !defined (__INTEL_COMPILER) 
   54 #pragma clang system_header 
   65   namespace FunctorCellTools {
 
   71     template<
typename centerViewType, 
typename vertViewType>
 
   72     KOKKOS_INLINE_FUNCTION
 
   73     void getBaryCenter(       centerViewType center,
 
   74                         const vertViewType verts) {
 
   76       const ordinal_type nvert = verts.extent(0);
 
   77       const ordinal_type dim   = verts.extent(1);
 
   83         typename centerViewType::value_type area = 0;
 
   84         for (ordinal_type i=0;i<nvert;++i) {
 
   85           const ordinal_type j = (i + 1)%nvert;
 
   86           const auto scale = verts(i,0)*verts(j,1) - verts(j,0)*verts(i,1);
 
   87           center(0) += (verts(i,0) + verts(j,0))*scale;
 
   88           center(1) += (verts(i,1) + verts(j,1))*scale;
 
   91         center(0) /= (6.0*area);
 
   92         center(1) /= (6.0*area);
 
   99         for (ordinal_type j=0;j<dim;++j) {
 
  101           for (ordinal_type i=0;i<nvert;++i) 
 
  102             center(j) += verts(i,j);
 
  110     template<
typename m
idPo
intViewType, 
typename nodeMapViewType, 
typename vertViewType>
 
  111     KOKKOS_INLINE_FUNCTION      
 
  112     void getMidPoints(       midPointViewType midpts,
 
  113                        const nodeMapViewType map,
 
  114                        const vertViewType verts) {
 
  115       const ordinal_type npts = map.extent(0);
 
  116       const ordinal_type dim  = verts.extent(1);
 
  118       for (ordinal_type i=0;i<npts;++i) {
 
  120         const ordinal_type nvert_per_subcell = map(i, 0);
 
  121         for (ordinal_type j=0;j<dim;++j) {
 
  123           for (ordinal_type k=1;k<=nvert_per_subcell;++k)
 
  124             midpts(i,j) += verts(map(i,k),j);
 
  125           midpts(i,j) /= nvert_per_subcell;
 
  130     template<
typename subcvCoordViewType,
 
  131              typename cellCoordViewType,
 
  132              typename mapViewType>
 
  137             subcvCoordViewType _subcvCoords;
 
  138       const cellCoordViewType  _cellCoords;
 
  139       const mapViewType        _edgeMap;
 
  141       KOKKOS_INLINE_FUNCTION
 
  143                                   cellCoordViewType  cellCoords_,
 
  144                                   mapViewType edgeMap_ )
 
  145         : _subcvCoords(subcvCoords_), _cellCoords(cellCoords_), _edgeMap(edgeMap_) {}
 
  147       KOKKOS_INLINE_FUNCTION
 
  148       void operator()(
const ordinal_type cell)
 const {
 
  150         const auto verts = Kokkos::subdynrankview( _cellCoords, cell, 
 
  151                                                    Kokkos::ALL(), Kokkos::ALL() );
 
  152         const ordinal_type nvert = verts.extent(0);
 
  153         const ordinal_type dim   = verts.extent(1);
 
  156         auto cvCoords = Kokkos::subdynrankview( _subcvCoords, cell, 
 
  157                                                 Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL() );
 
  160         typedef typename subcvCoordViewType::value_type value_type;
 
  161         value_type buf_center[2], buf_midpts[4*2];
 
  162         Kokkos::View<value_type*,Kokkos::Impl::ActiveExecutionMemorySpace> center(buf_center, 2);
 
  163         Kokkos::View<value_type**,Kokkos::Impl::ActiveExecutionMemorySpace> midpts(buf_midpts, 4, 2);
 
  165         getBaryCenter(center, verts);
 
  166         getMidPoints(midpts, _edgeMap, verts);
 
  168         for (ordinal_type i=0;i<nvert;++i) {
 
  169           for (ordinal_type j=0;j<dim;++j) {
 
  171             cvCoords(i, 0, j) = verts(i, j);
 
  172             cvCoords(i, 1, j) = midpts(i, j);
 
  173             cvCoords(i, 2, j) = center(j);
 
  174             cvCoords(i, 3, j) = midpts((i+nvert-1)%nvert, j);
 
  180     template<
typename subcvCoordViewType,
 
  181              typename cellCoordViewType,
 
  182              typename mapViewType>
 
  187             subcvCoordViewType _subcvCoords;
 
  188       const cellCoordViewType  _cellCoords;
 
  189       const mapViewType        _edgeMap, _faceMap;
 
  191       KOKKOS_INLINE_FUNCTION
 
  193                                    cellCoordViewType  cellCoords_,
 
  194                                    mapViewType edgeMap_,
 
  195                                    mapViewType faceMap_ )
 
  196         : _subcvCoords(subcvCoords_), _cellCoords(cellCoords_), _edgeMap(edgeMap_), _faceMap(faceMap_) {}
 
  198       KOKKOS_INLINE_FUNCTION
 
  199       void operator()(
const ordinal_type cell)
 const {
 
  201         const auto verts = Kokkos::subdynrankview( _cellCoords, cell, 
 
  202                                                    Kokkos::ALL(), Kokkos::ALL() );
 
  204         const ordinal_type dim   = verts.extent(1);
 
  207         auto cvCoords = Kokkos::subdynrankview( _subcvCoords, cell, 
 
  208                                                 Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL() );
 
  211         typedef typename subcvCoordViewType::value_type value_type;
 
  212         value_type buf_center[3], buf_edge_midpts[12*3], buf_face_midpts[6*3];
 
  213         Kokkos::View<value_type*,Kokkos::Impl::ActiveExecutionMemorySpace> center(buf_center, 3);
 
  214         Kokkos::View<value_type**,Kokkos::Impl::ActiveExecutionMemorySpace> edge_midpts(buf_edge_midpts, 12, 3);
 
  215         Kokkos::View<value_type**,Kokkos::Impl::ActiveExecutionMemorySpace> face_midpts(buf_face_midpts,  6, 3);
 
  217         getBaryCenter(center, verts);
 
  218         getMidPoints(edge_midpts, _edgeMap, verts);
 
  219         getMidPoints(face_midpts, _faceMap, verts);
 
  221         for (ordinal_type i=0;i<4;++i) {
 
  222           const ordinal_type ii = (i+4-1)%4;
 
  223           for (ordinal_type j=0;j<dim;++j) {
 
  227             cvCoords(i,  0,j) = verts(i,  j);
 
  228             cvCoords(i+4,4,j) = verts(i+4,j);
 
  232             cvCoords(i,  1,j) = edge_midpts(i,  j);
 
  233             cvCoords(i+4,5,j) = edge_midpts(i+4,j);
 
  237             cvCoords(i,  2,j) = face_midpts(4,j);
 
  238             cvCoords(i+4,6,j) = face_midpts(5,j);
 
  242             cvCoords(i,  3,j) = edge_midpts(ii,  j);
 
  243             cvCoords(i+4,7,j) = edge_midpts(ii+4,j);
 
  247             cvCoords(i,  4,j) = edge_midpts(i+8,j);
 
  248             cvCoords(i+4,0,j) = edge_midpts(i+8,j);
 
  252             cvCoords(i,  5,j) = face_midpts(i,j);
 
  253             cvCoords(i+4,1,j) = face_midpts(i,j);
 
  257             cvCoords(i,  6,j) = center(j);
 
  258             cvCoords(i+4,2,j) = center(j);
 
  262             cvCoords(i,  7,j) = face_midpts(ii,j);
 
  263             cvCoords(i+4,3,j) = face_midpts(ii,j);
 
  270     template<
typename subcvCoordViewType,
 
  271              typename cellCoordViewType,
 
  272              typename mapViewType>
 
  277             subcvCoordViewType _subcvCoords;
 
  278       const cellCoordViewType  _cellCoords;
 
  279       const mapViewType        _edgeMap, _faceMap;
 
  281       KOKKOS_INLINE_FUNCTION
 
  283                                     cellCoordViewType  cellCoords_,
 
  284                                     mapViewType edgeMap_,
 
  285                                     mapViewType faceMap_ )
 
  286         : _subcvCoords(subcvCoords_), _cellCoords(cellCoords_), _edgeMap(edgeMap_), _faceMap(faceMap_) {}
 
  288       KOKKOS_INLINE_FUNCTION
 
  289       void operator()(
const ordinal_type cell)
 const {
 
  291         const auto verts = Kokkos::subdynrankview( _cellCoords, cell, 
 
  292                                                    Kokkos::ALL(), Kokkos::ALL() );
 
  294         const ordinal_type dim   = verts.extent(1);
 
  297         auto cvCoords = Kokkos::subdynrankview( _subcvCoords, cell, 
 
  298                                                 Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL() );
 
  301         typedef typename subcvCoordViewType::value_type value_type;
 
  302         value_type buf_center[3], buf_edge_midpts[6*3], buf_face_midpts[4*3];
 
  303         Kokkos::View<value_type*,Kokkos::Impl::ActiveExecutionMemorySpace> center(buf_center, 3);
 
  304         Kokkos::View<value_type**,Kokkos::Impl::ActiveExecutionMemorySpace> edge_midpts(buf_edge_midpts,  6, 3);
 
  305         Kokkos::View<value_type**,Kokkos::Impl::ActiveExecutionMemorySpace> face_midpts(buf_face_midpts,  4, 3);
 
  307         getBaryCenter(center, verts);
 
  308         getMidPoints(edge_midpts, _edgeMap, verts);
 
  309         getMidPoints(face_midpts, _faceMap, verts);
 
  311         for (ordinal_type i=0;i<3;++i) {
 
  312           const ordinal_type ii = (i+3-1)%3;
 
  313           for (ordinal_type j=0;j<dim;++j) {
 
  315             cvCoords(i,0,j) = verts(i,j);
 
  318             cvCoords(i,1,j) = edge_midpts(i,j);
 
  321             cvCoords(i,2,j) = face_midpts(3,j);
 
  324             cvCoords(i,3,j) = edge_midpts(ii,j);
 
  327             cvCoords(i,4,j) = edge_midpts(i+3,j);
 
  330             cvCoords(i,5,j) = face_midpts(i,j);
 
  333             cvCoords(i,6,j) = center(j);
 
  336             cvCoords(i,7,j) = face_midpts(ii,j);
 
  340         for (ordinal_type j=0;j<dim;++j) {
 
  343           cvCoords(3,0,j) = verts(3,j);
 
  346           cvCoords(3,1,j) = edge_midpts(3,j);
 
  349           cvCoords(3,2,j) = face_midpts(2,j);
 
  352           cvCoords(3,3,j) = edge_midpts(5,j);
 
  355           cvCoords(3,4,j) = edge_midpts(4,j);
 
  358           cvCoords(3,5,j) = face_midpts(0,j);
 
  361           cvCoords(3,6,j) = center(j);
 
  364           cvCoords(3,7,j) = face_midpts(1,j);
 
  371   template<
typename SpT>
 
  372   template<
typename subcvCoordValueType, 
class ...subcvCoordProperties,
 
  373            typename cellCoordValueType,  
class ...cellCoordProperties>
 
  376   getSubcvCoords(       Kokkos::DynRankView<subcvCoordValueType,subcvCoordProperties...> subcvCoords,
 
  377                   const Kokkos::DynRankView<cellCoordValueType,cellCoordProperties...>   cellCoords,
 
  378                   const shards::CellTopology primaryCell ) {
 
  379 #ifdef HAVE_INTREPID2_DEBUG 
  380     INTREPID2_TEST_FOR_EXCEPTION( !hasReferenceCell(primaryCell), std::invalid_argument,
 
  381                                   ">>> ERROR (Intrepid2::CellTools::getSubcvCoords): the primary cell must have a reference cell." );
 
  383     INTREPID2_TEST_FOR_EXCEPTION( cellCoords.extent(1) != primaryCell.getVertexCount(), std::invalid_argument,
 
  384                                   ">>> ERROR (Intrepid2::CellTools::getSubcvCoords): cell coords dimension(1) does not match to # of vertices of the cell." );
 
  386     INTREPID2_TEST_FOR_EXCEPTION( cellCoords.extent(2) != primaryCell.getDimension(), std::invalid_argument,
 
  387                                   ">>> ERROR (Intrepid2::CellTools::getSubcvCoords): cell coords dimension(2) does not match to the dimension of the cell." );
 
  391     const ordinal_type numCells = cellCoords.extent(0);
 
  393     const ordinal_type spaceDim = cellCoords.extent(2);
 
  396     const ordinal_type numEdge = primaryCell.getSubcellCount(1);
 
  397     Kokkos::View<ordinal_type**,Kokkos::LayoutRight,Kokkos::HostSpace> edgeMapHost(
"CellTools::getSubcvCoords::edgeMapHost", numEdge, 3);
 
  398     for (ordinal_type i=0;i<numEdge;++i) {
 
  399       edgeMapHost(i,0) = primaryCell.getNodeCount(1, i);
 
  400       for (ordinal_type j=0;j<edgeMapHost(i,0);++j)
 
  401         edgeMapHost(i,j+1) = primaryCell.getNodeMap(1, i, j);
 
  404     const ordinal_type numFace = (spaceDim > 2 ? primaryCell.getSubcellCount(2) : 0);
 
  405     Kokkos::View<ordinal_type**,Kokkos::LayoutRight,Kokkos::HostSpace> faceMapHost(
"CellTools::getSubcvCoords::faceMapHost", numFace, 5);
 
  406     for (ordinal_type i=0;i<numFace;++i) {
 
  407       faceMapHost(i,0) = primaryCell.getNodeCount(2, i);
 
  408       for (ordinal_type j=0;j<faceMapHost(i,0);++j)
 
  409         faceMapHost(i,j+1) = primaryCell.getNodeMap(2, i, j);
 
  413     auto edgeMap = Kokkos::create_mirror_view(
typename SpT::memory_space(), edgeMapHost);
 
  414     auto faceMap = Kokkos::create_mirror_view(
typename SpT::memory_space(), faceMapHost);
 
  416     Kokkos::deep_copy(edgeMap, edgeMapHost);
 
  417     Kokkos::deep_copy(faceMap, faceMapHost);
 
  420     typedef Kokkos::DynRankView<subcvCoordValueType,subcvCoordProperties...> subcvCoordViewType;
 
  421     typedef Kokkos::DynRankView<cellCoordValueType,cellCoordProperties...>   cellCoordViewType;
 
  422     typedef Kokkos::View<ordinal_type**,Kokkos::LayoutRight,SpT>             mapViewType;
 
  424     typedef typename ExecSpace<typename subcvCoordViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
 
  426     const auto loopSize = numCells;
 
  427     Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
 
  429     switch (primaryCell.getKey()) {
 
  430     case shards::Triangle<3>::key:
 
  431     case shards::Quadrilateral<4>::key: {
 
  434       Kokkos::parallel_for( policy, FunctorType(subcvCoords, cellCoords, edgeMap) );
 
  437     case shards::Hexahedron<8>::key: {
 
  439       Kokkos::parallel_for( policy, FunctorType(subcvCoords, cellCoords, edgeMap, faceMap) );
 
  442     case shards::Tetrahedron<4>::key: {
 
  444       Kokkos::parallel_for( policy, FunctorType(subcvCoords, cellCoords, edgeMap, faceMap) );
 
  448       INTREPID2_TEST_FOR_EXCEPTION( 
true, std::invalid_argument,
 
  449                                     ">>> ERROR (Intrepid2::CellTools::getSubcvCoords: the give cell topology is not supported.");