From 16065f32f39dbc400b8e39a38aaa940c7fe7c739 Mon Sep 17 00:00:00 2001 From: Elias Pipping <elias.pipping@fu-berlin.de> Date: Mon, 12 Mar 2012 15:07:03 +0100 Subject: [PATCH] Add and Externalise MySolver class (mostly) --- src/mysolver.cc | 65 +++++++++++++++++++++++++++++++++++++++ src/mysolver.hh | 44 +++++++++++++++++++++++++++ src/mysolver_tmpl.cc | 38 +++++++++++++++++++++++ src/one-body-sample.cc | 69 ++++++++---------------------------------- 4 files changed, 159 insertions(+), 57 deletions(-) create mode 100644 src/mysolver.cc create mode 100644 src/mysolver.hh create mode 100644 src/mysolver_tmpl.cc diff --git a/src/mysolver.cc b/src/mysolver.cc new file mode 100644 index 00000000..7606e56d --- /dev/null +++ b/src/mysolver.cc @@ -0,0 +1,65 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_IPOPT +#undef HAVE_IPOPT +#endif + +#include <dune/solvers/common/numproc.hh> // Solver::FULL + +#include "mysolver.hh" + +template <int dim, class VectorType, class OperatorType, class GridType, + class BlockProblemType> +MySolver<dim, VectorType, OperatorType, GridType, BlockProblemType>::MySolver( + Dune::ParameterTree parset, int refinements, double solver_tolerance, + GridType const &grid, Dune::BitSetVector<dim> const &ignoreNodes) + : baseEnergyNorm(linearBaseSolverStep), + linearBaseSolver(&linearBaseSolverStep, + parset.get<int>("linear.maxiterations"), + solver_tolerance, &baseEnergyNorm, Solver::QUIET), + transferOperators(refinements), + multigridStep(new SolverType(linearIterationStep, nonlinearSmoother)) { + // linear iteration step + linearIterationStep.setNumberOfLevels(refinements + 1); + linearIterationStep.setMGType(parset.get<int>("linear.mu"), + parset.get<int>("linear.nu1"), + parset.get<int>("linear.nu2")); + linearIterationStep.basesolver_ = &linearBaseSolver; + linearIterationStep.setSmoother(&linearPresmoother, &linearPostsmoother); + + // transfer operators + for (auto &x : transferOperators) + x = new CompressedMultigridTransfer<VectorType>; + TransferOperatorAssembler<GridType>(grid) + .assembleOperatorPointerHierarchy(transferOperators); + linearIterationStep.setTransferOperators(transferOperators); + + // tnnmg iteration step + multigridStep->setSmoothingSteps(parset.get<int>("main.nu1"), + parset.get<int>("main.mu"), + parset.get<int>("main.nu2")); + multigridStep->ignoreNodes_ = &ignoreNodes; +} + +template <int dim, class VectorType, class OperatorType, class GridType, + class BlockProblemType> +MySolver<dim, VectorType, OperatorType, GridType, + BlockProblemType>::~MySolver() { + for (auto &x : transferOperators) + delete x; + + delete multigridStep; +} + +template <int dim, class VectorType, class OperatorType, class GridType, + class BlockProblemType> +typename MySolver<dim, VectorType, OperatorType, GridType, + BlockProblemType>::SolverType * +MySolver<dim, VectorType, OperatorType, GridType, + BlockProblemType>::getSolver() { + return multigridStep; +} + +//#include "mysolver_tmpl.cc" diff --git a/src/mysolver.hh b/src/mysolver.hh new file mode 100644 index 00000000..d80b755b --- /dev/null +++ b/src/mysolver.hh @@ -0,0 +1,44 @@ +#ifndef MYSOLVER_HH +#define MYSOLVER_HH + +#include <dune/common/bitsetvector.hh> +#include <dune/common/parametertree.hh> + +#include <dune/solvers/iterationsteps/multigridstep.hh> +#include <dune/solvers/iterationsteps/truncatedblockgsstep.hh> +#include <dune/solvers/norms/energynorm.hh> +#include <dune/solvers/solvers/loopsolver.hh> +#include <dune/tnnmg/iterationsteps/genericnonlineargs.hh> +#include <dune/solvers/transferoperators/compressedmultigridtransfer.hh> +#include <dune/fufem/assemblers/transferoperatorassembler.hh> +#include <dune/tnnmg/iterationsteps/tnnmgstep.hh> + +template <int dim, class VectorType, class OperatorType, class GridType, + class BlockProblemType> +class MySolver { +private: + typedef GenericNonlinearGS<BlockProblemType> NonlinearSmootherType; + typedef TruncatedNonsmoothNewtonMultigrid<BlockProblemType, + NonlinearSmootherType> SolverType; + +public: + MySolver(Dune::ParameterTree parset, int refinements, double solver_tolerance, + GridType const &grid, Dune::BitSetVector<dim> const &ignoreNodes); + + ~MySolver(); + + SolverType *getSolver(); + +private: + TruncatedBlockGSStep<OperatorType, VectorType> linearBaseSolverStep; + EnergyNorm<OperatorType, VectorType> baseEnergyNorm; + LoopSolver<VectorType> linearBaseSolver; + TruncatedBlockGSStep<OperatorType, VectorType> linearPresmoother; + TruncatedBlockGSStep<OperatorType, VectorType> linearPostsmoother; + MultigridStep<OperatorType, VectorType> linearIterationStep; + std::vector<CompressedMultigridTransfer<VectorType> *> transferOperators; + NonlinearSmootherType nonlinearSmoother; + SolverType *multigridStep; +}; + +#endif diff --git a/src/mysolver_tmpl.cc b/src/mysolver_tmpl.cc new file mode 100644 index 00000000..188501d4 --- /dev/null +++ b/src/mysolver_tmpl.cc @@ -0,0 +1,38 @@ +#include <dune/common/fmatrix.hh> +#include <dune/common/fvector.hh> +#include <dune/grid/yaspgrid.hh> +#include <dune/istl/bcrsmatrix.hh> +#include <dune/istl/bvector.hh> + +#include <dune/tectonic/myblockproblem.hh> +#include <dune/tectonic/myconvexproblem.hh> + +// {{{ 2D +typedef Dune::FieldVector<double, 2> SmallVector2; +typedef Dune::FieldMatrix<double, 2, 2> SmallMatrix2; +typedef Dune::BlockVector<SmallVector2> VectorType2; +typedef Dune::BCRSMatrix<SmallMatrix2> OperatorType2; + +typedef MyConvexProblem<OperatorType2, VectorType2> MyConvexProblemType2; +typedef MyBlockProblem<MyConvexProblemType2> MyBlockProblemType2; + +typedef Dune::YaspGrid<2> GridType2; + +template class MySolver<2, VectorType2, OperatorType2, GridType2, + MyBlockProblemType2>; +// }}} + +// {{{ 3D +typedef Dune::FieldVector<double, 3> SmallVector3; +typedef Dune::FieldMatrix<double, 3, 3> SmallMatrix3; +typedef Dune::BlockVector<SmallVector3> VectorType3; +typedef Dune::BCRSMatrix<SmallMatrix3> OperatorType3; + +typedef MyConvexProblem<OperatorType3, VectorType3> MyConvexProblemType3; +typedef MyBlockProblem<MyConvexProblemType3> MyBlockProblemType3; + +typedef Dune::YaspGrid<3> GridType3; + +template class MySolver<3, VectorType3, OperatorType3, GridType3, + MyBlockProblemType3>; +// }}} diff --git a/src/one-body-sample.cc b/src/one-body-sample.cc index ca674939..952e247a 100644 --- a/src/one-body-sample.cc +++ b/src/one-body-sample.cc @@ -6,10 +6,6 @@ #error srcdir unset #endif -#ifdef HAVE_IPOPT -#undef HAVE_IPOPT -#endif - #ifndef HAVE_PYTHON #error Python is required #endif @@ -42,20 +38,14 @@ #include <dune/fufem/assemblers/localassemblers/stvenantkirchhoffassembler.hh> #include <dune/fufem/assemblers/localassemblers/vonmisesstressassembler.hh> #include <dune/fufem/assemblers/operatorassembler.hh> -#include <dune/fufem/assemblers/transferoperatorassembler.hh> #include <dune/fufem/dunepython.hh> #include <dune/fufem/functions/basisgridfunction.hh> #include <dune/fufem/functionspacebases/p0basis.hh> #include <dune/fufem/functionspacebases/p1nodalbasis.hh> #include <dune/fufem/sharedpointermap.hh> #include <dune/solvers/common/numproc.hh> // Solver::FULL -#include <dune/solvers/iterationsteps/multigridstep.hh> -#include <dune/solvers/iterationsteps/truncatedblockgsstep.hh> #include <dune/solvers/norms/energynorm.hh> #include <dune/solvers/solvers/loopsolver.hh> -#include <dune/solvers/transferoperators/compressedmultigridtransfer.hh> -#include <dune/tnnmg/iterationsteps/genericnonlineargs.hh> -#include <dune/tnnmg/iterationsteps/tnnmgstep.hh> #include <dune/tectonic/myblockproblem.hh> #include <dune/tectonic/myconvexproblem.hh> @@ -65,6 +55,8 @@ #include "print.hh" #include "vtk.hh" +#include "mysolver.cc" // TODO + int const dim = 2; template <class GridView> @@ -139,7 +131,6 @@ int main(int argc, char *argv[]) { auto const solver_tolerance = parset.get<double>("solver.tolerance"); auto const refinements = parset.get<size_t>("grid.refinements"); - size_t const levels = refinements + 1; auto const verbose = parset.get<bool>("verbose"); Solver::VerbosityMode const verbosity = @@ -218,45 +209,11 @@ int main(int argc, char *argv[]) { auto const nodalIntegrals = assemble_frictional<GridType, GridView, SmallVector, P1Basis>( leafView, p1Basis, frictionalNodes); + // {{{ Set up TNNMG solver - // linear iteration step components - TruncatedBlockGSStep<OperatorType, VectorType> linearBaseSolverStep; - EnergyNorm<OperatorType, VectorType> baseEnergyNorm(linearBaseSolverStep); - LoopSolver<VectorType> linearBaseSolver( - &linearBaseSolverStep, - parset.get<int>("solver.tnnmg.linear.maxiterations"), solver_tolerance, - &baseEnergyNorm, Solver::QUIET); - TruncatedBlockGSStep<OperatorType, VectorType> linearPresmoother; - TruncatedBlockGSStep<OperatorType, VectorType> linearPostsmoother; - - // linear iteration step - MultigridStep<OperatorType, VectorType> linearIterationStep; - linearIterationStep.setNumberOfLevels(levels); - linearIterationStep.setMGType(parset.get<int>("solver.tnnmg.linear.mu"), - parset.get<int>("solver.tnnmg.linear.nu1"), - parset.get<int>("solver.tnnmg.linear.nu2")); - linearIterationStep.basesolver_ = &linearBaseSolver; - linearIterationStep.setSmoother(&linearPresmoother, &linearPostsmoother); - - // transfer operators - std::vector<CompressedMultigridTransfer<VectorType> *> transferOperators( - refinements); - for (auto &x : transferOperators) - x = new CompressedMultigridTransfer<VectorType>; - TransferOperatorAssembler<GridType>(*grid) - .assembleOperatorPointerHierarchy(transferOperators); - linearIterationStep.setTransferOperators(transferOperators); - - // tnnmg iteration step - typedef GenericNonlinearGS<MyBlockProblemType> NonlinearSmootherType; - NonlinearSmootherType nonlinearSmoother; - TruncatedNonsmoothNewtonMultigrid<MyBlockProblemType, NonlinearSmootherType> - multigridStep(linearIterationStep, nonlinearSmoother); - multigridStep.setSmoothingSteps(parset.get<int>("solver.tnnmg.main.nu1"), - parset.get<int>("solver.tnnmg.main.mu"), - parset.get<int>("solver.tnnmg.main.nu2")); - multigridStep.ignoreNodes_ = &ignoreNodes; - // }}} + MySolver<dim, VectorType, OperatorType, GridType, MyBlockProblemType> + mySolver(parset.sub("solver.tnnmg"), refinements, solver_tolerance, *grid, + ignoreNodes); std::fstream octave_writer("data", std::fstream::out); timer.reset(); @@ -286,10 +243,11 @@ int main(int argc, char *argv[]) { *myGlobalNonlinearity, b4); MyBlockProblemType myBlockProblem(parset, myConvexProblem); - multigridStep.setProblem(u4_diff, myBlockProblem); + auto multigridStep = mySolver.getSolver(); + multigridStep->setProblem(u4_diff, myBlockProblem); LoopSolver<VectorType> overallSolver( - &multigridStep, parset.get<size_t>("solver.tnnmg.maxiterations"), + multigridStep, parset.get<size_t>("solver.tnnmg.maxiterations"), solver_tolerance, &energyNorm, verbosity); overallSolver.solve(); @@ -330,10 +288,11 @@ int main(int argc, char *argv[]) { *myGlobalNonlinearity, b5); MyBlockProblemType myBlockProblem(parset, myConvexProblem); - multigridStep.setProblem(u5_diff, myBlockProblem); + auto multigridStep = mySolver.getSolver(); + multigridStep->setProblem(u5_diff, myBlockProblem); LoopSolver<VectorType> overallSolver( - &multigridStep, parset.get<size_t>("solver.tnnmg.maxiterations"), + multigridStep, parset.get<size_t>("solver.tnnmg.maxiterations"), solver_tolerance, &energyNorm, verbosity); overallSolver.solve(); @@ -376,10 +335,6 @@ int main(int argc, char *argv[]) { std::cout << "Making " << timesteps << " time steps took " << timer.elapsed() << "s" << std::endl; - // Clean up after the TNNMG solver - for (auto &x : transferOperators) - delete x; - octave_writer.close(); if (parset.get<bool>("printFrictionalBoundary")) { -- GitLab