LCOV - code coverage report
Current view: top level - ugbase/lib_algebra/operator/preconditioner - gauss_seidel.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 50 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 54 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Martin Rupp
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__GAUSS_SEIDEL__
      34              : #define __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__GAUSS_SEIDEL__
      35              : 
      36              : #include "lib_algebra/operator/interface/preconditioner.h"
      37              : #include "lib_algebra/algebra_common/core_smoothers.h"
      38              : #include "lib_algebra/algebra_common/sparsematrix_util.h"
      39              : #ifdef UG_PARALLEL
      40              :         #include "lib_algebra/parallelization/parallelization.h"
      41              :         #include "lib_algebra/parallelization/matrix_overlap.h"
      42              :         #include "lib_algebra/parallelization/parallel_matrix_overlap_impl.h"
      43              : #endif
      44              : 
      45              : #include "lib_algebra/ordering_strategies/algorithms/IOrderingAlgorithm.h"
      46              : #include "lib_algebra/algebra_common/permutation_util.h"
      47              : 
      48              : namespace ug{
      49              : 
      50              : template<typename TAlgebra>
      51              : class GaussSeidelBase : public IPreconditioner<TAlgebra>
      52              : {
      53              :         public:
      54              :         //      Algebra type
      55              :                 typedef TAlgebra algebra_type;
      56              : 
      57              :         //      Vector type
      58              :                 typedef typename TAlgebra::vector_type vector_type;
      59              : 
      60              :         //      Matrix type
      61              :                 typedef typename TAlgebra::matrix_type matrix_type;
      62              : 
      63              :         ///     Matrix Operator type
      64              :                 typedef typename IPreconditioner<TAlgebra>::matrix_operator_type matrix_operator_type;
      65              : 
      66              :         ///     Base type
      67              :                 typedef IPreconditioner<TAlgebra> base_type;
      68              : 
      69              :         ///     Ordering type
      70              :                 typedef std::vector<size_t> ordering_container_type;
      71              :                 typedef IOrderingAlgorithm<TAlgebra, ordering_container_type> ordering_algo_type;
      72              : 
      73              :         protected:
      74              :                 using base_type::set_debug;
      75              :                 using base_type::debug_writer;
      76              :                 using base_type::write_debug;
      77              : 
      78              :         public:
      79              :         //      Constructor
      80            0 :                 GaussSeidelBase() :
      81            0 :                         m_relax(1.0),
      82            0 :                         m_bConsistentInterfaces(false),
      83            0 :                         m_useOverlap(false) {};
      84              : 
      85              :         /// clone constructor
      86            0 :                 GaussSeidelBase( const GaussSeidelBase<TAlgebra> &parent )
      87              :                         : base_type(parent),
      88            0 :                           m_bConsistentInterfaces(parent.m_bConsistentInterfaces),
      89            0 :                           m_useOverlap(parent.m_useOverlap),
      90            0 :                           m_spOrderingAlgo(parent.m_spOrderingAlgo)
      91              :                 {
      92            0 :                         set_sor_relax(parent.m_relax);
      93            0 :                 }
      94              : 
      95              :         ///     set relaxation parameter to define a SOR-method
      96            0 :                 void set_sor_relax(number relaxFactor){ m_relax = relaxFactor;}
      97              : 
      98              :         ///     activates the new parallelization approach (disabled by default)
      99            0 :                 void enable_consistent_interfaces(bool enable) {m_bConsistentInterfaces = enable;}
     100              : 
     101            0 :                 void enable_overlap (bool enable) {m_useOverlap = enable;}
     102              : 
     103              :         ///     sets an ordering algorithm
     104              :                 void set_ordering_algorithm(SmartPtr<ordering_algo_type> ordering_algo){
     105              :                         m_spOrderingAlgo = ordering_algo;
     106              :                 }
     107              : 
     108              :                 virtual const char* name() const = 0;
     109              :         protected:
     110              : 
     111            0 :                 virtual bool supports_parallel() const {return true;}
     112              : 
     113              :         //      Preprocess routine
     114            0 :                 virtual bool preprocess(SmartPtr<MatrixOperator<matrix_type, vector_type> > pOp)
     115              :                 {
     116              :                         PROFILE_BEGIN_GROUP(GaussSeidel_preprocess, "algebra gaussseidel");
     117              :                         matrix_type *pA;
     118              : #ifdef UG_PARALLEL
     119              :                         if(pcl::NumProcs() > 1)
     120              :                         {
     121              :                                 if(m_useOverlap){
     122              :                                         m_A = *pOp;
     123              :                                         CreateOverlap(m_A);
     124              :                                         m_oD.set_layouts(m_A.layouts());
     125              :                                         m_oC.set_layouts(m_A.layouts());
     126              :                                         m_oD.resize(m_A.num_rows(), false);
     127              :                                         m_oC.resize(m_A.num_rows(), false);
     128              :                                 }
     129              :                                 else if (m_bConsistentInterfaces)
     130              :                                 {
     131              :                                         m_A = *pOp;
     132              :                                         MatMakeConsistentOverlap0(m_A);
     133              :                                 }
     134              :                                 else
     135              :                                 {
     136              :                                         //      copy original matrix
     137              :                                         MakeConsistent(*pOp, m_A);
     138              :                                         //      set zero on slaves
     139              :                                         std::vector<IndexLayout::Element> vIndex;
     140              :                                         CollectUniqueElements(vIndex,  m_A.layouts()->slave());
     141              :                                         SetDirichletRow(m_A, vIndex);
     142              :                                 }
     143              :                                 pA = &m_A;
     144              :                         }
     145              :                         else
     146              :                                 pA = &(*pOp);
     147              : #else
     148              :                         pA = &(*pOp);
     149              : #endif
     150            0 :                         THROW_IF_NOT_EQUAL(pA->num_rows(), pA->num_cols());
     151              : //                      UG_ASSERT(CheckDiagonalInvertible(A), "GS: A has noninvertible diagonal");
     152              :                         UG_COND_THROW(CheckDiagonalInvertible(*pA) == false, name() << ": A has noninvertible diagonal");
     153              : 
     154            0 :                         return true;
     155              :                 }
     156              : 
     157              :         //      Postprocess routine
     158            0 :                 virtual bool postprocess() {return true;}
     159              : 
     160              :                 virtual void step(const matrix_type &A, vector_type &c, const vector_type &d, const number relax) = 0;
     161              : 
     162              :         //      Stepping routine
     163            0 :                 virtual bool step(SmartPtr<MatrixOperator<matrix_type, vector_type> > pOp, vector_type& c, const vector_type& d)
     164              :                 {
     165              :                         PROFILE_BEGIN_GROUP(GaussSeidel_step, "algebra gaussseidel");
     166              : 
     167              : #ifdef UG_PARALLEL
     168              :                         if(pcl::NumProcs() > 1)
     169              :                         {
     170              :                                 if(m_useOverlap){
     171              :                                         for(size_t i = 0; i < d.size(); ++i)
     172              :                                                 m_oD[i] = d[i];
     173              :                                         for(size_t i = d.size(); i < m_oD.size(); ++i)
     174              :                                                 m_oD[i] = 0;
     175              :                                         m_oD.set_storage_type(PST_ADDITIVE);
     176              :                                         m_oD.change_storage_type(PST_CONSISTENT);
     177              : 
     178              :                                         step(m_A, m_oC, m_oD, m_relax);
     179              : 
     180              :                                         for(size_t i = 0; i < c.size(); ++i)
     181              :                                                 c[i] = m_oC[i];
     182              :                                         SetLayoutValues(&c, c.layouts()->slave(), 0);
     183              :                                         c.set_storage_type(PST_UNIQUE);
     184              :                                 }
     185              :                                 else if (m_bConsistentInterfaces)
     186              :                                 {
     187              :                                         // make defect consistent
     188              :                                         SmartPtr<vector_type> spDtmp = d.clone();
     189              :                                         spDtmp->change_storage_type(PST_CONSISTENT);
     190              : 
     191              :                                         THROW_IF_NOT_EQUAL_3(c.size(), spDtmp->size(), m_A.num_rows());
     192              :                                         step(m_A, c, *spDtmp, m_relax);
     193              : 
     194              :                                         // declare c unique to enforce that only master correction is used
     195              :                                         // when it is made consistent below
     196              :                                         c.set_storage_type(PST_UNIQUE);
     197              : 
     198              :                                         //UG_COND_THROW(!d.has_storage_type(PST_ADDITIVE), "Additive or unique defect expected.");
     199              :                                         //step(m_A, c, d, m_relax);
     200              :                                         //c.set_storage_type(PST_ADDITIVE);
     201              :                                 }
     202              :                                 else
     203              :                                 {
     204              :                                         // todo: do not clone every time
     205              :                                 //      make defect unique
     206              :                                         SmartPtr<vector_type> spDtmp = d.clone();
     207              :                                         spDtmp->change_storage_type(PST_UNIQUE);
     208              : 
     209              :                                         THROW_IF_NOT_EQUAL_3(c.size(), spDtmp->size(), m_A.num_rows());
     210              :                                         step(m_A, c, *spDtmp, m_relax);
     211              :                                         c.set_storage_type(PST_UNIQUE);
     212              :                                 }
     213              : 
     214              :                                 // make correction consistent
     215              :                                 c.change_storage_type(PST_CONSISTENT);
     216              : 
     217              :                                 return true;
     218              :                         }
     219              :                         else
     220              : #endif
     221              :                         {
     222            0 :                                 matrix_type &A = *pOp;
     223            0 :                                 THROW_IF_NOT_EQUAL_4(c.size(), d.size(), A.num_rows(), A.num_cols());
     224              : 
     225            0 :                                 step(A, c, d, m_relax);
     226              : #ifdef UG_PARALLEL
     227              :                                 c.set_storage_type(PST_CONSISTENT);
     228              : #endif
     229            0 :                                 return true;
     230              :                         }
     231              :                 }
     232              : 
     233              :         protected:
     234              : #ifdef UG_PARALLEL
     235              :                 matrix_type m_A;
     236              : #endif
     237              :         protected:
     238              :         ///     relaxation parameter
     239              :                 number m_relax;
     240              : 
     241              :         ///     for overlaps only
     242              :                 vector_type m_oD;
     243              :                 vector_type m_oC;
     244              : 
     245              :                 bool m_bConsistentInterfaces;
     246              :                 bool m_useOverlap;
     247              : 
     248              : 
     249              :         /// for ordering algorithms
     250              :                 SmartPtr<ordering_algo_type> m_spOrderingAlgo;
     251              : #ifdef NOT_YET
     252              :                 ordering_container_type m_ordering, m_old_ordering;
     253              :                 std::vector<size_t> m_newIndex, m_oldIndex;
     254              :                 bool m_bSortIsIdentity;
     255              : #endif
     256              : };
     257              : 
     258              : /// Gauss-Seidel preconditioner for the 'forward' ordering of the dofs
     259              : /**
     260              :  * This class implements the Gauss-Seidel preconditioner (and smoother) for the
     261              :  * 'forward' ordering of the dofs. When a relaxation parameter is set by the method
     262              :  * 'set_sor_relax', the resulting preconditioner is better known as (forward) 'SOR'-method.
     263              :  * References:
     264              :  * <ul>
     265              :  * <li> W. Hackbusch. Iterative solution of large sparse systems of equations. New York: Springer, 1994
     266              :  * </ul>
     267              :  *
     268              :  * \tparam      TAlgebra        Algebra type
     269              :  */
     270              : template <typename TAlgebra>
     271              : class GaussSeidel : public GaussSeidelBase<TAlgebra>
     272              : {
     273              :         typedef TAlgebra algebra_type;
     274              :         typedef typename TAlgebra::vector_type vector_type;
     275              :         typedef typename TAlgebra::matrix_type matrix_type;
     276              :         typedef GaussSeidelBase<TAlgebra> base_type;
     277              : 
     278              : public:
     279              :         //      Name of preconditioner
     280            0 :                 virtual const char* name() const {return "Gauss-Seidel";}
     281              : 
     282              :         /// constructor
     283            0 :                 GaussSeidel() : base_type() {}
     284              : 
     285              :         /// clone constructor
     286            0 :                 GaussSeidel( const GaussSeidel<TAlgebra> &parent )
     287            0 :                         : base_type(parent)
     288              :                 {       }
     289              : 
     290              :         ///     Clone
     291            0 :                 virtual SmartPtr<ILinearIterator<vector_type> > clone()
     292              :                 {
     293            0 :                         return make_sp(new GaussSeidel<algebra_type>(*this));
     294              :                 }
     295              : 
     296              :         //      Stepping routine
     297            0 :                 virtual void step(const matrix_type &A, vector_type &c, const vector_type &d, const number relax)
     298              :                 {
     299            0 :                         gs_step_LL(A, c, d, relax);
     300            0 :                 }
     301              : };
     302              : 
     303              : /// Gauss-Seidel preconditioner for the 'backward' ordering of the dofs
     304              : /**
     305              :  * This class implements the Gauss-Seidel preconditioner (and smoother) for the
     306              :  * 'backward' ordering of the dofs. When a relaxation parameter is set by the method
     307              :  * 'set_sor_relax', the resulting preconditioner is better known as backward 'SOR'-method.
     308              :  * References:
     309              :  * <ul>
     310              :  * <li> W. Hackbusch. Iterative solution of large sparse systems of equations. New York: Springer, 1994
     311              :  * </ul>
     312              :  *
     313              :  * \tparam      TAlgebra        Algebra type
     314              :  */
     315              : template <typename TAlgebra>
     316              : class BackwardGaussSeidel : public GaussSeidelBase<TAlgebra>
     317              : {
     318              :         typedef TAlgebra algebra_type;
     319              :         typedef typename TAlgebra::vector_type vector_type;
     320              :         typedef typename TAlgebra::matrix_type matrix_type;
     321              :         typedef GaussSeidelBase<TAlgebra> base_type;
     322              : 
     323              : public:
     324              :         //      Name of preconditioner
     325            0 :                 virtual const char* name() const {return "Backward Gauss-Seidel";}
     326              : 
     327              :         /// constructor
     328            0 :                 BackwardGaussSeidel() : base_type() {}
     329              : 
     330              :         /// clone constructor
     331            0 :                 BackwardGaussSeidel( const BackwardGaussSeidel<TAlgebra> &parent )
     332            0 :                         : base_type(parent)
     333              :                 {       }
     334              : 
     335              :         ///     Clone
     336            0 :                 virtual SmartPtr<ILinearIterator<vector_type> > clone()
     337              :                 {
     338            0 :                         return make_sp(new BackwardGaussSeidel<algebra_type>(*this));
     339              :                 }
     340              : 
     341              :         //      Stepping routine
     342            0 :                 virtual void step(const matrix_type &A, vector_type &c, const vector_type &d, const number relax)
     343              :                 {
     344            0 :                         gs_step_UR(A, c, d, relax);
     345            0 :                 }
     346              : };
     347              : 
     348              : 
     349              : template <typename TAlgebra>
     350              : class SymmetricGaussSeidel : public GaussSeidelBase<TAlgebra>
     351              : {
     352              :         typedef TAlgebra algebra_type;
     353              :         typedef typename TAlgebra::vector_type vector_type;
     354              :         typedef typename TAlgebra::matrix_type matrix_type;
     355              :         typedef GaussSeidelBase<TAlgebra> base_type;
     356              : 
     357              : public:
     358              :         //      Name of preconditioner
     359            0 :                 virtual const char* name() const {return "Symmetric Gauss-Seidel";}
     360              : 
     361              :         /// constructor
     362            0 :                 SymmetricGaussSeidel() : base_type() {}
     363              : 
     364              :         /// clone constructor
     365            0 :                 SymmetricGaussSeidel( const SymmetricGaussSeidel<TAlgebra> &parent )
     366            0 :                         : base_type(parent)
     367              :                 {       }
     368              : 
     369              :         ///     Clone
     370            0 :                 virtual SmartPtr<ILinearIterator<vector_type> > clone()
     371              :                 {
     372            0 :                         return make_sp(new SymmetricGaussSeidel<algebra_type>(*this));
     373              :                 }
     374              : 
     375              :         //      Stepping routine
     376            0 :                 virtual void step(const matrix_type &A, vector_type &c, const vector_type &d, const number relax)
     377              :                 {
     378            0 :                         sgs_step(A, c, d, relax);
     379            0 :                 }
     380              : };
     381              : 
     382              : } // end namespace ug
     383              : 
     384              : #endif // __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__GAUSS_SEIDEL__
        

Generated by: LCOV version 2.0-1