void PointTools:: getWarpBlendLattice( /**/ Kokkos::DynRankView<pointValueType,pointProperties...> points, const shards::CellTopology cell, const ordinal_type order, const ordinal_type offset ) { switch (cell.getKey()) { // case shards::Tetrahedron<4>::key: // case shards::Tetrahedron<8>::key: // case shards::Tetrahedron<10>::key: getWarpBlendLatticeTetrahedron( points, order, offset ); break; // case shards::Triangle<3>::key: // case shards::Triangle<4>::key: // case shards::Triangle<6>::key: getWarpBlendLatticeTriangle ( points, order, offset ); break; case shards::Line<2>::key: case shards::Line<3>::key: getWarpBlendLatticeLine ( points, order, offset ); break; default: { INTREPID2_TEST_FOR_EXCEPTION( true , std::invalid_argument , ">>> ERROR (Intrepid2::PointTools::getWarpBlendLattice): the specified cell type is not supported." ); } } }
ordinal_type PointTools:: getLatticeSize( const shards::CellTopology cellType, const ordinal_type order, const ordinal_type offset ) { #ifdef HAVE_INTREPID2_DEBUG INTREPID2_TEST_FOR_EXCEPTION( order < 0 || offset < 0, std::invalid_argument , ">>> ERROR (PointTools::getLatticeSize): order and offset must be positive values." ); #endif ordinal_type r_val = 0; switch (cellType.getKey()) { case shards::Tetrahedron<4>::key: case shards::Tetrahedron<8>::key: case shards::Tetrahedron<10>::key: { const auto effectiveOrder = order - 4 * offset; r_val = (effectiveOrder < 0 ? 0 :(effectiveOrder+1)*(effectiveOrder+2)*(effectiveOrder+3)/6); break; } case shards::Triangle<3>::key: case shards::Triangle<4>::key: case shards::Triangle<6>::key: { const auto effectiveOrder = order - 3 * offset; r_val = (effectiveOrder < 0 ? 0 : (effectiveOrder+1)*(effectiveOrder+2)/2); break; } case shards::Line<2>::key: case shards::Line<3>::key: { const auto effectiveOrder = order - 2 * offset; r_val = (effectiveOrder < 0 ? 0 : (effectiveOrder+1)); break; } default: { INTREPID2_TEST_FOR_EXCEPTION( true , std::invalid_argument , ">>> ERROR (Intrepid2::PointTools::getLatticeSize): the specified cell type is not supported." ); } } return r_val; }
//---------------------------------------------------------------------------// Teuchos::RCP<Intrepid::Basis<double,Intrepid::FieldContainer<double> > > IntrepidBasisFactory::create( const shards::CellTopology& cell_topo ) { Teuchos::RCP<Intrepid::Basis<double,Intrepid::FieldContainer<double> > > basis; switch( cell_topo.getKey() ){ case shards::Line<2>::key: basis = Teuchos::rcp( new Intrepid::Basis_HGRAD_LINE_C1_FEM< double,Intrepid::FieldContainer<double> >() ); break; case shards::Triangle<3>::key: basis = Teuchos::rcp( new Intrepid::Basis_HGRAD_TRI_C1_FEM< double,Intrepid::FieldContainer<double> >() ); break; case shards::Triangle<6>::key: basis = Teuchos::rcp( new Intrepid::Basis_HGRAD_TRI_C2_FEM< double,Intrepid::FieldContainer<double> >() ); break; case shards::Quadrilateral<4>::key: basis = Teuchos::rcp( new Intrepid::Basis_HGRAD_QUAD_C1_FEM< double,Intrepid::FieldContainer<double> >() ); break; case shards::Quadrilateral<9>::key: basis = Teuchos::rcp( new Intrepid::Basis_HGRAD_QUAD_C2_FEM< double,Intrepid::FieldContainer<double> >() ); break; case shards::Tetrahedron<4>::key: basis = Teuchos::rcp( new Intrepid::Basis_HGRAD_TET_C1_FEM< double,Intrepid::FieldContainer<double> >() ); break; case shards::Tetrahedron<10>::key: basis = Teuchos::rcp( new Intrepid::Basis_HGRAD_TET_C2_FEM< double,Intrepid::FieldContainer<double> >() ); break; case shards::Hexahedron<8>::key: basis = Teuchos::rcp( new Intrepid::Basis_HGRAD_HEX_C1_FEM< double,Intrepid::FieldContainer<double> >() ); break; case shards::Hexahedron<27>::key: basis = Teuchos::rcp( new Intrepid::Basis_HGRAD_HEX_C2_FEM< double,Intrepid::FieldContainer<double> >() ); break; case shards::Wedge<6>::key: basis = Teuchos::rcp( new Intrepid::Basis_HGRAD_WEDGE_C1_FEM< double,Intrepid::FieldContainer<double> >() ); break; case shards::Wedge<18>::key: basis = Teuchos::rcp( new Intrepid::Basis_HGRAD_WEDGE_C2_FEM< double,Intrepid::FieldContainer<double> >() ); break; case shards::Pyramid<5>::key: case shards::Pyramid<13>::key: case shards::Pyramid<14>::key: basis = Teuchos::rcp( new Intrepid::Basis_HGRAD_PYR_C1_FEM< double,Intrepid::FieldContainer<double> >() ); break; default: bool topology_supported = false; DTK_INSIST( topology_supported ); break; } return basis; }
void CellTools<SpT>:: setSubcellParametrization( subcellParamViewType &subcellParam, const ordinal_type subcellDim, const shards::CellTopology parentCell ) { #ifdef HAVE_INTREPID2_DEBUG INTREPID2_TEST_FOR_EXCEPTION( !hasReferenceCell(parentCell), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::setSubcellParametrization): the specified cell topology does not have a reference cell."); #endif // subcellParametrization is rank-3 FieldContainer with dimensions (SC, PCD, COEF) where: // - SC is the subcell count of subcells with the specified dimension in the parent cell // - PCD is Parent Cell Dimension, which gives the number of coordinate functions in the map // PCD = 2 for standard 2D cells and non-standard 2D cells: shell line and beam // PCD = 3 for standard 3D cells and non-standard 3D cells: shell Tri and Quad // - COEF is number of coefficients needed to specify a coordinate function: // COEFF = 2 for edge parametrizations // COEFF = 3 for both Quad and Tri face parametrizations. Because all Quad reference faces // are affine, the coefficient of the bilinear term u*v is zero and is not stored, i.e., // 3 coefficients are sufficient to store Quad face parameterization maps. // // Edge parametrization maps [-1,1] to edge defined by (v0, v1) // Face parametrization maps [-1,1]^2 to quadrilateral face (v0, v1, v2, v3), or // standard 2-simplex {(0,0),(1,0),(0,1)} to traingle face (v0, v1, v2). // This defines orientation-preserving parametrizations with respect to reference edge and // face orientations induced by their vertex order. // get subcellParametrization dimensions: (sc, pcd, coeff) const auto sc = parentCell.getSubcellCount(subcellDim); const auto pcd = parentCell.getDimension(); const auto coeff = (subcellDim == 1) ? 2 : 3; INTREPID2_TEST_FOR_EXCEPTION( subcellDim < 1 || subcellDim > static_cast<ordinal_type>(pcd-1), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::setSubcellParametrization): Parametrizations defined in a range between 1 and (dim-1)"); // create a view subcellParam = subcellParamViewType("CellTools::setSubcellParametrization", sc, pcd, coeff); referenceNodeDataViewType v0("CellTools::setSubcellParametrization::v0", Parameters::MaxDimension), v1("CellTools::setSubcellParametrization::v1", Parameters::MaxDimension), v2("CellTools::setSubcellParametrization::v1", Parameters::MaxDimension), v3("CellTools::setSubcellParametrization::v1", Parameters::MaxDimension); if (subcellDim == 1) { // Edge parametrizations of 2D and 3D cells (shell lines and beams are 2D cells with edges) for (size_type subcellOrd=0;subcellOrd<sc;++subcellOrd) { // vertexK[0] = x_k; vertexK[1] = y_k; vertexK[2] = z_k; z_k = 0 for 2D cells // Note that ShellLine and Beam are 2D cells! const auto v0ord = parentCell.getNodeMap(subcellDim, subcellOrd, 0); const auto v1ord = parentCell.getNodeMap(subcellDim, subcellOrd, 1); getReferenceVertex(v0, parentCell, v0ord); getReferenceVertex(v1, parentCell, v1ord); // x(t) = (x0 + x1)/2 + t*(x1 - x0)/2 subcellParam(subcellOrd, 0, 0) = (v0[0] + v1[0])/2.0; subcellParam(subcellOrd, 0, 1) = (v1[0] - v0[0])/2.0; // y(t) = (y0 + y1)/2 + t*(y1 - y0)/2 subcellParam(subcellOrd, 1, 0) = (v0[1] + v1[1])/2.0; subcellParam(subcellOrd, 1, 1) = (v1[1] - v0[1])/2.0; if( pcd == 3 ) { // z(t) = (z0 + z1)/2 + t*(z1 - z0)/2 subcellParam(subcellOrd, 2, 0) = (v0[2] + v1[2])/2.0; subcellParam(subcellOrd, 2, 1) = (v1[2] - v0[2])/2.0; } } } else if (subcellDim == 2) { // Face parametrizations of 3D cells: (shell Tri and Quad are 3D cells with faces) // A 3D cell can have both Tri and Quad faces, but because they are affine images of the // parametrization domain, 3 coefficients are enough to store them in both cases. for (size_type subcellOrd=0;subcellOrd<sc;++subcellOrd) { switch (parentCell.getKey(subcellDim,subcellOrd)) { case shards::Triangle<3>::key: case shards::Triangle<4>::key: case shards::Triangle<6>::key: { const auto v0ord = parentCell.getNodeMap(subcellDim, subcellOrd, 0); const auto v1ord = parentCell.getNodeMap(subcellDim, subcellOrd, 1); const auto v2ord = parentCell.getNodeMap(subcellDim, subcellOrd, 2); getReferenceVertex(v0, parentCell, v0ord); getReferenceVertex(v1, parentCell, v1ord); getReferenceVertex(v2, parentCell, v2ord); // x(u,v) = x0 + (x1 - x0)*u + (x2 - x0)*v subcellParam(subcellOrd, 0, 0) = v0[0]; subcellParam(subcellOrd, 0, 1) = v1[0] - v0[0]; subcellParam(subcellOrd, 0, 2) = v2[0] - v0[0]; // y(u,v) = y0 + (y1 - y0)*u + (y2 - y0)*v subcellParam(subcellOrd, 1, 0) = v0[1]; subcellParam(subcellOrd, 1, 1) = v1[1] - v0[1]; subcellParam(subcellOrd, 1, 2) = v2[1] - v0[1]; // z(u,v) = z0 + (z1 - z0)*u + (z2 - z0)*v subcellParam(subcellOrd, 2, 0) = v0[2]; subcellParam(subcellOrd, 2, 1) = v1[2] - v0[2]; subcellParam(subcellOrd, 2, 2) = v2[2] - v0[2]; break; } case shards::Quadrilateral<4>::key: case shards::Quadrilateral<8>::key: case shards::Quadrilateral<9>::key: { const auto v0ord = parentCell.getNodeMap(subcellDim, subcellOrd, 0); const auto v1ord = parentCell.getNodeMap(subcellDim, subcellOrd, 1); const auto v2ord = parentCell.getNodeMap(subcellDim, subcellOrd, 2); const auto v3ord = parentCell.getNodeMap(subcellDim, subcellOrd, 3); getReferenceVertex(v0, parentCell, v0ord); getReferenceVertex(v1, parentCell, v1ord); getReferenceVertex(v2, parentCell, v2ord); getReferenceVertex(v3, parentCell, v3ord); // x(u,v) = (x0+x1+x2+x3)/4+u*(-x0+x1+x2-x3)/4+v*(-x0-x1+x2+x3)/4+uv*(0=x0-x1+x2-x3)/4 subcellParam(subcellOrd, 0, 0) = ( v0[0] + v1[0] + v2[0] + v3[0])/4.0; subcellParam(subcellOrd, 0, 1) = (-v0[0] + v1[0] + v2[0] - v3[0])/4.0; subcellParam(subcellOrd, 0, 2) = (-v0[0] - v1[0] + v2[0] + v3[0])/4.0; // y(u,v) = (y0+y1+y2+y3)/4+u*(-y0+y1+y2-y3)/4+v*(-y0-y1+y2+y3)/4+uv*(0=y0-y1+y2-y3)/4 subcellParam(subcellOrd, 1, 0) = ( v0[1] + v1[1] + v2[1] + v3[1])/4.0; subcellParam(subcellOrd, 1, 1) = (-v0[1] + v1[1] + v2[1] - v3[1])/4.0; subcellParam(subcellOrd, 1, 2) = (-v0[1] - v1[1] + v2[1] + v3[1])/4.0; // z(u,v) = (z0+z1+z2+z3)/4+u*(-z0+z1+z2-z3)/4+v*(-z0-z1+z2+z3)/4+uv*(0=z0-z1+z2-z3)/4 subcellParam(subcellOrd, 2, 0) = ( v0[2] + v1[2] + v2[2] + v3[2])/4.0; subcellParam(subcellOrd, 2, 1) = (-v0[2] + v1[2] + v2[2] - v3[2])/4.0; subcellParam(subcellOrd, 2, 2) = (-v0[2] - v1[2] + v2[2] + v3[2])/4.0; break; } default: { INTREPID2_TEST_FOR_EXCEPTION( true, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::setSubcellParametrization): parametrization not defined for the specified face topology."); } } } } }
void CellTools<SpT>:: getSubcellParametrization( subcellParamViewType &subcellParam, const ordinal_type subcellDim, const shards::CellTopology parentCell ) { #ifdef HAVE_INTREPID2_DEBUG INTREPID2_TEST_FOR_EXCEPTION( !hasReferenceCell(parentCell), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getSubcellParametrization): the specified cell topology does not have a reference cell."); #endif if (!isSubcellParametrizationSet_) setSubcellParametrization(); // Select subcell parametrization according to its parent cell type const auto pcd = parentCell.getDimension(); // parent cell dim INTREPID2_TEST_FOR_EXCEPTION( subcellDim < 1 || subcellDim > static_cast<ordinal_type>(pcd-1), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getSubcellParametrization): Parametrizations defined in a range between 1 and (dim-1)"); switch (parentCell.getKey() ) { case shards::Tetrahedron<4>::key: case shards::Tetrahedron<8>::key: case shards::Tetrahedron<10>::key: case shards::Tetrahedron<11>::key: subcellParam = ( subcellDim == 2 ? subcellParamData_.tetFaces : subcellParamData_.tetEdges ); break; case shards::Hexahedron<8>::key: case shards::Hexahedron<20>::key: case shards::Hexahedron<27>::key: subcellParam = ( subcellDim == 2 ? subcellParamData_.hexFaces : subcellParamData_.hexEdges ); break; case shards::Pyramid<5>::key: case shards::Pyramid<13>::key: case shards::Pyramid<14>::key: subcellParam = ( subcellDim == 2 ? subcellParamData_.pyrFaces : subcellParamData_.pyrEdges ); break; case shards::Wedge<6>::key: case shards::Wedge<15>::key: case shards::Wedge<18>::key: subcellParam = ( subcellDim == 2 ? subcellParamData_.wedgeFaces : subcellParamData_.wedgeEdges ); break; case shards::Triangle<3>::key: case shards::Triangle<4>::key: case shards::Triangle<6>::key: subcellParam = subcellParamData_.triEdges; break; case shards::Quadrilateral<4>::key: case shards::Quadrilateral<8>::key: case shards::Quadrilateral<9>::key: subcellParam = subcellParamData_.quadEdges; break; // case shards::ShellTriangle<3>::key: // case shards::ShellTriangle<6>::key: subcellParam = ( subcellDim == 2 ? subcellParamData_.shellTriFaces : subcellParamData_.shellTriEdges ); break; // case shards::ShellQuadrilateral<4>::key: // case shards::ShellQuadrilateral<8>::key: // case shards::ShellQuadrilateral<9>::key: subcellParam = ( subcellDim == 2 ? subcellParamData_.shellQuadFaces : subcellParamData_.shellQuadEdges ); break; case shards::ShellLine<2>::key: case shards::ShellLine<3>::key: case shards::Beam<2>::key: case shards::Beam<3>::key: subcellParam = subcellParamData_.lineEdges; break; default: { INTREPID2_TEST_FOR_EXCEPTION( true, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getSubcellParametrization): invalid cell topology."); } } }