48#ifndef __INTREPID2_ORIENTATIONTOOLS_DEF_MODIFY_BASIS_HPP__
49#define __INTREPID2_ORIENTATIONTOOLS_DEF_MODIFY_BASIS_HPP__
52#if defined (__clang__) && !defined (__INTEL_COMPILER)
53#pragma clang system_header
61 template<
typename elemOrtValueType,
class ...elemOrtProperties,
62 typename elemNodeValueType,
class ...elemNodeProperties>
65 getOrientation( Kokkos::DynRankView<elemOrtValueType,elemOrtProperties...> elemOrts,
66 const Kokkos::DynRankView<elemNodeValueType,elemNodeProperties...> elemNodes,
67 const shards::CellTopology cellTopo,
70 auto elemOrtsHost = Kokkos::create_mirror_view(elemOrts);
71 auto elemNodesHost = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), elemNodes);
73 const ordinal_type numCells = elemNodes.extent(0);
74 for (
auto cell=0;cell<numCells;++cell) {
75 const auto nodes = Kokkos::subview(elemNodesHost, cell, Kokkos::ALL());
76 elemOrtsHost(cell) = Orientation::getOrientation(cellTopo, nodes, isSide);
79 Kokkos::deep_copy(elemOrts, elemOrtsHost);
82 template<
typename ortViewType,
83 typename OutputViewType,
84 typename inputViewType,
87 typename dataViewType>
90 OutputViewType output;
92 o2tViewType ordinalToTag;
93 t2oViewType tagToOrdinal;
95 const dataViewType matData;
96 const ordinal_type cellDim, numVerts, numEdges, numFaces, numPoints, dimBasis;
99 OutputViewType output_,
100 inputViewType input_,
101 o2tViewType ordinalToTag_,
102 t2oViewType tagToOrdinal_,
103 const dataViewType matData_,
104 const ordinal_type cellDim_,
105 const ordinal_type numVerts_,
106 const ordinal_type numEdges_,
107 const ordinal_type numFaces_,
108 const ordinal_type numPoints_,
109 const ordinal_type dimBasis_)
113 ordinalToTag(ordinalToTag_),
114 tagToOrdinal(tagToOrdinal_),
120 numPoints(numPoints_),
124 KOKKOS_INLINE_FUNCTION
125 void operator()(
const ordinal_type cell)
const {
126 typedef typename inputViewType::non_const_value_type input_value_type;
128 auto out = Kokkos::subview(output, cell, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
129 auto in = (input.rank() == output.rank()) ?
130 Kokkos::subview(input, cell, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL())
131 : Kokkos::subview(input, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
134 ordinal_type existEdgeDofs = 0;
136 ordinal_type ortEdges[12];
137 orts(cell).getEdgeOrientation(ortEdges, numEdges);
140 for (ordinal_type edgeId=0;edgeId<numEdges;++edgeId) {
141 const ordinal_type ordEdge = (1 < tagToOrdinal.extent(0) ? (
static_cast<size_type
>(edgeId) < tagToOrdinal.extent(1) ? tagToOrdinal(1, edgeId, 0) : -1) : -1);
145 const ordinal_type ndofEdge = ordinalToTag(ordEdge, 3);
146 const auto mat = Kokkos::subview(matData,
147 edgeId, ortEdges[edgeId],
148 Kokkos::ALL(), Kokkos::ALL());
150 for (ordinal_type j=0;j<numPoints;++j)
151 for (ordinal_type i=0;i<ndofEdge;++i) {
152 const ordinal_type ii = tagToOrdinal(1, edgeId, i);
154 for (ordinal_type k=0;k<dimBasis;++k) {
155 input_value_type temp = 0.0;
156 for (ordinal_type l=0;l<ndofEdge;++l) {
157 const ordinal_type ll = tagToOrdinal(1, edgeId, l);
158 temp += mat(i,l)*in(ll, j, k);
160 out(ii, j, k) = temp;
169 ordinal_type ortFaces[12];
170 orts(cell).getFaceOrientation(ortFaces, numFaces);
173 for (ordinal_type faceId=0;faceId<numFaces;++faceId) {
174 const ordinal_type ordFace = (2 < tagToOrdinal.extent(0) ? (
static_cast<size_type
>(faceId) < tagToOrdinal.extent(1) ? tagToOrdinal(2, faceId, 0) : -1) : -1);
177 const ordinal_type ndofFace = ordinalToTag(ordFace, 3);
178 const auto mat = Kokkos::subview(matData,
179 numEdges*existEdgeDofs+faceId, ortFaces[faceId],
180 Kokkos::ALL(), Kokkos::ALL());
182 for (ordinal_type j=0;j<numPoints;++j)
183 for (ordinal_type i=0;i<ndofFace;++i) {
184 const ordinal_type ii = tagToOrdinal(2, faceId, i);
186 for (ordinal_type k=0;k<dimBasis;++k) {
187 input_value_type temp = 0.0;
188 for (ordinal_type l=0;l<ndofFace;++l) {
189 const ordinal_type ll = tagToOrdinal(2, faceId, l);
190 temp += mat(i,l)*in(ll, j, k);
192 out(ii, j, k) = temp;
200 ordinal_type faceOrt(0), edgeOrt(0);
201 if(cellDim == 2) orts(cell).getFaceOrientation(&faceOrt, 1);
203 const ordinal_type ordFace = (2 < tagToOrdinal.extent(0) ? (
static_cast<size_type
>(0) < tagToOrdinal.extent(1) ? tagToOrdinal(2, 0, 0) : -1) : -1);
206 const ordinal_type ndofFace = ordinalToTag(ordFace, 3);
207 const auto mat = Kokkos::subview(matData,
208 numEdges*existEdgeDofs, faceOrt,
209 Kokkos::ALL(), Kokkos::ALL());
211 for (ordinal_type j=0;j<numPoints;++j)
212 for (ordinal_type i=0;i<ndofFace;++i) {
213 const ordinal_type ii = tagToOrdinal(2, 0, i);
215 for (ordinal_type k=0;k<dimBasis;++k) {
216 input_value_type temp = 0.0;
217 for (ordinal_type l=0;l<ndofFace;++l) {
218 const ordinal_type ll = tagToOrdinal(2, 0, l);
219 temp += mat(i,l)*in(ll, j, k);
221 out(ii, j, k) = temp;
227 if(cellDim == 1) orts(cell).getEdgeOrientation(&edgeOrt, 1);
229 const ordinal_type ordEdge = (1 < tagToOrdinal.extent(0) ? (
static_cast<size_type
>(0) < tagToOrdinal.extent(1) ? tagToOrdinal(1, 0, 0) : -1) : -1);
232 const ordinal_type ndofEdge = ordinalToTag(ordEdge, 3);
233 const auto mat = Kokkos::subview(matData,
235 Kokkos::ALL(), Kokkos::ALL());
237 for (ordinal_type j=0;j<numPoints;++j)
238 for (ordinal_type i=0;i<ndofEdge;++i) {
239 const ordinal_type ii = tagToOrdinal(1, 0, i);
241 for (ordinal_type k=0;k<dimBasis;++k) {
242 input_value_type temp = 0.0;
243 for (ordinal_type l=0;l<ndofEdge;++l) {
244 const ordinal_type ll = tagToOrdinal(1, 0, l);
245 temp += mat(i,l)*in(ll, j, k);
247 out(ii, j, k) = temp;
255 template<
typename DT>
256 template<
typename outputValueType,
class ...outputProperties,
257 typename inputValueType,
class ...inputProperties,
258 typename OrientationViewType,
263 const Kokkos::DynRankView<inputValueType, inputProperties...> input,
264 const OrientationViewType orts,
265 const BasisType* basis ) {
266#ifdef HAVE_INTREPID2_DEBUG
268 if (input.rank() == output.rank())
270 for (size_type i=0;i<input.rank();++i)
271 INTREPID2_TEST_FOR_EXCEPTION( input.extent(i) != output.extent(i), std::invalid_argument,
272 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Input and output dimension does not match.");
274 else if (input.rank() == output.rank() - 1)
276 for (size_type i=0;i<input.rank();++i)
277 INTREPID2_TEST_FOR_EXCEPTION( input.extent(i) != output.extent(i+1), std::invalid_argument,
278 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Input dimensions must match output dimensions exactly, or else match all but the first dimension (in the case that input does not have a 'cell' dimension).");
282 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
283 ">>> ERROR (OrientationTools::modifyBasisByOrientation): input and output ranks must either match, or input rank must be one less than that of output.")
286 INTREPID2_TEST_FOR_EXCEPTION(
static_cast<ordinal_type
>(output.extent(1)) != basis->getCardinality(), std::invalid_argument,
287 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Field dimension of input/output does not match to basis cardinality.");
291 const shards::CellTopology cellTopo = basis->getBaseCellTopology();
292 const ordinal_type cellDim = cellTopo.getDimension();
295 if(input.rank() == output.rank())
296 Kokkos::deep_copy(output, input);
300 if ((cellDim < 3) || basis->requireOrientation()) {
301 auto ordinalToTag = Kokkos::create_mirror_view_and_copy(
typename DT::memory_space(), basis->getAllDofTags());
302 auto tagToOrdinal = Kokkos::create_mirror_view_and_copy(
typename DT::memory_space(), basis->getAllDofOrdinal());
305 numCells = output.extent(0),
307 numPoints = output.extent(2),
308 dimBasis = output.extent(3);
312 ordinal_type numVerts(0), numEdges(0), numFaces(0);
314 if (basis->requireOrientation()) {
315 numVerts = cellTopo.getVertexCount()*ordinal_type(basis->getDofCount(0, 0) > 0);
316 numEdges = cellTopo.getEdgeCount()*ordinal_type(basis->getDofCount(1, 0) > 0);
317 numFaces = cellTopo.getFaceCount()*ordinal_type(basis->getDofCount(2, 0) > 0);
320 const Kokkos::RangePolicy<typename DT::execution_space> policy(0, numCells);
323 decltype(output),
decltype(input),
324 decltype(ordinalToTag),
decltype(tagToOrdinal),
325 decltype(matData)> FunctorType;
330 ordinalToTag, tagToOrdinal,
332 cellDim, numVerts, numEdges, numFaces,
333 numPoints, dimBasis));
Header file for the Intrepid2::Orientation class.