Skip to content
Snippets Groups Projects
riemanniantrsolver.hh 6.13 KiB
Newer Older
  • Learn to ignore specific revisions
  • #ifndef RIEMANNIAN_TRUST_REGION_SOLVER_HH
    #define RIEMANNIAN_TRUST_REGION_SOLVER_HH
    
    #include <vector>
    
    
    #include <dune/common/bitsetvector.hh>
    
    
    #include <dune/istl/bcrsmatrix.hh>
    #include <dune/istl/bvector.hh>
    
    
    #include <dune/solvers/common/boxconstraint.hh>
    
    #include <dune/solvers/norms/h1seminorm.hh>
    
    Oliver Sander's avatar
    Oliver Sander committed
    #include <dune/solvers/solvers/iterativesolver.hh>
    
    #include <dune/solvers/solvers/loopsolver.hh>
    
    Sander, Oliver's avatar
    Sander, Oliver committed
    #include <dune/gfe/periodic1dpq1nodalbasis.hh>
    
    
    #include <dune/grid/utility/globalindexset.hh>
    
    #include <dune/gfe/parallel/globalp1mapper.hh>
    
    #include <dune/gfe/parallel/globalp2mapper.hh>
    
    #include <dune/gfe/parallel/p2mapper.hh>
    
    /** \brief Assign GlobalMapper and LocalMapper types to a dune-fufem FunctionSpaceBasis */
    
    template <typename GridView, typename Basis>
    
    struct MapperFactory
    {};
    
    
    /** \brief Specialization for PQ1NodalBasis */
    template <typename GridView>
    
    struct MapperFactory<GridView, Dune::Functions::PQkNodalBasis<GridView,1> >
    
    {
        typedef Dune::GlobalP1Mapper<GridView> GlobalMapper;
        typedef Dune::MultipleCodimMultipleGeomTypeMapper<GridView, Dune::MCMGVertexLayout> LocalMapper;
    };
    
    
    Sander, Oliver's avatar
    Sander, Oliver committed
    // This case is not going to actually work, but I need the specialization to make
    // the sequential code compile.
    template <typename GridView>
    struct MapperFactory<GridView, Dune::Functions::Periodic1DPQ1NodalBasis<GridView> >
    {
        typedef Dune::GlobalP1Mapper<GridView> GlobalMapper;
        typedef Dune::MultipleCodimMultipleGeomTypeMapper<GridView, Dune::MCMGVertexLayout> LocalMapper;
    };
    
    
    struct MapperFactory<GridView, Dune::Functions::PQkNodalBasis<GridView,2> >
    
    {
        typedef Dune::GlobalP2Mapper<GridView> GlobalMapper;
        typedef P2BasisMapper<GridView> LocalMapper;
    };
    
    
    /** \brief Specialization for PQ3NodalBasis */
    template <typename GridView>
    
    struct MapperFactory<GridView, Dune::Functions::PQkNodalBasis<GridView,3> >
    
    {
        // Error: we don't currently have a global P3 mapper
    };
    
    
    /** \brief Riemannian trust-region solver for geodesic finite-element problems */
    
    template <class Basis, class TargetSpace>
    
    class RiemannianTrustRegionSolver
    
        : public IterativeSolver<std::vector<TargetSpace>,
    
                                 Dune::BitSetVector<TargetSpace::TangentVector::dimension> >
    
        typedef typename Basis::GridView::Grid GridType;
    
    
        const static int blocksize = TargetSpace::TangentVector::dimension;
    
    
        const static int gridDim = GridType::dimension;
    
        // Centralize the field type here
        typedef double field_type;
    
    
        // Some types that I need
    
        typedef Dune::BCRSMatrix<Dune::FieldMatrix<field_type, blocksize, blocksize> > MatrixType;
        typedef Dune::BlockVector<Dune::FieldVector<field_type, blocksize> >           CorrectionType;
    
        typedef std::vector<TargetSpace>                                               SolutionType;
    
        typedef typename MapperFactory<typename Basis::GridView,Basis>::GlobalMapper GlobalMapper;
        typedef typename MapperFactory<typename Basis::GridView,Basis>::LocalMapper LocalMapper;
    
            : IterativeSolver<std::vector<TargetSpace>, Dune::BitSetVector<blocksize> >(0,100,NumProc::FULL),
    
              hessianMatrix_(nullptr), h1SemiNorm_(NULL)
    
        {
          std::fill(scaling_.begin(), scaling_.end(), 1.0);
        }
    
        /** \brief Set up the solver using a monotone multigrid method as the inner solver */
    
        void setup(const GridType& grid,
    
                   const GeodesicFEAssembler<Basis, TargetSpace>* assembler,
    
                   const SolutionType& x,
    
                   const Dune::BitSetVector<blocksize>& dirichletNodes,
    
                   double tolerance,
    
                   int maxTrustRegionSteps,
                   double initialTrustRegionRadius,
                   int multigridIterations,
                   double mgTolerance,
    
                   int mu,
    
                   int nu1,
                   int nu2,
                   int baseIterations,
    
                   double baseTolerance,
                   bool instrumented);
    
        void setScaling(const Dune::FieldVector<double,blocksize>& scaling)
        {
    
          scaling_ = scaling;
    
        void setIgnoreNodes(const Dune::BitSetVector<blocksize>& ignoreNodes)
        {
            ignoreNodes_ = &ignoreNodes;
            Dune::shared_ptr<LoopSolver<CorrectionType> > loopSolver = std::dynamic_pointer_cast<LoopSolver<CorrectionType> >(innerSolver_);
            assert(loopSolver);
            loopSolver->iterationStep_->ignoreNodes_ = ignoreNodes_;
        }
    
        void setInitialSolution(const SolutionType& x) DUNE_DEPRECATED {
            x_ = x;
        }
    
        void setInitialIterate(const SolutionType& x) {
    
            x_ = x;
        }
    
        SolutionType getSol() const {return x_;}
    
    protected:
    
    
        std::unique_ptr<GlobalMapper> globalMapper_;
    
        /** \brief The grid */
        const GridType* grid_;
    
        /** \brief The solution vector */
        SolutionType x_;
    
        /** \brief The initial trust-region radius in the maximum-norm */
        double initialTrustRegionRadius_;
    
    
        /** \brief Trust-region norm scaling */
        Dune::FieldVector<double,blocksize> scaling_;
    
    
        /** \brief Maximum number of trust-region steps */
        int maxTrustRegionSteps_;
    
        /** \brief Maximum number of multigrid iterations */
    
    
        /** \brief Error tolerance of the multigrid QP solver */
    
    
        /** \brief Hessian matrix */
    
        std::unique_ptr<MatrixType> hessianMatrix_;
    
    
        /** \brief The assembler for the material law */
    
        const GeodesicFEAssembler<Basis, TargetSpace>* assembler_;
    
        /** \brief The solver for the quadratic inner problems */
    
        std::shared_ptr<Solver> innerSolver_;
    
        /** \brief Contains 'true' everywhere -- the trust-region is bounded */
    
        Dune::BitSetVector<blocksize> hasObstacle_;
    
        /** \brief The Dirichlet nodes */
        const Dune::BitSetVector<blocksize>* ignoreNodes_;
    
    
        /** \brief The norm used to measure multigrid convergence */
        H1SemiNorm<CorrectionType>* h1SemiNorm_;
    
        /** \brief An L2-norm, really.  The H1SemiNorm class is badly named */
        std::shared_ptr<H1SemiNorm<CorrectionType> > l2Norm_;
    
    
        /** \brief If set to true we log convergence speed and other stuff */
        bool instrumented_;