49 #ifndef __INTREPID2_ARRAYTOOLS_DEF_CONTRACTIONS_HPP__ 
   50 #define __INTREPID2_ARRAYTOOLS_DEF_CONTRACTIONS_HPP__ 
   55     namespace FunctorArrayTools {
 
   59     template < 
typename outFieldViewType , 
typename leftFieldViewType , 
typename rightFieldViewType >
 
   61       outFieldViewType     _outputFields;
 
   62       leftFieldViewType    _leftFields;
 
   63       rightFieldViewType   _rightFields;
 
   65       typedef typename outFieldViewType::value_type value_type;
 
   67       KOKKOS_INLINE_FUNCTION
 
   69               leftFieldViewType leftFields_,
 
   70               rightFieldViewType rightFields_,
 
   72         : _outputFields(outputFields_), _leftFields(leftFields_), _rightFields(rightFields_), _sumInto(sumInto_) {}
 
   74       KOKKOS_INLINE_FUNCTION
 
   75       void operator()(
const size_type iter)
 const {
 
   76         size_type cl, lbf, rbf;
 
   77         unrollIndex( cl, lbf, rbf, 
 
   78                            _outputFields.extent(0),
 
   79                            _outputFields.extent(1),
 
   80                            _outputFields.extent(2),
 
   83         const size_type npts = _leftFields.extent(2);
 
   84         const ordinal_type iend = _leftFields.extent(3);
 
   85         const ordinal_type jend = _leftFields.extent(4);
 
   88         for (size_type qp = 0; qp < npts; ++qp) 
 
   89           for (ordinal_type i = 0; i < iend; ++i) 
 
   90             for (ordinal_type j = 0; j < jend; ++j) 
 
   91               tmp += _leftFields(cl, lbf, qp, i, j)*_rightFields(cl, rbf, qp, i, j);
 
   93           _outputFields( cl, lbf, rbf ) = _outputFields( cl, lbf, rbf ) + tmp;
 
   95           _outputFields( cl, lbf, rbf ) = tmp;
 
  100   template<
typename SpT>
 
  101   template<
typename outputFieldValueType, 
class ...outputFieldProperties,
 
  102            typename leftFieldValueType,   
class ...leftFieldProperties,
 
  103            typename rightFieldValueType,  
class ...rightFieldProperties>
 
  106   contractFieldField(       Kokkos::DynRankView<outputFieldValueType,outputFieldProperties...> outputFields,
 
  107                       const Kokkos::DynRankView<leftFieldValueType,  leftFieldProperties...>   leftFields,
 
  108                       const Kokkos::DynRankView<rightFieldValueType, rightFieldProperties...>  rightFields,
 
  109                       const bool sumInto ) {
 
  111     typedef Kokkos::DynRankView<outputFieldValueType,outputFieldProperties...> outFieldViewType;
 
  112     typedef Kokkos::DynRankView<leftFieldValueType,leftFieldProperties...> leftFieldViewType;
 
  113     typedef Kokkos::DynRankView<rightFieldValueType,rightFieldProperties...> rightFieldViewType;
 
  115     typedef typename ExecSpace< typename outFieldViewType::execution_space, SpT >::ExecSpaceType ExecSpaceType;
 
  118     const size_type loopSize = leftFields.extent(0)*leftFields.extent(1)*rightFields.extent(1);
 
  119     Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
 
  120     Kokkos::parallel_for( policy, FunctorType(outputFields, leftFields, rightFields, sumInto) );
 
  124     namespace FunctorArrayTools {
 
  128     template < 
typename outputFieldsViewType , 
typename inputDataViewType , 
typename inputFieldsViewType >
 
  130       outputFieldsViewType  _outputFields;
 
  131       inputDataViewType     _inputData;
 
  132       inputFieldsViewType   _inputFields;
 
  134       typedef typename outputFieldsViewType::value_type value_type;
 
  136       KOKKOS_INLINE_FUNCTION
 
  138               inputDataViewType inputData_,
 
  139               inputFieldsViewType inputFields_,
 
  141         : _outputFields(outputFields_), _inputData(inputData_), _inputFields(inputFields_), _sumInto(sumInto_) {}
 
  143       KOKKOS_DEFAULTED_FUNCTION
 
  144       ~F_contractDataField() = 
default;
 
  146       KOKKOS_INLINE_FUNCTION
 
  147       void operator()(
const size_type iter)
 const {
 
  150                            _inputFields.extent(0),
 
  151                            _inputFields.extent(1),
 
  154         auto result = Kokkos::subview( _outputFields, cl, bf );
 
  156         const auto field = Kokkos::subview( _inputFields, cl, bf, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL() );
 
  157         const auto data  = Kokkos::subview( _inputData,   cl,     Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL() );
 
  159         const size_type npts = field.extent(0);
 
  160         const ordinal_type iend = field.extent(1);
 
  161         const ordinal_type jend = field.extent(2);
 
  165         if(_inputData.extent(1) != 1)
 
  166           for (size_type qp = 0; qp < npts; ++qp)
 
  167             for (ordinal_type i = 0; i < iend; ++i)
 
  168               for (ordinal_type j = 0; j < jend; ++j)
 
  169                 tmp += field(qp, i, j) * data(qp, i, j);
 
  171           for (size_type qp = 0; qp < npts; ++qp)
 
  172             for (ordinal_type i = 0; i < iend; ++i)
 
  173               for (ordinal_type j = 0; j < jend; ++j)
 
  174                 tmp += field(qp, i, j) * data(0, i, j);
 
  177           result() = result() + tmp;
 
  184   template<
typename SpT>
 
  185   template<
typename outputFieldValueType, 
class ...outputFieldProperties,
 
  186            typename inputDataValueType,   
class ...inputDataProperties,
 
  187            typename inputFieldValueType,  
class ...inputFieldProperties>
 
  190   contractDataField(       Kokkos::DynRankView<outputFieldValueType,outputFieldProperties...>  outputFields,
 
  191                      const Kokkos::DynRankView<inputDataValueType,  inputDataProperties...>    inputData,
 
  192                      const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...>   inputFields,
 
  193                      const bool sumInto ) {
 
  195     typedef Kokkos::DynRankView<outputFieldValueType,outputFieldProperties...>                 outputFieldsViewType;
 
  196     typedef Kokkos::DynRankView<inputDataValueType,  inputDataProperties...>                   inputDataViewType;
 
  197     typedef Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...>                  inputFieldsViewType;
 
  199     typedef typename ExecSpace< typename inputFieldsViewType::execution_space , SpT >::ExecSpaceType               ExecSpaceType;
 
  201     const size_type loopSize = inputFields.extent(0)*inputFields.extent(1);
 
  202     Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
 
  203     Kokkos::parallel_for( policy, FunctorType(outputFields, inputData, inputFields, sumInto) );
 
  207     namespace FunctorArrayTools {
 
  211     template < 
typename outputDataViewType , 
typename inputDataLeftViewType , 
typename inputDataRightViewType >
 
  213       outputDataViewType  _outputData;
 
  214       inputDataLeftViewType   _inputDataLeft;
 
  215       inputDataRightViewType  _inputDataRight;
 
  217       typedef typename outputDataViewType::value_type value_type;
 
  219       KOKKOS_INLINE_FUNCTION
 
  221               inputDataLeftViewType inputDataLeft_,
 
  222               inputDataRightViewType inputDataRight_,
 
  224         : _outputData(outputData_), _inputDataLeft(inputDataLeft_), _inputDataRight(inputDataRight_), _sumInto(sumInto_) {}
 
  226       KOKKOS_DEFAULTED_FUNCTION
 
  227       ~F_contractDataData() = 
default;
 
  229       KOKKOS_INLINE_FUNCTION
 
  230       void operator()(
const size_type iter)
 const {
 
  231         const size_type cl = iter;
 
  233         auto result = Kokkos::subview( _outputData, cl );
 
  234         const auto left  = Kokkos::subview( _inputDataLeft,  cl, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL() );
 
  235         const auto right = Kokkos::subview( _inputDataRight, cl, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL() );
 
  237         size_type npts = left.extent(0);
 
  238         ordinal_type iend = left.extent(1);
 
  239         ordinal_type jend = left.extent(2);
 
  242         for (size_type qp = 0; qp < npts; ++qp) 
 
  243           for (ordinal_type i = 0; i < iend; ++i) 
 
  244             for (ordinal_type j = 0; j < jend; ++j) 
 
  245               tmp += left(qp, i, j)*right(qp, i, j);
 
  248           result() = result() + tmp;
 
  255   template<
typename SpT>
 
  256   template<
typename outputDataValueType,     
class ...outputDataProperties,
 
  257            typename inputDataLeftValueType,  
class ...inputDataLeftProperties,
 
  258            typename inputDataRightValueType, 
class ...inputDataRightProperties>
 
  261   contractDataData(       Kokkos::DynRankView<outputDataValueType,    outputDataProperties...>          outputData,
 
  262                     const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...>  inputDataLeft,
 
  263                     const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
 
  264                     const bool sumInto ) {
 
  265     typedef Kokkos::DynRankView<outputDataValueType,    outputDataProperties...>       outputDataViewType;
 
  266     typedef Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...>    inputDataLeftViewType;
 
  267     typedef Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...>   inputDataRightViewType;
 
  269     typedef typename ExecSpace< typename inputDataLeftViewType::execution_space , SpT>::ExecSpaceType  ExecSpaceType;
 
  271     const size_type loopSize = inputDataLeft.extent(0);
 
  272     Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
 
  273     Kokkos::parallel_for( policy, FunctorType(outputData, inputDataLeft, inputDataRight, sumInto) );
 
  278   template<
typename ExecSpaceType>
 
  279   template<
typename outputFieldValueType, 
class ...outputFieldProperties,
 
  280            typename leftFieldValueType,   
class ...leftFieldProperties,
 
  281            typename rightFieldValueType,  
class ...rightFieldProperties>
 
  285                             const Kokkos::DynRankView<leftFieldValueType,  leftFieldProperties...>   leftFields,
 
  286                             const Kokkos::DynRankView<rightFieldValueType, rightFieldProperties...>  rightFields,
 
  287                             const bool sumInto ) {
 
  289 #ifdef HAVE_INTREPID2_DEBUG 
  291       INTREPID2_TEST_FOR_EXCEPTION( leftFields.rank() != 3, std::invalid_argument,
 
  292                                       ">>> ERROR (ArrayTools::contractFieldFieldScalar): Rank of the left input argument must equal 3!");
 
  293       INTREPID2_TEST_FOR_EXCEPTION( rightFields.rank() != 3, std::invalid_argument,
 
  294                                       ">>> ERROR (ArrayTools::contractFieldFieldScalar): Rank of right input argument must equal 3!");
 
  295       INTREPID2_TEST_FOR_EXCEPTION( outputFields.rank() != 3, std::invalid_argument,
 
  296                                       ">>> ERROR (ArrayTools::contractFieldFieldScalar): Rank of output argument must equal 3!");
 
  297       INTREPID2_TEST_FOR_EXCEPTION( leftFields.extent(0) != rightFields.extent(0), std::invalid_argument,
 
  298                                       ">>> ERROR (ArrayTools::contractFieldFieldScalar): Zeroth dimensions (number of integration domains) of the left and right input containers must agree!");
 
  299       INTREPID2_TEST_FOR_EXCEPTION( leftFields.extent(2) != rightFields.extent(2), std::invalid_argument,
 
  300                                       ">>> ERROR (ArrayTools::contractFieldFieldScalar): Second dimensions (numbers of integration points) of the left and right input containers must agree!");
 
  301       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(0) != rightFields.extent(0), std::invalid_argument,
 
  302                                       ">>> ERROR (ArrayTools::contractFieldFieldScalar): Zeroth dimensions (numbers of integration domains) of the input and output containers must agree!");
 
  303       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(1) != leftFields.extent(1), std::invalid_argument,
 
  304                                       ">>> ERROR (ArrayTools::contractFieldFieldScalar): First dimension of output container and first dimension of left input container must agree!");
 
  305       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(2) != rightFields.extent(1), std::invalid_argument,
 
  306                                       ">>> ERROR (ArrayTools::contractFieldFieldScalar): Second dimension of output container and first dimension of right input container must agree!");
 
  318   template<
typename ExecSpaceType>
 
  319   template<
typename outputFieldValueType, 
class ...outputFieldProperties,
 
  320            typename leftFieldValueType,   
class ...leftFieldProperties,
 
  321            typename rightFieldValueType,  
class ...rightFieldProperties>
 
  325                             const Kokkos::DynRankView<leftFieldValueType,  leftFieldProperties...>   leftFields,
 
  326                             const Kokkos::DynRankView<rightFieldValueType, rightFieldProperties...>  rightFields,
 
  327                             const bool sumInto ) {
 
  329 #ifdef HAVE_INTREPID2_DEBUG 
  331       INTREPID2_TEST_FOR_EXCEPTION( leftFields.rank() != 4, std::invalid_argument,
 
  332                                       ">>> ERROR (ArrayTools::contractFieldFieldVector): Rank of the left input argument must equal 4!");
 
  333       INTREPID2_TEST_FOR_EXCEPTION( rightFields.rank() != 4, std::invalid_argument,
 
  334                                       ">>> ERROR (ArrayTools::contractFieldFieldVector): Rank of right input argument must equal 4!");
 
  335       INTREPID2_TEST_FOR_EXCEPTION( outputFields.rank() != 3, std::invalid_argument,
 
  336                                       ">>> ERROR (ArrayTools::contractFieldFieldVector): Rank of output argument must equal 3!");
 
  337       INTREPID2_TEST_FOR_EXCEPTION( leftFields.extent(0) != rightFields.extent(0), std::invalid_argument,
 
  338                                       ">>> ERROR (ArrayTools::contractFieldFieldVector): Zeroth dimensions (number of integration domains) of the left and right input containers must agree!");
 
  339       INTREPID2_TEST_FOR_EXCEPTION( leftFields.extent(2) != rightFields.extent(2), std::invalid_argument,
 
  340                                       ">>> ERROR (ArrayTools::contractFieldFieldVector): Second dimensions (numbers of integration points) of the left and right input containers must agree!");
 
  341       INTREPID2_TEST_FOR_EXCEPTION( leftFields.extent(3) != rightFields.extent(3), std::invalid_argument,
 
  342                                       ">>> ERROR (ArrayTools::contractFieldFieldVector): Third dimensions (numbers of vector components) of the left and right input containers must agree!");
 
  343       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(0) != rightFields.extent(0), std::invalid_argument,
 
  344                                       ">>> ERROR (ArrayTools::contractFieldFieldVector): Zeroth dimensions (numbers of integration domains) of the input and output containers must agree!");
 
  345       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(1) != leftFields.extent(1), std::invalid_argument,
 
  346                                       ">>> ERROR (ArrayTools::contractFieldFieldVector): First dimension of output container and first dimension of left input container must agree!");
 
  347       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(2) != rightFields.extent(1), std::invalid_argument,
 
  348                                       ">>> ERROR (ArrayTools::contractFieldFieldVector): Second dimension of output container and first dimension of right input container must agree!");
 
  359   template<
typename ExecSpaceType>
 
  360   template<
typename outputFieldValueType, 
class ...outputFieldProperties,
 
  361            typename leftFieldValueType,   
class ...leftFieldProperties,
 
  362            typename rightFieldValueType,  
class ...rightFieldProperties>
 
  366                             const Kokkos::DynRankView<leftFieldValueType,  leftFieldProperties...>   leftFields,
 
  367                             const Kokkos::DynRankView<rightFieldValueType, rightFieldProperties...>  rightFields,
 
  368                             const bool sumInto ) {
 
  370 #ifdef HAVE_INTREPID2_DEBUG 
  372       INTREPID2_TEST_FOR_EXCEPTION( leftFields.rank()  != 5, std::invalid_argument,
 
  373                                       ">>> ERROR (ArrayTools::contractFieldFieldTensor): Rank of the left input argument must equal 5!");
 
  374       INTREPID2_TEST_FOR_EXCEPTION( rightFields.rank() != 5, std::invalid_argument,
 
  375                                       ">>> ERROR (ArrayTools::contractFieldFieldTensor): Rank of right input argument must equal 5!");
 
  376       INTREPID2_TEST_FOR_EXCEPTION( outputFields.rank() != 3, std::invalid_argument,
 
  377                                       ">>> ERROR (ArrayTools::contractFieldFieldTensor): Rank of output argument must equal 3!");
 
  378       INTREPID2_TEST_FOR_EXCEPTION( leftFields.extent(0) != rightFields.extent(0), std::invalid_argument,
 
  379                                       ">>> ERROR (ArrayTools::contractFieldFieldTensor): Zeroth dimensions (number of integration domains) of the left and right input containers must agree!");
 
  380       INTREPID2_TEST_FOR_EXCEPTION( leftFields.extent(2) != rightFields.extent(2), std::invalid_argument,
 
  381                                       ">>> ERROR (ArrayTools::contractFieldFieldTensor): Second dimensions (numbers of integration points) of the left and right input containers must agree!");
 
  382       INTREPID2_TEST_FOR_EXCEPTION( leftFields.extent(3) != rightFields.extent(3), std::invalid_argument,
 
  383                                       ">>> ERROR (ArrayTools::contractFieldFieldTensor): Third dimensions (first tensor dimensions) of the left and right input containers must agree!");
 
  384       INTREPID2_TEST_FOR_EXCEPTION( leftFields.extent(4) != rightFields.extent(4), std::invalid_argument,
 
  385                                       ">>> ERROR (ArrayTools::contractFieldFieldTensor): Fourth dimensions (second tensor dimensions) of the left and right input containers must agree!");
 
  386       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(0) != rightFields.extent(0), std::invalid_argument,
 
  387                                       ">>> ERROR (ArrayTools::contractFieldFieldTensor): Zeroth dimensions (numbers of integration domains) of the input and output containers must agree!");
 
  388       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(1) != leftFields.extent(1), std::invalid_argument,
 
  389                                       ">>> ERROR (ArrayTools::contractFieldFieldTensor): First dimension of output container and first dimension of left input container must agree!");
 
  390       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(2) != rightFields.extent(1), std::invalid_argument,
 
  391                                       ">>> ERROR (ArrayTools::contractFieldFieldTensor): Second dimension of output container and first dimension of right input container must agree!");
 
  402   template<
typename ExecSpaceType>
 
  403   template<
typename outputFieldValueType, 
class ...outputFieldProperties,
 
  404            typename inputDataValueType,   
class ...inputDataProperties,
 
  405            typename inputFieldValueType,  
class ...inputFieldProperties>
 
  409                            const Kokkos::DynRankView<inputDataValueType,  inputDataProperties...>    inputData,
 
  410                            const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...>   inputFields,
 
  411                            const bool sumInto ) {
 
  413 #ifdef HAVE_INTREPID2_DEBUG 
  415       INTREPID2_TEST_FOR_EXCEPTION( inputFields.rank()  != 3, std::invalid_argument,
 
  416                                       ">>> ERROR (ArrayTools::contractDataFieldScalar): Rank of the fields input argument must equal 3!");
 
  417       INTREPID2_TEST_FOR_EXCEPTION( inputData.rank() != 2, std::invalid_argument,
 
  418                                       ">>> ERROR (ArrayTools::contractDataFieldScalar): Rank of the data input argument must equal 2!");
 
  419       INTREPID2_TEST_FOR_EXCEPTION( outputFields.rank() != 2, std::invalid_argument,
 
  420                                       ">>> ERROR (ArrayTools::contractDataFieldScalar): Rank of output argument must equal 2!");
 
  421       INTREPID2_TEST_FOR_EXCEPTION( inputFields.extent(0) != inputData.extent(0), std::invalid_argument,
 
  422                                       ">>> ERROR (ArrayTools::contractDataFieldScalar): Zeroth dimensions (number of integration domains) of the fields and data input containers must agree!");
 
  424       INTREPID2_TEST_FOR_EXCEPTION( inputData.extent(1) != inputFields.extent(2) &&
 
  425                                       inputData.extent(1) != 1, std::invalid_argument,
 
  426                                       ">>> ERROR (ArrayTools::contractDataFieldScalar): Second dimension of fields input container and first dimension of data input container (number of integration points) must agree or first data dimension must be 1!");
 
  427       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(0) != inputFields.extent(0), std::invalid_argument,
 
  428                                       ">>> ERROR (ArrayTools::contractDataFieldScalar): Zeroth dimensions (numbers of integration domains) of the fields input and output containers must agree!");      
 
  429       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(1) != inputFields.extent(1), std::invalid_argument,
 
  430                                       ">>> ERROR (ArrayTools::contractDataFieldScalar): First dimensions (number of fields) of the fields input and output containers must agree!");
 
  441   template<
