47 #ifndef __INTREPID2_PROJECTIONTOOLS_HPP__
48 #define __INTREPID2_PROJECTIONTOOLS_HPP__
50 #include "Intrepid2_ConfigDefs.hpp"
54 #include "Shards_CellTopology.hpp"
55 #include "Shards_BasicTopologies.hpp"
100 #include "Teuchos_LAPACK.hpp"
105 #ifdef HAVE_INTREPID2_KOKKOSKERNELS
106 #include "KokkosBatched_QR_Serial_Internal.hpp"
107 #include "KokkosBatched_ApplyQ_Serial_Internal.hpp"
108 #include "KokkosBatched_Trsv_Serial_Internal.hpp"
109 #include "KokkosBatched_Util.hpp"
112 namespace Intrepid2 {
114 namespace Experimental {
182 template<
typename ExecSpaceType>
186 using EvalPointsType =
typename ProjectionStruct<ExecSpaceType, double>::EvalPointsType;
205 template<
typename BasisType,
206 typename ortValueType,
class ...ortProperties>
209 const Kokkos::DynRankView<ortValueType, ortProperties...> cellOrientations,
210 const BasisType* cellBasis,
212 const EvalPointsType evalPointType = EvalPointsType::TARGET
234 template<
typename basisCoeffsValueType,
class ...basisCoeffsProperties,
235 typename funValsValueType,
class ...funValsProperties,
237 typename ortValueType,
class ...ortProperties>
239 getL2BasisCoeffs(Kokkos::DynRankView<basisCoeffsValueType,basisCoeffsProperties...> basisCoeffs,
240 const Kokkos::DynRankView<funValsValueType,funValsProperties...> targetAtEvalPoints,
241 const typename BasisType::ScalarViewType evaluationPoints,
242 const Kokkos::DynRankView<ortValueType, ortProperties...> cellOrientations,
243 const BasisType* cellBasis,
266 template<
typename BasisType,
267 typename ortValueType,
class ...ortProperties>
270 typename BasisType::ScalarViewType gradEvalPoints,
271 const Kokkos::DynRankView<ortValueType, ortProperties...> cellOrientations,
272 const BasisType* cellBasis,
274 const EvalPointsType evalPointType = EvalPointsType::TARGET
300 template<
typename basisCoeffsValueType,
class ...basisCoeffsProperties,
301 typename funValsValueType,
class ...funValsProperties,
303 typename ortValueType,
class ...ortProperties>
305 getHGradBasisCoeffs(Kokkos::DynRankView<basisCoeffsValueType,basisCoeffsProperties...> basisCoeffs,
306 const Kokkos::DynRankView<funValsValueType,funValsProperties...> targetAtEvalPoints,
307 const Kokkos::DynRankView<funValsValueType,funValsProperties...> targetGradAtGradEvalPoints,
308 const typename BasisType::ScalarViewType evaluationPoints,
309 const typename BasisType::ScalarViewType gradEvalPoints,
310 const Kokkos::DynRankView<ortValueType, ortProperties...> cellOrientations,
311 const BasisType* cellBasis,
334 template<
typename BasisType,
335 typename ortValueType,
class ...ortProperties>
338 typename BasisType::ScalarViewType curlEvalPoints,
339 const Kokkos::DynRankView<ortValueType, ortProperties...> cellOrientations,
340 const BasisType* cellBasis,
342 const EvalPointsType evalPointType = EvalPointsType::TARGET
370 template<
typename basisCoeffsValueType,
class ...basisCoeffsProperties,
371 typename funValsValueType,
class ...funValsProperties,
373 typename ortValueType,
class ...ortProperties>
375 getHCurlBasisCoeffs(Kokkos::DynRankView<basisCoeffsValueType,basisCoeffsProperties...> basisCoeffs,
376 const Kokkos::DynRankView<funValsValueType,funValsProperties...> targetAtEvalPoints,
377 const Kokkos::DynRankView<funValsValueType,funValsProperties...> targetCurlAtCurlEvalPoints,
378 const typename BasisType::ScalarViewType evaluationPoints,
379 const typename BasisType::ScalarViewType curlEvalPoints,
380 const Kokkos::DynRankView<ortValueType, ortProperties...> cellOrientations,
381 const BasisType* cellBasis,
404 template<
typename BasisType,
405 typename ortValueType,
class ...ortProperties>
408 typename BasisType::ScalarViewType divEvalPoints,
409 const Kokkos::DynRankView<ortValueType, ortProperties...> cellOrientations,
410 const BasisType* cellBasis,
412 const EvalPointsType evalPointType = EvalPointsType::TARGET
438 template<
typename basisCoeffsValueType,
class ...basisCoeffsProperties,
439 typename funValsValueType,
class ...funValsProperties,
441 typename ortValueType,
class ...ortProperties>
443 getHDivBasisCoeffs(Kokkos::DynRankView<basisCoeffsValueType,basisCoeffsProperties...> basisCoeffs,
444 const Kokkos::DynRankView<funValsValueType,funValsProperties...> targetAtEvalPoints,
445 const Kokkos::DynRankView<funValsValueType,funValsProperties...> targetDivAtDivEvalPoints,
446 const typename BasisType::ScalarViewType evaluationPoints,
447 const typename BasisType::ScalarViewType divEvalPoints,
448 const Kokkos::DynRankView<ortValueType, ortProperties...> cellOrientations,
449 const BasisType* cellBasis,
468 template<
typename BasisType,
469 typename ortValueType,
class ...ortProperties>
472 const Kokkos::DynRankView<ortValueType, ortProperties...> cellOrientations,
473 const BasisType* cellBasis,
475 const EvalPointsType evalPointType = EvalPointsType::TARGET
496 template<
typename basisCoeffsValueType,
class ...basisCoeffsProperties,
497 typename funValsValueType,
class ...funValsProperties,
499 typename ortValueType,
class ...ortProperties>
501 getHVolBasisCoeffs(Kokkos::DynRankView<basisCoeffsValueType,basisCoeffsProperties...> basisCoeffs,
502 const Kokkos::DynRankView<funValsValueType,funValsProperties...> targetAtEvalPoints,
503 const typename BasisType::ScalarViewType evaluationPoints,
504 const Kokkos::DynRankView<ortValueType, ortProperties...> cellOrientations,
505 const BasisType* cellBasis,
521 std::string systemName_;
522 bool matrixIndependentOfCell_;
531 ElemSystem (std::string systemName,
bool matrixIndependentOfCell) :
532 systemName_(systemName), matrixIndependentOfCell_(matrixIndependentOfCell){};
561 template<
typename ViewType1,
typename ViewType2,
typename ViewType3,
typename ViewType4>
562 void solve(ViewType1 basisCoeffs, ViewType2 elemMat, ViewType2 elemRhs, ViewType2 tau,
563 ViewType3 w,
const ViewType4 elemDof, ordinal_type n, ordinal_type m=0) {
564 #ifdef HAVE_INTREPID2_KOKKOSKERNELS
565 solveParallel(basisCoeffs, elemMat, elemRhs, tau,
576 #ifdef HAVE_INTREPID2_KOKKOSKERNELS
577 template<
typename ViewType1,
typename ViewType2,
typename ViewType3,
typename ViewType4>
578 void solveParallel(ViewType1 basisCoeffs, ViewType2 elemMat, ViewType2 elemRhs, ViewType2 taul,
579 ViewType3 work,
const ViewType4 elemDof, ordinal_type n, ordinal_type m) {
581 ordinal_type numCells = basisCoeffs.extent(0);
583 if(matrixIndependentOfCell_) {
584 auto A0 = Kokkos::subview(elemMat, 0, Kokkos::ALL(), Kokkos::ALL());
585 auto tau0 = Kokkos::subview(taul, 0, Kokkos::ALL());
587 auto A0_host = Kokkos::create_mirror_view_and_copy(
typename ExecSpaceType::memory_space(), A0);
588 auto tau0_host = Kokkos::create_mirror_view(
typename ExecSpaceType::memory_space(), tau0);
591 for(ordinal_type i=n; i<n+m; ++i)
592 for(ordinal_type j=0; j<n; ++j)
593 A0_host(i,j) = A0_host(j,i);
595 auto w0_host = Kokkos::create_mirror_view(Kokkos::subview(work, 0, Kokkos::ALL()));
598 KokkosBatched::SerialQR_Internal::invoke(A0_host.extent(0), A0_host.extent(1),
599 A0_host.data(), A0_host.stride_0(), A0_host.stride_1(),
600 tau0_host.data(), tau0_host.stride_0(), w0_host.data());
602 Kokkos::deep_copy(A0, A0_host);
603 Kokkos::deep_copy(tau0, tau0_host);
605 Kokkos::parallel_for (systemName_,
606 Kokkos::RangePolicy<ExecSpaceType, int> (0, numCells),
607 KOKKOS_LAMBDA (
const size_t ic) {
608 auto w = Kokkos::subview(work, ic, Kokkos::ALL());
610 auto b = Kokkos::subview(elemRhs, ic, Kokkos::ALL());
613 KokkosBatched::SerialApplyQ_RightNoTransForwardInternal::invoke(
614 1, A0.extent(0), A0.extent(1),
615 A0.data(), A0.stride_0(), A0.stride_1(),
616 tau0.data(), tau0.stride_0(),
617 b.data(), 1, b.stride_0(),
621 KokkosBatched::SerialTrsvInternalUpper<KokkosBatched::Algo::Trsv::Unblocked>::invoke(
false,
624 A0.data(), A0.stride_0(), A0.stride_1(),
625 b.data(), b.stride_0());
628 for(ordinal_type i=0; i<n; ++i){
629 basisCoeffs(ic,elemDof(i)) = b(i);
635 Kokkos::parallel_for (systemName_,
636 Kokkos::RangePolicy<ExecSpaceType, int> (0, numCells),
637 KOKKOS_LAMBDA (
const size_t ic) {
639 auto A = Kokkos::subview(elemMat, ic, Kokkos::ALL(), Kokkos::ALL());
640 auto tau = Kokkos::subview(taul, ic, Kokkos::ALL());
641 auto w = Kokkos::subview(work, ic, Kokkos::ALL());
643 for(ordinal_type i=n; i<n+m; ++i)
644 for(ordinal_type j=0; j<n; ++j)
648 KokkosBatched::SerialQR_Internal::invoke(A.extent(0), A.extent(1),
649 A.data(), A.stride_0(), A.stride_1(), tau.data(), tau.stride_0(), w.data());
651 auto b = Kokkos::subview(elemRhs, ic, Kokkos::ALL());
654 KokkosBatched::SerialApplyQ_RightNoTransForwardInternal::invoke(
655 1, A.extent(0), A.extent(1),
656 A.data(), A.stride_0(), A.stride_1(),
657 tau.data(), tau.stride_0(),
658 b.data(), 1, b.stride_0(),
662 KokkosBatched::SerialTrsvInternalUpper<KokkosBatched::Algo::Trsv::Unblocked>::invoke(
false,
665 A.data(), A.stride_0(), A.stride_1(),
666 b.data(), b.stride_0());
669 for(ordinal_type i=0; i<n; ++i){
670 basisCoeffs(ic,elemDof(i)) = b(i);
680 template<
typename ViewType1,
typename ViewType2,
typename ViewType3,
typename ViewType4>
681 void solveSerial(ViewType1 basisCoeffs, ViewType2 elemMat, ViewType2 elemRhs, ViewType2 ,
682 ViewType3,
const ViewType4 elemDof, ordinal_type n, ordinal_type m) {
683 using valueType =
typename ViewType2::value_type;
684 using host_space_type =
typename Kokkos::Impl::is_space<ExecSpaceType>::host_mirror_space::execution_space;
685 Kokkos::View<valueType**,Kokkos::LayoutLeft,host_space_type>
686 serialElemMat(
"serialElemMat", n+m, n+m);
687 Teuchos::LAPACK<ordinal_type,valueType> lapack_;
688 ordinal_type numCells = basisCoeffs.extent(0);
690 if(matrixIndependentOfCell_) {
691 ViewType2 elemRhsTrans(
"transRhs", elemRhs.extent(1), elemRhs.extent(0));
692 Kokkos::View<valueType**,Kokkos::LayoutLeft,host_space_type>
693 pivVec(
"pivVec", m+n + std::max(m+n, numCells), 1);
695 Kokkos::View<valueType**,Kokkos::LayoutLeft,host_space_type> serialElemRhs(
"serialElemRhs", n+m, numCells);
697 auto A = Kokkos::create_mirror_view_and_copy(
typename ExecSpaceType::memory_space(),
698 Kokkos::subview(elemMat, 0, Kokkos::ALL(), Kokkos::ALL()));
699 auto b = Kokkos::create_mirror_view_and_copy(
typename ExecSpaceType::memory_space(), elemRhs);
701 auto serialBasisCoeffs = Kokkos::create_mirror_view_and_copy(
702 typename ExecSpaceType::memory_space(), basisCoeffs);
704 for(ordinal_type i=0; i<m+n; ++i) {
705 for(ordinal_type ic=0; ic< numCells; ++ic)
706 serialElemRhs(i,ic) = b(ic,i);
707 for(ordinal_type j=0; j<n; ++j)
708 serialElemMat(j,i) = A(j,i);
711 for(ordinal_type i=n; i<n+m; ++i)
712 for(ordinal_type j=0; j<n; ++j)
713 serialElemMat(i,j) = serialElemMat(j,i);
715 ordinal_type info = 0;
716 lapack_.GELS(
'N', n+m, n+m, numCells,
717 serialElemMat.data(), serialElemMat.stride_1(),
718 serialElemRhs.data(), serialElemRhs.stride_1(),
719 pivVec.data(), pivVec.extent(0),
722 for(ordinal_type i=0; i<n; ++i) {
723 for (ordinal_type ic = 0; ic < numCells; ic++)
724 serialBasisCoeffs(ic,elemDof(i)) = serialElemRhs(i,ic);
728 Kokkos::View<valueType**,Kokkos::LayoutLeft,host_space_type> pivVec(
"pivVec", 2*(m+n), 1);
729 Kokkos::View<valueType**,Kokkos::LayoutLeft,host_space_type> serialElemRhs(
"serialElemRhs", n+m, 1 );
730 for (ordinal_type ic = 0; ic < numCells; ic++) {
731 auto A = Kokkos::create_mirror_view_and_copy(
typename ExecSpaceType::memory_space(),
732 Kokkos::subview(elemMat, ic, Kokkos::ALL(), Kokkos::ALL()));
733 auto b = Kokkos::create_mirror_view_and_copy(
typename ExecSpaceType::memory_space(),
734 Kokkos::subview(elemRhs, ic, Kokkos::ALL()));
735 auto basisCoeffs_ = Kokkos::subview(basisCoeffs, ic, Kokkos::ALL());
736 auto serialBasisCoeffs = Kokkos::create_mirror_view_and_copy(
typename ExecSpaceType::memory_space(),
739 Kokkos::deep_copy(serialElemMat,valueType(0));
741 for(ordinal_type i=0; i<m+n; ++i) {
742 serialElemRhs(i,0) = b(i);
743 for(ordinal_type j=0; j<n; ++j)
744 serialElemMat(j,i) = A(j,i);
747 for(ordinal_type i=n; i<n+m; ++i)
748 for(ordinal_type j=0; j<n; ++j)
749 serialElemMat(i,j) = serialElemMat(j,i);
752 ordinal_type info = 0;
753 lapack_.GELS(
'N', n+m, n+m, 1,
754 serialElemMat.data(), serialElemMat.stride_1(),
755 serialElemRhs.data(), serialElemRhs.stride_1(),
756 pivVec.data(), pivVec.extent(0),
760 std::stringstream ss;
761 ss <<
">>> ERROR (Intrepid::ProjectionTools::getBasisCoeffs): "
762 <<
"LAPACK return with error code: "
764 INTREPID2_TEST_FOR_EXCEPTION(
true, std::runtime_error, ss.str().c_str() );
767 for(ordinal_type i=0; i<n; ++i) {
768 serialBasisCoeffs(elemDof(i)) = serialElemRhs(i,0);
770 Kokkos::deep_copy(basisCoeffs_,serialBasisCoeffs);
Header file for the Intrepid2::Basis_HGRAD_LINE_Cn_FEM class.
Header file for the Intrepid2::Basis_HDIV_TET_I1_FEM class.
Header file for the Intrepid2::Basis_HCURL_HEX_In_FEM class.
Header file for the Intrepid2::Basis_HDIV_HEX_I1_FEM class.
Header file for the Intrepid2::Basis_HDIV_WEDGE_I1_FEM class.
Header file for the Intrepid2::Basis_HDIV_HEX_In_FEM class.
Header function for Intrepid2::Util class and other utility functions.
Header file for the Intrepid2::Basis_HGRAD_TRI_Cn_FEM class.
Header file for the Intrepid2::Basis_HVOL_LINE_Cn_FEM class.
Header file for the Intrepid2::Basis_HDIV_QUAD_I1_FEM class.
Header file for the Intrepid2::Basis_HCURL_TET_In_FEM class.
Header file for the Intrepid2::Basis_HGRAD_TET_Cn_FEM class.
Header file for the Intrepid2::Basis_HDIV_TRI_I1_FEM class.
Header file for the Intrepid2::Basis_HDIV_QUAD_In_FEM class.
Header file for the Intrepid2::Basis_HCURL_QUAD_In_FEM class.
Header file for the Intrepid2::Basis_HDIV_TRI_In_FEM class.
Contains definitions of custom data types in Intrepid2.
Header file for the Intrepid2::Basis_HGRAD_QUAD_Cn_FEM class.
Header file for the Intrepid2::Basis_HDIV_TET_In_FEM class.
Header file for the Intrepid2::Experimental::ProjectionStruct.
Header file for the Intrepid2::Basis_HCURL_QUAD_I1_FEM class.
Header file for the Intrepid2::Basis_HCURL_WEDGE_I1_FEM class.
Header file for the Intrepid2::Basis_HCURL_TET_I1_FEM class.
Header file for the Intrepid2::Basis_HCURL_HEX_I1_FEM class.
An helper class to compute the evaluation points and weights needed for performing projections...
Header file for the Intrepid2::Basis_HCURL_TRI_I1_FEM class.
Header file for the Intrepid2::Basis_HVOL_TRI_Cn_FEM class.
Header file for the abstract base class Intrepid2::Basis.
Header file for the Intrepid2::Basis_HCURL_TRI_In_FEM class.
Header file for the Intrepid2::Basis_HGRAD_HEX_Cn_FEM class.