diff --git a/dune/istl/test/.gitignore b/dune/istl/test/.gitignore index 490ba7b93b90bb6e20f94b9f7d8a8f96a0c536db..e671429ad954d69d2c5d4c8b7d2df30df7819470 100644 --- a/dune/istl/test/.gitignore +++ b/dune/istl/test/.gitignore @@ -37,3 +37,4 @@ umfpacktest testmat_0.idx testmat_0.mm testvec_0.mm +bcrsimplicitbuildtest diff --git a/dune/istl/test/CMakeLists.txt b/dune/istl/test/CMakeLists.txt index 9c9ad552e9f769cff6fe0632b90958c99ea32f2a..900c90ac0ea818f6982495774d27845d993facc1 100644 --- a/dune/istl/test/CMakeLists.txt +++ b/dune/istl/test/CMakeLists.txt @@ -2,6 +2,7 @@ set(NORMALTEST basearraytest bvectortest bcrsbuildtest + bcrsimplicitbuildtest dotproducttest iotest inverseoperator2prectest @@ -55,6 +56,8 @@ add_executable(matrixtest "matrixtest.cc") add_executable(bvectortest "bvectortest.cc") add_executable(vbvectortest "vbvectortest.cc") add_executable(bcrsbuildtest "bcrsbuild.cc") +add_executable(bcrsimplicitbuildtest "bcrsbuild.cc") +set_property(TARGET bcrsimplicitbuildtest APPEND PROPERTY COMPILE_DEFINITIONS "DUNE_ISTL_WITH_CHECKING=1") add_executable(matrixiteratortest "matrixiteratortest.cc") add_executable(mmtest mmtest.cc) add_executable(mv "mv.cc") diff --git a/dune/istl/test/Makefile.am b/dune/istl/test/Makefile.am index bd531d34644ba5ca62e7a0ad38a0d1715e69be43..0994ef977e65b6b4e0211fc8549b9efc0bf069c5 100644 --- a/dune/istl/test/Makefile.am +++ b/dune/istl/test/Makefile.am @@ -23,6 +23,7 @@ endif # which tests where program to build and run are equal NORMALTESTS = basearraytest \ bcrsbuildtest \ + bcrsimplicitbuildtest \ bvectortest \ complexrhstest \ dotproducttest \ @@ -99,6 +100,9 @@ basearraytest_SOURCES = basearraytest.cc bcrsbuildtest_SOURCES = bcrsbuild.cc +bcrsimplicitbuildtest_SOURCES = bcrsimplicitbuild.cc +bcrsimplicitbuildtest_CPPFLAGS = $(AM_CPPFLAGS) -DDUNE_ISTL_WITH_CHECKING=1 + bvectortest_SOURCES = bvectortest.cc complexrhstest_SOURCES = complexrhstest.cc laplacian.hh diff --git a/dune/istl/test/bcrsimplicitbuild.cc b/dune/istl/test/bcrsimplicitbuild.cc new file mode 100644 index 0000000000000000000000000000000000000000..6f20f4633211619090a8f0825f03953397f026aa --- /dev/null +++ b/dune/istl/test/bcrsimplicitbuild.cc @@ -0,0 +1,321 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: + +#include "config.h" + +#undef NDEBUG // make sure assert works + +#include <dune/common/float_cmp.hh> +#include <dune/common/fmatrix.hh> +#include <dune/common/exceptions.hh> +#include <dune/istl/bcrsmatrix.hh> + +typedef Dune::BCRSMatrix<Dune::FieldMatrix<double,1,1> > ScalarMatrix; + +void buildMatrix(ScalarMatrix& m) +{ + m.entry(0,0) = 1.0; m.entry(0,1) = 1.0; m.entry(0,2) = 1.0; m.entry(0,3) = 1.0; + m.entry(1,0) = 1.0; m.entry(1,1) = 1.0; m.entry(1,2) = 1.0; + m.entry(2,1) = 1.0; m.entry(2,2) = 1.0; m.entry(2,3) = 1.0; + m.entry(3,2) = 1.0; m.entry(3,3) = 1.0; m.entry(3,4) = 1.0; + m.entry(4,3) = 1.0; m.entry(4,4) = 1.0; m.entry(4,5) = 1.0; + m.entry(5,4) = 1.0; m.entry(5,5) = 1.0; m.entry(5,6) = 1.0; + m.entry(6,5) = 1.0; m.entry(6,6) = 1.0; m.entry(6,7) = 1.0; + m.entry(7,6) = 1.0; m.entry(7,7) = 1.0; m.entry(7,8) = 1.0; + m.entry(8,7) = 1.0; m.entry(8,8) = 1.0; m.entry(8,9) = 1.0; + m.entry(9,8) = 1.0; m.entry(9,9) = 1.0; + // add some more entries in random order + m.entry(7,3) = 1.0; + m.entry(6,0) = 1.0; + m.entry(3,8) = 1.0; +} + +template<typename M> +void setMatrix(M& m) +{ + m[0][0] = 1.0; m[0][1] = 1.0; m[0][2] = 1.0; m[0][3] = 1.0; + m[1][0] = 1.0; m[1][1] = 1.0; m[1][2] = 1.0; + m[2][1] = 1.0; m[2][2] = 1.0; m[2][3] = 1.0; + m[3][2] = 1.0; m[3][3] = 1.0; m[3][4] = 1.0; + m[4][3] = 1.0; m[4][4] = 1.0; m[4][5] = 1.0; + m[5][4] = 1.0; m[5][5] = 1.0; m[5][6] = 1.0; + m[6][5] = 1.0; m[6][6] = 1.0; m[6][7] = 1.0; + m[7][6] = 1.0; m[7][7] = 1.0; m[7][8] = 1.0; + m[8][7] = 1.0; m[8][8] = 1.0; m[8][9] = 1.0; + m[9][8] = 1.0; m[9][9] = 1.0; + // add some more entries in random order + m[7][3] = 1.0; + m[6][0] = 1.0; + m[3][8] = 1.0; +} + +void testImplicitBuild() +{ + ScalarMatrix m(10,10,3,0.1,ScalarMatrix::implicit); + buildMatrix(m); + ScalarMatrix::CompressionStatistics stats = m.compress(); + assert(Dune::FloatCmp::eq(stats.avg,33./10.)); + assert(stats.maximum == 4); + assert(stats.overflow_total == 4); + setMatrix(m); +} + +void testImplicitBuildWithInsufficientOverflow() +{ + try { + ScalarMatrix m(10,10,1,0,ScalarMatrix::implicit); + // add diagonal entries + completely fill the first row with entries + // with the current base buffer of 4 * avg, that should be enough to make + // compress fail. + for (int i = 0; i < 10; ++i) + { + m.entry(i,i) = 1.0; + m.entry(0,i) = 1.0; + } + m.compress(); + assert(false && "compress() should have thrown an exception"); + } catch (Dune::ImplicitModeOverflowExhausted& e) { + // test passed + } +} + +void testSetterInterface() +{ + ScalarMatrix m; + m.setBuildMode(ScalarMatrix::implicit); + m.setImplicitBuildModeParameters(3,0.1); + m.setSize(10,10); + buildMatrix(m); + ScalarMatrix::CompressionStatistics stats = m.compress(); + assert(Dune::FloatCmp::eq(stats.avg,33.0/10.0)); + assert(stats.maximum == 4); + assert(stats.overflow_total == 4); +} + +void testDoubleSetSize() +{ + ScalarMatrix m; + m.setBuildMode(ScalarMatrix::implicit); + m.setImplicitBuildModeParameters(3,0.1); + m.setSize(14,14); + m.setSize(10,10); + buildMatrix(m); + ScalarMatrix::CompressionStatistics stats = m.compress(); + assert(Dune::FloatCmp::eq(stats.avg,33.0/10.0)); + assert(stats.maximum == 4); + assert(stats.overflow_total == 4); +} + +void testInvalidBuildModeConstructorCall() +{ + try { + ScalarMatrix m(10,10,1,-1.0,ScalarMatrix::random); + assert(false && "Constructor should have thrown an exception!"); + } catch (Dune::BCRSMatrixError& e) { + // test passed + } +} + +void testNegativeOverflowConstructorCall() +{ + try { + ScalarMatrix m(10,10,1,-1.0,ScalarMatrix::implicit); + assert(false && "Constructor should have thrown an exception!"); + } catch (Dune::BCRSMatrixError& e) { + // test passed + } +} + +void testInvalidSetImplicitBuildModeParameters() +{ + try { + ScalarMatrix m; + m.setBuildMode(ScalarMatrix::implicit); + m.setImplicitBuildModeParameters(1,-1.0); + assert(false && "setImplicitBuildModeParameters() should have thrown an exception!"); + } catch (Dune::BCRSMatrixError& e) { + // test passed + } +} + +void testSetImplicitBuildModeParametersAfterSetSize() +{ + try { + ScalarMatrix m; + m.setBuildMode(ScalarMatrix::implicit); + m.setImplicitBuildModeParameters(3,0.1); + m.setSize(10,10); + m.setImplicitBuildModeParameters(4,0.1); + assert(false && "setImplicitBuildModeParameters() should have thrown an exception!"); + } catch (Dune::InvalidStateException& e) { + // test passed + } +} + +void testSetSizeWithNonzeroes() +{ + try { + ScalarMatrix m; + m.setBuildMode(ScalarMatrix::implicit); + m.setImplicitBuildModeParameters(3,0.1); + m.setSize(10,10,300); + assert(false && "setSize() should have thrown an exception!"); + } catch (Dune::BCRSMatrixError& e) { + // test passed + } +} + +void testCopyConstructionAndAssignment() +{ + ScalarMatrix m(10,10,3,0.1,ScalarMatrix::implicit); + buildMatrix(m); + m.compress(); + ScalarMatrix m2(m); + m2 = 3.0; + ScalarMatrix m3(m); + m3 = m2; + ScalarMatrix m4; + m4 = m; +} + +void testInvalidCopyConstruction() +{ + try { + ScalarMatrix m(10,10,3,0.1,ScalarMatrix::implicit); + buildMatrix(m); + ScalarMatrix m2(m); + assert(false && "copy constructor should have thrown an exception!"); + } catch (Dune::InvalidStateException& e) { + // test passed + } +} + +void testInvalidCopyAssignment() +{ + ScalarMatrix m(10,10,3,0.1,ScalarMatrix::implicit); + buildMatrix(m); + // copy incomplete matrix into empty one + try { + ScalarMatrix m2; + assert(false && "operator=() should have thrown an exception!"); + } catch (Dune::InvalidStateException& e) { + // test passed + } + // copy incomplete matrix into full one + try { + ScalarMatrix m2(10,10,3,0.1,ScalarMatrix::implicit); + buildMatrix(m2); + m2.compress(); + m2 = m; + assert(false && "operator=() should have thrown an exception!"); + } catch (Dune::InvalidStateException& e) { + // test passed + } + // copy fully build matrix into half-built one + m.compress(); + try { + ScalarMatrix m2(10,10,3,0.1,ScalarMatrix::implicit); + buildMatrix(m2); + m2 = m; + assert(false && "operator=() should have thrown an exception!"); + } catch (Dune::InvalidStateException& e) { + // test passed + } +} + +void testEntryConsistency() +{ + ScalarMatrix m(10,10,3,0.1,ScalarMatrix::implicit); + assert(Dune::FloatCmp::eq(static_cast<const double&>(m.entry(0,3)),0.0)); + assert(Dune::FloatCmp::eq(static_cast<const double&>(m.entry(7,6)),0.0)); + buildMatrix(m); + assert(Dune::FloatCmp::eq(static_cast<const double&>(m.entry(0,3)),1.0)); + assert(Dune::FloatCmp::eq(static_cast<const double&>(m.entry(7,6)),1.0)); + m.entry(4,4) += 3.0; + assert(Dune::FloatCmp::eq(static_cast<const double&>(m.entry(4,4)),4.0)); + m.compress(); + assert(Dune::FloatCmp::eq(static_cast<const double&>(m[0][3]),1.0)); + assert(Dune::FloatCmp::eq(static_cast<const double&>(m[7][6]),1.0)); + assert(Dune::FloatCmp::eq(static_cast<const double&>(m[4][4]),4.0)); +} + +void testEntryAfterCompress() +{ + try { + ScalarMatrix m(10,10,3,0.1,ScalarMatrix::implicit); + buildMatrix(m); + m.compress(); + m.entry(3,3); + assert(false && "entry() should have thrown an exception!"); + } catch (Dune::BCRSMatrixError& e) { + // test passed + } +} + +void testBracketOperatorBeforeCompress() +{ + try { + ScalarMatrix m(10,10,3,0.1,ScalarMatrix::implicit); + buildMatrix(m); + m[3][3]; + assert(false && "operator[]() should have thrown an exception!"); + } catch (Dune::BCRSMatrixError& e) { + // test passed + } +} + +void testConstBracketOperatorBeforeCompress() +{ + try { + ScalarMatrix m(10,10,3,0.1,ScalarMatrix::implicit); + buildMatrix(m); + const_cast<const ScalarMatrix&>(m)[3][3]; + assert(false && "operator[]() should have thrown an exception!"); + } catch (Dune::BCRSMatrixError& e) { + // test passed + } +} + +void testImplicitMatrixBuilder() +{ + ScalarMatrix m(10,10,3,0.1,ScalarMatrix::implicit); + Dune::ImplicitMatrixBuilder<ScalarMatrix> b(m); + setMatrix(b); + m.compress(); + setMatrix(m); +} + +void testImplicitMatrixBuilderExtendedConstructor() +{ + ScalarMatrix m; + Dune::ImplicitMatrixBuilder<ScalarMatrix> b(m,10,10,3,0.1); + setMatrix(b); + m.compress(); + setMatrix(m); +} + +int main() +{ + try{ + testImplicitBuild(); + testImplicitBuildWithInsufficientOverflow(); + testSetterInterface(); + testDoubleSetSize(); + testInvalidBuildModeConstructorCall(); + testNegativeOverflowConstructorCall(); + testInvalidSetImplicitBuildModeParameters(); + testSetImplicitBuildModeParametersAfterSetSize(); + testSetSizeWithNonzeroes(); + testCopyConstructionAndAssignment(); + testInvalidCopyConstruction(); + testEntryConsistency(); + testEntryAfterCompress(); + testBracketOperatorBeforeCompress(); + testConstBracketOperatorBeforeCompress(); + testImplicitMatrixBuilder(); + testImplicitMatrixBuilderExtendedConstructor(); + }catch(Dune::Exception& e) { + std::cerr << e <<std::endl; + return 1; + } +}