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
58 template<
typename SpT>
59 template<
typename ptViewType>
60 KOKKOS_INLINE_FUNCTION
63 #ifdef HAVE_INTREPID2_DEBUG
64 INTREPID2_TEST_FOR_ABORT( pts.rank() != 2,
65 ">>> ERROR (Intrepid::OrientationTools::isLeftHandedCell): " \
66 "Point array is supposed to have rank 2.");
68 typedef typename ptViewType::value_type value_type;
70 const auto dim = pts.extent(1);
75 const value_type v[2][2] = { { pts(1,0) - pts(0,0), pts(1,1) - pts(0,1) },
76 { pts(2,0) - pts(0,0), pts(2,1) - pts(0,1) } };
78 det = (v[0][0]*v[1][1] - v[1][0]*v[0][1]);
83 const value_type v[3][3] = { { pts(1,0) - pts(0,0), pts(1,1) - pts(0,1), pts(1,2) - pts(0,2) },
84 { pts(2,0) - pts(0,0), pts(2,1) - pts(0,1), pts(2,2) - pts(0,2) },
85 { pts(3,0) - pts(0,0), pts(3,1) - pts(0,1), pts(3,2) - pts(0,2) } };
87 det = (v[0][0] * v[1][1] * v[2][2] +
88 v[0][1] * v[1][2] * v[2][0] +
89 v[0][2] * v[1][0] * v[2][1] -
90 v[0][2] * v[1][1] * v[2][0] -
91 v[0][0] * v[1][2] * v[2][1] -
92 v[0][1] * v[1][0] * v[2][2]);
96 INTREPID2_TEST_FOR_ABORT(
true,
97 ">>> ERROR (Intrepid::Orientation::isLeftHandedCell): " \
98 "Dimension of points must be 2 or 3");
104 template<
typename SpT>
105 template<
typename elemOrtValueType,
class ...elemOrtProperties,
106 typename elemNodeValueType,
class ...elemNodeProperties>
109 getOrientation( Kokkos::DynRankView<elemOrtValueType,elemOrtProperties...> elemOrts,
110 const Kokkos::DynRankView<elemNodeValueType,elemNodeProperties...> elemNodes,
111 const shards::CellTopology cellTopo) {
113 typedef typename Kokkos::Impl::is_space<SpT>::host_mirror_space::execution_space host_space_type;
114 auto elemOrtsHost = Kokkos::create_mirror_view(
typename host_space_type::memory_space(), elemOrts);
115 auto elemNodesHost = Kokkos::create_mirror_view(
typename host_space_type::memory_space(), elemNodes);
117 const ordinal_type numCells = elemNodes.extent(0);
118 for (
auto cell=0;cell<numCells;++cell) {
119 const auto nodes = Kokkos::subview(elemNodesHost, cell, Kokkos::ALL());
120 elemOrtsHost(cell) = Orientation::getOrientation(cellTopo, nodes);
123 Kokkos::deep_copy(elemOrts, elemOrtsHost);
126 template<
typename SpT>
127 template<
typename outputValueType,
class ...outputProperties,
128 typename inputValueType,
class ...inputProperties,
129 typename ortValueType,
class ...ortProperties,
130 typename BasisPtrType>
134 const Kokkos::DynRankView<inputValueType, inputProperties...> input,
135 const Kokkos::DynRankView<ortValueType, ortProperties...> orts,
136 const BasisPtrType basis ) {
137 #ifdef HAVE_INTREPID2_DEBUG
139 INTREPID2_TEST_FOR_EXCEPTION( input.rank() != output.rank(), std::invalid_argument,
140 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Input and output rank are not 3.");
141 for (size_type i=0;i<input.rank();++i)
142 INTREPID2_TEST_FOR_EXCEPTION( input.extent(i) != output.extent(i), std::invalid_argument,
143 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Input and output dimension does not match.");
145 INTREPID2_TEST_FOR_EXCEPTION( static_cast<ordinal_type>(input.extent(1)) != basis->getCardinality(), std::invalid_argument,
146 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Field dimension of input/output does not match to basis cardinality.");
149 typedef typename decltype(input)::non_const_value_type input_value_type;
151 if (basis->requireOrientation()) {
152 auto ordinalToTag = Kokkos::create_mirror_view(
typename SpT::memory_space(), basis->getAllDofTags());
153 auto tagToOrdinal = Kokkos::create_mirror_view(
typename SpT::memory_space(), basis->getAllDofOrdinal());
155 Kokkos::deep_copy(ordinalToTag, basis->getAllDofTags());
156 Kokkos::deep_copy(tagToOrdinal, basis->getAllDofOrdinal());
159 numCells = output.extent(0),
161 numPoints = output.extent(2),
162 dimBasis = output.extent(3);
165 const shards::CellTopology cellTopo = basis->getBaseCellTopology();
168 numVerts = cellTopo.getVertexCount()*ordinal_type(basis->getDofCount(0, 0) > 0),
169 numEdges = cellTopo.getEdgeCount()*ordinal_type(basis->getDofCount(1, 0) > 0),
170 numFaces = cellTopo.getFaceCount();
172 for (
auto cell=0;cell<numCells;++cell) {
173 auto out = Kokkos::subview(output, cell, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
174 auto in = Kokkos::subview(input, cell, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
177 for (ordinal_type vertId=0;vertId<numVerts;++vertId) {
178 const ordinal_type i = (
static_cast<size_type
>(vertId) < tagToOrdinal.extent(1) ? tagToOrdinal(0, vertId, 0) : -1);
180 for (ordinal_type j=0;j<numPoints;++j)
181 for (ordinal_type k=0;k<dimBasis;++k)
182 out(i, j, k) = in(i, j, k);
187 const ordinal_type cellDim = cellTopo.getDimension();
188 const ordinal_type ordIntr = (
static_cast<size_type
>(cellDim) < tagToOrdinal.extent(0) ? tagToOrdinal(cellDim, 0, 0) : -1);
190 const ordinal_type ndofIntr = ordinalToTag(ordIntr, 3);
191 for (ordinal_type i=0;i<ndofIntr;++i) {
192 const ordinal_type ii = tagToOrdinal(cellDim, 0, i);
193 for (ordinal_type j=0;j<numPoints;++j)
194 for (ordinal_type k=0;k<dimBasis;++k)
195 out(ii, j, k) = in(ii, j, k);
201 ordinal_type existEdgeDofs = 0;
203 ordinal_type ortEdges[12];
204 orts(cell).getEdgeOrientation(ortEdges, numEdges);
207 for (ordinal_type edgeId=0;edgeId<numEdges;++edgeId) {
208 const ordinal_type ordEdge = (1 < tagToOrdinal.extent(0) ? (
static_cast<size_type
>(edgeId) < tagToOrdinal.extent(1) ? tagToOrdinal(1, edgeId, 0) : -1) : -1);
212 const ordinal_type ndofEdge = ordinalToTag(ordEdge, 3);
213 const auto mat = Kokkos::subview(matData,
214 edgeId, ortEdges[edgeId],
215 Kokkos::ALL(), Kokkos::ALL());
217 for (ordinal_type j=0;j<numPoints;++j)
218 for (ordinal_type i=0;i<ndofEdge;++i) {
219 const ordinal_type ii = tagToOrdinal(1, edgeId, i);
221 for (ordinal_type k=0;k<dimBasis;++k) {
222 input_value_type temp = 0.0;
223 for (ordinal_type l=0;l<ndofEdge;++l) {
224 const ordinal_type ll = tagToOrdinal(1, edgeId, l);
225 temp += mat(i,l)*in(ll, j, k);
227 out(ii, j, k) = temp;
236 ordinal_type ortFaces[12];
237 orts(cell).getFaceOrientation(ortFaces, numFaces);
240 for (ordinal_type faceId=0;faceId<numFaces;++faceId) {
241 const ordinal_type ordFace = (2 < tagToOrdinal.extent(0) ? (
static_cast<size_type
>(faceId) < tagToOrdinal.extent(1) ? tagToOrdinal(2, faceId, 0) : -1) : -1);
244 const ordinal_type ndofFace = ordinalToTag(ordFace, 3);
245 const auto mat = Kokkos::subview(matData,
246 numEdges*existEdgeDofs+faceId, ortFaces[faceId],
247 Kokkos::ALL(), Kokkos::ALL());
249 for (ordinal_type j=0;j<numPoints;++j)
250 for (ordinal_type i=0;i<ndofFace;++i) {
251 const ordinal_type ii = tagToOrdinal(2, faceId, i);
253 for (ordinal_type k=0;k<dimBasis;++k) {
254 input_value_type temp = 0.0;
255 for (ordinal_type l=0;l<ndofFace;++l) {
256 const ordinal_type ll = tagToOrdinal(2, faceId, l);
257 temp += mat(i,l)*in(ll, j, k);
259 out(ii, j, k) = temp;
268 Kokkos::deep_copy(output, input);