typename ExecSpaceType>
 
  442   template<
typename outputFieldValueType, 
class ...outputFieldProperties,
 
  443            typename inputDataValueType,   
class ...inputDataProperties,
 
  444            typename inputFieldValueType,  
class ...inputFieldProperties>
 
  448                            const Kokkos::DynRankView<inputDataValueType,  inputDataProperties...>   inputData,
 
  449                            const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...>  inputFields,
 
  450                            const bool sumInto ) {
 
  452 #ifdef HAVE_INTREPID2_DEBUG 
  454       INTREPID2_TEST_FOR_EXCEPTION( inputFields.rank()  != 4, std::invalid_argument,
 
  455                                       ">>> ERROR (ArrayTools::contractDataFieldVector): Rank of the fields input argument must equal 4!");
 
  456       INTREPID2_TEST_FOR_EXCEPTION( inputData.rank() != 3, std::invalid_argument,
 
  457                                       ">>> ERROR (ArrayTools::contractDataFieldVector): Rank of the data input argument must equal 3!");
 
  458       INTREPID2_TEST_FOR_EXCEPTION( outputFields.rank() != 2, std::invalid_argument,
 
  459                                       ">>> ERROR (ArrayTools::contractDataFieldVector): Rank of output argument must equal 2!");
 
  460       INTREPID2_TEST_FOR_EXCEPTION( inputFields.extent(0) != inputData.extent(0), std::invalid_argument,
 
  461                                       ">>> ERROR (ArrayTools::contractDataFieldVector): Zeroth dimensions (number of integration domains) of the fields and data input containers must agree!");
 
  462       INTREPID2_TEST_FOR_EXCEPTION( inputData.extent(1) != inputFields.extent(2) &&
 
  463                                       inputData.extent(1) != 1, std::invalid_argument,
 
  464                                       ">>> ERROR (ArrayTools::contractDataFieldVector): Second dimension of the fields input container and first dimension of data input container (number of integration points) must agree or first data dimension must be 1!");
 
  465       INTREPID2_TEST_FOR_EXCEPTION( inputFields.extent(3) != inputData.extent(2), std::invalid_argument,
 
  466                                       ">>> ERROR (ArrayTools::contractDataFieldVector): Third dimension of the fields input container and second dimension of data input container (vector index) must agree!");
 
  467       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(0) != inputFields.extent(0), std::invalid_argument,
 
  468                                       ">>> ERROR (ArrayTools::contractDataFieldVector): Zeroth dimensions (numbers of integration domains) of the fields input and output containers must agree!");
 
  469       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(1) != inputFields.extent(1), std::invalid_argument,
 
  470                                       ">>> ERROR (ArrayTools::contractDataFieldVector): First dimensions of output container and fields input container (number of fields) must agree!");
 
  482   template<
