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 
25 namespace 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(ll, j, k) : in(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(ii, j, k) : out(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(ll, j, k) : in(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(ii, j, k) : out(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(ll, j, k) : in(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(ii, j, k) : out(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(ll, j, k) : in(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(ii, j, k) : out(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
Kokkos::View< double ****, DeviceType > CoeffMatrixDataViewType
subcell ordinal, orientation, matrix m x n
static void clone(Kokkos::DynRankView< outputValueType, outputProperties...> output, const Kokkos::DynRankView< inputValueType, inputProperties...> input)
Clone input array.
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.
Header file for the Intrepid2::Orientation class.
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.
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 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...