Basis_HGRAD_LINE_C1_FEM<SpT,OT,PT>:: Basis_HGRAD_LINE_C1_FEM() : impl_(this) { this->basisCardinality_ = 2; this->basisDegree_ = 1; this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >() ); this->basisType_ = BASIS_FEM_DEFAULT; this->basisCoordinates_ = COORDINATES_CARTESIAN; // initialize tags { // Basis-dependent intializations const ordinal_type tagSize = 4; // size of DoF tag, i.e., number of fields in the tag const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim const ordinal_type posScOrd = 1; // position in the tag, counting from 0, of the subcell ordinal const ordinal_type posDfOrd = 2; // position in the tag, counting from 0, of DoF ordinal relative to the subcell // An array with local DoF tags assigned to basis functions, in the order of their local enumeration ordinal_type tags[8] = { 0, 0, 0, 1, 0, 1, 0, 1 }; // host tags ordinal_type_array_1d_host tagView(&tags[0], 8); // Basis-independent function sets tag and enum data in tagToOrdinal_ and ordinalToTag_ arrays: // tags are constructed on host and sent to devices //ordinal_type_array_2d_host ordinalToTag; //ordinal_type_array_3d_host tagToOrdinal; this->setOrdinalTagData(this->tagToOrdinal_, this->ordinalToTag_, tagView, this->basisCardinality_, tagSize, posScDim, posScOrd, posDfOrd); //this->tagToOrdinal_ = Kokkos::create_mirror_view(typename SpT::memory_space(), tagToOrdinal); //Kokkos::deep_copy(this->tagToOrdinal_, tagToOrdinal); //this->ordinalToTag_ = Kokkos::create_mirror_view(typename SpT::memory_space(), ordinalToTag); //Kokkos::deep_copy(this->ordinalToTag_, ordinalToTag); } // dofCoords on host and create its mirror view to device Kokkos::DynRankView<PT,typename SpT::array_layout,Kokkos::HostSpace> dofCoords("dofCoordsHost", this->basisCardinality_,this->basisCellTopology_.getDimension()); dofCoords(0,0) = -1.0; dofCoords(1,0) = 1.0; this->dofCoords_ = Kokkos::create_mirror_view(typename SpT::memory_space(), dofCoords); Kokkos::deep_copy(this->dofCoords_, dofCoords); }
Basis_HCURL_TRI_I1_FEM<SpT,OT,PT>:: Basis_HCURL_TRI_I1_FEM() { this->basisCardinality_ = 3; this->basisDegree_ = 1; this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Triangle<3> >() ); this->basisType_ = BASIS_FEM_DEFAULT; this->basisCoordinates_ = COORDINATES_CARTESIAN; // initialize tags { // Basis-dependent intializations const ordinal_type tagSize = 4; // size of DoF tag const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim const ordinal_type posScOrd = 1; // position in the tag, counting from 0, of the subcell ordinal const ordinal_type posDfOrd = 2; // position in the tag, counting from 0, of DoF ordinal relative to the subcell // An array with local DoF tags assigned to basis functions, in the order of their local enumeration ordinal_type tags[12] = { 1, 0, 0, 1, 1, 1, 0, 1, 1, 2, 0, 1 }; // host tags ordinal_type_array_1d_host tagView(&tags[0], 12); // Basis-independent function sets tag and enum data in tagToOrdinal_ and ordinalToTag_ arrays: this->setOrdinalTagData(this->tagToOrdinal_, this->ordinalToTag_, tagView, this->basisCardinality_, tagSize, posScDim, posScOrd, posDfOrd); } // dofCoords on host and create its mirror view to device Kokkos::DynRankView<typename scalarViewType::value_type,typename SpT::array_layout,Kokkos::HostSpace> dofCoords("dofCoordsHost", this->basisCardinality_,this->basisCellTopology_.getDimension()); dofCoords(0,0) = 0.5; dofCoords(0,1) = 0.0; dofCoords(1,0) = 0.5; dofCoords(1,1) = 0.5; dofCoords(2,0) = 0.0; dofCoords(2,1) = 0.5; this->dofCoords_ = Kokkos::create_mirror_view(typename SpT::memory_space(), dofCoords); Kokkos::deep_copy(this->dofCoords_, dofCoords); // dofCoeffs on host and create its mirror view to device Kokkos::DynRankView<typename scalarViewType::value_type,typename SpT::array_layout,Kokkos::HostSpace> dofCoeffs("dofCoeffsHost", this->basisCardinality_,this->basisCellTopology_.getDimension()); dofCoeffs(0,0) = 1.0; dofCoeffs(0,1) = 0.0; dofCoeffs(1,0) = -1.0; dofCoeffs(1,1) = 1.0; dofCoeffs(2,0) = 0.0; dofCoeffs(2,1) = -1.0; this->dofCoeffs_ = Kokkos::create_mirror_view(typename SpT::memory_space(), dofCoeffs); Kokkos::deep_copy(this->dofCoeffs_, dofCoeffs); }
Basis_Constant_FEM<SpT,OT,PT>:: Basis_Constant_FEM(const shards::CellTopology cellTopo) { const ordinal_type spaceDim = cellTopo.getDimension(); this->basisCardinality_ = 1; this->basisDegree_ = 0; this->basisCellTopology_ = cellTopo; this->basisType_ = Intrepid2::BASIS_FEM_DEFAULT; this->basisCoordinates_ = Intrepid2::COORDINATES_CARTESIAN; // initialize tags { // Basis-dependent intializations const ordinal_type tagSize = 4; // size of DoF tag, i.e., number of fields in the tag const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim const ordinal_type posScOrd = 1; // position in the tag, counting from 0, of the subcell ordinal const ordinal_type posDfOrd = 2; // position in the tag, counting from 0, of DoF ordinal relative to the subcell // An array with local DoF tags assigned to the basis functions, in the order of their local enumeration ordinal_type tags[4] = { spaceDim, 0, 0, 1 }; ordinal_type_array_1d_host tagView(&tags[0], 4); this->setOrdinalTagData(this->tagToOrdinal_, this->ordinalToTag_, tagView, this->basisCardinality_, tagSize, posScDim, posScOrd, posDfOrd); } // dofCoords on host and create its mirror view to device Kokkos::DynRankView<typename scalarViewType::value_type,typename SpT::array_layout,Kokkos::HostSpace> dofCoords("dofCoordsHost", this->basisCardinality_, spaceDim), cellVerts("cellVerts", spaceDim); CellTools<SpT>::getReferenceCellCenter(Kokkos::subview(dofCoords, 0, Kokkos::ALL()), cellVerts, cellTopo); this->dofCoords_ = Kokkos::create_mirror_view(typename SpT::memory_space(), dofCoords); Kokkos::deep_copy(this->dofCoords_, dofCoords); }
Basis_HCURL_HEX_I1_FEM<SpT,OT,PT>:: Basis_HCURL_HEX_I1_FEM() : impl_(this) { this->basisCardinality_ = 12; this->basisDegree_ = 1; this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >() ); this->basisType_ = BASIS_FEM_DEFAULT; this->basisCoordinates_ = COORDINATES_CARTESIAN; // initialize tags { // Basis-dependent intializations const ordinal_type tagSize = 4; // size of DoF tag const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim const ordinal_type posScOrd = 1; // position in the tag, counting from 0, of the subcell ordinal const ordinal_type posDfOrd = 2; // position in the tag, counting from 0, of DoF ordinal relative to the subcell // An array with local DoF tags assigned to basis functions, in the order of their local enumeration ordinal_type tags[48] = { 1, 0, 0, 1, 1, 1, 0, 1, 1, 2, 0, 1, 1, 3, 0, 1, 1, 4, 0, 1, 1, 5, 0, 1, 1, 6, 0, 1, 1, 7, 0, 1, 1, 8, 0, 1, 1, 9, 0, 1, 1, 10, 0, 1, 1, 11, 0, 1 }; // when exec space is device, this wrapping relies on uvm. ordinal_type_array_1d_host tagView(&tags[0], 48); // Basis-independent function sets tag and enum data in tagToOrdinal_ and ordinalToTag_ arrays: this->setOrdinalTagData(this->tagToOrdinal_, this->ordinalToTag_, tagView, this->basisCardinality_, tagSize, posScDim, posScOrd, posDfOrd); } // dofCoords on host and create its mirror view to device Kokkos::DynRankView<PT,typename SpT::array_layout,Kokkos::HostSpace> dofCoords("dofCoordsHost", this->basisCardinality_,this->basisCellTopology_.getDimension()); dofCoords(0,0) = 0.0; dofCoords(0,1) = -1.0; dofCoords(0,2) = -1.0; dofCoords(1,0) = 1.0; dofCoords(1,1) = 0.0; dofCoords(1,2) = -1.0; dofCoords(2,0) = 0.0; dofCoords(2,1) = 1.0; dofCoords(2,2) = -1.0; dofCoords(3,0) = -1.0; dofCoords(3,1) = 0.0; dofCoords(3,2) = -1.0; dofCoords(4,0) = 0.0; dofCoords(4,1) = -1.0; dofCoords(4,2) = 1.0; dofCoords(5,0) = 1.0; dofCoords(5,1) = 0.0; dofCoords(5,2) = 1.0; dofCoords(6,0) = 0.0; dofCoords(6,1) = 1.0; dofCoords(6,2) = 1.0; dofCoords(7,0) = -1.0; dofCoords(7,1) = 0.0; dofCoords(7,2) = 1.0; dofCoords(8,0) = -1.0; dofCoords(8,1) = -1.0; dofCoords(8,2) = 0.0; dofCoords(9,0) = 1.0; dofCoords(9,1) = -1.0; dofCoords(9,2) = 0.0; dofCoords(10,0) = 1.0; dofCoords(10,1) = 1.0; dofCoords(10,2) = 0.0; dofCoords(11,0) = -1.0; dofCoords(11,1) = 1.0; dofCoords(11,2) = 0.0; this->dofCoords_ = Kokkos::create_mirror_view(typename SpT::memory_space(), dofCoords); Kokkos::deep_copy(this->dofCoords_, dofCoords); }
Basis_HGRAD_LINE_Cn_FEM<SpT,OT,PT>:: Basis_HGRAD_LINE_Cn_FEM( const ordinal_type order, const EPointType pointType ) { this->basisCardinality_ = order+1; this->basisDegree_ = order; this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >() ); this->basisType_ = BASIS_FEM_FIAT; this->basisCoordinates_ = COORDINATES_CARTESIAN; const ordinal_type card = this->basisCardinality_; // points are computed in the host and will be copied Kokkos::DynRankView<typename scalarViewType::value_type,typename SpT::array_layout,Kokkos::HostSpace> dofCoords("Hgrad::Line::Cn::dofCoords", card, 1); switch (pointType) { case POINTTYPE_EQUISPACED: case POINTTYPE_WARPBLEND: { // lattice ordering { const ordinal_type offset = 0; PointTools::getLattice( dofCoords, this->basisCellTopology_, order, offset, pointType ); } // topological order // { // // two vertices // dofCoords(0,0) = -1.0; // dofCoords(1,0) = 1.0; // // internal points // typedef Kokkos::pair<ordinal_type,ordinal_type> range_type; // auto pts = Kokkos::subview(dofCoords, range_type(2, card), Kokkos::ALL()); // const auto offset = 1; // PointTools::getLattice( pts, // this->basisCellTopology_, // order, offset, // pointType ); // } break; } case POINTTYPE_GAUSS: { // internal points only PointTools::getGaussPoints( dofCoords, order ); break; } default: { INTREPID2_TEST_FOR_EXCEPTION( !isValidPointType(pointType), std::invalid_argument , ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_Cn_FEM) invalid pointType." ); } } this->dofCoords_ = Kokkos::create_mirror_view(typename SpT::memory_space(), dofCoords); Kokkos::deep_copy(this->dofCoords_, dofCoords); // form Vandermonde matrix; actually, this is the transpose of the VDM, // this matrix is used in LAPACK so it should be column major and left layout const ordinal_type lwork = card*card; Kokkos::DynRankView<typename scalarViewType::value_type,Kokkos::LayoutLeft,Kokkos::HostSpace> vmat("Hgrad::Line::Cn::vmat", card, card), work("Hgrad::Line::Cn::work", lwork), ipiv("Hgrad::Line::Cn::ipiv", card); const double alpha = 0.0, beta = 0.0; Impl::Basis_HGRAD_LINE_Cn_FEM_JACOBI:: getValues<Kokkos::HostSpace::execution_space,Parameters::MaxNumPtsPerBasisEval> (vmat, dofCoords, order, alpha, beta, OPERATOR_VALUE); ordinal_type info = 0; Teuchos::LAPACK<ordinal_type,typename scalarViewType::value_type> lapack; lapack.GETRF(card, card, vmat.data(), vmat.stride_1(), (ordinal_type*)ipiv.data(), &info); INTREPID2_TEST_FOR_EXCEPTION( info != 0, std::runtime_error , ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_Cn_FEM) lapack.GETRF returns nonzero info." ); lapack.GETRI(card, vmat.data(), vmat.stride_1(), (ordinal_type*)ipiv.data(), work.data(), lwork, &info); INTREPID2_TEST_FOR_EXCEPTION( info != 0, std::runtime_error , ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_Cn_FEM) lapack.GETRI returns nonzero info." ); // create host mirror Kokkos::DynRankView<typename scalarViewType::value_type,typename SpT::array_layout,Kokkos::HostSpace> vinv("Hgrad::Line::Cn::vinv", card, card); for (ordinal_type i=0;i<card;++i) for (ordinal_type j=0;j<card;++j) vinv(i,j) = vmat(j,i); this->vinv_ = Kokkos::create_mirror_view(typename SpT::memory_space(), vinv); Kokkos::deep_copy(this->vinv_ , vinv); // initialize tags { const bool is_vertex_included = (pointType != POINTTYPE_GAUSS); // Basis-dependent initializations const ordinal_type tagSize = 4; // size of DoF tag, i.e., number of fields in the tag const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim const ordinal_type posScOrd = 1; // position in the tag, counting from 0, of the subcell ordinal const ordinal_type posDfOrd = 2; // position in the tag, counting from 0, of DoF ordinal relative to the subcell ordinal_type tags[Parameters::MaxOrder+1][4]; // now we check the points for association if (is_vertex_included) { // lattice order { const auto v0 = 0; tags[v0][0] = 0; // vertex dof tags[v0][1] = 0; // vertex id tags[v0][2] = 0; // local dof id tags[v0][3] = 1; // total number of dofs in this vertex const ordinal_type iend = card - 2; for (ordinal_type i=0;i<iend;++i) { const auto e = i + 1; tags[e][0] = 1; // edge dof tags[e][1] = 0; // edge id tags[e][2] = i; // local dof id tags[e][3] = iend; // total number of dofs in this edge } const auto v1 = card -1; tags[v1][0] = 0; // vertex dof tags[v1][1] = 1; // vertex id tags[v1][2] = 0; // local dof id tags[v1][3] = 1; // total number of dofs in this vertex } // topological order // { // tags[0][0] = 0; // vertex dof // tags[0][1] = 0; // vertex id // tags[0][2] = 0; // local dof id // tags[0][3] = 1; // total number of dofs in this vertex // tags[1][0] = 0; // vertex dof // tags[1][1] = 1; // vertex id // tags[1][2] = 0; // local dof id // tags[1][3] = 1; // total number of dofs in this vertex // const ordinal_type iend = card - 2; // for (ordinal_type i=0;i<iend;++i) { // const auto ii = i + 2; // tags[ii][0] = 1; // edge dof // tags[ii][1] = 0; // edge id // tags[ii][2] = i; // local dof id // tags[ii][3] = iend; // total number of dofs in this edge // } // } } else { for (ordinal_type i=0;i<card;++i) { tags[i][0] = 1; // edge dof tags[i][1] = 0; // edge id tags[i][2] = i; // local dof id tags[i][3] = card; // total number of dofs in this edge } } ordinal_type_array_1d_host tagView(&tags[0][0], card*4); // Basis-independent function sets tag and enum data in tagToOrdinal_ and ordinalToTag_ arrays: // tags are constructed on host this->setOrdinalTagData(this->tagToOrdinal_, this->ordinalToTag_, tagView, this->basisCardinality_, tagSize, posScDim, posScOrd, posDfOrd); } }