typename ExecSpaceType>
 
  483   template<
typename outputFieldValueType, 
class ...outputFieldProperties,
 
  484            typename inputDataValueType,   
class ...inputDataProperties,
 
  485            typename inputFieldValueType,  
class ...inputFieldProperties>
 
  489                            const Kokkos::DynRankView<inputDataValueType,  inputDataProperties...>   inputData,
 
  490                            const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...>  inputFields,
 
  491                            const bool sumInto ) {
 
  493 #ifdef HAVE_INTREPID2_DEBUG 
  495       INTREPID2_TEST_FOR_EXCEPTION( inputFields.rank()  != 5, std::invalid_argument,
 
  496                                       ">>> ERROR (ArrayTools::contractDataFieldTensor): Rank of the fields input argument must equal 5!");
 
  497       INTREPID2_TEST_FOR_EXCEPTION( inputData.rank() != 4, std::invalid_argument,
 
  498                                       ">>> ERROR (ArrayTools::contractDataFieldTensor): Rank of the data input argument must equal 4!");
 
  499       INTREPID2_TEST_FOR_EXCEPTION( outputFields.rank() != 2, std::invalid_argument,
 
  500                                       ">>> ERROR (ArrayTools::contractDataFieldTensor): Rank of output argument must equal 2!");
 
  501       INTREPID2_TEST_FOR_EXCEPTION( inputFields.extent(0) != inputData.extent(0), std::invalid_argument,
 
  502                                       ">>> ERROR (ArrayTools::contractDataFieldTensor): Zeroth dimensions (number of integration domains) of the fields and data input containers must agree!");
 
  503       INTREPID2_TEST_FOR_EXCEPTION( inputData.extent(1) != inputFields.extent(2) && inputData.extent(1) != 1, std::invalid_argument,
 
  504                                       ">>> ERROR (ArrayTools::contractDataFieldTensor): Second dimension of the fields input container and first dimension of data input container (number of integration points) must agree or first data dimension must be 1!");
 
  505       INTREPID2_TEST_FOR_EXCEPTION( inputFields.extent(3) != inputData.extent(2), std::invalid_argument,
 
  506                                       ">>> ERROR (ArrayTools::contractDataFieldTensor): Third dimension of the fields input container and second dimension of data input container (first tensor dimension) must agree!");
 
  507       INTREPID2_TEST_FOR_EXCEPTION( inputFields.extent(4) != inputData.extent(3), std::invalid_argument,
 
  508                                       ">>> ERROR (ArrayTools::contractDataFieldTensor): Fourth dimension of the fields input container and third dimension of data input container (second tensor dimension) must agree!");
 
  509       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(0) != inputFields.extent(0), std::invalid_argument,
 
  510                                       ">>> ERROR (ArrayTools::contractDataFieldTensor): Zeroth dimensions (numbers of integration domains) of the fields input and output containers must agree!");
 
  511       INTREPID2_TEST_FOR_EXCEPTION( outputFields.extent(1) != inputFields.extent(1), std::invalid_argument,
 
  512                                       ">>> ERROR (ArrayTools::contractDataFieldTensor): First dimensions (number of fields) of output container and fields input container must agree!");
 
  524   template<
