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.