16 #ifndef __INTREPID2_CUBATURE_CONTROLVOLUME_SIDE_DEF_HPP__
17 #define __INTREPID2_CUBATURE_CONTROLVOLUME_SIDE_DEF_HPP__
21 template <
typename DT,
typename PT,
typename WT>
26 primaryCellTopo_ = cellTopology;
29 const auto spaceDim = primaryCellTopo_.getDimension();
32 subcvCellTopo_ = shards::CellTopology(shards::getCellTopologyData<shards::Quadrilateral<4> >());
35 subcvCellTopo_ = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >());
43 const auto maxNumNodesPerSide = 10;
44 const auto numSideNodeMaps = (spaceDim == 2 ? 1 : 2);
46 const ordinal_type sideOrd[2] = { 1, 5 };
47 Kokkos::View<ordinal_type**,Kokkos::HostSpace> sideNodeMapHost(
"CubatureControlVolumeSide::sideNodeMapHost",
48 numSideNodeMaps, maxNumNodesPerSide);
50 const auto sideDim = spaceDim - 1;
51 for (ordinal_type i=0;i<numSideNodeMaps;++i) {
52 const auto side = sideOrd[i];
53 sideNodeMapHost(i,0) = subcvCellTopo_.getNodeCount(sideDim, side);
54 for (ordinal_type j=0;j<sideNodeMapHost(i,0);++j)
55 sideNodeMapHost(i,j+1) = subcvCellTopo_.getNodeMap(sideDim, side, j);
57 sideNodeMap_ = Kokkos::create_mirror_view(
typename DT::memory_space(), sideNodeMapHost);
58 Kokkos::deep_copy(sideNodeMap_, sideNodeMapHost);
60 Kokkos::DynRankView<PT,DT> sideCenterLocal(
"CubatureControlVolumeSide::sideCenterLocal",
64 sidePoints_ = Kokkos::DynRankView<PT,DT>(
"CubatureControlVolumeSide::sidePoints", numSideNodeMaps, spaceDim);
65 for (ordinal_type i=0;i<numSideNodeMaps;++i) {
66 const auto sideRange = Kokkos::pair<ordinal_type,ordinal_type>(i, i+1);
67 auto sidePoint = Kokkos::subdynrankview(sidePoints_, sideRange, Kokkos::ALL());
76 template <
typename DT,
typename PT,
typename WT>
80 weightViewType cubWeights,
81 PointViewType cellCoords )
const {
82 #ifdef HAVE_INTREPID2_DEBUG
83 INTREPID2_TEST_FOR_EXCEPTION( cubPoints.rank() != 3, std::invalid_argument,
84 ">>> ERROR (CubatureControlVolumeSide): cubPoints must have rank 3 (C,P,D).");
85 INTREPID2_TEST_FOR_EXCEPTION( cubWeights.rank() != 3, std::invalid_argument,
86 ">>> ERROR (CubatureControlVolumeSide): cubWeights must have rank 2 (C,P,D).");
87 INTREPID2_TEST_FOR_EXCEPTION( cellCoords.rank() != 3, std::invalid_argument,
88 ">>> ERROR (CubatureControlVolumeSide): cellCoords must have rank 3 of (C,P,D).");
90 INTREPID2_TEST_FOR_EXCEPTION( cubPoints.extent(0) != cellCoords.extent(0) ||
91 cubPoints.extent(0) != cubWeights.extent(0), std::invalid_argument,
92 ">>> ERROR (CubatureControlVolumeSide): cubPoints, cubWeights and cellCoords dimension(0) are not consistent, numCells");
94 INTREPID2_TEST_FOR_EXCEPTION( cubPoints.extent(2) != cellCoords.extent(2) ||
95 cubPoints.extent(2) != cubWeights.extent(2) ||
96 static_cast<ordinal_type
>(cubPoints.extent(2)) != getDimension(), std::invalid_argument,
97 ">>> ERROR (CubatureControlVolumeSide): cubPoints, cellCoords, this->getDimension() are not consistent, spaceDim.");
99 typedef Kokkos::DynRankView<PT,DT> tempPointViewType;
102 const auto numCells = cellCoords.extent(0);
103 const auto numNodesPerCell = cellCoords.extent(1);
104 const auto spaceDim = cellCoords.extent(2);
106 const auto numNodesPerSubcv = subcvCellTopo_.getNodeCount();
107 tempPointViewType subcvCoords(
"CubatureControlVolumeSide::subcvCoords",
108 numCells, numNodesPerCell, numNodesPerSubcv, spaceDim);
113 const auto numSideNodeMaps = (spaceDim == 2 ? 1 : 2);
114 const ordinal_type sideOrd[2] = { 1, 5 };
116 Kokkos::pair<ordinal_type,ordinal_type> nodeRangePerSide[2]={};
119 switch (primaryCellTopo_.getKey()) {
120 case shards::Triangle<3>::key:
121 case shards::Quadrilateral<4>::key:
122 nodeRangePerSide[0].first = 0;
123 nodeRangePerSide[0].second = nodeRangePerSide[0].first + numNodesPerCell;
125 case shards::Hexahedron<8>::key:
126 nodeRangePerSide[0].first = 0;
127 nodeRangePerSide[0].second = nodeRangePerSide[0].first + numNodesPerCell;
128 nodeRangePerSide[1].first = numNodesPerCell;
129 nodeRangePerSide[1].second = nodeRangePerSide[1].first + 4;
131 case shards::Tetrahedron<4>::key:
132 nodeRangePerSide[0].first = 0;
133 nodeRangePerSide[0].second = nodeRangePerSide[0].first + numNodesPerCell;
134 nodeRangePerSide[1].first = 3;
135 nodeRangePerSide[1].second = nodeRangePerSide[1].first + 3;
139 for (ordinal_type i=0;i<numSideNodeMaps;++i) {
140 const auto numSubcvPoints = 1;
141 const auto numNodesPerThisSide = nodeRangePerSide[i].second - nodeRangePerSide[i].first;
142 tempPointViewType subcvJacobian(
"CubatureControlVolume::subcvJacobian",
143 numCells, numNodesPerThisSide, numSubcvPoints, spaceDim, spaceDim);
145 tempPointViewType subcvSideNormal(
"CubatureControlVolume::subcvSideNormal",
146 numCells, numNodesPerThisSide, numSubcvPoints, spaceDim);
149 const auto sideRange = Kokkos::pair<ordinal_type,ordinal_type>(i, i+1);
150 const auto sidePoint = Kokkos::subdynrankview(sidePoints_, sideRange, Kokkos::ALL());
152 for (
auto node=0;node<numNodesPerThisSide;++node) {
153 auto subcvJacobianNode = Kokkos::subdynrankview(subcvJacobian, Kokkos::ALL(), node, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
154 auto subcvCoordsNode = Kokkos::subdynrankview(subcvCoords, Kokkos::ALL(), node, Kokkos::ALL(), Kokkos::ALL());
155 auto subcvSideNormalNode = Kokkos::subdynrankview(subcvSideNormal, Kokkos::ALL(), node, Kokkos::ALL(), Kokkos::ALL());
168 typedef Kokkos::View<ordinal_type*,DT> mapViewType;
169 const auto sideNodeMap = Kokkos::subview(sideNodeMap_, i, Kokkos::ALL());
173 const auto loopSize = numCells;
174 Kokkos::RangePolicy<typename DT::execution_space,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
178 auto cubPointsThisSide = Kokkos::subdynrankview(cubPoints, Kokkos::ALL(), nodeRangePerSide[i], Kokkos::ALL());
179 auto cubWeightsThisSide = Kokkos::subdynrankview(cubWeights, Kokkos::ALL(), nodeRangePerSide[i], Kokkos::ALL());
181 Kokkos::parallel_for( policy, FunctorType(cubPointsThisSide,
virtual void getCubature(PointViewType cubPoints, weightViewType cubWeights, PointViewType cellCoords) const override
Returns cubature points and weights (return arrays must be pre-sized/pre-allocated).
CubatureControlVolumeSide(const shards::CellTopology cellTopology)