Intrepid2
Intrepid2_OrientationToolsDefModifyBasis.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
10
15#ifndef __INTREPID2_ORIENTATIONTOOLS_DEF_MODIFY_BASIS_HPP__
16#define __INTREPID2_ORIENTATIONTOOLS_DEF_MODIFY_BASIS_HPP__
17
18// disable clang warnings
19#if defined (__clang__) && !defined (__INTEL_COMPILER)
20#pragma clang system_header
21#endif
22
24
25namespace Intrepid2 {
26
27 template<typename DT>
28 template<typename elemOrtValueType, class ...elemOrtProperties,
29 typename elemNodeValueType, class ...elemNodeProperties>
30 void
32 getOrientation( Kokkos::DynRankView<elemOrtValueType,elemOrtProperties...> elemOrts,
33 const Kokkos::DynRankView<elemNodeValueType,elemNodeProperties...> elemNodes,
34 const shards::CellTopology cellTopo,
35 bool isSide) {
36 // small meta data modification and it uses shards; let's do this on host
37 auto elemOrtsHost = Kokkos::create_mirror_view(elemOrts);
38 auto elemNodesHost = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), elemNodes);
39
40 const ordinal_type numCells = elemNodes.extent(0);
41 for (auto cell=0;cell<numCells;++cell) {
42 const auto nodes = Kokkos::subview(elemNodesHost, cell, Kokkos::ALL());
43 elemOrtsHost(cell) = Orientation::getOrientation(cellTopo, nodes, isSide);
44 }
45
46 Kokkos::deep_copy(elemOrts, elemOrtsHost);
47 }
48
49 template<typename ortViewType,
50 typename OutputViewType,
51 typename inputViewType,
52 typename o2tViewType,
53 typename t2oViewType,
54 typename dataViewType>
56 ortViewType orts;
57 OutputViewType output;
58 inputViewType input;
59 o2tViewType ordinalToTag;
60 t2oViewType tagToOrdinal;
61
62 const dataViewType matData;
63 const ordinal_type cellDim, numVerts, numEdges, numFaces, numPoints, dimBasis;
64 const bool leftMultiply;
65 // for simple left-multiplied basis value modification, numPoints is the dimension after the field dimension
66 // for matrix value modification (C,F1,F2), numPoints is F2 when left multiplied, and F1 when right multiplied
67 const bool transpose; // when true, multiply by the transpose of the matrix
68
69 F_modifyBasisByOrientation(ortViewType orts_,
70 OutputViewType output_,
71 inputViewType input_,
72 o2tViewType ordinalToTag_,
73 t2oViewType tagToOrdinal_,
74 const dataViewType matData_,
75 const ordinal_type cellDim_,
76 const ordinal_type numVerts_,
77 const ordinal_type numEdges_,
78 const ordinal_type numFaces_,
79 const ordinal_type numPoints_,
80 const ordinal_type dimBasis_,
81 const bool leftMultiply_ = true,
82 const bool transpose_ = false)
83 : orts(orts_),
84 output(output_),
85 input(input_),
86 ordinalToTag(ordinalToTag_),
87 tagToOrdinal(tagToOrdinal_),
88 matData(matData_),
89 cellDim(cellDim_),
90 numVerts(numVerts_),
91 numEdges(numEdges_),
92 numFaces(numFaces_),
93 numPoints(numPoints_),
94 dimBasis(dimBasis_),
95 leftMultiply(leftMultiply_),
96 transpose(transpose_)
97 {}
98
99 KOKKOS_INLINE_FUNCTION
100 void operator()(const ordinal_type cell) const {
101 typedef typename inputViewType::non_const_value_type input_value_type;
102
103 auto out = Kokkos::subview(output, cell, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
104 auto in = (input.rank() == output.rank()) ?
105 Kokkos::subview(input, cell, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL())
106 : Kokkos::subview(input, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
107
108 // edge transformation
109 ordinal_type existEdgeDofs = 0;
110 if (numEdges > 0) {
111 ordinal_type ortEdges[12];
112 orts(cell).getEdgeOrientation(ortEdges, numEdges);
113
114 // apply coeff matrix
115 for (ordinal_type edgeId=0;edgeId<numEdges;++edgeId) {
116 const ordinal_type ordEdge = (1 < tagToOrdinal.extent(0) ? (static_cast<size_type>(edgeId) < tagToOrdinal.extent(1) ? tagToOrdinal(1, edgeId, 0) : -1) : -1);
117
118 if (ordEdge != -1) {
119 existEdgeDofs = 1;
120 const ordinal_type ndofEdge = ordinalToTag(ordEdge, 3);
121 const auto mat = Kokkos::subview(matData,
122 edgeId, ortEdges[edgeId],
123 Kokkos::ALL(), Kokkos::ALL());
124
125 for (ordinal_type j=0;j<numPoints;++j)
126 for (ordinal_type i=0;i<ndofEdge;++i) {
127 const ordinal_type ii = tagToOrdinal(1, edgeId, i);
128
129 for (ordinal_type k=0;k<dimBasis;++k) {
130 input_value_type temp = 0.0;
131 for (ordinal_type l=0;l<ndofEdge;++l) {
132 const ordinal_type ll = tagToOrdinal(1, edgeId, l);
133 auto & input_ = leftMultiply ? in.access(ll, j, k) : in.access(j, ll, k);
134 auto & mat_il = transpose ? mat(l,i) : mat(i,l);
135 temp += mat_il*input_;
136 }
137 auto & output_ = leftMultiply ? out.access(ii, j, k) : out.access(j, ii, k);
138 output_ = temp;
139 }
140 }
141 }
142 }
143 }
144
145 // face transformation
146 if (numFaces > 0) {
147 ordinal_type ortFaces[12];
148 orts(cell).getFaceOrientation(ortFaces, numFaces);
149
150 // apply coeff matrix
151 for (ordinal_type faceId=0;faceId<numFaces;++faceId) {
152 const ordinal_type ordFace = (2 < tagToOrdinal.extent(0) ? (static_cast<size_type>(faceId) < tagToOrdinal.extent(1) ? tagToOrdinal(2, faceId, 0) : -1) : -1);
153
154 if (ordFace != -1) {
155 const ordinal_type ndofFace = ordinalToTag(ordFace, 3);
156 const auto mat = Kokkos::subview(matData,
157 numEdges*existEdgeDofs+faceId, ortFaces[faceId],
158 Kokkos::ALL(), Kokkos::ALL());
159
160 for (ordinal_type j=0;j<numPoints;++j)
161 for (ordinal_type i=0;i<ndofFace;++i) {
162 const ordinal_type ii = tagToOrdinal(2, faceId, i);
163
164 for (ordinal_type k=0;k<dimBasis;++k) {
165 input_value_type temp = 0.0;
166 for (ordinal_type l=0;l<ndofFace;++l) {
167 const ordinal_type ll = tagToOrdinal(2, faceId, l);
168 auto & input_ = leftMultiply ? in.access(ll, j, k) : in.access(j, ll, k);
169 auto & mat_il = transpose ? mat(l,i) : mat(i,l);
170 temp += mat_il*input_;
171 }
172
173 auto & output_ = leftMultiply ? out.access(ii, j, k) : out.access(j, ii, k);
174 output_ = temp;
175 }
176 }
177 }
178 }
179 }
180
181 //side orientations
182 ordinal_type faceOrt(0), edgeOrt(0);
183 if(cellDim == 2) orts(cell).getFaceOrientation(&faceOrt, 1);
184 if (faceOrt != 0) {
185 const ordinal_type ordFace = (2 < tagToOrdinal.extent(0) ? (static_cast<size_type>(0) < tagToOrdinal.extent(1) ? tagToOrdinal(2, 0, 0) : -1) : -1);
186
187 if (ordFace != -1) {
188 const ordinal_type ndofFace = ordinalToTag(ordFace, 3);
189 const auto mat = Kokkos::subview(matData,
190 numEdges*existEdgeDofs, faceOrt,
191 Kokkos::ALL(), Kokkos::ALL());
192
193 for (ordinal_type j=0;j<numPoints;++j)
194 for (ordinal_type i=0;i<ndofFace;++i) {
195 const ordinal_type ii = tagToOrdinal(2, 0, i);
196
197 for (ordinal_type k=0;k<dimBasis;++k) {
198 input_value_type temp = 0.0;
199 for (ordinal_type l=0;l<ndofFace;++l) {
200 const ordinal_type ll = tagToOrdinal(2, 0, l);
201 auto & input_ = leftMultiply ? in.access(ll, j, k) : in.access(j, ll, k);
202 auto & mat_il = transpose ? mat(l,i) : mat(i,l);
203 temp += mat_il*input_;
204 }
205 auto & output_ = leftMultiply ? out.access(ii, j, k) : out.access(j, ii, k);
206 output_ = temp;
207 }
208 }
209 }
210 }
211
212 if(cellDim == 1) orts(cell).getEdgeOrientation(&edgeOrt, 1);
213 if (edgeOrt != 0) {
214 const ordinal_type ordEdge = (1 < tagToOrdinal.extent(0) ? (static_cast<size_type>(0) < tagToOrdinal.extent(1) ? tagToOrdinal(1, 0, 0) : -1) : -1);
215
216 if (ordEdge != -1) {
217 const ordinal_type ndofEdge = ordinalToTag(ordEdge, 3);
218 const auto mat = Kokkos::subview(matData,
219 0, edgeOrt,
220 Kokkos::ALL(), Kokkos::ALL());
221
222 for (ordinal_type j=0;j<numPoints;++j)
223 for (ordinal_type i=0;i<ndofEdge;++i) {
224 const ordinal_type ii = tagToOrdinal(1, 0, i);
225
226 for (ordinal_type k=0;k<dimBasis;++k) {
227 input_value_type temp = 0.0;
228 for (ordinal_type l=0;l<ndofEdge;++l) {
229 const ordinal_type ll = tagToOrdinal(1, 0, l);
230 auto & input_ = leftMultiply ? in.access(ll, j, k) : in.access(j, ll, k);
231 auto & mat_il = transpose ? mat(l,i) : mat(i,l);
232 temp += mat_il*input_;
233 }
234 auto & output_ = leftMultiply ? out.access(ii, j, k) : out.access(j, ii, k);
235 output_ = temp;
236 }
237 }
238 }
239 }
240 }
241 };
242
243 template<typename DT>
244 template<typename outputValueType, class ...outputProperties,
245 typename inputValueType, class ...inputProperties,
246 typename OrientationViewType,
247 typename BasisType>
248 void
250 modifyBasisByOrientation( Kokkos::DynRankView<outputValueType,outputProperties...> output,
251 const Kokkos::DynRankView<inputValueType, inputProperties...> input,
252 const OrientationViewType orts,
253 const BasisType* basis,
254 const bool transpose) {
255#ifdef HAVE_INTREPID2_DEBUG
256 {
257 if (input.rank() == output.rank())
258 {
259 for (size_type i=0;i<input.rank();++i)
260 INTREPID2_TEST_FOR_EXCEPTION( input.extent(i) != output.extent(i), std::invalid_argument,
261 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Input and output dimensions do not match.");
262 }
263 else if (input.rank() == output.rank() - 1)
264 {
265 for (size_type i=0;i<input.rank();++i)
266 INTREPID2_TEST_FOR_EXCEPTION( input.extent(i) != output.extent(i+1), std::invalid_argument,
267 ">>> 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).");
268 }
269 else
270 {
271 INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument,
272 ">>> ERROR (OrientationTools::modifyBasisByOrientation): input and output ranks must either match, or input rank must be one less than that of output.")
273 }
274
275 INTREPID2_TEST_FOR_EXCEPTION( static_cast<ordinal_type>(output.extent(1)) != basis->getCardinality(), std::invalid_argument,
276 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Field dimension of input/output does not match to basis cardinality.");
277 }
278#endif
279
280 const shards::CellTopology cellTopo = basis->getBaseCellTopology();
281 const ordinal_type cellDim = cellTopo.getDimension();
282
283 //Initialize output with values from input
284 if(input.rank() == output.rank())
285 Kokkos::deep_copy(output, input);
286 else
287 RealSpaceTools<DT>::clone(output, input);
288
289 if ((cellDim < 3) || basis->requireOrientation()) {
290 auto ordinalToTag = Kokkos::create_mirror_view_and_copy(typename DT::memory_space(), basis->getAllDofTags());
291 auto tagToOrdinal = Kokkos::create_mirror_view_and_copy(typename DT::memory_space(), basis->getAllDofOrdinal());
292
293 const ordinal_type
294 numCells = output.extent(0),
295 //numBasis = output.extent(1),
296 numPoints = output.extent(2),
297 dimBasis = output.extent(3); //returns 1 when output.rank() < 4;
298
299 const CoeffMatrixDataViewType matData = createCoeffMatrix(basis);
300
301 ordinal_type numVerts(0), numEdges(0), numFaces(0);
302
303 if (basis->requireOrientation()) {
304 numVerts = cellTopo.getVertexCount()*ordinal_type(basis->getDofCount(0, 0) > 0);
305 numEdges = cellTopo.getEdgeCount()*ordinal_type(basis->getDofCount(1, 0) > 0);
306 numFaces = cellTopo.getFaceCount()*ordinal_type(basis->getDofCount(2, 0) > 0);
307 }
308
309 bool leftMultiply = true;
310
311 const Kokkos::RangePolicy<typename DT::execution_space> policy(0, numCells);
313 <decltype(orts),
314 decltype(output),decltype(input),
315 decltype(ordinalToTag),decltype(tagToOrdinal),
316 decltype(matData)> FunctorType;
317 Kokkos::parallel_for
318 (policy,
319 FunctorType(orts,
320 output, input,
321 ordinalToTag, tagToOrdinal,
322 matData,
323 cellDim, numVerts, numEdges, numFaces,
324 numPoints, dimBasis, leftMultiply, transpose));
325 }
326 }
327
328 template<typename DT>
329 template<typename outputValueType, class ...outputProperties,
330 typename inputValueType, class ...inputProperties,
331 typename OrientationViewType,
332 typename BasisType>
333 void
335 modifyBasisByOrientationTranspose( Kokkos::DynRankView<outputValueType,outputProperties...> output,
336 const Kokkos::DynRankView<inputValueType, inputProperties...> input,
337 const OrientationViewType orts,
338 const BasisType* basis ) {
339 bool transpose = true;
340 modifyBasisByOrientation(output, input, orts, basis, transpose);
341 }
342
343 template<typename DT>
344 template<typename outputValueType, class ...outputProperties,
345 typename inputValueType, class ...inputProperties,
346 typename OrientationViewType,
347 typename BasisType>
348 void
350 modifyBasisByOrientationInverse( Kokkos::DynRankView<outputValueType,outputProperties...> output,
351 const Kokkos::DynRankView<inputValueType, inputProperties...> input,
352 const OrientationViewType orts,
353 const BasisType* basis,
354 const bool transpose ) {
355 #ifdef HAVE_INTREPID2_DEBUG
356 {
357 if (input.rank() == output.rank())
358 {
359 for (size_type i=0;i<input.rank();++i)
360 INTREPID2_TEST_FOR_EXCEPTION( input.extent(i) != output.extent(i), std::invalid_argument,
361 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Input and output dimensions do not match.");
362 }
363 else if (input.rank() == output.rank() - 1)
364 {
365 for (size_type i=0;i<input.rank();++i)
366 INTREPID2_TEST_FOR_EXCEPTION( input.extent(i) != output.extent(i+1), std::invalid_argument,
367 ">>> 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).");
368 }
369 else
370 {
371 INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument,
372 ">>> ERROR (OrientationTools::modifyBasisByOrientation): input and output ranks must either match, or input rank must be one less than that of output.")
373 }
374
375 INTREPID2_TEST_FOR_EXCEPTION( static_cast<ordinal_type>(output.extent(1)) != basis->getCardinality(), std::invalid_argument,
376 ">>> ERROR (OrientationTools::modifyBasisByOrientation): Field dimension of input/output does not match to basis cardinality.");
377 }
378 #endif
379
380 const shards::CellTopology cellTopo = basis->getBaseCellTopology();
381 const ordinal_type cellDim = cellTopo.getDimension();
382
383 //Initialize output with values from input
384 if(input.rank() == output.rank())
385 Kokkos::deep_copy(output, input);
386 else
387 RealSpaceTools<DT>::clone(output, input);
388
389 if ((cellDim < 3) || basis->requireOrientation()) {
390 auto ordinalToTag = Kokkos::create_mirror_view_and_copy(typename DT::memory_space(), basis->getAllDofTags());
391 auto tagToOrdinal = Kokkos::create_mirror_view_and_copy(typename DT::memory_space(), basis->getAllDofOrdinal());
392
393 const ordinal_type
394 numCells = output.extent(0),
395 //numBasis = output.extent(1),
396 numPoints = output.extent(2),
397 dimBasis = output.extent(3); //returns 1 when output.rank() < 4;
398
399 const CoeffMatrixDataViewType matData = createInvCoeffMatrix(basis);
400
401 ordinal_type numVerts(0), numEdges(0), numFaces(0);
402
403 if (basis->requireOrientation()) {
404 numVerts = cellTopo.getVertexCount()*ordinal_type(basis->getDofCount(0, 0) > 0);
405 numEdges = cellTopo.getEdgeCount()*ordinal_type(basis->getDofCount(1, 0) > 0);
406 numFaces = cellTopo.getFaceCount()*ordinal_type(basis->getDofCount(2, 0) > 0);
407 }
408
409 bool leftMultiply = true;
410
411 const Kokkos::RangePolicy<typename DT::execution_space> policy(0, numCells);
413 <decltype(orts),
414 decltype(output),decltype(input),
415 decltype(ordinalToTag),decltype(tagToOrdinal),
416 decltype(matData)> FunctorType;
417 Kokkos::parallel_for
418 (policy,
419 FunctorType(orts,
420 output, input,
421 ordinalToTag, tagToOrdinal,
422 matData,
423 cellDim, numVerts, numEdges, numFaces,
424 numPoints, dimBasis, leftMultiply, transpose));
425 }
426 }
427
428 template<typename DT>
429 template<typename outputValueType, class ...outputProperties,
430 typename inputValueType, class ...inputProperties,
431 typename OrientationViewType,
432 typename BasisTypeLeft,
433 typename BasisTypeRight>
434 void
436 modifyMatrixByOrientation(Kokkos::DynRankView<outputValueType,outputProperties...> output,
437 const Kokkos::DynRankView<inputValueType, inputProperties...> input,
438 const OrientationViewType orts,
439 const BasisTypeLeft* basisLeft,
440 const BasisTypeRight* basisRight)
441 {
442 const ordinal_type numCells = output.extent(0);
443 const ordinal_type numFieldsLeft = basisLeft->getCardinality();
444 const ordinal_type numFieldsRight = basisRight->getCardinality();
445#ifdef HAVE_INTREPID2_DEBUG
446 {
447 if (input.rank() == output.rank())
448 {
449 for (size_type i=0;i<input.rank();++i)
450 INTREPID2_TEST_FOR_EXCEPTION( input.extent(i) != output.extent(i), std::invalid_argument,
451 ">>> ERROR (OrientationTools::modifyMatrixByOrientation): Input and output dimensions do not match.");
452 }
453 else if (input.rank() == output.rank() - 1)
454 {
455 for (size_type i=0;i<input.rank();++i)
456 INTREPID2_TEST_FOR_EXCEPTION( input.extent(i) != output.extent(i+1), std::invalid_argument,
457 ">>> ERROR (OrientationTools::modifyMatrixByOrientation): 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).");
458 }
459 else
460 {
461 INTREPID2_TEST_FOR_EXCEPTION(true, std::invalid_argument,
462 ">>> ERROR (OrientationTools::modifyMatrixByOrientation): input and output ranks must either match, or input rank must be one less than that of output.")
463 }
464
465 INTREPID2_TEST_FOR_EXCEPTION( static_cast<ordinal_type>(output.extent(1)) != numFieldsLeft, std::invalid_argument,
466 ">>> ERROR (OrientationTools::modifyMatrixByOrientation): First field dimension of input/output does not match left basis cardinality.");
467 INTREPID2_TEST_FOR_EXCEPTION( static_cast<ordinal_type>(output.extent(2)) != numFieldsRight, std::invalid_argument,
468 ">>> ERROR (OrientationTools::modifyMatrixByOrientation): Second field dimension of input/output does not match right basis cardinality.");
469 INTREPID2_TEST_FOR_EXCEPTION( static_cast<ordinal_type>(output.extent(3)) != 1, std::invalid_argument,
470 ">>> ERROR (OrientationTools::modifyMatrixByOrientation): Third dimension of output must be 1.");
471
472 }
473#endif
474 const shards::CellTopology cellTopo = basisLeft->getBaseCellTopology();
475 const ordinal_type cellDim = cellTopo.getDimension();
476
477 // apply orientations on left
478 decltype(output) outputLeft("temp view - output from left application", numCells, numFieldsLeft, numFieldsRight);
479
480 //Initialize outputLeft with values from input
481 if(input.rank() == output.rank())
482 Kokkos::deep_copy(outputLeft, input);
483 else
484 RealSpaceTools<DT>::clone(outputLeft, input);
485
486 if ((cellDim < 3) || basisLeft->requireOrientation()) {
487 bool leftMultiply = true;
488 auto ordinalToTag = Kokkos::create_mirror_view_and_copy(typename DT::memory_space(), basisLeft->getAllDofTags());
489 auto tagToOrdinal = Kokkos::create_mirror_view_and_copy(typename DT::memory_space(), basisLeft->getAllDofOrdinal());
490
491 const ordinal_type
492 numOtherFields = output.extent(2),
493 dimBasis = output.extent(3); //returns 1 when output.rank() < 4;
494
495 const CoeffMatrixDataViewType matData = createCoeffMatrix(basisLeft);
496
497 ordinal_type numVerts(0), numEdges(0), numFaces(0);
498
499 if (basisLeft->requireOrientation()) {
500 numVerts = cellTopo.getVertexCount()*ordinal_type(basisLeft->getDofCount(0, 0) > 0);
501 numEdges = cellTopo.getEdgeCount()*ordinal_type(basisLeft->getDofCount(1, 0) > 0);
502 numFaces = cellTopo.getFaceCount()*ordinal_type(basisLeft->getDofCount(2, 0) > 0);
503 }
504
505 const Kokkos::RangePolicy<typename DT::execution_space> policy(0, numCells);
507 <decltype(orts),
508 decltype(outputLeft),decltype(input),
509 decltype(ordinalToTag),decltype(tagToOrdinal),
510 decltype(matData)> FunctorType;
511 Kokkos::parallel_for
512 (policy,
513 FunctorType(orts,
514 outputLeft, input,
515 ordinalToTag, tagToOrdinal,
516 matData,
517 cellDim, numVerts, numEdges, numFaces,
518 numOtherFields, dimBasis, leftMultiply));
519 }
520
521 // apply orientations on right
522 //Initialize output with values from outputLeft
523 Kokkos::deep_copy(output, outputLeft);
524 if ((cellDim < 3) || basisRight->requireOrientation()) {
525 bool leftMultiply = false;
526 auto ordinalToTag = Kokkos::create_mirror_view_and_copy(typename DT::memory_space(), basisRight->getAllDofTags());
527 auto tagToOrdinal = Kokkos::create_mirror_view_and_copy(typename DT::memory_space(), basisRight->getAllDofOrdinal());
528
529 const ordinal_type
530 numOtherFields = output.extent(1),
531 dimBasis = output.extent(3); //returns 1 when output.rank() < 4;
532
533 const CoeffMatrixDataViewType matData = createCoeffMatrix(basisRight);
534
535 ordinal_type numVerts(0), numEdges(0), numFaces(0);
536
537 if (basisRight->requireOrientation()) {
538 numVerts = cellTopo.getVertexCount()*ordinal_type(basisRight->getDofCount(0, 0) > 0);
539 numEdges = cellTopo.getEdgeCount()*ordinal_type(basisRight->getDofCount(1, 0) > 0);
540 numFaces = cellTopo.getFaceCount()*ordinal_type(basisRight->getDofCount(2, 0) > 0);
541 }
542
543 const Kokkos::RangePolicy<typename DT::execution_space> policy(0, numCells);
545 <decltype(orts),
546 decltype(output),decltype(outputLeft),
547 decltype(ordinalToTag),decltype(tagToOrdinal),
548 decltype(matData)> FunctorType;
549 Kokkos::parallel_for
550 (policy,
551 FunctorType(orts,
552 output, outputLeft,
553 ordinalToTag, tagToOrdinal,
554 matData,
555 cellDim, numVerts, numEdges, numFaces,
556 numOtherFields, dimBasis, leftMultiply));
557 }
558 }
559
560} // namespace Intrepid2
561
562#endif
Header file for the Intrepid2::Orientation class.
static void modifyBasisByOrientationInverse(Kokkos::DynRankView< outputValueType, outputProperties... > output, const Kokkos::DynRankView< inputValueType, inputProperties... > input, const OrientationViewType orts, const BasisType *basis, const bool transpose=false)
Modify basis due to orientation, applying the inverse of the operator applied in modifyBasisByOrienta...
static void modifyBasisByOrientation(Kokkos::DynRankView< outputValueType, outputProperties... > output, const Kokkos::DynRankView< inputValueType, inputProperties... > input, const OrientationViewType orts, const BasisType *basis, const bool transpose=false)
Modify basis due to orientation.
Kokkos::View< double ****, DeviceType > CoeffMatrixDataViewType
subcell ordinal, orientation, matrix m x n
static void modifyMatrixByOrientation(Kokkos::DynRankView< outputValueType, outputProperties... > output, const Kokkos::DynRankView< inputValueType, inputProperties... > input, const OrientationViewType orts, const BasisTypeLeft *basisLeft, const BasisTypeRight *basisRight)
Modify an assembled (C,F1,F2) matrix according to orientation of the cells.
static void getOrientation(Kokkos::DynRankView< elemOrtValueType, elemOrtProperties... > elemOrts, const Kokkos::DynRankView< elemNodeValueType, elemNodeProperties... > elemNodes, const shards::CellTopology cellTopo, bool isSide=false)
Compute orientations of cells in a workset.
static void modifyBasisByOrientationTranspose(Kokkos::DynRankView< outputValueType, outputProperties... > output, const Kokkos::DynRankView< inputValueType, inputProperties... > input, const OrientationViewType orts, const BasisType *basis)
Modify basis due to orientation, applying the transpose of the operator applied in modifyBasisByOrien...
static void clone(Kokkos::DynRankView< outputValueType, outputProperties... > output, const Kokkos::DynRankView< inputValueType, inputProperties... > input)
Clone input array.