void Basis_HGRAD_LINE_Cn_FEM:: getValues( Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues, const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints, const Kokkos::DynRankView<vinvValueType, vinvProperties...> vinv, const EOperator operatorType ) { typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType; typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType; typedef Kokkos::DynRankView<vinvValueType, vinvProperties...> vinvViewType; typedef typename ExecSpace<typename inputPointViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType; // loopSize corresponds to cardinality const auto loopSizeTmp1 = (inputPoints.dimension(0)/numPtsPerEval); const auto loopSizeTmp2 = (inputPoints.dimension(0)%numPtsPerEval != 0); const auto loopSize = loopSizeTmp1 + loopSizeTmp2; Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize); typedef typename inputPointViewType::value_type inputPointType; const ordinal_type cardinality = outputValues.dimension(0); auto vcprop = Kokkos::common_view_alloc_prop(inputPoints); typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType; workViewType work(Kokkos::view_alloc("Basis_HGRAD_LINE_Cn_FEM::getValues::work", vcprop), cardinality, inputPoints.dimension(0)); switch (operatorType) { case OPERATOR_VALUE: { typedef Functor<outputValueViewType,inputPointViewType,vinvViewType,workViewType, OPERATOR_VALUE,numPtsPerEval> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinv, work) ); break; } case OPERATOR_GRAD: case OPERATOR_D1: case OPERATOR_D2: case OPERATOR_D3: case OPERATOR_D4: case OPERATOR_D5: case OPERATOR_D6: case OPERATOR_D7: case OPERATOR_D8: case OPERATOR_D9: case OPERATOR_D10: { typedef Functor<outputValueViewType,inputPointViewType,vinvViewType,workViewType, OPERATOR_Dn,numPtsPerEval> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinv, work, getOperatorOrder(operatorType)) ); break; } default: { INTREPID2_TEST_FOR_EXCEPTION( true , std::invalid_argument, ">>> ERROR (Basis_HGRAD_LINE_Cn_FEM): Operator type not implemented" ); //break; commented out because this always throws } } }
void CellTools<SpT>:: mapToPhysicalFrame( /**/ Kokkos::DynRankView<physPointValueType,physPointProperties...> physPoints, const Kokkos::DynRankView<refPointValueType,refPointProperties...> refPoints, const Kokkos::DynRankView<worksetCellValueType,worksetCellProperties...> worksetCell, const HGradBasisPtrType basis ) { #ifdef HAVE_INTREPID2_DEBUG CellTools_mapToPhysicalFrameArgs( physPoints, refPoints, worksetCell, basis->getBaseCellTopology() ); #endif const auto cellTopo = basis->getBaseCellTopology(); const auto numCells = worksetCell.dimension(0); //points can be rank-2 (P,D), or rank-3 (C,P,D) const auto refPointRank = refPoints.rank(); const auto numPoints = (refPointRank == 2 ? refPoints.dimension(0) : refPoints.dimension(1)); const auto basisCardinality = basis->getCardinality(); typedef Kokkos::DynRankView<physPointValueType,physPointProperties...> physPointViewType; typedef Kokkos::DynRankView<decltype(basis->getDummyOutputValue()),SpT> valViewType; valViewType vals; switch (refPointRank) { case 2: { // refPoints is (P,D): single set of ref. points is mapped to one or multiple physical cells vals = valViewType("CellTools::mapToPhysicalFrame::vals", basisCardinality, numPoints); basis->getValues(vals, refPoints, OPERATOR_VALUE); break; } case 3: { // refPoints is (C,P,D): multiple sets of ref. points are mapped to matching number of physical cells. vals = valViewType("CellTools::mapToPhysicalFrame::vals", numCells, basisCardinality, numPoints); for (size_type cell=0;cell<numCells;++cell) basis->getValues(Kokkos::subdynrankview( vals, cell, Kokkos::ALL(), Kokkos::ALL() ), Kokkos::subdynrankview( refPoints, cell, Kokkos::ALL(), Kokkos::ALL() ), OPERATOR_VALUE); break; } } typedef Kokkos::DynRankView<worksetCellValueType,worksetCellProperties...> worksetCellViewType; typedef FunctorCellTools::F_mapToPhysicalFrame<physPointViewType,worksetCellViewType,valViewType> FunctorType; typedef typename ExecSpace<typename worksetCellViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType; const auto loopSize = physPoints.dimension(0)*physPoints.dimension(1); Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize); Kokkos::parallel_for( policy, FunctorType(physPoints, worksetCell, vals) ); }
void Basis_HGRAD_QUAD_C1_FEM:: getValues( Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues, const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints, const EOperator operatorType ) { typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType; typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType; typedef typename ExecSpace<typename inputPointViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType; // Number of evaluation points = dim 0 of inputPoints const auto loopSize = inputPoints.dimension(0); Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize); switch (operatorType) { case OPERATOR_VALUE: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_VALUE> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) ); break; } case OPERATOR_GRAD: case OPERATOR_D1: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_GRAD> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) ); break; } case OPERATOR_CURL: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_CURL> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) ); break; } case OPERATOR_DIV: { INTREPID2_TEST_FOR_EXCEPTION( operatorType == OPERATOR_DIV, std::invalid_argument, ">>> ERROR (Basis_HGRAD_QUAD_C1_FEM): DIV is invalid operator for rank-0 (scalar) functions in 2D"); break; } case OPERATOR_D2: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_D2> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) ); break; } case OPERATOR_D3: case OPERATOR_D4: case OPERATOR_D5: case OPERATOR_D6: case OPERATOR_D7: case OPERATOR_D8: case OPERATOR_D9: case OPERATOR_D10: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_MAX> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) ); break; } default: { INTREPID2_TEST_FOR_EXCEPTION( !Intrepid2::isValidOperator(operatorType), std::invalid_argument, ">>> ERROR (Basis_HGRAD_QUAD_C1_FEM): Invalid operator type"); } } }
void Basis_HCURL_TRI_I1_FEM<SpT,OT,PT>::Internal:: getDofCoords( Kokkos::DynRankView<dofCoordValueType,dofCoordProperties...> dofCoords ) const { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HCURL_TRI_I1_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( dofCoords.dimension(0) != obj_->basisCardinality_, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HCURL_TRI_I1_FEM::getDofCoords) mismatch in number of dof and 0th dimension of dofCoords array"); // Verify 1st dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( dofCoords.dimension(1) != obj_->basisCellTopology_.getDimension(), std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HCURL_TRI_I1_FEM::getDofCoords) incorrect reference cell (1st) dimension in dofCoords array"); #endif Kokkos::deep_copy(dofCoords, obj_->dofCoords_); }
ordinal_type compareToAnalytic( std::ifstream &inputFile, const Kokkos::DynRankView<ValueType,testMatProperties...> testMat, const ValueType reltol, const ordinal_type iprint, const TypeOfExactData analyticDataType ) { INTREPID2_TEST_FOR_EXCEPTION( testMat.rank() != 2, std::invalid_argument, ">>> ERROR (compareToAnalytic): testMat must have rank 2"); Teuchos::RCP<std::ostream> outStream; Teuchos::oblackholestream outNothing; if (iprint > 0) outStream = Teuchos::rcp(&std::cout, false); else outStream = Teuchos::rcp(&outNothing, false); // Save the format state of the original std::cout. Teuchos::oblackholestream oldFormatState; oldFormatState.copyfmt(std::cout); std::string line; ValueType testentry; ValueType abstol; ValueType absdiff; ordinal_type i = 0, j = 0; ordinal_type err = 0; while (! inputFile.eof() && i < static_cast<ordinal_type>(testMat.dimension(0)) ) { std::getline(inputFile,line); std::istringstream linestream(line); std::string chunk; j = 0; while( linestream >> chunk ) { ordinal_type num1; ordinal_type num2; std::string::size_type loc = chunk.find( "/", 0); if( loc != std::string::npos ) { chunk.replace( loc, 1, " "); std::istringstream chunkstream(chunk); chunkstream >> num1; chunkstream >> num2; testentry = (ValueType)(num1)/(ValueType)(num2); abstol = ( std::fabs(testentry) < reltol ? reltol : std::fabs(reltol*testentry) ); absdiff = std::fabs(testentry - testMat(i, j)); if (absdiff > abstol) { ++err; *outStream << "FAILURE --> "; } *outStream << "entry[" << i << "," << j << "]:" << " " << testMat(i, j) << " " << num1 << "/" << num2 << " " << absdiff << " " << "<?" << " " << abstol << "\n"; } else { std::istringstream chunkstream(chunk); if (analyticDataType == INTREPID2_UTILS_FRACTION) { chunkstream >> num1; testentry = (ValueType)(num1); } else if (analyticDataType == INTREPID2_UTILS_SCALAR)
void ArrayTools<SpT>::Internal:: dotMultiply( /**/ Kokkos::DynRankView<outputValueType, outputProperties...> output, const Kokkos::DynRankView<leftInputValueType, leftInputProperties...> leftInput, const Kokkos::DynRankView<rightInputValueType,rightInputProperties...> rightInput, const bool hasField ) { typedef Kokkos::DynRankView<outputValueType, outputProperties...> outputViewType; typedef Kokkos::DynRankView<leftInputValueType, leftInputProperties...> leftInputViewType; typedef Kokkos::DynRankView<rightInputValueType,rightInputProperties...> rightInputViewType; typedef FunctorArrayTools::F_dotMultiply<outputViewType, leftInputViewType, rightInputViewType> FunctorType; typedef typename ExecSpace< typename leftInputViewType::execution_space , SpT >::ExecSpaceType ExecSpaceType; const size_type loopSize = ( hasField ? output.dimension(0)*output.dimension(1)*output.dimension(2) : /**/ output.dimension(0)*output.dimension(1) ); Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize); Kokkos::parallel_for( policy, FunctorType(output, leftInput, rightInput, hasField) ); }
void Basis_HGRAD_LINE_C1_FEM<SpT>:: getDofCoords( Kokkos::DynRankView<dofCoordValueType,dofCoordProperties...> dofCoords ) const { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_C1_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( dofCoords.dimension(0) != this->basisCardinality_, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_C1_FEM::getDofCoords) mismatch in number of dof and 0th dimension of dofCoords array"); // Verify 1st dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( dofCoords.dimension(1) != this->basisCellTopology_.getDimension(), std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_C1_FEM::getDofCoords) incorrect reference cell (1st) dimension in dofCoords array"); #endif dofCoords(0,0) = -1.0; dofCoords(1,0) = 1.0; }
void Basis_HGRAD_TRI_Cn_FEM_ORTH:: getValues( /**/ Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues, const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints, const ordinal_type order, const EOperator operatorType ) { typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType; typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType; typedef typename ExecSpace<typename inputPointViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType; // loopSize corresponds to the # of points const auto loopSizeTmp1 = (inputPoints.dimension(0)/numPtsPerEval); const auto loopSizeTmp2 = (inputPoints.dimension(0)%numPtsPerEval != 0); const auto loopSize = loopSizeTmp1 + loopSizeTmp2; Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize); switch (operatorType) { case OPERATOR_VALUE: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_VALUE,numPtsPerEval> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, order) ); break; } case OPERATOR_GRAD: case OPERATOR_D1: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_GRAD,numPtsPerEval> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, order) ); break; } case OPERATOR_D2: case OPERATOR_D3: case OPERATOR_D4: case OPERATOR_D5: case OPERATOR_D6: case OPERATOR_D7: case OPERATOR_D8: case OPERATOR_D9: case OPERATOR_D10: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_Dn,numPtsPerEval> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, order, getOperatorOrder(operatorType)) ); break; } case OPERATOR_DIV: case OPERATOR_CURL: { INTREPID2_TEST_FOR_EXCEPTION( operatorType == OPERATOR_DIV || operatorType == OPERATOR_CURL, std::invalid_argument, ">>> ERROR (Basis_HGRAD_TRI_Cn_FEM_ORTH): invalid operator type (div and curl)."); break; } default: { INTREPID2_TEST_FOR_EXCEPTION( !Intrepid2::isValidOperator(operatorType), std::invalid_argument, ">>> ERROR (Basis_HGRAD_TRI_Cn_FEM_ORTH): invalid operator type"); } } }
KOKKOS_INLINE_FUNCTION void Basis_HGRAD_TRI_C1_FEM<SpT,OT,PT>::Serial<opType>:: getValues( /**/ Kokkos::DynRankView<outputValueValueType,outputValueProperties...> output, const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> input ) { switch (opType) { case OPERATOR_VALUE: { const auto x = input(0); const auto y = input(1); // output is a rank-2 array with dimensions (basisCardinality_) output(0) = 1.0 - x - y; output(1) = x; output(2) = y; break; } case OPERATOR_GRAD: { // output is a rank-3 array with dimensions (basisCardinality_, spaceDim) output(0, 0) = -1.0; output(0, 1) = -1.0; output(1, 0) = 1.0; output(1, 1) = 0.0; output(2, 0) = 0.0; output(2, 1) = 1.0; break; } case OPERATOR_CURL: { output(0, 0) = -1.0; output(0, 1) = 1.0; output(1, 0) = 0.0; output(1, 1) = -1.0; output(2, 0) = 1.0; output(2, 1) = 0.0; break; } case OPERATOR_MAX: { const auto jend = output.dimension(1); const auto iend = output.dimension(0); for (size_type j=0;j<jend;++j) for (size_type i=0;i<iend;++i) output(i, j) = 0.0; break; } default: { INTREPID2_TEST_FOR_ABORT( opType != OPERATOR_VALUE && opType != OPERATOR_GRAD && opType != OPERATOR_CURL && opType != OPERATOR_MAX, ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_C1_FEM::Serial::getValues) operator is not supported"); } } }
void Basis_HGRAD_LINE_C1_FEM<SpT,OT,PT>::Internal:: getValues( /**/ Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues, const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints, const EOperator operatorType ) const { #ifdef HAVE_INTREPID2_DEBUG Intrepid2::getValues_HGRAD_Args(outputValues, inputPoints, operatorType, obj_->getBaseCellTopology(), obj_->getCardinality() ); #endif typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType; typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType; typedef typename ExecSpace<typename inputPointViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType; // Number of evaluation points = dim 0 of inputPoints const auto loopSize = inputPoints.dimension(0); Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize); switch (operatorType) { case OPERATOR_VALUE: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_VALUE> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) ); break; } case OPERATOR_GRAD: case OPERATOR_DIV: case OPERATOR_CURL: case OPERATOR_D1: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_GRAD> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) ); break; } case OPERATOR_D2: case OPERATOR_D3: case OPERATOR_D4: case OPERATOR_D5: case OPERATOR_D6: case OPERATOR_D7: case OPERATOR_D8: case OPERATOR_D9: case OPERATOR_D10: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_MAX> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) ); break; } default: { INTREPID2_TEST_FOR_EXCEPTION( !Intrepid2::isValidOperator(operatorType), std::invalid_argument, ">>> ERROR (Basis_HGRAD_LINE_C1_FEM): Invalid operator type"); } } }
/** Get the local coordinates for this field. This is independent of element * locations. * * \param[in,out] coords Coordinates associated with this field type. */ void Intrepid2FieldPattern:: getInterpolatoryCoordinates(const Kokkos::DynRankView<double,PHX::Device> & cellVertices, Kokkos::DynRankView<double,PHX::Device> & coords) const { TEUCHOS_ASSERT(cellVertices.rank()==3); int numCells = cellVertices.dimension(0); // grab the local coordinates Kokkos::DynRankView<double,PHX::Device> localCoords; getInterpolatoryCoordinates(localCoords); // resize the coordinates field container coords = Kokkos::DynRankView<double,PHX::Device>("coords",numCells,localCoords.dimension(0),getDimension()); if(numCells>0) { Intrepid2::CellTools<PHX::Device> cellTools; cellTools.mapToPhysicalFrame(coords,localCoords,cellVertices,intrepidBasis_->getBaseCellTopology()); } }
void OrientationTools<SpT>:: getOrientation(/**/ Kokkos::DynRankView<elemOrtValueType,elemOrtProperties...> elemOrts, const Kokkos::DynRankView<elemNodeValueType,elemNodeProperties...> elemNodes, const shards::CellTopology cellTopo) { // small meta data modification and it uses shards; let's do this on host typedef typename Kokkos::Impl::is_space<SpT>::host_mirror_space::execution_space host_space_type; auto elemOrtsHost = Kokkos::create_mirror_view(typename host_space_type::memory_space(), elemOrts); auto elemNodesHost = Kokkos::create_mirror_view(typename host_space_type::memory_space(), elemNodes); const ordinal_type numCells = elemNodes.dimension(0); for (auto cell=0;cell<numCells;++cell) { const auto nodes = Kokkos::subview(elemNodesHost, cell, Kokkos::ALL()); elemOrtsHost(cell) = Orientation::getOrientation(cellTopo, nodes); } Kokkos::deep_copy(elemOrts, elemOrtsHost); }
void PointTools:: getLattice( /**/ Kokkos::DynRankView<pointValueType,pointProperties...> points, const shards::CellTopology cell, const ordinal_type order, const ordinal_type offset, const EPointType pointType ) { #ifdef HAVE_INTREPID2_DEBUG INTREPID2_TEST_FOR_EXCEPTION( points.rank() != 2, std::invalid_argument , ">>> ERROR (PointTools::getLattice): points rank must be 2." ); INTREPID2_TEST_FOR_EXCEPTION( order < 0 || offset < 0, std::invalid_argument , ">>> ERROR (PointTools::getLattice): order and offset must be positive values." ); const size_type latticeSize = getLatticeSize( cell, order, offset ); const size_type spaceDim = cell.getDimension(); INTREPID2_TEST_FOR_EXCEPTION( points.dimension(0) != latticeSize || points.dimension(1) != spaceDim, std::invalid_argument , ">>> ERROR (PointTools::getLattice): dimension does not match to lattice size." ); #endif // const auto latticeSize = getLatticeSize( cell, order, offset ); // const auto spaceDim = cell.getDimension(); // // the interface assumes that the input array follows the cell definition // // so, let's match all dimensions according to the cell specification // typedef Kokkos::pair<ordinal_type,ordinal_type> range_type; // auto pts = Kokkos::subview( points, // range_type(0, latticeSize), // range_type(0, spaceDim) ); switch (pointType) { case POINTTYPE_EQUISPACED: getEquispacedLattice( points, cell, order, offset ); break; case POINTTYPE_WARPBLEND: getWarpBlendLattice ( points, cell, order, offset ); break; default: { INTREPID2_TEST_FOR_EXCEPTION( true , std::invalid_argument , ">>> ERROR (PointTools::getLattice): invalid EPointType." ); } } }
KOKKOS_INLINE_FUNCTION void Basis_HGRAD_LINE_C1_FEM<SpT,OT,PT>::Serial<opType>:: getValues( /**/ Kokkos::DynRankView<outputValueValueType,outputValueProperties...> output, const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> input ) { switch (opType) { case OPERATOR_VALUE : { const auto x = input(); output(0) = (1.0 - x)/2.0; output(1) = (1.0 + x)/2.0; break; } case OPERATOR_GRAD : { output(0, 0) = -0.5; output(1, 0) = 0.5; break; } case OPERATOR_MAX : { const auto jend = output.dimension(1); const auto iend = output.dimension(0); for (size_type j=0;j<jend;++j) for (size_type i=0;i<iend;++i) output(i, j) = 0.0; break; } default: { INTREPID2_TEST_FOR_ABORT( opType != OPERATOR_VALUE && opType != OPERATOR_GRAD && opType != OPERATOR_MAX, ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_C1_FEM::Serial::getValues) operator is not supported"); } } }
KOKKOS_INLINE_FUNCTION void Basis_HGRAD_TET_C2_FEM<SpT,OT,PT>::Serial<opType>:: getValues( /**/ Kokkos::DynRankView<outputValueValueType,outputValueProperties...> output, const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> input ) { switch (opType) { case OPERATOR_VALUE: { const auto x = input(0); const auto y = input(1); const auto z = input(2); // output is a rank-2 array with dimensions (basisCardinality_, dim0) output(0) = (-1. + x + y + z)*(-1. + 2.*x + 2.*y + 2.*z); output(1) = x*(-1. + 2.*x); output(2) = y*(-1. + 2.*y); output(3) = z*(-1. + 2.*z); output(4) = -4.*x*(-1. + x + y + z); output(5) = 4.*x*y; output(6) = -4.*y*(-1. + x + y + z); output(7) = -4.*z*(-1. + x + y + z); output(8) = 4.*x*z; output(9) = 4.*y*z; break; } case OPERATOR_D1: case OPERATOR_GRAD: { const auto x = input(0); const auto y = input(1); const auto z = input(2); // output is a rank-3 array with dimensions (basisCardinality_, dim0, spaceDim) output(0, 0) = -3.+ 4.*x + 4.*y + 4.*z; output(0, 1) = -3.+ 4.*x + 4.*y + 4.*z; output(0, 2) = -3.+ 4.*x + 4.*y + 4.*z; output(1, 0) = -1.+ 4.*x; output(1, 1) = 0.; output(1, 2) = 0.; output(2, 0) = 0.; output(2, 1) = -1.+ 4.*y; output(2, 2) = 0.; output(3, 0) = 0.; output(3, 1) = 0.; output(3, 2) = -1.+ 4.*z; output(4, 0) = -4.*(-1.+ 2*x + y + z); output(4, 1) = -4.*x; output(4, 2) = -4.*x; output(5, 0) = 4.*y; output(5, 1) = 4.*x; output(5, 2) = 0.; output(6, 0) = -4.*y; output(6, 1) = -4.*(-1.+ x + 2*y + z); output(6, 2) = -4.*y; output(7, 0) = -4.*z; output(7, 1) = -4.*z; output(7, 2) = -4.*(-1.+ x + y + 2*z); output(8, 0) = 4.*z; output(8, 1) = 0.; output(8, 2) = 4.*x; output(9, 0) = 0.; output(9, 1) = 4.*z; output(9, 2) = 4.*y; break; } case OPERATOR_D2: { output(0, 0) = 4.; output(0, 1) = 4.; output(0, 2) = 4.; output(0, 3) = 4.; output(0, 4) = 4.; output(0, 5) = 4.; output(1, 0) = 4.; output(1, 1) = 0.; output(1, 2) = 0.; output(1, 3) = 0.; output(1, 4) = 0.; output(1, 5) = 0.; output(2, 0) = 0.; output(2, 1) = 0.; output(2, 2) = 0.; output(2, 3) = 4.; output(2, 4) = 0.; output(2, 5) = 0.; output(3, 0) = 0.; output(3, 1) = 0.; output(3, 2) = 0.; output(3, 3) = 0.; output(3, 4) = 0.; output(3, 5) = 4.; output(4, 0) = -8.; output(4, 1) = -4.; output(4, 2) = -4.; output(4, 3) = 0.; output(4, 4) = 0.; output(4, 5) = 0.; output(5, 0) = 0.; output(5, 1) = 4.; output(5, 2) = 0.; output(5, 3) = 0.; output(5, 4) = 0.; output(5, 5) = 0.; output(6, 0) = 0.; output(6, 1) = -4.; output(6, 2) = 0.; output(6, 3) = -8.; output(6, 4) = -4.; output(6, 5) = 0; output(7, 0) = 0.; output(7, 1) = 0.; output(7, 2) = -4.; output(7, 3) = 0.; output(7, 4) = -4.; output(7, 5) = -8.; output(8, 0) = 0.; output(8, 1) = 0.; output(8, 2) = 4.; output(8, 3) = 0.; output(8, 4) = 0.; output(8, 5) = 0.; output(9, 0) = 0.; output(9, 1) = 0.; output(9, 2) = 0.; output(9, 3) = 0.; output(9, 4) = 4.; output(9, 5) = 0.; break; } case OPERATOR_MAX: { const auto jend = output.dimension(1); const auto iend = output.dimension(0); for (auto j=0;j<jend;++j) for (auto i=0;i<iend;++i) output(i, j) = 0.0; break; } default: { INTREPID2_TEST_FOR_ABORT( opType != OPERATOR_VALUE && opType != OPERATOR_GRAD && opType != OPERATOR_D1 && opType != OPERATOR_D2 && opType != OPERATOR_MAX, ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_C2_FEM::Serial::getValues) operator is not supported"); } } }
void OrientationTools<SpT>:: modifyBasisByOrientation(/**/ Kokkos::DynRankView<outputValueType,outputProperties...> output, const Kokkos::DynRankView<inputValueType, inputProperties...> input, const Kokkos::DynRankView<ortValueType, ortProperties...> orts, const BasisPtrType basis ) { #ifdef HAVE_INTREPID2_DEBUG { INTREPID2_TEST_FOR_EXCEPTION( input.rank() != output.rank(), std::invalid_argument, ">>> ERROR (OrientationTools::modifyBasisByOrientation): Input and output rank are not 3."); for (ordinal_type i=0;i<input.rank();++i) INTREPID2_TEST_FOR_EXCEPTION( input.dimension(i) != output.dimension(i), std::invalid_argument, ">>> ERROR (OrientationTools::modifyBasisByOrientation): Input and output dimension does not match."); INTREPID2_TEST_FOR_EXCEPTION( input.dimension(1) != basis->getCardinality(), std::invalid_argument, ">>> ERROR (OrientationTools::modifyBasisByOrientation): Field dimension of input/output does not match to basis cardinality."); INTREPID2_TEST_FOR_EXCEPTION( input.dimension(3) != basis->getBaseCellTopology().getDimension(), std::invalid_argument, ">>> ERROR (OrientationTools::modifyBasisByOrientation): Space dimension of input/output does not match to topology dimension."); } #endif if (basis->requireOrientation()) { auto ordinalToTag = Kokkos::create_mirror_view(typename SpT::memory_space(), basis->getAllDofTags()); auto tagToOrdinal = Kokkos::create_mirror_view(typename SpT::memory_space(), basis->getAllDofOrdinal()); Kokkos::deep_copy(ordinalToTag, basis->getAllDofTags()); Kokkos::deep_copy(tagToOrdinal, basis->getAllDofOrdinal()); const ordinal_type numCells = output.dimension(0), //numBasis = output.dimension(1), numPoints = output.dimension(2), dimBasis = output.dimension(3); const CoeffMatrixDataViewType matData = createCoeffMatrix(basis); const shards::CellTopology cellTopo = basis->getBaseCellTopology(); const ordinal_type numVerts = cellTopo.getVertexCount(), numEdges = cellTopo.getEdgeCount(), numFaces = cellTopo.getFaceCount(); const ordinal_type intrDim = ( numEdges == 0 ? 1 : numFaces == 0 ? 2 : /**/ 3 ); for (auto cell=0;cell<numCells;++cell) { auto out = Kokkos::subview(output, cell, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL()); auto in = Kokkos::subview(input, cell, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL()); // vertex copy (no orientation) for (auto vertId=0;vertId<numVerts;++vertId) { const auto i = tagToOrdinal(0, vertId, 0); if (i != -1) // if dof does not exist i returns with -1 for (auto j=0;j<numPoints;++j) for (auto k=0;k<dimBasis;++k) out(i, j, k) = in(i, j, k); } // interior copy { const auto ordIntr = tagToOrdinal(intrDim, 0, 0); if (ordIntr != -1) { const auto ndofIntr = ordinalToTag(ordIntr, 3); for (auto i=0;i<ndofIntr;++i) { const auto ii = tagToOrdinal(intrDim, 0, i); for (auto j=0;j<numPoints;++j) for (auto k=0;k<dimBasis;++k) out(ii, j, k) = in(ii, j, k); } } } // edge transformation if (numEdges > 0) { ordinal_type ortEdges[12]; orts(cell).getEdgeOrientation(ortEdges, numEdges); // apply coeff matrix for (auto edgeId=0;edgeId<numEdges;++edgeId) { const auto ordEdge = tagToOrdinal(1, edgeId, 0); if (ordEdge != -1) { const auto ndofEdge = ordinalToTag(ordEdge, 3); const auto mat = Kokkos::subview(matData, edgeId, ortEdges[edgeId], Kokkos::ALL(), Kokkos::ALL()); for (auto j=0;j<numPoints;++j) for (auto i=0;i<ndofEdge;++i) { const auto ii = tagToOrdinal(1, edgeId, i); for (auto k=0;k<dimBasis;++k) { double temp = 0.0; for (auto l=0;l<ndofEdge;++l) { const auto ll = tagToOrdinal(1, edgeId, l); temp += mat(i,l)*in(ll, j, k); } out(ii, j, k) = temp; } } } } } // face transformation if (numFaces > 0) { ordinal_type ortFaces[12]; orts(cell).getFaceOrientation(ortFaces, numFaces); // apply coeff matrix for (auto faceId=0;faceId<numFaces;++faceId) { const auto ordFace = tagToOrdinal(2, faceId, 0); if (ordFace != -1) { const auto ndofFace = ordinalToTag(ordFace, 3); const auto mat = Kokkos::subview(matData, numEdges+faceId, ortFaces[faceId], Kokkos::ALL(), Kokkos::ALL()); for (auto j=0;j<numPoints;++j) for (auto i=0;i<ndofFace;++i) { const auto ii = tagToOrdinal(2, faceId, i); for (auto k=0;k<dimBasis;++k) { double temp = 0.0; for (auto l=0;l<ndofFace;++l) { const auto ll = tagToOrdinal(2, faceId, l); temp += mat(i,l)*in(ll, j, k); } out(ii, j, k) = temp; } } } } } } } else { Kokkos::deep_copy(output, input); } }
void CellTools<SpT>:: mapToReferenceSubcell( /**/ Kokkos::DynRankView<refSubcellPointValueType,refSubcellPointProperties...> refSubcellPoints, const Kokkos::DynRankView<paramPointValueType,paramPointProperties...> paramPoints, const ordinal_type subcellDim, const ordinal_type subcellOrd, const shards::CellTopology parentCell ) { #ifdef HAVE_INTREPID2_DEBUG INTREPID2_TEST_FOR_EXCEPTION( !hasReferenceCell(parentCell), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::mapToReferenceSubcell): the specified cell topology does not have a reference cell."); INTREPID2_TEST_FOR_EXCEPTION( subcellDim != 1 && subcellDim != 2, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::mapToReferenceSubcell): method defined only for 1 and 2-dimensional subcells."); INTREPID2_TEST_FOR_EXCEPTION( subcellOrd < 0 || subcellOrd >= parentCell.getSubcellCount(subcellDim), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::mapToReferenceSubcell): subcell ordinal out of range."); // refSubcellPoints is rank-2 (P,D1), D1 = cell dimension INTREPID2_TEST_FOR_EXCEPTION( refSubcellPoints.rank() != 2, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::mapToReferenceSubcell): refSubcellPoints must have rank 2."); INTREPID2_TEST_FOR_EXCEPTION( refSubcellPoints.dimension(1) != parentCell.getDimension(), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::mapToReferenceSubcell): refSubcellPoints dimension (1) does not match to parent cell dimension."); // paramPoints is rank-2 (P,D2) with D2 = subcell dimension INTREPID2_TEST_FOR_EXCEPTION( paramPoints.rank() != 2, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::mapToReferenceSubcell): paramPoints must have rank 2."); INTREPID2_TEST_FOR_EXCEPTION( paramPoints.dimension(1) != subcellDim, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::mapToReferenceSubcell): paramPoints dimension (1) does not match to subcell dimension."); // cross check: refSubcellPoints and paramPoints: dimension 0 must match INTREPID2_TEST_FOR_EXCEPTION( refSubcellPoints.dimension(0) < paramPoints.dimension(0), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::mapToReferenceSubcell): refSubcellPoints dimension (0) does not match to paramPoints dimension(0)."); #endif const auto cellDim = parentCell.getDimension(); const auto numPts = paramPoints.dimension(0); // Get the subcell map, i.e., the coefficients of the parametrization function for the subcell // can i get this map from devices ? subcellParamViewType subcellMap; getSubcellParametrization( subcellMap, subcellDim, parentCell ); // subcell parameterization should be small computation (numPts is small) and it should be decorated with // kokkos inline... let's not do this yet // Apply the parametrization map to every point in parameter domain switch (subcellDim) { case 2: { for (size_type pt=0;pt<numPts;++pt) { const auto u = paramPoints(pt, 0); const auto v = paramPoints(pt, 1); // map_dim(u,v) = c_0(dim) + c_1(dim)*u + c_2(dim)*v because both Quad and Tri ref faces are affine! for (size_type i=0;i<cellDim;++i) refSubcellPoints(pt, i) = subcellMap(subcellOrd, i, 0) + ( subcellMap(subcellOrd, i, 1)*u + subcellMap(subcellOrd, i, 2)*v ); } break; } case 1: { for (size_type pt=0;pt<numPts;++pt) { const auto u = paramPoints(pt, 0); for (size_type i=0;i<cellDim;++i) refSubcellPoints(pt, i) = subcellMap(subcellOrd, i, 0) + ( subcellMap(subcellOrd, i, 1)*u ); } break; } default: { INTREPID2_TEST_FOR_EXCEPTION( subcellDim != 1 && subcellDim != 2, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::mapToReferenceSubcell): method defined only for 1 and 2-subcells"); } } }
void ArrayTools<ExecSpaceType>:: scalarMultiplyDataData( /**/ Kokkos::DynRankView<outputDataValueType, outputDataProperties...> outputData, const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft, const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight, const bool reciprocal ) { #ifdef HAVE_INTREPID2_DEBUG { INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.rank() != 2, std::invalid_argument, ">>> ERROR (ArrayTools::scalarMultiplyDataData): Left input data container must have rank 2."); if (outputData.rank() <= inputDataRight.rank()) { INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.rank() < 2 || inputDataRight.rank() > 4, std::invalid_argument, ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 2, 3, or 4."); INTREPID2_TEST_FOR_EXCEPTION( outputData.rank() != inputDataRight.rank(), std::invalid_argument, ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input and output data containers must have the same rank."); INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.dimension(0) != inputDataLeft.dimension(0), std::invalid_argument, ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions (number of integration domains) of the left and right data input containers must agree!"); INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.dimension(1) != inputDataRight.dimension(1) && inputDataLeft.dimension(1) != 1, std::invalid_argument, ">>> ERROR (ArrayTools::scalarMultiplyDataData): First dimensions of the left and right data input containers (number of integration points) must agree, or first dimension of the left data input container must be 1!"); for (size_type i=0;i<inputDataRight.rank();++i) { INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.dimension(i) != outputData.dimension(i), std::invalid_argument, ">>> ERROR (ArrayTools::scalarMultiplyDataData): inputDataRight dimension (i) does not match to the dimension (i) of outputData"); } } else { INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.rank() < 1 || inputDataRight.rank() > 3, std::invalid_argument, ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 1, 2, or 3."); INTREPID2_TEST_FOR_EXCEPTION( outputData.rank() != (inputDataRight.rank()+1), std::invalid_argument, ">>> ERROR (ArrayTools::scalarMultiplyDataData): The rank of the right input data container must be one less than the rank of the output data container."); INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.dimension(1) != inputDataRight.dimension(0) && inputDataLeft.dimension(1) != 1, std::invalid_argument, ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimension of the right input data container and first dimension of the left data input container (number of integration points) must agree or first dimension of the left data input container must be 1!"); INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.dimension(0) != outputData.dimension(0), std::invalid_argument, ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions of data output and left data input containers (number of integration domains) must agree!"); for (size_type i=0;i<inputDataRight.rank();++i) { INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.dimension(i) != outputData.dimension(i+1), std::invalid_argument, ">>> ERROR (ArrayTools::scalarMultiplyDataData): inputDataRight dimension (i) does not match to the dimension (i+1) of outputData"); } } } #endif // body ArrayTools<ExecSpaceType>::Internal::scalarMultiply( outputData, inputDataLeft, inputDataRight, false, reciprocal ); }
KOKKOS_INLINE_FUNCTION void Basis_HGRAD_HEX_C1_FEM<SpT>::Serial<opType>:: getValues( /**/ Kokkos::DynRankView<outputValueValueType,outputValueProperties...> output, const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> input ) { switch (opType) { case OPERATOR_VALUE : { const auto x = input(0); const auto y = input(1); const auto z = input(2); // output is a rank-2 array with dimensions (basisCardinality_, dim0) output(0) = (1.0 - x)*(1.0 - y)*(1.0 - z)/8.0; output(1) = (1.0 + x)*(1.0 - y)*(1.0 - z)/8.0; output(2) = (1.0 + x)*(1.0 + y)*(1.0 - z)/8.0; output(3) = (1.0 - x)*(1.0 + y)*(1.0 - z)/8.0; output(4) = (1.0 - x)*(1.0 - y)*(1.0 + z)/8.0; output(5) = (1.0 + x)*(1.0 - y)*(1.0 + z)/8.0; output(6) = (1.0 + x)*(1.0 + y)*(1.0 + z)/8.0; output(7) = (1.0 - x)*(1.0 + y)*(1.0 + z)/8.0; break; } case OPERATOR_GRAD : { const auto x = input(0); const auto y = input(1); const auto z = input(2); // output is a rank-3 array with dimensions (basisCardinality_, dim0, spaceDim) output(0, 0) = -(1.0 - y)*(1.0 - z)/8.0; output(0, 1) = -(1.0 - x)*(1.0 - z)/8.0; output(0, 2) = -(1.0 - x)*(1.0 - y)/8.0; output(1, 0) = (1.0 - y)*(1.0 - z)/8.0; output(1, 1) = -(1.0 + x)*(1.0 - z)/8.0; output(1, 2) = -(1.0 + x)*(1.0 - y)/8.0; output(2, 0) = (1.0 + y)*(1.0 - z)/8.0; output(2, 1) = (1.0 + x)*(1.0 - z)/8.0; output(2, 2) = -(1.0 + x)*(1.0 + y)/8.0; output(3, 0) = -(1.0 + y)*(1.0 - z)/8.0; output(3, 1) = (1.0 - x)*(1.0 - z)/8.0; output(3, 2) = -(1.0 - x)*(1.0 + y)/8.0; output(4, 0) = -(1.0 - y)*(1.0 + z)/8.0; output(4, 1) = -(1.0 - x)*(1.0 + z)/8.0; output(4, 2) = (1.0 - x)*(1.0 - y)/8.0; output(5, 0) = (1.0 - y)*(1.0 + z)/8.0; output(5, 1) = -(1.0 + x)*(1.0 + z)/8.0; output(5, 2) = (1.0 + x)*(1.0 - y)/8.0; output(6, 0) = (1.0 + y)*(1.0 + z)/8.0; output(6, 1) = (1.0 + x)*(1.0 + z)/8.0; output(6, 2) = (1.0 + x)*(1.0 + y)/8.0; output(7, 0) = -(1.0 + y)*(1.0 + z)/8.0; output(7, 1) = (1.0 - x)*(1.0 + z)/8.0; output(7, 2) = (1.0 - x)*(1.0 + y)/8.0; break; } case OPERATOR_D2 : { const auto x = input(0); const auto y = input(1); const auto z = input(2); // output is a rank-3 array with dimensions (basisCardinality_, dim0, D2Cardinality = 6) output(0, 0) = 0.0; // {2, 0, 0} output(0, 1) = (1.0 - z)/8.0; // {1, 1, 0} output(0, 2) = (1.0 - y)/8.0; // {1, 0, 1} output(0, 3) = 0.0; // {0, 2, 0} output(0, 4) = (1.0 - x)/8.0; // {0, 1, 1} output(0, 5) = 0.0; // {0, 0, 2} output(1, 0) = 0.0; // {2, 0, 0} output(1, 1) = -(1.0 - z)/8.0; // {1, 1, 0} output(1, 2) = -(1.0 - y)/8.0; // {1, 0, 1} output(1, 3) = 0.0; // {0, 2, 0} output(1, 4) = (1.0 + x)/8.0; // {0, 1, 1} output(1, 5) = 0.0; // {0, 0, 2} output(2, 0) = 0.0; // {2, 0, 0} output(2, 1) = (1.0 - z)/8.0; // {1, 1, 0} output(2, 2) = -(1.0 + y)/8.0; // {1, 0, 1} output(2, 3) = 0.0; // {0, 2, 0} output(2, 4) = -(1.0 + x)/8.0; // {0, 1, 1} output(2, 5) = 0.0; // {0, 0, 2} output(3, 0) = 0.0; // {2, 0, 0} output(3, 1) = -(1.0 - z)/8.0; // {1, 1, 0} output(3, 2) = (1.0 + y)/8.0; // {1, 0, 1} output(3, 3) = 0.0; // {0, 2, 0} output(3, 4) = -(1.0 - x)/8.0; // {0, 1, 1} output(3, 5) = 0.0; // {0, 0, 2} output(4, 0) = 0.0; // {2, 0, 0} output(4, 1) = (1.0 + z)/8.0; // {1, 1, 0} output(4, 2) = -(1.0 - y)/8.0; // {1, 0, 1} output(4, 3) = 0.0; // {0, 2, 0} output(4, 4) = -(1.0 - x)/8.0; // {0, 1, 1} output(4, 5) = 0.0; // {0, 0, 2} output(5, 0) = 0.0; // {2, 0, 0} output(5, 1) = -(1.0 + z)/8.0; // {1, 1, 0} output(5, 2) = (1.0 - y)/8.0; // {1, 0, 1} output(5, 3) = 0.0; // {0, 2, 0} output(5, 4) = -(1.0 + x)/8.0; // {0, 1, 1} output(5, 5) = 0.0; // {0, 0, 2} output(6, 0) = 0.0; // {2, 0, 0} output(6, 1) = (1.0 + z)/8.0; // {1, 1, 0} output(6, 2) = (1.0 + y)/8.0; // {1, 0, 1} output(6, 3) = 0.0; // {0, 2, 0} output(6, 4) = (1.0 + x)/8.0; // {0, 1, 1} output(6, 5) = 0.0; // {0, 0, 2} output(7, 0) = 0.0; // {2, 0, 0} output(7, 1) = -(1.0 + z)/8.0; // {1, 1, 0} output(7, 2) = -(1.0 + y)/8.0; // {1, 0, 1} output(7, 3) = 0.0; // {0, 2, 0} output(7, 4) = (1.0 - x)/8.0; // {0, 1, 1} output(7, 5) = 0.0; // {0, 0, 2} break; } case OPERATOR_MAX : { const auto jend = output.dimension(1); const auto iend = output.dimension(0); for (auto j=0;j<jend;++j) for (auto i=0;i<iend;++i) output(i, j) = 0.0; break; } default: { INTREPID2_TEST_FOR_ABORT( opType != OPERATOR_VALUE && opType != OPERATOR_GRAD && opType != OPERATOR_CURL && opType != OPERATOR_D2 && opType != OPERATOR_MAX, ">>> ERROR: (Intrepid2::Basis_HGRAD_HEX_C1_FEM::Serial::getValues) operator is not supported"); } } }
void Basis_HDIV_TRI_I1_FEM:: getValues( Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues, const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints, const EOperator operatorType ) { typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType; typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType; typedef typename ExecSpace<typename inputPointViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType; // Number of evaluation points = dim 0 of inputPoints const auto loopSize = inputPoints.dimension(0); Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize); switch (operatorType) { case OPERATOR_VALUE: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_VALUE> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) ); break; } case OPERATOR_DIV: { typedef Functor<outputValueViewType,inputPointViewType,OPERATOR_DIV> FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) ); break; } case OPERATOR_CURL: { INTREPID2_TEST_FOR_EXCEPTION( (operatorType == OPERATOR_CURL), std::invalid_argument, ">>> ERROR (Basis_HDIV_TRI_I1_FEM): CURL is invalid operator for HDIV Basis Functions"); break; } case OPERATOR_GRAD: { INTREPID2_TEST_FOR_EXCEPTION( (operatorType == OPERATOR_GRAD), std::invalid_argument, ">>> ERROR (Basis_HDIV_TRI_I1_FEM): GRAD is invalid operator for HDIV Basis Functions"); break; } case OPERATOR_D1: case OPERATOR_D2: case OPERATOR_D3: case OPERATOR_D4: case OPERATOR_D5: case OPERATOR_D6: case OPERATOR_D7: case OPERATOR_D8: case OPERATOR_D9: case OPERATOR_D10: { INTREPID2_TEST_FOR_EXCEPTION( ( (operatorType == OPERATOR_D1) && (operatorType == OPERATOR_D2) && (operatorType == OPERATOR_D3) && (operatorType == OPERATOR_D4) && (operatorType == OPERATOR_D5) && (operatorType == OPERATOR_D6) && (operatorType == OPERATOR_D7) && (operatorType == OPERATOR_D8) && (operatorType == OPERATOR_D9) && (operatorType == OPERATOR_D10) ), std::invalid_argument, ">>> ERROR (Basis_HDIV_TRI_I1_FEM): Invalid operator type"); break; } default: { INTREPID2_TEST_FOR_EXCEPTION( ( (operatorType != OPERATOR_VALUE) && (operatorType != OPERATOR_GRAD) && (operatorType != OPERATOR_CURL) && (operatorType != OPERATOR_DIV) && (operatorType != OPERATOR_D1) && (operatorType != OPERATOR_D2) && (operatorType != OPERATOR_D3) && (operatorType != OPERATOR_D4) && (operatorType != OPERATOR_D5) && (operatorType != OPERATOR_D6) && (operatorType != OPERATOR_D7) && (operatorType != OPERATOR_D8) && (operatorType != OPERATOR_D9) && (operatorType != OPERATOR_D10) ), std::invalid_argument, ">>> ERROR (Basis_HDIV_TRI_I1_FEM): Invalid operator type"); } } }
void CubatureTensor<SpT,PT,WT>:: getCubatureImpl( Kokkos::DynRankView<cubPointValueType, cubPointProperties...> cubPoints, Kokkos::DynRankView<cubWeightValueType,cubWeightProperties...> cubWeights ) const { #ifdef HAVE_INTREPID2_DEBUG // check size of cubPoints and cubWeights INTREPID2_TEST_FOR_EXCEPTION( static_cast<ordinal_type>(cubPoints.dimension(0)) < this->getNumPoints() || static_cast<ordinal_type>(cubPoints.dimension(1)) < this->getDimension() || static_cast<ordinal_type>(cubWeights.dimension(0)) < this->getNumPoints(), std::out_of_range, ">>> ERROR (CubatureTensor): Insufficient space allocated for cubature points or weights."); #endif typedef Kokkos::DynRankView<cubPointValueType, SpT> cubPointViewType; typedef Kokkos::DynRankView<cubWeightValueType,SpT> cubWeightViewType; // mirroring and where the data is problematic... when it becomes a problem, then deal with it. cubPointViewType tmpPoints [Parameters::MaxDimension]; cubWeightViewType tmpWeights[Parameters::MaxDimension]; // this temporary allocation can be member of cubature; for now, let's do this way. // this is cubature setup on the reference cell and called for tensor elements. for (auto k=0;k<this->numCubatures_;++k) { const auto &cub = this->cubatures_[k]; tmpPoints [k] = cubPointViewType ("CubatureTensor::getCubature::tmpPoints", cub.getNumPoints(), cub.getDimension()); tmpWeights[k] = cubWeightViewType("CubatureTensor::getCubature::tmpWeights", cub.getNumPoints()); cub.getCubature(tmpPoints[k], tmpWeights[k]); } { const auto npts = this->getNumPoints(); const auto dim = this->getDimension(); const Kokkos::pair<ordinal_type,ordinal_type> pointRange(0, npts); const Kokkos::pair<ordinal_type,ordinal_type> dimRange(0, dim); Kokkos::deep_copy(Kokkos::subdynrankview(cubPoints, pointRange, dimRange), 0.0); Kokkos::deep_copy(Kokkos::subdynrankview(cubWeights, pointRange), 1.0); } // when the input containers are device space, this is better computed on host and copy to devices // fill tensor cubature { ordinal_type offset[Parameters::MaxDimension+1] = {}; for (auto k=0;k<this->numCubatures_;++k) { offset[k+1] = offset[k] + this->cubatures_[k].getDimension(); } ordinal_type ii = 0, i[3] = {}; switch (this->numCubatures_) { case 2: { const ordinal_type npts[] = { this->cubatures_[0].getNumPoints(), this->cubatures_[1].getNumPoints() }; const ordinal_type dim [] = { this->cubatures_[0].getDimension(), this->cubatures_[1].getDimension() }; for (i[1]=0;i[1]<npts[1];++i[1]) for (i[0]=0;i[0]<npts[0];++i[0]) { for (auto nc=0;nc<2;++nc) { cubWeights(ii) *= tmpWeights[nc](i[nc]); for (ordinal_type j=0;j<dim[nc];++j) cubPoints(ii, offset[nc]+j) = tmpPoints[nc](i[nc], j); } ++ii; } break; } case 3: { const ordinal_type npts[] = { this->cubatures_[0].getNumPoints(), this->cubatures_[1].getNumPoints(), this->cubatures_[2].getNumPoints() }; const ordinal_type dim [] = { this->cubatures_[0].getDimension(), this->cubatures_[1].getDimension(), this->cubatures_[2].getDimension() }; for (i[2]=0;i[2]<npts[2];++i[2]) for (i[1]=0;i[1]<npts[1];++i[1]) for (i[0]=0;i[0]<npts[0];++i[0]) { for (auto nc=0;nc<3;++nc) { cubWeights(ii) *= tmpWeights[nc](i[nc]); for (ordinal_type j=0;j<dim[nc];++j) cubPoints(ii, offset[nc]+j) = tmpPoints[nc](i[nc], j); } ++ii; } break; } default: { INTREPID2_TEST_FOR_EXCEPTION( this->numCubatures_ != 2 || this->numCubatures_ != 3, std::runtime_error, ">>> ERROR (CubatureTensor::getCubature): CubatureTensor supports only 2 or 3 component direct cubatures."); } } } }
void ArrayTools<ExecSpaceType>:: dotMultiplyDataData( /**/ Kokkos::DynRankView<outputDataValueType, outputDataProperties...> outputData, const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft, const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight ) { #ifdef HAVE_INTREPID2_DEBUG { if (inputDataRight.rank() >= inputDataLeft.rank()) { INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.rank() < 2 || inputDataLeft.rank() > 4, std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): Left data input container must have rank 2, 3 or 4."); INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.rank() != inputDataLeft.rank(), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): The rank of the right data input container must equal the rank of the left data input container."); INTREPID2_TEST_FOR_EXCEPTION( outputData.rank() != 2, std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): Data output container must have rank 2."); INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.dimension(1) != inputDataRight.dimension(1) && inputDataLeft.dimension(1) != 1, std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): First dimensions of the left and right data input containers (number of integration points) must agree or first left data dimension must be 1!"); for (size_type i=0;i<inputDataLeft.rank();++i) { if (i != 1) { INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.dimension(i) != inputDataRight.dimension(i), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): inputDataLeft dimension (i) does not match to the dimension (i) of inputDataRight"); } } for (size_type i=0;i<outputData.rank();++i) { INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.dimension(i) != outputData.dimension(i), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): inputDataRight dimension (i) does not match to the dimension (i) of outputData"); } } else { INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.rank() < 2 || inputDataLeft.rank() > 4, std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): Left data input container must have rank 2, 3 or 4."); INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.rank() != (inputDataLeft.rank()-1), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): Right data input container must have rank one less than the rank of left data input container."); INTREPID2_TEST_FOR_EXCEPTION( outputData.rank() != 2, std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): Data output container must have rank 2."); INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.dimension(1) != inputDataRight.dimension(0) && inputDataLeft.dimension(1) != 1, std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): Zeroth dimension of the right data input container and first dimension of left data input container (number of integration points) must agree or first left data dimension must be 1!"); INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.dimension(0) != outputData.dimension(1), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): Zeroth dimension of the right data input container and first dimension of output data container (number of integration points) must agree!"); INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.dimension(0) != outputData.dimension(0), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): Zeroth dimensions of the left data input and data output containers (number of integration domains) must agree!"); for (size_type i=1;i<inputDataRight.rank();++i) { INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.dimension(i+1) != inputDataRight.dimension(i), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataData): inputDataLeft dimension (i+1) does not match to the dimension (i) of inputDataRight"); } } } #endif ArrayTools<ExecSpaceType>::Internal::dotMultiply( outputData, inputDataLeft, inputDataRight, false ); }
void ArrayTools<ExecSpaceType>:: dotMultiplyDataField( /**/ Kokkos::DynRankView<outputFieldValueType,outputFieldProperties...> outputFields, const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData, const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) { #ifdef HAVE_INTREPID2_DEBUG { if (inputFields.rank() > inputData.rank()) { INTREPID2_TEST_FOR_EXCEPTION( inputData.rank() < 2 || inputData.rank() > 4, std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): Input data container must have rank 2, 3 or 4."); INTREPID2_TEST_FOR_EXCEPTION( inputFields.rank() != (inputData.rank()+1), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): Input fields container must have rank one larger than the rank of the input data container."); INTREPID2_TEST_FOR_EXCEPTION( outputFields.rank() != 3, std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): Output fields container must have rank 3."); INTREPID2_TEST_FOR_EXCEPTION( inputFields.dimension(0) != inputData.dimension(0), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimensions (number of integration domains) of the fields and data input containers must agree!"); INTREPID2_TEST_FOR_EXCEPTION( inputData.dimension(1) != inputFields.dimension(2) && inputData.dimension(1) != 1, std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): 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!"); for (size_type i=2;i<inputData.rank();++i) { INTREPID2_TEST_FOR_EXCEPTION( inputData.dimension(i) != inputFields.dimension(i+1), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): inputData dimension (i) does not match to the dimension (i+1) of inputFields"); } for (size_t i=0;i<outputFields.rank();++i) { INTREPID2_TEST_FOR_EXCEPTION( inputFields.dimension(i) != outputFields.dimension(i), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): inputFields dimension (i) does not match to the dimension (i+1) of outputFields"); } } else { INTREPID2_TEST_FOR_EXCEPTION( inputData.rank() < 2 || inputData.rank() > 4, std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): Input data container must have rank 2, 3 or 4."); INTREPID2_TEST_FOR_EXCEPTION( inputFields.rank() != inputData.rank(), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): The rank of fields input container must equal the rank of data input container."); INTREPID2_TEST_FOR_EXCEPTION( outputFields.rank() != 3, std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): Output fields container must have rank 3."); INTREPID2_TEST_FOR_EXCEPTION( inputData.dimension(1) != inputFields.dimension(1) && inputData.dimension(1) != 1, std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): First dimensions of the fields and data input containers (number of integration points) must agree or first data dimension must be 1!"); INTREPID2_TEST_FOR_EXCEPTION( inputFields.dimension(0) != outputFields.dimension(1), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimension of the fields input container and first dimension of the fields output container (number of fields) must agree!"); INTREPID2_TEST_FOR_EXCEPTION( inputFields.dimension(1) != outputFields.dimension(2), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): First dimension of the fields input container and second dimension of the fields output container (number of integration points) must agree!"); INTREPID2_TEST_FOR_EXCEPTION( outputFields.dimension(0) != inputData.dimension(0), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimensions of the fields output and data input containers (number of integration domains) must agree!"); for (size_type i=2;i<inputData.rank();++i) { INTREPID2_TEST_FOR_EXCEPTION( inputData.dimension(i) != inputFields.dimension(i), std::invalid_argument, ">>> ERROR (ArrayTools::dotMultiplyDataField): inputData dimension (i) does not match to the dimension (i) of inputFields"); } } } #endif ArrayTools<ExecSpaceType>::Internal::dotMultiply( outputFields, inputData, inputFields, true ); }