49 #ifndef Intrepid2_DirectSumBasis_h 
   50 #define Intrepid2_DirectSumBasis_h 
   52 #include <Kokkos_View.hpp> 
   53 #include <Kokkos_DynRankView.hpp> 
   67   template<
typename Basis1, 
typename Basis2>
 
   69   : 
public Basis<typename Basis1::ExecutionSpace,
 
   70                  typename Basis1::OutputValueType,
 
   71                  typename Basis1::PointValueType>
 
   79     using OrdinalTypeArray1DHost = 
typename Basis1::OrdinalTypeArray1DHost;
 
   80     using OrdinalTypeArray2DHost = 
typename Basis1::OrdinalTypeArray2DHost;
 
   82     using ExecutionSpace  = 
typename Basis1::ExecutionSpace;
 
   83     using OutputValueType = 
typename Basis1::OutputValueType;
 
   84     using PointValueType  = 
typename Basis1::PointValueType;
 
   86     using OutputViewType = 
typename Basis1::OutputViewType;
 
   87     using PointViewType  = 
typename Basis1::PointViewType;
 
   88     using ScalarViewType = 
typename Basis1::ScalarViewType;
 
   96     basis1_(basis1),basis2_(basis2)
 
   98       INTREPID2_TEST_FOR_EXCEPTION(basis1.getBasisType() != basis2.getBasisType(), std::invalid_argument, 
"basis1 and basis2 must agree in basis type");
 
   99       INTREPID2_TEST_FOR_EXCEPTION(basis1.getBaseCellTopology().getKey() != basis2.getBaseCellTopology().getKey(),
 
  100                                  std::invalid_argument, 
"basis1 and basis2 must agree in cell topology");
 
  101       INTREPID2_TEST_FOR_EXCEPTION(basis1.getCoordinateSystem() != basis2.getCoordinateSystem(),
 
  102                                  std::invalid_argument, 
"basis1 and basis2 must agree in coordinate system");
 
  105       this->
basisDegree_       = std::max(basis1.getDegree(), basis2.getDegree());
 
  108         std::ostringstream basisName;
 
  109         basisName << basis1.getName() << 
