Intrepid2
Intrepid2_CubatureControlVolumeSideDef.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Intrepid2 Package
4//
5// Copyright 2007 NTESS and the Intrepid2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
16#ifndef __INTREPID2_CUBATURE_CONTROLVOLUME_SIDE_DEF_HPP__
17#define __INTREPID2_CUBATURE_CONTROLVOLUME_SIDE_DEF_HPP__
18
19namespace Intrepid2 {
20
21 template <typename DT, typename PT, typename WT>
23 CubatureControlVolumeSide(const shards::CellTopology cellTopology) {
24
25 // define primary cell topology with given one
26 primaryCellTopo_ = cellTopology;
27
28 // subcell is defined either hex or quad according to dimension
29 const auto spaceDim = primaryCellTopo_.getDimension();
30 switch (spaceDim) {
31 case 2:
32 subcvCellTopo_ = shards::CellTopology(shards::getCellTopologyData<shards::Quadrilateral<4> >());
33 break;
34 case 3:
35 subcvCellTopo_ = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >());
36 break;
37 }
38
39 // computation order is always one;
40 degree_ = 1;
41
42 // precompute reference side points that are repeatedly used in get cubature
43 const auto maxNumNodesPerSide = 10;
44 const auto numSideNodeMaps = (spaceDim == 2 ? 1 : 2);
45
46 const ordinal_type sideOrd[2] = { 1, 5 };
47 Kokkos::View<ordinal_type**,Kokkos::HostSpace> sideNodeMapHost("CubatureControlVolumeSide::sideNodeMapHost",
48 numSideNodeMaps, maxNumNodesPerSide);
49
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);
56 }
57 sideNodeMap_ = Kokkos::create_mirror_view(typename DT::memory_space(), sideNodeMapHost);
58 Kokkos::deep_copy(sideNodeMap_, sideNodeMapHost);
59
60 Kokkos::DynRankView<PT,DT> sideCenterLocal("CubatureControlVolumeSide::sideCenterLocal",
61 1, sideDim);
62
63 // map to reference subcell function relies on uvm; some utility functions in cell tools still need uvm
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());
69 sideCenterLocal,
70 sideDim,
71 sideOrd[i],
72 subcvCellTopo_);
73 }
74 }
75
76 template <typename DT, typename PT, typename WT>
77 void
79 getCubature( PointViewType cubPoints,
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).");
89
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");
93
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.");
98#endif
99 typedef Kokkos::DynRankView<PT,DT> tempPointViewType;
100
101 // get array dimensions
102 const auto numCells = cellCoords.extent(0);
103 const auto numNodesPerCell = cellCoords.extent(1);
104 const auto spaceDim = cellCoords.extent(2);
105
106 const auto numNodesPerSubcv = subcvCellTopo_.getNodeCount();
107 tempPointViewType subcvCoords("CubatureControlVolumeSide::subcvCoords",
108 numCells, numNodesPerCell, numNodesPerSubcv, spaceDim);
110 cellCoords,
111 primaryCellTopo_);
112
113 const auto numSideNodeMaps = (spaceDim == 2 ? 1 : 2);
114 const ordinal_type sideOrd[2] = { 1, 5 };
115
116 Kokkos::pair<ordinal_type,ordinal_type> nodeRangePerSide[2]={};
117
118 // the second rage is cell specific to handle remained sides
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;
124 break;
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;
130 break;
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;
136 break;
137 }
138
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);
144
145 tempPointViewType subcvSideNormal("CubatureControlVolume::subcvSideNormal",
146 numCells, numNodesPerThisSide, numSubcvPoints, spaceDim);
147
148 // numNodesPerCell is maximum 8; this repeated run is necessary because of cell tools input consideration
149 const auto sideRange = Kokkos::pair<ordinal_type,ordinal_type>(i, i+1);
150 const auto sidePoint = Kokkos::subdynrankview(sidePoints_, sideRange, Kokkos::ALL());
151
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());
156
157 CellTools<DT>::setJacobian(subcvJacobianNode, // C, P, D, D
158 sidePoint, // P, D
159 subcvCoordsNode, // C, N, D
160 subcvCellTopo_);
161
162 CellTools<DT>::getPhysicalSideNormals(subcvSideNormalNode, // C, P, D
163 subcvJacobianNode,
164 sideOrd[i],
165 subcvCellTopo_); // C, P, D, D
166 }
167
168 typedef Kokkos::View<ordinal_type*,DT> mapViewType;
169 const auto sideNodeMap = Kokkos::subview(sideNodeMap_, i, Kokkos::ALL());
170
171 //typedef typename ExecSpace<typename PointViewType::execution_space,DT>::ExecSpaceType ExecSpaceType;
172
173 const auto loopSize = numCells;
174 Kokkos::RangePolicy<typename DT::execution_space,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
175
177
178 auto cubPointsThisSide = Kokkos::subdynrankview(cubPoints, Kokkos::ALL(), nodeRangePerSide[i], Kokkos::ALL());
179 auto cubWeightsThisSide = Kokkos::subdynrankview(cubWeights, Kokkos::ALL(), nodeRangePerSide[i], Kokkos::ALL());
180
181 Kokkos::parallel_for( policy, FunctorType(cubPointsThisSide,
182 cubWeightsThisSide,
183 subcvCoords,
184 subcvSideNormal,
185 sideNodeMap) );
186 }
187 }
188
189}
190
191#endif
192
static void getSubcvCoords(Kokkos::DynRankView< subcvCoordValueType, subcvCoordProperties... > subcvCoords, const Kokkos::DynRankView< cellCoordValueType, cellCoordProperties... > cellCoords, const shards::CellTopology primaryCell)
Computes coordinates of sub-control volumes in each primary cell.
static void mapToReferenceSubcell(refSubcellViewType refSubcellPoints, const paramPointViewType paramPoints, const ordinal_type subcellDim, const ordinal_type subcellOrd, const shards::CellTopology parentCell)
Computes parameterization maps of 1- and 2-subcells of reference cells.
static void setJacobian(JacobianViewType jacobian, const PointViewType points, const WorksetType worksetCell, const Teuchos::RCP< HGradBasisType > basis, const int startCell=0, const int endCell=-1)
Computes the Jacobian matrix DF of the reference-to-physical frame map F.
static void getPhysicalSideNormals(Kokkos::DynRankView< sideNormalValueType, sideNormalProperties... > sideNormals, const Kokkos::DynRankView< worksetJacobianValueType, worksetJacobianProperties... > worksetJacobians, const ordinal_type worksetSideOrd, const shards::CellTopology parentCell)
Computes non-normalized normal vectors to physical sides in a side workset .
CubatureControlVolumeSide(const shards::CellTopology cellTopology)
virtual void getCubature(PointViewType cubPoints, weightViewType cubWeights, PointViewType cellCoords) const override
Returns cubature points and weights (return arrays must be pre-sized/pre-allocated).