typename ExecSpaceType>
 
  525   template<
typename outputDataValueType,     
class ...outputDataProperties,
 
  526            typename inputDataLeftValueType,  
class ...inputDataLeftProperties,
 
  527            typename inputDataRightValueType, 
class ...inputDataRightProperties>
 
  531                           const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...>  inputDataLeft,
 
  532                           const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
 
  533                           const bool sumInto ) {
 
  535 #ifdef HAVE_INTREPID2_DEBUG 
  537       INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.rank()  != 2, std::invalid_argument,
 
  538                                       ">>> ERROR (ArrayTools::contractDataDataScalar): Rank of the left input argument must equal 2!");
 
  539       INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.rank() != 2, std::invalid_argument,
 
  540                                       ">>> ERROR (ArrayTools::contractDataDataScalar): Rank of right input argument must equal 2!");
 
  541       INTREPID2_TEST_FOR_EXCEPTION( outputData.rank() != 1, std::invalid_argument,
 
  542                                       ">>> ERROR (ArrayTools::contractDataDataScalar): Rank of output argument must equal 1!");
 
  543       INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.extent(0) != inputDataRight.extent(0), std::invalid_argument,
 
  544                                       ">>> ERROR (ArrayTools::contractDataDataScalar): Zeroth dimensions (number of integration domains) of the left and right input containers must agree!");
 
  545       INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.extent(1) != inputDataRight.extent(1), std::invalid_argument,
 
  546                                       ">>> ERROR (ArrayTools::contractDataDataScalar): First dimensions (numbers of integration points) of the left and right input containers must agree!");
 
  547       INTREPID2_TEST_FOR_EXCEPTION( outputData.extent(0) != inputDataRight.extent(0), std::invalid_argument,
 
  548                                       ">>> ERROR (ArrayTools::contractDataDataScalar): Zeroth dimensions (numbers of integration domains) of the input and output containers must agree!");
 
  559   template<
