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_and_copy(
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 ortViewType,
127 typename OutputViewType,
128 typename inputViewType,
129 typename o2tViewType,
130 typename t2oViewType,
131 typename dataViewType>
134 OutputViewType output;
136 o2tViewType ordinalToTag;
137 t2oViewType tagToOrdinal;
139 const dataViewType matData;
140 const ordinal_type cellDim, numVerts, numEdges, numFaces, numPoints, dimBasis;
143 OutputViewType output_,
144 inputViewType input_,
145 o2tViewType ordinalToTag_,
146 t2oViewType tagToOrdinal_,
147 const dataViewType matData_,
148 const ordinal_type cellDim_,
149 const ordinal_type numVerts_,
150 const ordinal_type numEdges_,
151 const ordinal_type numFaces_,
152 const ordinal_type numPoints_,
153 const ordinal_type dimBasis_)
157 ordinalToTag(ordinalToTag_),
158 tagToOrdinal(tagToOrdinal_),
164 numPoints(numPoints_),
168 KOKKOS_INLINE_FUNCTION
169 void operator()(
const ordinal_type cell)
const {
170 typedef typename inputViewType::non_const_value_type input_value_type;
172 auto out = Kokkos::subview(output, cell, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
173 auto in = Kokkos::subview(input, cell, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
176 for (ordinal_type vertId=0;vertId<numVerts;++vertId) {
177 const ordinal_type i = (
static_cast<size_type
>(vertId) < tagToOrdinal.extent(1) ? tagToOrdinal(0, vertId, 0) : -1);
179 for (ordinal_type j=0;j<numPoints;++j)
180 for (ordinal_type k=0;k<dimBasis;++k)
181 out(i, j, k) = in(i, j, k);
186 const ordinal_type ordIntr = (
static_cast<size_type
>(cellDim) < tagToOrdinal.extent(0) ? tagToOrdinal(cellDim, 0, 0) : -1);
188 const ordinal_type ndofIntr = ordinalToTag(ordIntr, 3);
189 for (ordinal_type i=0;i<ndofIntr;++i) {
190 const ordinal_type ii = tagToOrdinal(cellDim, 0, i);
191 for (ordinal_type j=0;j<numPoints;++j)
192 for (ordinal_type k=0;k<dimBasis;++k)
193 out(ii, j, k) = in(ii, j, k);
199 ordinal_type existEdgeDofs = 0;
201 ordinal_type ortEdges[12];
202 orts(cell).getEdgeOrientation(ortEdges, numEdges);
205 for (ordinal_type edgeId=0;edgeId<numEdges;++edgeId) {
206 const ordinal_type ordEdge = (1 < tagToOrdinal.extent(0) ? (
static_cast<size_type
>(edgeId) < tagToOrdinal.extent(1) ? tagToOrdinal(1, edgeId, 0) : -1) : -1);
210 const ordinal_type ndofEdge = ordinalToTag(ordEdge, 3);
211 const auto mat = Kokkos::subview(matData,
212 edgeId, ortEdges[edgeId],
213 Kokkos::ALL(), Kokkos::ALL());
215 for (ordinal_type j=0;j<numPoints;++j)
216 for (ordinal_type i=0;i<ndofEdge;++i) {
217 const ordinal_type ii = tagToOrdinal(1, edgeId, i);
219 for (ordinal_type k=0;k<dimBasis;++k) {
220 input_value_type temp = 0.0;
221 for (ordinal_type l=0;l<ndofEdge;++l) {
222 const ordinal_type ll = tagToOrdinal(1, edgeId, l);
223 temp += mat(i,l)*in(ll, j, k);
225 out(ii, j, k) = temp;
234 ordinal_type ortFaces[12];
235 orts(cell).getFaceOrientation(ortFaces, numFaces);
238 for (ordinal_type faceId=0;faceId<numFaces;++faceId) {
239 const ordinal_type ordFace = (2 < tagToOrdinal.extent(0) ? (
static_cast<size_type
>(faceId) < tagToOrdinal.extent(1) ? tagToOrdinal(2, faceId, 0) : -1) : -1);
242 const ordinal_type ndofFace = ordinalToTag(ordFace, 3);
243 const auto mat = Kokkos::subview(matData,
244 numEdges*existEdgeDofs+faceId, ortFaces[faceId],
245 Kokkos::ALL(), Kokkos::ALL());
247 for (ordinal_type j=0;j<numPoints;++j)
248 for (ordinal_type i=0;i<ndofFace;++i) {
249 const ordinal_type ii = tagToOrdinal(2, faceId, i);
251 for (ordinal_type k=0;k<dimBasis;++k) {
252 input_value_type temp = 0.0;
253 for (ordinal_type l=0;l<ndofFace;++l) {
254 const ordinal_type ll = tagToOrdinal(2, faceId, l);
255 temp += mat(i,l)*in(ll, j, k);
257 out(ii, j, k) = temp;
266 template<
typename SpT>
267 template<
typename outputValueType,
class ...outputProperties,
268 typename inputValueType,
class ...inputProperties,
269 typename ortValueType,
class ...ortProperties,
270 typename BasisPtrType>
274 const Kokkos::DynRankView<inputValueType, inputProperties...> input,
275 const Kokkos::DynRankView<ortValueType, ortProperties...> orts,
276 const BasisPtrType basis ) {
277 #ifdef HAVE_INTREPID2_DEBUG
279 INTREPID2_TEST_FOR_EXCEPTION( input.rank() != output.rank(), std::invalid_argument,
280 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Input and output rank are not 3.");
281 for (size_type i=0;i<input.rank();++i)
282 INTREPID2_TEST_FOR_EXCEPTION( input.extent(i) != output.extent(i), std::invalid_argument,
283 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Input and output dimension does not match.");
285 INTREPID2_TEST_FOR_EXCEPTION( static_cast<ordinal_type>(input.extent(1)) != basis->getCardinality(), std::invalid_argument,
286 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Field dimension of input/output does not match to basis cardinality.");
290 if (basis->requireOrientation()) {
291 auto ordinalToTag = Kokkos::create_mirror_view(
typename SpT::memory_space(), basis->getAllDofTags());
292 auto tagToOrdinal = Kokkos::create_mirror_view(
typename SpT::memory_space(), basis->getAllDofOrdinal());
294 Kokkos::deep_copy(ordinalToTag, basis->getAllDofTags());
295 Kokkos::deep_copy(tagToOrdinal, basis->getAllDofOrdinal());
298 numCells = output.extent(0),
300 numPoints = output.extent(2),
301 dimBasis = output.extent(3);
304 const shards::CellTopology cellTopo = basis->getBaseCellTopology();
307 cellDim = cellTopo.getDimension(),
308 numVerts = cellTopo.getVertexCount()*ordinal_type(basis->getDofCount(0, 0) > 0),
309 numEdges = cellTopo.getEdgeCount()*ordinal_type(basis->getDofCount(1, 0) > 0),
310 numFaces = cellTopo.getFaceCount();
312 const Kokkos::RangePolicy<SpT> policy(0, numCells);
315 decltype(output),decltype(input),
316 decltype(ordinalToTag),decltype(tagToOrdinal),
317 decltype(matData)> FunctorType;
318 Kokkos::parallel_for(policy,
321 ordinalToTag, tagToOrdinal,
323 cellDim, numVerts, numEdges, numFaces,
324 numPoints, dimBasis));
326 Kokkos::deep_copy(output, input);