" + " << basis2.getName();
 
  110         name_ = basisName.str();
 
  117       if (this->
basisType_ == BASIS_FEM_HIERARCHICAL)
 
  119         int degreeLength = basis1_.getPolynomialDegreeLength();
 
  120         INTREPID2_TEST_FOR_EXCEPTION(degreeLength != basis2_.getPolynomialDegreeLength(), std::invalid_argument, 
"Basis1 and Basis2 must agree on polynomial degree length");
 
  124         for (
int fieldOrdinal1=0; fieldOrdinal1<basis1_.getCardinality(); fieldOrdinal1++)
 
  126           int fieldOrdinal = fieldOrdinal1;
 
  127           auto polynomialDegree = basis1.getPolynomialDegreeOfField(fieldOrdinal1);
 
  128           for (
int d=0; d<degreeLength; d++)
 
  133         for (
int fieldOrdinal2=0; fieldOrdinal2<basis2_.getCardinality(); fieldOrdinal2++)
 
  135           int fieldOrdinal = basis1.getCardinality() + fieldOrdinal2;
 
  137           auto polynomialDegree = basis2.getPolynomialDegreeOfField(fieldOrdinal2);
 
  138           for (
int d=0; d<degreeLength; d++)
 
  150         const ordinal_type tagSize  = 4;        
 
  151         const ordinal_type posScDim = 0;        
 
  152         const ordinal_type posScOrd = 1;        
 
  153         const ordinal_type posDfOrd = 2;        
 
  159         unsigned spaceDim  = cellTopo.getDimension();
 
  161         ordinal_type basis2Offset = basis1_.getCardinality();
 
  163         for (
unsigned d=0; d<=spaceDim; d++)
 
  165           unsigned subcellCount = cellTopo.getSubcellCount(d);
 
  166           for (
unsigned subcellOrdinal=0; subcellOrdinal<subcellCount; subcellOrdinal++)
 
  168             ordinal_type subcellDofCount1 = basis1.getDofCount(d, subcellOrdinal);
 
  169             ordinal_type subcellDofCount2 = basis2.getDofCount(d, subcellOrdinal);
 
  171             ordinal_type subcellDofCount = subcellDofCount1 + subcellDofCount2;
 
  172             for (ordinal_type localDofID=0; localDofID<subcellDofCount; localDofID++)
 
  174               ordinal_type fieldOrdinal;
 
  175               if (localDofID < subcellDofCount1)
 
  178                 fieldOrdinal = basis1_.getDofOrdinal(d, subcellOrdinal, localDofID);
 
  183                 fieldOrdinal = basis2Offset + basis2_.getDofOrdinal(d, subcellOrdinal, localDofID - subcellDofCount1);
 
  185               tagView(fieldOrdinal*tagSize+0) = d; 
 
  186               tagView(fieldOrdinal*tagSize+1) = subcellOrdinal;
 
  187               tagView(fieldOrdinal*tagSize+2) = localDofID;
 
  188               tagView(fieldOrdinal*tagSize+3) = subcellDofCount;
 
  197                                 this->basisCardinality_,
 
  214       const int basisCardinality1 = basis1_.getCardinality();
 
  215       const int basisCardinality2 = basis2_.getCardinality();
 
  216       const int basisCardinality  = basisCardinality1 + basisCardinality2;
 
  218       auto dofCoords1 = Kokkos::subview(dofCoords, std::make_pair(0,basisCardinality1),                Kokkos::ALL());
 
  219       auto dofCoords2 = Kokkos::subview(dofCoords, std::make_pair(basisCardinality1,basisCardinality), Kokkos::ALL());
 
  221       basis1_.getDofCoords(dofCoords1);
 
  222       basis2_.getDofCoords(dofCoords2);
 
  232       return name_.c_str();
 
  259                            const EOperator operatorType = OPERATOR_VALUE )
 const override 
  261       int cardinality1 = basis1_.getCardinality();
 
  262       int cardinality2 = basis2_.getCardinality();
 
  264       auto range1 = std::make_pair(0,cardinality1);
 
  265       auto range2 = std::make_pair(cardinality1,cardinality1+cardinality2);
 
  266       if (outputValues.rank() == 2) 
 
  268         auto outputValues1 = Kokkos::subview(outputValues, range1, Kokkos::ALL());
 
  269         auto outputValues2 = Kokkos::subview(outputValues, range2, Kokkos::ALL());
 
  271         basis1_.getValues(outputValues1, inputPoints, operatorType);
 
  272         basis2_.getValues(outputValues2, inputPoints, operatorType);
 
  274       else if (outputValues.rank() == 3) 
 
  276         auto outputValues1 = Kokkos::subview(outputValues, range1, Kokkos::ALL(), Kokkos::ALL());
 
  277         auto outputValues2 = Kokkos::subview(outputValues, range2, Kokkos::ALL(), Kokkos::ALL());
 
  279         basis1_.getValues(outputValues1, inputPoints, operatorType);
 
  280         basis2_.getValues(outputValues2, inputPoints, operatorType);
 
  282       else if (outputValues.rank() == 4) 
 
  284         auto outputValues1 = Kokkos::subview(outputValues, range1, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
 
  285         auto outputValues2 = Kokkos::subview(outputValues, range2, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
 
  287         basis1_.getValues(outputValues1, inputPoints, operatorType);
 
  288         basis2_.getValues(outputValues2, inputPoints, operatorType);
 
  290       else if (outputValues.rank() == 5) 
 
  292         auto outputValues1 = Kokkos::subview(outputValues, range1, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
 
  293         auto outputValues2 = Kokkos::subview(outputValues, range2, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
 
  295         basis1_.getValues(outputValues1, inputPoints, operatorType);
 
  296         basis2_.getValues(outputValues2, inputPoints, operatorType);
 
  298       else if (outputValues.rank() == 6) 
 
  300         auto outputValues1 = Kokkos::subview(outputValues, range1, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
 
  301         auto outputValues2 = Kokkos::subview(outputValues, range2, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
 
  303         basis1_.getValues(outputValues1, inputPoints, operatorType);
 
  304         basis2_.getValues(outputValues2, inputPoints, operatorType);
 
  306       else if (outputValues.rank() == 7) 
 
  308         auto outputValues1 = Kokkos::subview(outputValues, range1, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
 
  309         auto outputValues2 = Kokkos::subview(outputValues, range2, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
 
  311         basis1_.getValues(outputValues1, inputPoints, operatorType);
 
  312         basis2_.getValues(outputValues2, inputPoints, operatorType);
 
  316         INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument, 
"Unsupported outputValues rank");
 
Kokkos::View< ordinal_type *, typename Basis_Derived_HDIV_Family1_QUAD< HGRAD_LINE, HVOL_LINE >::ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array. 
 
Kokkos::View< ordinal_type **, typename Basis_Derived_HDIV_Family1_QUAD< HGRAD_LINE, HVOL_LINE >::ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray2DHost
View type for 2d host array. 
 
OrdinalTypeArray3DHost tagToOrdinal_
DoF tag to ordinal lookup table. 
 
ordinal_type basisCardinality_
Cardinality of the basis, i.e., the number of basis functions/degrees-of-freedom. ...
 
ECoordinates basisCoordinates_
The coordinate system for which the basis is defined. 
 
virtual void getDofCoords(ScalarViewType dofCoords) const override
Fills in spatial locations (coordinates) of degrees of freedom (nodes) on the reference cell...
 
An abstract base class that defines interface for concrete basis implementations for Finite Element (...
 
virtual void getValues(OutputViewType outputValues, const PointViewType inputPoints, const EOperator operatorType=OPERATOR_VALUE) const override
Evaluation of a FEM basis on a reference cell. 
 
ordinal_type basisDegree_
Degree of the largest complete polynomial space that can be represented by the basis. 
 
virtual const char * getName() const override
Returns basis name. 
 
EBasis basisType_
Type of the basis. 
 
Basis_DirectSumBasis(Basis1 basis1, Basis2 basis2)
Constructor. 
 
A basis that is the direct sum of two other bases. 
 
Kokkos::DynRankView< OutputValueType, Kokkos::LayoutStride, Basis_Derived_HDIV_Family1_QUAD< HGRAD_LINE, HVOL_LINE >::ExecutionSpace > OutputViewType
View type for basis value output. 
 
OrdinalTypeArray2DHost fieldOrdinalPolynomialDegree_
Polynomial degree for each degree of freedom. Only defined for hierarchical bases right now...
 
void setOrdinalTagData(OrdinalTypeView3D &tagToOrdinal, OrdinalTypeView2D &ordinalToTag, const OrdinalTypeView1D tags, const ordinal_type basisCard, const ordinal_type tagSize, const ordinal_type posScDim, const ordinal_type posScOrd, const ordinal_type posDfOrd)
Fills ordinalToTag_ and tagToOrdinal_ by basis-specific tag data. 
 
Kokkos::DynRankView< PointValueType, Kokkos::LayoutStride, Basis_Derived_HDIV_Family1_QUAD< HGRAD_LINE, HVOL_LINE >::ExecutionSpace > PointViewType
View type for input points. 
 
Kokkos::DynRankView< scalarType, Kokkos::LayoutStride, Basis_Derived_HDIV_Family1_QUAD< HGRAD_LINE, HVOL_LINE >::ExecutionSpace > ScalarViewType
View type for scalars. 
 
OrdinalTypeArray2DHost ordinalToTag_
"true" if tagToOrdinal_ and ordinalToTag_ have been initialized 
 
shards::CellTopology basisCellTopology_
Base topology of the cells for which the basis is defined. See the Shards package for definition of b...