typename ExecSpaceType>
 
  560   template<
typename outputDataValueType,     
class ...outputDataProperties,
 
  561            typename inputDataLeftValueType,  
class ...inputDataLeftProperties,
 
  562            typename inputDataRightValueType, 
class ...inputDataRightProperties>
 
  566                           const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...>  inputDataLeft,
 
  567                           const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
 
  568                           const bool sumInto ) {
 
  570 #ifdef HAVE_INTREPID2_DEBUG 
  572       INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.rank()  != 3, std::invalid_argument,
 
  573                                       ">>> ERROR (ArrayTools::contractDataDataVector): Rank of the left input argument must equal 3!");
 
  574       INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.rank() != 3, std::invalid_argument,
 
  575                                       ">>> ERROR (ArrayTools::contractDataDataVector): Rank of right input argument must equal 3!");
 
  576       INTREPID2_TEST_FOR_EXCEPTION( outputData.rank() != 1, std::invalid_argument,
 
  577                                       ">>> ERROR (ArrayTools::contractDataDataVector): Rank of output argument must equal 1!");
 
  578       INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.extent(0) != inputDataRight.extent(0), std::invalid_argument,
 
  579                                       ">>> ERROR (ArrayTools::contractDataDataVector): Zeroth dimensions (number of integration domains) of the left and right input containers must agree!");
 
  580       INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.extent(1) != inputDataRight.extent(1), std::invalid_argument,
 
  581                                       ">>> ERROR (ArrayTools::contractDataDataVector): First dimensions (numbers of integration points) of the left and right input containers must agree!");
 
  582       INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.extent(2) != inputDataRight.extent(2), std::invalid_argument,
 
  583                                       ">>> ERROR (ArrayTools::contractDataDataVector): Second dimensions (numbers of vector components) of the left and right input containers must agree!");
 
  584       INTREPID2_TEST_FOR_EXCEPTION( outputData.extent(0) != inputDataRight.extent(0), std::invalid_argument,
 
  585                                       ">>> ERROR (ArrayTools::contractDataDataVector): Zeroth dimensions (numbers of integration domains) of the input and output containers must agree!");
 
  596   template<
