int Integration_Test05(const bool verbose) { Teuchos::RCP<std::ostream> outStream; Teuchos::oblackholestream bhs; // outputs nothing if (verbose) outStream = Teuchos::rcp(&std::cout, false); else outStream = Teuchos::rcp(&bhs, false); Teuchos::oblackholestream oldFormatState; oldFormatState.copyfmt(std::cout); typedef typename Kokkos::Impl::is_space<DeviceSpaceType>::host_mirror_space::execution_space HostSpaceType ; *outStream << "DeviceSpace:: "; DeviceSpaceType::print_configuration(*outStream, false); *outStream << "HostSpace:: "; HostSpaceType::print_configuration(*outStream, false); *outStream << "===============================================================================\n" << "| |\n" << "| Unit Test (CubatureDirect,CubatureTensor) |\n" << "| |\n" << "| 1) Computing integrals of monomials on reference cells in 2D |\n" << "| |\n" << "| Questions? Contact Pavel Bochev ([email protected]) or |\n" << "| Denis Ridzal ([email protected]) or |\n" << "| Kyungjoo Kim ([email protected]). |\n" << "| |\n" << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" << "| Trilinos website: http://trilinos.sandia.gov |\n" << "| |\n" << "===============================================================================\n" << "| TEST 1: integrals of monomials in 2D |\n" << "===============================================================================\n"; typedef Kokkos::DynRankView<ValueType,DeviceSpaceType> DynRankView; #define ConstructWithLabel(obj, ...) obj(#obj, __VA_ARGS__) typedef ValueType pointValueType; typedef ValueType weightValueType; typedef CubatureDirectTriDefault<DeviceSpaceType,pointValueType,weightValueType> CubatureTriType; const auto tol = 10.0 * Parameters::Tolerence; int errorFlag = 0; // get names of files with analytic values std::string basedir = "../data"; std::stringstream namestream; std::string filename; namestream << basedir << "/TRI_integrals" << ".dat"; namestream >> filename; *outStream << "filename = " << filename << std::endl; std::ifstream filecompare(filename); // compute and compare integrals try { const auto maxDeg = Parameters::MaxCubatureDegreeTri; const auto polySize = (maxDeg+1)*(maxDeg+2)/2; // test inegral values DynRankView ConstructWithLabel(testInt, maxDeg+1, polySize); // analytic integral values const auto analyticMaxDeg = 20; const auto analyticPolySize = (analyticMaxDeg+1)*(analyticMaxDeg+2)/2; DynRankView ConstructWithLabel(analyticInt, analyticPolySize, 1); // storage for cubatrue points and weights DynRankView ConstructWithLabel(cubPoints, Parameters::MaxIntegrationPoints, Parameters::MaxDimension); DynRankView ConstructWithLabel(cubWeights, Parameters::MaxIntegrationPoints); // compute integrals for (auto cubDeg=0;cubDeg<=maxDeg;++cubDeg) { CubatureTriType triCub(cubDeg); ordinal_type cnt = 0; for (auto xDeg=0;xDeg<=cubDeg;++xDeg) for (auto yDeg=0;yDeg<=(cubDeg-xDeg);++yDeg,++cnt) testInt(cubDeg, cnt) = computeIntegralOfMonomial<ValueType>(triCub, cubPoints, cubWeights, xDeg, yDeg); } // get analytic values if (filecompare.is_open()) { getAnalytic(analyticInt, filecompare); filecompare.close(); } // perform comparison for (auto cubDeg=0;cubDeg<=maxDeg;++cubDeg) { ordinal_type offset = 0, cnt = 0; for (auto xDeg=0;xDeg<=cubDeg;++xDeg,offset += (analyticMaxDeg - cubDeg)) { for (auto yDeg=0;yDeg<=(cubDeg-xDeg);++yDeg,++cnt) { const auto loc = cnt + offset; const auto abstol = ( analyticInt(loc,0) == 0.0 ? tol : std::fabs(tol*analyticInt(loc,0)) ); const auto absdiff = std::fabs(analyticInt(loc,0) - testInt(cubDeg,cnt)); *outStream << "Cubature order " << std::setw(2) << std::left << cubDeg << " integrating " << "x^" << std::setw(2) << std::left << xDeg << " * y^" << std::setw(2) << yDeg << ":" << " " << std::scientific << std::setprecision(16) << testInt(cubDeg,cnt) << " " << analyticInt(loc,0) << " " << std::setprecision(4) << absdiff << " " << "<?" << " " << abstol << "\n"; if (absdiff > abstol) { errorFlag++; *outStream << std::right << std::setw(111) << "^^^^---FAILURE!\n"; } } } } *outStream << "\n"; } catch (std::logic_error err) { *outStream << err.what() << "\n"; errorFlag = -1; } if (errorFlag != 0) std::cout << "End Result: TEST FAILED\n"; else std::cout << "End Result: TEST PASSED\n"; // reset format state of std::cout std::cout.copyfmt(oldFormatState); return errorFlag; }
int Integration_Test01(const bool verbose) { Teuchos::RCP<std::ostream> outStream; Teuchos::oblackholestream bhs; // outputs nothing if (verbose) outStream = Teuchos::rcp(&std::cout, false); else outStream = Teuchos::rcp(&bhs, false); Teuchos::oblackholestream oldFormatState; oldFormatState.copyfmt(std::cout); typedef typename Kokkos::Impl::is_space<DeviceSpaceType>::host_mirror_space::execution_space HostSpaceType ; *outStream << "DeviceSpace:: "; DeviceSpaceType::print_configuration(*outStream, false); *outStream << "HostSpace:: "; HostSpaceType::print_configuration(*outStream, false); *outStream << "===============================================================================\n" << "| |\n" << "| Unit Test (CubatureDirect,CubatureTensor) |\n" << "| |\n" << "| 1) Computing volumes of reference cells |\n" << "| |\n" << "| Questions? Contact Pavel Bochev ([email protected]) or |\n" << "| Denis Ridzal ([email protected]) or |\n" << "| Kyungjoo Kim ([email protected]). |\n" << "| |\n" << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" << "| Trilinos website: http://trilinos.sandia.gov |\n" << "| |\n" << "===============================================================================\n"; typedef Kokkos::DynRankView<ValueType,DeviceSpaceType> DynRankView; #define ConstructWithLabel(obj, ...) obj(#obj, __VA_ARGS__) typedef ValueType pointValueType; typedef ValueType weightValueType; typedef CubatureDirectLineGauss <DeviceSpaceType,pointValueType,weightValueType> CubatureLineType; typedef CubatureDirectLineGaussJacobi20<DeviceSpaceType,pointValueType,weightValueType> CubatureLineJacobiType; typedef CubatureDirectTriDefault <DeviceSpaceType,pointValueType,weightValueType> CubatureTriType; typedef CubatureDirectTetDefault <DeviceSpaceType,pointValueType,weightValueType> CubatureTetType; typedef CubatureTensor <DeviceSpaceType,pointValueType,weightValueType> CubatureTensorType; typedef CubatureTensorPyr <DeviceSpaceType,pointValueType,weightValueType> CubatureTensorPyrType; const auto tol = 100.0 * tolerence(); int errorFlag = 0; *outStream << "\n" << "===============================================================================\n" << "| TEST 1: exception |\n" << "===============================================================================\n"; try { ordinal_type nthrow = 0, ncatch = 0; #ifdef HAVE_INTREPID2_DEBUG *outStream << "-> Line testing\n\n"; { INTREPID2_TEST_ERROR_EXPECTED( CubatureLineType(-1) ); INTREPID2_TEST_ERROR_EXPECTED( CubatureLineType(Parameters::MaxCubatureDegreeEdge+1) ); } *outStream << "-> Triangle testing\n\n"; { INTREPID2_TEST_ERROR_EXPECTED( CubatureTriType triCub(-1) ); INTREPID2_TEST_ERROR_EXPECTED( CubatureTriType triCub(Parameters::MaxCubatureDegreeTri+1) ); } *outStream << "-> Tetrahedron testing\n\n"; { INTREPID2_TEST_ERROR_EXPECTED( CubatureTetType tetCub(-1) ); INTREPID2_TEST_ERROR_EXPECTED( CubatureTetType tetCub(Parameters::MaxCubatureDegreeTet+1) ); } #endif if (nthrow != ncatch) { errorFlag++; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; *outStream << "# of catch ("<< ncatch << ") is different from # of throw (" << ncatch << ")\n"; } } catch (std::logic_error err) { *outStream << err.what() << "\n"; errorFlag = -1000; }; *outStream << "\n" << "===============================================================================\n" << "| TEST 2: basic functionalities |\n" << "===============================================================================\n"; try { *outStream << "-> Line testing\n\n"; { CubatureLineType lineCub(4); INTREPID2_TEST_FOR_EXCEPTION( lineCub.getDimension() != 1, std::logic_error, ">>> ERROR (Integration::Test01): line cubature must have 1 dimension."); INTREPID2_TEST_FOR_EXCEPTION( lineCub.getAccuracy() != 4, std::logic_error, ">>> ERROR (Integration::Test01): line cubature reports wrong accuracy."); } *outStream << "-> Triangle testing\n\n"; { CubatureTriType triCub(17); INTREPID2_TEST_FOR_EXCEPTION( triCub.getNumPoints() != 61, std::logic_error, ">>> ERROR (Integration::Test01): triangle cubature reports a wrong number of points."); INTREPID2_TEST_FOR_EXCEPTION( triCub.getDimension() != 2, std::logic_error, ">>> ERROR (Integration::Test01): triangle cubature reports a wrong dimension."); } *outStream << "-> Tetrahedron testing\n\n"; { CubatureTetType tetCub(17); INTREPID2_TEST_FOR_EXCEPTION( tetCub.getNumPoints() != 495, std::logic_error, ">>> ERROR (Integration::Test01): tetrahedron cubature reports a wrong number of points."); INTREPID2_TEST_FOR_EXCEPTION( tetCub.getDimension() != 3, std::logic_error, ">>> ERROR (Integration::Test01): tetrahedron cubature reports a wrong dimension."); } *outStream << "-> Quad testing\n\n"; { CubatureTensorType quadCub( CubatureLineType(3), CubatureLineType(7) ); INTREPID2_TEST_FOR_EXCEPTION( quadCub.getDimension() != 2, std::logic_error, ">>> ERROR (Integration::Test01): quad cubature must have 2 dimension."); ordinal_type accuracy[Parameters::MaxDimension]; quadCub.getAccuracy( accuracy ); INTREPID2_TEST_FOR_EXCEPTION( accuracy[0] != 3 || accuracy[1] != 7, std::logic_error, ">>> ERROR (Integration::Test01): quad cubature reports wrong accuracy."); } *outStream << "-> Hex testing\n\n"; { CubatureTensorType hexCub( CubatureLineType(1), CubatureLineType(4), CubatureLineType(2) ); INTREPID2_TEST_FOR_EXCEPTION( hexCub.getDimension() != 3, std::logic_error, ">>> ERROR (Integration::Test01): hex cubature must have 3 dimension."); ordinal_type accuracy[Parameters::MaxDimension]; hexCub.getAccuracy( accuracy ); INTREPID2_TEST_FOR_EXCEPTION( accuracy[0] != 1 || accuracy[1] != 4 || accuracy[2] != 2, std::logic_error, ">>> ERROR (Integration::Test01): hex cubature reports wrong accuracy."); } *outStream << "-> Prism testing\n\n"; { CubatureTensorType prismCub( CubatureTriType(4), CubatureLineType(3) ); INTREPID2_TEST_FOR_EXCEPTION( prismCub.getDimension() != 3, std::logic_error, ">>> ERROR (Integration::Test01): prism cubature must have 3 dimension."); ordinal_type accuracy[Parameters::MaxDimension]; prismCub.getAccuracy( accuracy ); INTREPID2_TEST_FOR_EXCEPTION( accuracy[0] != 4 || accuracy[1] != 3, std::logic_error, ">>> ERROR (Integration::Test01): prism cubature reports wrong accuracy."); } } catch (std::logic_error err) { *outStream << err.what() << "\n"; errorFlag = -1000; }; *outStream << "===============================================================================\n" << "| TEST 3: volume computations |\n" << "===============================================================================\n"; try { DynRankView ConstructWithLabel(cubPoints, Parameters::MaxIntegrationPoints, Parameters::MaxDimension); DynRankView ConstructWithLabel(cubWeights, Parameters::MaxIntegrationPoints); *outStream << "-> Line testing\n\n"; { for (ordinal_type deg=0;deg<=Parameters::MaxCubatureDegreeEdge;++deg) { CubatureLineType cub(deg); cub.getCubature(cubPoints, cubWeights); const auto npts = cub.getNumPoints(); const auto testVol = computeRefVolume(npts, cubWeights); const auto refVol = 2.0; if (std::abs(testVol - refVol) > tol) { *outStream << std::setw(30) << "Line volume --> " << std::setw(10) << std::scientific << testVol << std::setw(10) << "diff = " << std::setw(10) << std::scientific << std::abs(testVol - refVol) << "\n"; ++errorFlag; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; } } } *outStream << "-> Triangle testing\n\n"; { for (auto deg=0;deg<=Parameters::MaxCubatureDegreeTri;++deg) { CubatureTriType cub(deg); cub.getCubature(cubPoints, cubWeights); const auto npts = cub.getNumPoints(); const auto testVol = computeRefVolume(npts, cubWeights); const auto refVol = 0.5; if (std::abs(testVol - refVol) > tol) { *outStream << std::setw(30) << "Triangle volume --> " << std::setw(10) << std::scientific << testVol << std::setw(10) << "diff = " << std::setw(10) << std::scientific << std::abs(testVol - refVol) << "\n"; ++errorFlag; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; } } } *outStream << "-> Quad testing\n\n"; { for (ordinal_type y_deg=0;y_deg<=Parameters::MaxCubatureDegreeEdge;++y_deg) for (ordinal_type x_deg=0;x_deg<=Parameters::MaxCubatureDegreeEdge;++x_deg) { const auto x_line = CubatureLineType(x_deg); const auto y_line = CubatureLineType(y_deg); CubatureTensorType cub( x_line, y_line ); cub.getCubature(cubPoints, cubWeights); const auto npts = cub.getNumPoints(); const auto testVol = computeRefVolume(npts, cubWeights); const auto refVol = 4.0; if (std::abs(testVol - refVol) > tol) { *outStream << std::setw(30) << "Quadrilateral volume --> " << std::setw(10) << std::scientific << testVol << std::setw(10) << "diff = " << std::setw(10) << std::scientific << std::abs(testVol - refVol) << "\n"; ++errorFlag; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; } } } *outStream << "-> Tetrahedron testing\n\n"; { for (auto deg=0;deg<=Parameters::MaxCubatureDegreeTet;++deg) { CubatureTetType cub(deg); cub.getCubature(cubPoints, cubWeights); const auto npts = cub.getNumPoints(); const auto testVol = computeRefVolume(npts, cubWeights); const auto refVol = 1.0/6.0; if (std::abs(testVol - refVol) > tol) { *outStream << std::setw(30) << "Tetrahedron volume --> " << std::setw(10) << std::scientific << testVol << std::setw(10) << "diff = " << std::setw(10) << std::scientific << std::abs(testVol - refVol) << "\n"; ++errorFlag; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; } } } *outStream << "-> Hexahedron testing\n\n"; { // when hex is tested with max cubature degree edge, it exceeds max integration points 1001 for (ordinal_type z_deg=0;z_deg<Parameters::MaxCubatureDegreeEdge;++z_deg) for (ordinal_type y_deg=0;y_deg<Parameters::MaxCubatureDegreeEdge;++y_deg) for (ordinal_type x_deg=0;x_deg<Parameters::MaxCubatureDegreeEdge;++x_deg) { const auto x_line = CubatureLineType(x_deg); const auto y_line = CubatureLineType(y_deg); const auto z_line = CubatureLineType(z_deg); CubatureTensorType cub( x_line, y_line, z_line ); cub.getCubature(cubPoints, cubWeights); const auto npts = cub.getNumPoints(); const auto testVol = computeRefVolume(npts, cubWeights); const auto refVol = 8.0; if (std::abs(testVol - refVol) > tol) { *outStream << std::setw(30) << "Hexahedron volume --> " << std::setw(10) << std::scientific << testVol << std::setw(10) << "diff = " << std::setw(10) << std::scientific << std::abs(testVol - refVol) << "\n"; ++errorFlag; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; } } } *outStream << "-> Prism testing\n\n"; { for (auto z_deg=0;z_deg<Parameters::MaxCubatureDegreeEdge;++z_deg) for (auto xy_deg=0;xy_deg<Parameters::MaxCubatureDegreeTri;++xy_deg) { const auto xy_tri = CubatureTriType(xy_deg); const auto z_line = CubatureLineType(z_deg); CubatureTensorType cub( xy_tri, z_line ); cub.getCubature(cubPoints, cubWeights); const auto npts = cub.getNumPoints(); const auto testVol = computeRefVolume(npts, cubWeights); const auto refVol = 1.0; if (std::abs(testVol - refVol) > tol) { *outStream << std::setw(30) << "Wedge volume --> " << std::setw(10) << std::scientific << testVol << std::setw(10) << "diff = " << std::setw(10) << std::scientific << std::abs(testVol - refVol) << "\n"; ++errorFlag; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; } } } *outStream << "-> Pyramid testing: over-integration by 2 (due to duffy transformation) \n\n"; { for (auto deg=0;deg<=Parameters::MaxCubatureDegreePyr;++deg) { const auto xy_line = CubatureLineType(deg); const auto z_line = CubatureLineJacobiType(deg); CubatureTensorPyrType cub( xy_line, xy_line, z_line ); cub.getCubature(cubPoints, cubWeights); const auto npts = cub.getNumPoints(); const auto testVol = computeRefVolume(npts, cubWeights); const auto refVol = 4.0/3.0; if (std::abs(testVol - refVol) > tol) { *outStream << std::setw(30) << "Pyramid volume --> " << std::setw(10) << std::scientific << testVol << std::setw(10) << "diff = " << std::setw(10) << std::scientific << std::abs(testVol - refVol) << "\n"; ++errorFlag; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; } } } *outStream << "-> Hypercube testing\n\n"; // later.... refVol = 32 // for (int deg=0; deg<=20; deg++) { // Teuchos::RCP<CubatureLineType > lineCub = Teuchos::rcp(new CubatureLineType(deg)); // CubatureTensorType hypercubeCub(lineCub, 5); // int numCubPoints = hypercubeCub.getNumPoints(); // FieldContainer<DeviceSpaceType> cubPoints( numCubPoints, hypercubeCub.getDimension() ); // FieldContainer<DeviceSpaceType> cubWeights( numCubPoints ); // hypercubeCub.getCubature(cubPoints, cubWeights); // testVol = 0; // for (int i=0; i<numCubPoints; i++) // testVol += cubWeights(i); // *outStream << std::setw(30) << "5-D Hypercube volume --> " << std::setw(10) << std::scientific << testVol << // std::setw(10) << "diff = " << std::setw(10) << std::scientific << std::abs(testVol - volumeList[8]) << "\n"; // if (std::abs(testVol - volumeList[8])/std::abs(testVol) > tol) { // errorFlag = 1; // *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; // } // } } catch (std::logic_error err) { *outStream << err.what() << "\n"; errorFlag = -1; }; if (errorFlag != 0) std::cout << "End Result: TEST FAILED\n"; else std::cout << "End Result: TEST PASSED\n"; // reset format state of std::cout std::cout.copyfmt(oldFormatState); Kokkos::finalize(); return errorFlag; }