#include"config.h" #include "anisotropic.hh" #include #include #include #include #include #include #include #include template void randomize(const M& mat, V& b) { V x=b; srand((unsigned)std::clock()); typedef typename V::iterator iterator; for(iterator i=x.begin(); i != x.end(); ++i) *i=(rand() / (RAND_MAX + 1.0)); mat.mv(static_cast(x), b); } void testTwoLevelMethod() { const int BS=1; int N=100; typedef Dune::ParallelIndexSet ParallelIndexSet; ParallelIndexSet indices; typedef Dune::FieldMatrix MatrixBlock; typedef Dune::BCRSMatrix BCRSMat; typedef Dune::FieldVector VectorBlock; typedef Dune::BlockVector Vector; typedef Dune::MatrixAdapter Operator; typedef Dune::CollectiveCommunication Comm; Comm c; int n; BCRSMat mat = setupAnisotropic2d(N, indices, c, &n, 1); Vector b(mat.N()), x(mat.M()); x=0; randomize(mat, b); #ifndef USE_OVERLAPPINGSCHWARZ // Smoother used for the finest level typedef Dune::SeqSSOR FSmoother; FSmoother fineSmoother(mat,1,1.0); #else // Smoother used for the finest level. There is an additional // template parameter to provide the subdomain solver. typedef Dune::SeqOverlappingSchwarz FSmoother; // Type of the subdomain vector typedef FSmoother::subdomain_vector SubdomainVector; // Create subdomain. std::size_t stride=2; SubdomainVector subdomains((((N-1)/stride)+1)*(((N-1)/stride)+1)); for(int i=0; i CSmoother; typedef Dune::Amg::SmootherTraits::Arguments SmootherArgs; typedef Dune::Amg::CoarsenCriterion< Dune::Amg::UnSymmetricCriterion > Criterion; typedef Dune::Amg::AggregationLevelTransferPolicy TransferPolicy; typedef Dune::Amg::OneStepAMGCoarseSolverPolicy CoarsePolicy; // Policy for coarse solver creation Criterion crit; CoarsePolicy coarsePolicy=CoarsePolicy(SmootherArgs(), crit); TransferPolicy transferPolicy(crit); Operator fop(mat); Dune::Amg::TwoLevelMethod preconditioner(fop, Dune::stackobject_to_shared_ptr(fineSmoother), transferPolicy, coarsePolicy); Dune::GeneralizedPCGSolver amgCG(fop,preconditioner,.8,80,2); Dune::Amg::TwoLevelMethod preconditioner1(preconditioner); Dune::InverseOperatorResult res; amgCG.apply(x,b,res); } int main() { testTwoLevelMethod(); return 0; }