typename ExecSpaceType>
 
  597   template<
typename outputDataValueType,     
class ...outputDataProperties,
 
  598            typename inputDataLeftValueType,  
class ...inputDataLeftProperties,
 
  599            typename inputDataRightValueType, 
class ...inputDataRightProperties>
 
  603                           const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...>  inputDataLeft,
 
  604                           const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
 
  605                           const bool sumInto ) {
 
  607 #ifdef HAVE_INTREPID2_DEBUG 
  609       INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.rank()  != 4, std::invalid_argument,
 
  610                                       ">>> ERROR (ArrayTools::contractDataDataTensor): Rank of the left input argument must equal 4");
 
  611       INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.rank() != 4, std::invalid_argument,
 
  612                                       ">>> ERROR (ArrayTools::contractDataDataTensor): Rank of right input argument must equal 4!");
 
  613       INTREPID2_TEST_FOR_EXCEPTION( outputData.rank() != 1, std::invalid_argument,
 
  614                                       ">>> ERROR (ArrayTools::contractDataDataTensor): Rank of output argument must equal 1!");
 
  615       INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.extent(0) != inputDataRight.extent(0), std::invalid_argument,
 
  616                                       ">>> ERROR (ArrayTools::contractDataDataTensor): Zeroth dimensions (number of integration domains) of the left and right input containers must agree!");
 
  617       INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.extent(1) != inputDataRight.extent(1), std::invalid_argument,
 
  618                                       ">>> ERROR (ArrayTools::contractDataDataTensor): First dimensions (numbers of integration points) of the left and right input containers must agree!");
 
  619       INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.extent(2) != inputDataRight.extent(2), std::invalid_argument,
 
  620                                       ">>> ERROR (ArrayTools::contractDataDataTensor): Second dimensions (first tensor dimensions) of the left and right input containers must agree!");
 
  621       INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.extent(3) != inputDataRight.extent(3), std::invalid_argument,
 
  622                                       ">>> ERROR (ArrayTools::contractDataDataTensor): Third dimensions (second tensor dimensions) of the left and right input containers must agree!");
 
  623       INTREPID2_TEST_FOR_EXCEPTION( outputData.extent(0) != inputDataRight.extent(0), std::invalid_argument,
 
  624                                       ">>> ERROR (ArrayTools::contractDataDataTensor): Zeroth dimensions (numbers of integration domains) of the input and output containers must agree!");