15#ifndef __INTREPID2_ORIENTATIONTOOLS_DEF_MATRIX_DATA_HPP__
16#define __INTREPID2_ORIENTATIONTOOLS_DEF_MATRIX_DATA_HPP__
19#if defined (__clang__) && !defined (__INTEL_COMPILER)
20#pragma clang system_header
26 template<
typename BasisHostType>
28 OrientationTools<DT>::createCoeffMatrixInternal(
const BasisHostType* basis,
const bool inverse) {
29 const std::string name(basis->getName());
30 CoeffMatrixDataViewType matData;
32 const auto cellTopo = basis->getBaseCellTopology();
33 const ordinal_type numEdges = cellTopo.getSubcellCount(1);
34 const ordinal_type numFaces = cellTopo.getSubcellCount(2);
35 ordinal_type matDim = 0, matDim1 = 0, matDim2 = 0, numOrts = 0, numSubCells;
36 for(ordinal_type i=0; i<numEdges; ++i) {
37 matDim1 = std::max(matDim1, basis->getDofCount(1,i));
38 numOrts = std::max(numOrts,2);
40 for(ordinal_type i=0; i<numFaces; ++i) {
41 matDim2 = std::max(matDim2, basis->getDofCount(2,i));
42 numOrts = std::max(numOrts,2*ordinal_type(cellTopo.getSideCount(2,i)));
44 matDim = std::max(matDim1,matDim2);
45 numSubCells = (matDim1>0)*numEdges + (matDim2>0)*numFaces;
48 matData = CoeffMatrixDataViewType(
"Orientation::CoeffMatrix::"+name,
54 if(basis->getFunctionSpace() == FUNCTION_SPACE_HGRAD) {
55 init_HGRAD(matData, basis, inverse);
56 }
else if (basis->getFunctionSpace() == FUNCTION_SPACE_HCURL) {
57 init_HCURL(matData, basis, inverse);
58 }
else if (basis->getFunctionSpace() == FUNCTION_SPACE_HDIV) {
59 init_HDIV(matData, basis, inverse);
60 }
else if (basis->getFunctionSpace() == FUNCTION_SPACE_HVOL) {
61 init_HVOL(matData, basis, inverse);
67 template<
typename BasisHostType>
69 OrientationTools<DT>::createEdgeOperatorsInternal(
const BasisHostType* basis, CoeffMatrixDataViewType matData)
71 const int EDGE_DIM = 1;
72 const int FACE_DIM = 2;
74 const std::string name(basis->getName());
75 OperatorViewType operators;
77 auto matDataHost = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), matData);
79 ordinal_type matDim1 = 0, matDim2 = 0, numOrts = 0, numEdgeOrts = 0;
80 const auto cellTopo = basis->getBaseCellTopology();
82 const ordinal_type numEdges = cellTopo.getSubcellCount(EDGE_DIM);
83 const ordinal_type numFaces = cellTopo.getSubcellCount(FACE_DIM);
84 for(ordinal_type i=0; i<numEdges; ++i) {
85 matDim1 = std::max(matDim1, basis->getDofCount(EDGE_DIM,i));
86 numEdgeOrts = std::max(numOrts,2);
87 numOrts = numEdgeOrts;
89 for(ordinal_type i=0; i<numFaces; ++i) {
90 matDim2 = std::max(matDim2, basis->getDofCount(2,i));
91 numOrts = std::max(numOrts,2*ordinal_type(cellTopo.getSideCount(FACE_DIM,i)));
94 operators = OperatorViewType(
"Orientation::EdgeOperators::"+name,
95 numEdges, numOrts, 2);
99 auto operatorsHost = Kokkos::create_mirror_view(operators);
104 for (ordinal_type subcellOrdinal=0; subcellOrdinal<static_cast<ordinal_type>(operatorsHost.extent(0)); ++subcellOrdinal)
106 for (ordinal_type ortOrdinal=0; ortOrdinal<static_cast<ordinal_type>(operatorsHost.extent(1)); ++ortOrdinal)
108 for (ordinal_type transposeInt=0; transposeInt<static_cast<ordinal_type>(operatorsHost.extent(2)); ++transposeInt)
110 operatorsHost(subcellOrdinal, ortOrdinal, transposeInt) = OrientationOperator<DT>();
118 Kokkos::deep_copy(operators, operatorsHost);
123 auto ordinalToTag = basis->getAllDofTags();
124 auto tagToOrdinal = basis->getAllDofOrdinal();
126 const ordinal_type numEdges = cellTopo.getSubcellCount(1);
130 for (ordinal_type edgeId=0;edgeId<numEdges;++edgeId)
132 for (ordinal_type edgeOrt=0; edgeOrt<numEdgeOrts; edgeOrt++)
134 std::vector<ordinal_type> nonIdentityDofs;
135 std::vector<ordinal_type> rowOffsets;
136 std::vector<ordinal_type> colIDs;
137 std::vector<double> weights;
139 const ordinal_type ordEdge = (1 < tagToOrdinal.extent(0) ? (
static_cast<size_type
>(edgeId) < tagToOrdinal.extent(1) ? tagToOrdinal(EDGE_DIM, edgeId, 0) : -1) : -1);
141 ordinal_type rowOffset = 0;
143 const ordinal_type ndofEdge = ordinalToTag(ordEdge, 3);
144 const auto mat = Kokkos::subview(matDataHost,
146 Kokkos::ALL(), Kokkos::ALL());
148 for (ordinal_type i=0;i<ndofEdge;++i) {
149 const ordinal_type ii = tagToOrdinal(EDGE_DIM, edgeId, i);
155 bool deviatesFromIdentity =
false;
156 for (ordinal_type l=0;l<ndofEdge;++l) {
157 const ordinal_type ll = tagToOrdinal(EDGE_DIM, edgeId, l);
158 auto & mat_il = mat(i,l);
162 if ((mat_il != 1.0) || (ii != ll))
164 deviatesFromIdentity =
true;
170 deviatesFromIdentity =
true;
173 INTREPID2_TEST_FOR_EXCEPTION(nnz == 0, std::invalid_argument,
"Each dof should have *some* nonzero weight");
174 if (deviatesFromIdentity)
177 nonIdentityDofs.push_back(ii);
178 rowOffsets.push_back(rowOffset);
181 for (ordinal_type l=0;l<ndofEdge;++l)
183 const ordinal_type ll = tagToOrdinal(EDGE_DIM, edgeId, l);
184 auto & mat_il = mat(i,l);
187 colIDs.push_back(ll);
188 weights.push_back(mat_il);
193 rowOffsets.push_back(rowOffset);
196 std::vector<bool> transposeVector {
false,
true};
197 for (
const bool transpose : transposeVector)
199 ordinal_type transposeInt = transpose ? 1 : 0;
200 OrientationOperator<DT> orientationOperator = constructOrientationOperatorInternal(nonIdentityDofs, rowOffsets, colIDs, weights, transpose);
201 operatorsHost(edgeId, edgeOrt, transposeInt) = orientationOperator;
208 Kokkos::deep_copy(operators, operatorsHost);
213 template<
typename DT>
214 template<
typename BasisHostType>
216 OrientationTools<DT>::createFaceOperatorsInternal(
const BasisHostType* basis, CoeffMatrixDataViewType matData)
218 const int EDGE_DIM = 1;
219 const int FACE_DIM = 2;
221 const std::string name(basis->getName());
222 OperatorViewType operators;
224 auto matDataHost = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), matData);
226 ordinal_type matDim1 = 0, matDim2 = 0, numOrts = 0, numEdgeOrts = 0, maxFaceOrts = 0;
227 const auto cellTopo = basis->getBaseCellTopology();
229 const ordinal_type numEdges = cellTopo.getSubcellCount(EDGE_DIM);
230 const ordinal_type numFaces = cellTopo.getSubcellCount(FACE_DIM);
231 for(ordinal_type i=0; i<numEdges; ++i) {
232 matDim1 = std::max(matDim1, basis->getDofCount(EDGE_DIM,i));
233 numEdgeOrts = std::max(numOrts,2);
234 numOrts = numEdgeOrts;
236 for(ordinal_type i=0; i<numFaces; ++i) {
237 matDim2 = std::max(matDim2, basis->getDofCount(FACE_DIM,i));
238 const ordinal_type faceEdgeCount =
static_cast<ordinal_type
>(cellTopo.getSideCount(FACE_DIM,i));
239 maxFaceOrts = std::max(maxFaceOrts,2*faceEdgeCount);
241 numOrts = std::max(numOrts,maxFaceOrts);
245 operators = OperatorViewType(
"Orientation::FaceOperators::"+name,
246 numFaces, numOrts, 2);
250 auto operatorsHost = Kokkos::create_mirror_view(operators);
255 for (ordinal_type subcellOrdinal=0; subcellOrdinal<static_cast<ordinal_type>(operatorsHost.extent(0)); ++subcellOrdinal)
257 for (ordinal_type ortOrdinal=0; ortOrdinal<static_cast<ordinal_type>(operatorsHost.extent(1)); ++ortOrdinal)
259 for (ordinal_type transposeInt=0; transposeInt<static_cast<ordinal_type>(operatorsHost.extent(2)); ++transposeInt)
261 operatorsHost(subcellOrdinal, ortOrdinal, transposeInt) = OrientationOperator<DT>();
269 Kokkos::deep_copy(operators, operatorsHost);
274 ordinal_type existEdgeDofs = (matDim1 > 0) ? 1 : 0;
276 if ((basis->getFunctionSpace() != FUNCTION_SPACE_HDIV) || (cellTopo.getDimension() == 3))
278 auto ordinalToTag = basis->getAllDofTags();
279 auto tagToOrdinal = basis->getAllDofOrdinal();
281 const ordinal_type numEdges = cellTopo.getSubcellCount(1);
282 const ordinal_type numFaces = cellTopo.getSubcellCount(2);
286 for (ordinal_type faceId=0;faceId<numFaces;++faceId)
288 const ordinal_type ordFace = (2 < tagToOrdinal.extent(0) ? (
static_cast<size_type
>(faceId) < tagToOrdinal.extent(1) ? tagToOrdinal(FACE_DIM, faceId, 0) : -1) : -1);
290 const ordinal_type numFaceOrts = 2*ordinal_type(cellTopo.getSideCount(FACE_DIM,faceId));
292 for (ordinal_type faceOrt=0; faceOrt<numFaceOrts; faceOrt++)
294 std::vector<ordinal_type> nonIdentityDofs;
295 std::vector<ordinal_type> rowOffsets;
296 std::vector<ordinal_type> colIDs;
297 std::vector<double> weights;
299 ordinal_type rowOffset = 0;
302 const ordinal_type ndofFace = ordinalToTag(ordFace, 3);
303 const auto mat = Kokkos::subview(matDataHost,
304 numEdges*existEdgeDofs+faceId, faceOrt,
305 Kokkos::ALL(), Kokkos::ALL());
306 for (ordinal_type i=0;i<ndofFace;++i) {
308 const ordinal_type ii = tagToOrdinal(FACE_DIM, faceId, i);
314 bool deviatesFromIdentity =
false;
315 for (ordinal_type l=0;l<ndofFace;++l) {
316 const ordinal_type ll = tagToOrdinal(FACE_DIM, faceId, l);
317 auto & mat_il = mat(i,l);
321 if ((mat_il != 1.0) || (ii != ll))
323 deviatesFromIdentity =
true;
329 deviatesFromIdentity =
true;
332 INTREPID2_TEST_FOR_EXCEPTION(nnz == 0, std::invalid_argument,
"Each dof should have *some* nonzero weight");
333 if (deviatesFromIdentity)
336 nonIdentityDofs.push_back(ii);
337 rowOffsets.push_back(rowOffset);
340 for (ordinal_type l=0;l<ndofFace;++l)
342 const ordinal_type ll = tagToOrdinal(FACE_DIM, faceId, l);
343 auto & mat_il = mat(i,l);
346 colIDs.push_back(ll);
347 weights.push_back(mat_il);
352 rowOffsets.push_back(rowOffset);
353 std::vector<bool> transposeVector {
false,
true};
354 for (
const bool transpose : transposeVector)
356 ordinal_type transposeInt = transpose ? 1 : 0;
357 OrientationOperator<DT> orientationOperator = constructOrientationOperatorInternal(nonIdentityDofs, rowOffsets, colIDs, weights, transpose);
358 operatorsHost(faceId, faceOrt, transposeInt) = orientationOperator;
366 Kokkos::deep_copy(operators, operatorsHost);
374 template<
typename DT>
375 template<
typename BasisHostType>
379 BasisHostType
const *cellBasis,
380 const bool inverse) {
382 const auto cellTopo = cellBasis->getBaseCellTopology();
383 const ordinal_type numEdges = cellTopo.getSubcellCount(1);
384 const ordinal_type numFaces = cellTopo.getSubcellCount(2);
386 typename BasisHostType::OutputValueType,
387 typename BasisHostType::PointValueType>
389 BasisHostType
const *subcellBasis;
392 subcellBasis = cellBasis;
393 const ordinal_type numOrt = 2;
394 for (ordinal_type edgeId=0;edgeId<numEdges;++edgeId) {
395 if(cellBasis->getDofCount(1, edgeId) < 1)
continue;
396 if(cellTopo.getDimension()!=1) {
397 basisPtr = cellBasis->getSubCellRefBasis(1,edgeId);
398 subcellBasis = basisPtr.get();
401 for (ordinal_type edgeOrt=0;edgeOrt<numOrt;++edgeOrt) {
402 auto mat = Kokkos::subview(matData,
404 Kokkos::ALL(), Kokkos::ALL());
407 *subcellBasis, *cellBasis,
408 edgeId, edgeOrt, inverse);
413 subcellBasis = cellBasis;
414 for (ordinal_type faceId=0;faceId<numFaces;++faceId) {
416 const ordinal_type numOrt = 2*cellTopo.getSideCount(2,faceId);
417 if(cellBasis->getDofCount(2, faceId) < 1)
continue;
418 if(cellTopo.getDimension()!=2) {
419 basisPtr = cellBasis->getSubCellRefBasis(2,faceId);
420 subcellBasis = basisPtr.get();
422 for (ordinal_type faceOrt=0;faceOrt<numOrt;++faceOrt) {
423 auto mat = Kokkos::subview(matData,
424 numEdges+faceId, faceOrt,
425 Kokkos::ALL(), Kokkos::ALL());
428 *subcellBasis, *cellBasis,
429 faceId, faceOrt, inverse);
438 template<
typename DT>
439 template<
typename BasisHostType>
443 BasisHostType
const *cellBasis,
const bool inverse) {
444 const auto cellTopo = cellBasis->getBaseCellTopology();
445 const ordinal_type numEdges = cellTopo.getSubcellCount(1);
446 const ordinal_type numFaces = cellTopo.getSubcellCount(2);
448 typename BasisHostType::OutputValueType,
449 typename BasisHostType::PointValueType>
451 BasisHostType
const* subcellBasis;
454 subcellBasis = cellBasis;
455 const ordinal_type numOrt = 2;
456 for (ordinal_type edgeId=0;edgeId<numEdges;++edgeId) {
457 if(cellBasis->getDofCount(1, edgeId) < 1)
continue;
458 if(cellTopo.getDimension()!=1) {
459 basisPtr = cellBasis->getSubCellRefBasis(1,edgeId);
460 subcellBasis = basisPtr.get();
462 for (ordinal_type edgeOrt=0;edgeOrt<numOrt;++edgeOrt) {
463 auto mat = Kokkos::subview(matData,
465 Kokkos::ALL(), Kokkos::ALL());
467 *subcellBasis, *cellBasis,
468 edgeId, edgeOrt, inverse);
473 subcellBasis = cellBasis;
474 for (ordinal_type faceId=0;faceId<numFaces;++faceId) {
476 const ordinal_type numOrt = 2*cellTopo.getSideCount(2,faceId);
477 if(cellBasis->getDofCount(2, faceId) < 1)
continue;
478 if(cellTopo.getDimension()!=2) {
479 basisPtr = cellBasis->getSubCellRefBasis(2,faceId);
480 subcellBasis = basisPtr.get();
482 for (ordinal_type faceOrt=0;faceOrt<numOrt;++faceOrt) {
483 auto mat = Kokkos::subview(matData,
484 numEdges+faceId, faceOrt,
485 Kokkos::ALL(), Kokkos::ALL());
488 *subcellBasis, *cellBasis,
489 faceId, faceOrt, inverse);
498 template<
typename DT>
499 template<
typename BasisHostType>
503 BasisHostType
const *cellBasis,
const bool inverse) {
504 const auto cellTopo = cellBasis->getBaseCellTopology();
505 const ordinal_type numSides = cellTopo.getSideCount();
506 const ordinal_type sideDim = cellTopo.getDimension()-1;
508 typename BasisHostType::OutputValueType,
509 typename BasisHostType::PointValueType>
513 for (ordinal_type sideId=0;sideId<numSides;++sideId) {
514 if(cellBasis->getDofCount(sideDim, sideId) < 1)
continue;
515 const ordinal_type numOrt = (sideDim == 1) ? 2 : 2*cellTopo.getSideCount(sideDim,sideId);
516 subcellBasisPtr = cellBasis->getSubCellRefBasis(sideDim,sideId);
517 for (ordinal_type faceOrt=0;faceOrt<numOrt;++faceOrt) {
518 auto mat = Kokkos::subview(matData,
520 Kokkos::ALL(), Kokkos::ALL());
522 *subcellBasisPtr, *cellBasis,
523 sideId, faceOrt, inverse);
532 template<
typename DT>
533 template<
typename BasisHostType>
537 BasisHostType
const *cellBasis,
const bool inverse) {
539 const auto cellTopo = cellBasis->getBaseCellTopology();
540 const ordinal_type numEdges = (cellTopo.getDimension()==1);
541 const ordinal_type numFaces = (cellTopo.getDimension()==2);
544 const ordinal_type numOrt = 2;
545 for (ordinal_type edgeId=0;edgeId<numEdges;++edgeId) {
546 if(cellBasis->getDofCount(1, edgeId) < 1)
continue;
547 for (ordinal_type edgeOrt=0;edgeOrt<numOrt;++edgeOrt) {
548 auto mat = Kokkos::subview(matData,
550 Kokkos::ALL(), Kokkos::ALL());
552 (mat, *cellBasis, edgeOrt, inverse);
557 for (ordinal_type faceId=0;faceId<numFaces;++faceId) {
559 const ordinal_type numOrt = 2*cellTopo.getSideCount(2,faceId);
560 if(cellBasis->getDofCount(2, faceId) < 1)
continue;
561 for (ordinal_type faceOrt=0;faceOrt<numOrt;++faceOrt) {
562 auto mat = Kokkos::subview(matData,
563 numEdges+faceId, faceOrt,
564 Kokkos::ALL(), Kokkos::ALL());
566 (mat, *cellBasis, faceOrt, inverse);
572 template<
typename DT>
573 template<
typename BasisType>
576 static bool hookRegistered =
false;
579 Kokkos::push_finalize_hook( [=] {
580 ortCoeffData.clear();
582 hookRegistered =
true;
585 const KeyType key(basis->getName(), basis->getDegree());
586 const auto found = ortCoeffData.find(key);
589 if (found == ortCoeffData.end()) {
591 auto basis_host = basis->getHostBasis();
592 matData = createCoeffMatrixInternal(basis_host.getRawPtr());
593 ortCoeffData.insert(std::make_pair(key, matData));
596 matData = found->second;
602 template<
typename DT>
603 template<
typename BasisType>
606 static bool hookRegistered =
false;
609 Kokkos::push_finalize_hook( [=] {
610 ortInvCoeffData.clear();
612 hookRegistered =
true;
615 const KeyType key(basis->getName(), basis->getDegree());
616 const auto found = ortInvCoeffData.find(key);
619 if (found == ortInvCoeffData.end()) {
621 auto basis_host = basis->getHostBasis();
622 matData = createCoeffMatrixInternal(basis_host.getRawPtr(),
true);
623 ortInvCoeffData.insert(std::make_pair(key, matData));
626 matData = found->second;
632 template<
typename DT>
633 template<
typename BasisType>
636 static bool hookRegistered =
false;
639 Kokkos::push_finalize_hook( [=] {
640 edgeOperatorData.clear();
641 faceOperatorData.clear();
643 hookRegistered =
true;
646 const std::pair<std::string,ordinal_type> key(basis->getName(), basis->getDegree());
647 const auto edgeFound = edgeOperatorData.find(key);
648 const auto faceFound = faceOperatorData.find(key);
650 OperatorViewType edgeOperator, faceOperator;
651 if (edgeFound == edgeOperatorData.end()) {
653 auto basis_host = basis->getHostBasis();
654 auto matData = createCoeffMatrix(basis);
656 edgeOperator = createEdgeOperatorsInternal(basis_host.get(), matData);
658 edgeOperatorData.insert(std::make_pair(key, edgeOperator));
660 faceOperator = createFaceOperatorsInternal(basis_host.get(), matData);
661 faceOperatorData.insert(std::make_pair(key, faceOperator));
664 edgeOperator = edgeFound->second;
665 INTREPID2_TEST_FOR_EXCEPTION(faceFound == faceOperatorData.end(), std::invalid_argument,
"edgeOperator found while faceOperator was not");
666 faceOperator = faceFound->second;
669 return std::make_tuple(edgeOperator,faceOperator);
672 template<
typename DT>
673 template<
typename BasisType>
676 static bool hookRegistered =
false;
679 Kokkos::push_finalize_hook( [=] {
680 invEdgeOperatorData.clear();
681 invFaceOperatorData.clear();
683 hookRegistered =
true;
686 const std::pair<std::string,ordinal_type> key(basis->getName(), basis->getDegree());
687 const auto edgeFound = invEdgeOperatorData.find(key);
688 const auto faceFound = invFaceOperatorData.find(key);
690 OperatorViewType edgeOperator, faceOperator;
691 if (edgeFound == invEdgeOperatorData.end()) {
693 auto basis_host = basis->getHostBasis();
694 auto matData = createInvCoeffMatrix(basis);
696 edgeOperator = createEdgeOperatorsInternal(basis_host.get(), matData);
697 invEdgeOperatorData.insert(std::make_pair(key, edgeOperator));
699 faceOperator = createFaceOperatorsInternal(basis_host.get(), matData);
700 invFaceOperatorData.insert(std::make_pair(key, faceOperator));
703 edgeOperator = edgeFound->second;
704 INTREPID2_TEST_FOR_EXCEPTION(faceFound == invFaceOperatorData.end(), std::invalid_argument,
"edgeOperator found while faceOperator was not");
705 faceOperator = faceFound->second;
708 return std::make_tuple(edgeOperator,faceOperator);
711 template<
typename DT>
713 ortCoeffData.clear();
714 ortInvCoeffData.clear();
716 edgeOperatorData.clear();
717 invEdgeOperatorData.clear();
718 faceOperatorData.clear();
719 invFaceOperatorData.clear();
721 doubleViewAllocations.clear();
722 ordinalViewAllocations.clear();
725 template<
typename DT>
727 const std::vector<ordinal_type> &rowOffsets,
728 const std::vector<ordinal_type> &colIDs,
729 const std::vector<double> &weights,
const bool transpose)
731 static bool hookRegistered =
false;
734 Kokkos::push_finalize_hook( [=] {
735 doubleViewAllocations.clear();
736 ordinalViewAllocations.clear();
738 hookRegistered =
true;
741 const int numRows =
static_cast<int>(nonIdentityDofs.size());
746 const int numWeights = rowOffsets[numRows];
748 const bool isWeightedPermutation = (nonIdentityDofs.size() == weights.size());
749 const int numOffsetsToStore = isWeightedPermutation ? 0 : numRows+1;
751 Kokkos::View<ordinal_type*,DT> rowIndices(
"OrientationOperator: rowIndices", numRows);
752 Kokkos::View<ordinal_type*,DT> offsetForRowOrdinal(
"OrientationOperator: rowOffsets", numOffsetsToStore);
753 Kokkos::View<ordinal_type*,DT> packedColumnIndices(
"OrientationOperator: packedColumnIndices", numWeights);
754 Kokkos::View<double*, DT> packedWeights(
"OrientationOperator: packedWeights", numWeights);
756 auto rowIndicesHost = Kokkos::create_mirror_view(rowIndices);
757 auto offsetForRowOrdinalHost = Kokkos::create_mirror_view(offsetForRowOrdinal);
758 auto packedColumnIndicesHost = Kokkos::create_mirror_view(packedColumnIndices);
759 auto packedWeightsHost = Kokkos::create_mirror_view(packedWeights);
761 for (
int rowOrdinal=0; rowOrdinal<numRows; rowOrdinal++)
763 rowIndicesHost(rowOrdinal) = nonIdentityDofs[rowOrdinal];
764 int thisRowOffset = rowOffsets[rowOrdinal];
765 int nextRowOffset = rowOffsets[rowOrdinal+1];
766 if (isWeightedPermutation)
768 INTREPID2_TEST_FOR_EXCEPTION(nextRowOffset - thisRowOffset != 1, std::invalid_argument,
"Invalid orientation operator arguments: if number of weights is equal to the number of row indices, then row offsets should exactly match row ordinals (i.e., there should be exactly one column for every row entry).");
772 offsetForRowOrdinalHost(rowOrdinal) = thisRowOffset;
774 for (
int i=thisRowOffset; i<nextRowOffset; i++)
776 packedColumnIndicesHost(i) = colIDs[i];
777 packedWeightsHost(i) = weights[i];
780 if (!isWeightedPermutation)
782 offsetForRowOrdinalHost(numRows) = numWeights;
785 Kokkos::deep_copy(rowIndices, rowIndicesHost);
786 Kokkos::deep_copy(offsetForRowOrdinal, offsetForRowOrdinalHost);
787 Kokkos::deep_copy(packedColumnIndices, packedColumnIndicesHost);
788 Kokkos::deep_copy(packedWeights, packedWeightsHost);
791 ordinalViewAllocations.push_back(rowIndices);
792 ordinalViewAllocations.push_back(offsetForRowOrdinal);
793 ordinalViewAllocations.push_back(packedColumnIndices);
794 doubleViewAllocations.push_back(packedWeights);
799 UnmanagedOrdinalView rowIndicesUnmanaged (rowIndices.data(), rowIndices.extent(0));
800 UnmanagedOrdinalView offsetForRowOrdinalUnmanaged(offsetForRowOrdinal.data(), offsetForRowOrdinal.extent(0));
801 UnmanagedOrdinalView packedColumnIndicesUnmanaged(packedColumnIndices.data(), packedColumnIndices.extent(0));
802 UnmanagedDoubleView packedWeightsUnmanaged (packedWeights.data(), packedWeights.extent(0));
804 if (!isWeightedPermutation)
807 packedColumnIndicesUnmanaged, packedWeightsUnmanaged);
809 return orientationOperator;
814 packedColumnIndicesUnmanaged, packedWeightsUnmanaged);
816 return orientationOperator;
823 std::map<ordinal_type, std::map<ordinal_type,double> > transposeOperator;
824 std::set<ordinal_type> opRows(nonIdentityDofs.begin(), nonIdentityDofs.end());
826 for (ordinal_type rowOrdinal = 0; rowOrdinal < numRows; rowOrdinal++)
828 const ordinal_type & rowID = nonIdentityDofs[rowOrdinal];
829 const ordinal_type & rowOffset = rowOffsets[rowOrdinal];
831 const ordinal_type numCols = rowOffsets[rowOrdinal+1] - rowOffset;
832 for (ordinal_type colOrdinal=0; colOrdinal<numCols; colOrdinal++)
834 const ordinal_type & colID = colIDs[rowOffset + colOrdinal];
835 const double & weight = weights[rowOffset + colOrdinal];
836 transposeOperator[colID][rowID] = weight;
837 if (opRows.find(colID) == opRows.end())
840 transposeOperator[colID][colID] = 1.0;
845 std::vector<ordinal_type> nonIdentityColDofs;
846 std::vector<ordinal_type> colOffsets;
847 std::vector<ordinal_type> rowIDs;
848 std::vector<double> weightsTranspose;
850 colOffsets.push_back(0);
851 for (
const auto & entry : transposeOperator)
853 const ordinal_type & colID = entry.first;
854 nonIdentityColDofs.push_back(colID);
855 const auto & rowMap = entry.second;
856 for (
const auto & rowEntry : rowMap)
858 const ordinal_type & rowID = rowEntry.first;
859 const double & weight = rowEntry.second;
861 rowIDs.push_back(rowID);
862 weightsTranspose.push_back(weight);
864 colOffsets.push_back(
static_cast<ordinal_type
>(rowIDs.size()));
867 return constructOrientationOperatorInternal(nonIdentityColDofs, colOffsets, rowIDs, weightsTranspose,
false);
Teuchos::RCP< Basis< DeviceType, OutputType, PointType > > BasisPtr
Basis Pointer.