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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Andreas Vogel
       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__LINEAR_SOLVER__
      34              : #define __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__LINEAR_SOLVER__
      35              : #include <iostream>
      36              : #include <string>
      37              : 
      38              : #include "lib_algebra/operator/interface/preconditioned_linear_operator_inverse.h"
      39              : #include "lib_algebra/operator/interface/linear_solver_profiling.h"
      40              : #include "lib_algebra/operator/interface/pprocess.h"
      41              : #ifdef UG_PARALLEL
      42              :         #include "lib_algebra/parallelization/parallelization.h"
      43              : #endif
      44              : 
      45              : namespace ug{
      46              : 
      47              : /// linear solver using abstract preconditioner interface
      48              : /**
      49              :  * This class is a linear iterating scheme, that uses any implementation
      50              :  * of the ILinearIterator interface to precondition the iteration.
      51              :  *
      52              :  * \tparam              TAlgebra                algebra type
      53              :  */
      54              : template <typename TVector>
      55            0 : class LinearSolver
      56              :         : public IPreconditionedLinearOperatorInverse<TVector>
      57              : {
      58              :         public:
      59              :         ///     Vector type
      60              :                 typedef TVector vector_type;
      61              : 
      62              :         ///     Base type
      63              :                 typedef IPreconditionedLinearOperatorInverse<vector_type> base_type;
      64              : 
      65              :         ///     constructors
      66            0 :                 LinearSolver() : base_type() {}
      67              : 
      68            0 :                 LinearSolver(SmartPtr<ILinearIterator<vector_type,vector_type> > spPrecond)
      69            0 :                         : base_type ( spPrecond )  {}
      70              : 
      71            0 :                 LinearSolver(SmartPtr<ILinearIterator<vector_type,vector_type> > spPrecond, SmartPtr<IConvergenceCheck<vector_type> > spConvCheck)
      72            0 :                         : base_type ( spPrecond, spConvCheck)  {}
      73              : 
      74              :         protected:
      75              :                 using base_type::convergence_check;
      76              :                 using base_type::linear_operator;
      77              :                 using base_type::preconditioner;
      78              :                 using base_type::write_debug;
      79              : 
      80              :         public:
      81              :         ///     returns the name of the solver
      82            0 :                 virtual const char* name() const {return "Iterative Linear Solver";}
      83              : 
      84              :         ///     returns if parallel solving is supported
      85            0 :                 virtual bool supports_parallel() const
      86              :                 {
      87            0 :                         if(preconditioner().valid())
      88            0 :                                 return preconditioner()->supports_parallel();
      89              :                         else return true;
      90              :                 }
      91              : 
      92              :                 /**
      93              :                  * Compute a correction c := B*d using one iterative step
      94              :                  * Internally the defect is updated d := d - A*c = b - A*(x+c)
      95              :                  * @param c
      96              :                  * @param d
      97              :                  */
      98            0 :                 bool compute_correction(vector_type &c, vector_type &d)
      99              :                 {
     100            0 :                         if(preconditioner().valid()) {
     101              :                                 LS_PROFILE_BEGIN(LS_ApplyPrecond);
     102              : 
     103            0 :                                 if(!preconditioner()->apply_update_defect(c, d))
     104              :                                 {
     105              :                                         UG_LOG("ERROR in 'LinearSolver': Could not apply preconditioner. Aborting.\n");
     106            0 :                                         return false;
     107              :                                 }
     108              :                                 LS_PROFILE_END(LS_ApplyPrecond);
     109              :                         }
     110              :                         return true;
     111              :                 }
     112              : 
     113              :         ///     solves the system and returns the last defect
     114            0 :                 virtual bool apply_return_defect(vector_type& x, vector_type& b)
     115              :                 {
     116              : 
     117              :                         LS_PROFILE_BEGIN(LS_ApplyReturnDefect);
     118              : 
     119              :                         #ifdef UG_PARALLEL
     120              :                         if(!b.has_storage_type(PST_ADDITIVE) || !x.has_storage_type(PST_CONSISTENT))
     121              :                                 UG_THROW("LinearSolver::apply: Inadequate parallel storage format of Vectors: "
     122              :                                                         << b.get_storage_type() << " for b (expected " << PST_ADDITIVE << "), "
     123              :                                                         << x.get_storage_type() << " for x (expected " << PST_CONSISTENT << ")");
     124              :                         #endif
     125              : 
     126              :                 //      debug output
     127            0 :                         if(this->vector_debug_writer_valid())
     128            0 :                                 write_debug(b, std::string("LS_RHS") + ".vec");
     129              :                         
     130              :                 //      rename b as d (for convenience)
     131              :                         vector_type& d = b;
     132              : 
     133              :                 //      build defect:  d := b - J*x
     134              :                         LS_PROFILE_BEGIN(LS_BuildDefect);
     135            0 :                         linear_operator()->apply_sub(d, x);
     136              :                         LS_PROFILE_END(LS_BuildDefect);
     137              : 
     138              :                 //      create correction
     139              :                         LS_PROFILE_BEGIN(LS_CreateCorrection);
     140            0 :                         SmartPtr<vector_type> spC = x.clone_without_values();
     141              :                         vector_type& c = *spC;
     142              :                         #ifdef UG_PARALLEL
     143              :                                 // this is ok if clone_without_values() inits with zeros
     144              :                                 c.set_storage_type(PST_CONSISTENT);
     145              :                         #endif
     146              :                         LS_PROFILE_END(LS_CreateCorrection);
     147              : 
     148              :                         LS_PROFILE_BEGIN(LS_ComputeStartDefect);
     149            0 :                         prepare_conv_check();
     150            0 :                         convergence_check()->start(d);
     151              :                         LS_PROFILE_END(LS_ComputeStartDefect);
     152              : 
     153              :                         int loopCnt = 0;
     154            0 :                         write_debugXCD(x, c, d, loopCnt, false);
     155              : 
     156              :                 //      Iteration loop
     157            0 :                         while(!convergence_check()->iteration_ended())
     158              :                         {
     159            0 :                                 enter_precond_debug_section(loopCnt);
     160            0 :                                 if( !compute_correction(c, d) )
     161              :                                 {
     162            0 :                                         this->leave_vector_debug_writer_section();
     163            0 :                                         return false;
     164              :                                 }
     165            0 :                                 this->leave_vector_debug_writer_section();
     166              : 
     167              :                         //      post-process the correction
     168            0 :                                 m_corr_post_process.apply (c);
     169              : 
     170              :                         //      add correction to solution: x += c
     171              :                                 LS_PROFILE_BEGIN(LS_AddCorrection);
     172            0 :                                 x += c;
     173              :                                 LS_PROFILE_END(LS_AddCorrection);
     174              :                                 
     175            0 :                                 write_debugXCD(x, c, d, ++loopCnt, true);
     176              : 
     177              :                         //      compute norm of new defect (in parallel)
     178              :                                 LS_PROFILE_BEGIN(LS_ComputeNewDefectNorm);
     179            0 :                                 convergence_check()->update(d);
     180              :                                 LS_PROFILE_END(LS_ComputeNewDefectNorm);
     181              :                         }
     182              : 
     183              :                 //      write some information when ending the iteration
     184            0 :                         if(!convergence_check()->post())
     185              :                         {
     186              :                                 UG_LOG("ERROR in 'LinearSolver::apply': post-convergence-check "
     187              :                                                 "signaled failure. Aborting.\n");
     188              :                                 return false;
     189              :                         }
     190              : 
     191              :                 //      end profiling of whole function
     192              :                         LS_PROFILE_END(LS_ApplyReturnDefect);
     193              : 
     194              :                 //      we're done
     195              :                         return true;
     196              :                 }
     197              :                 
     198              :         ///     adds a post-process for the iterates
     199            0 :                 void add_postprocess_corr (SmartPtr<IPProcessVector<vector_type> > p)
     200              :                 {
     201            0 :                         m_corr_post_process.add (p);
     202            0 :                 }
     203              : 
     204              :         ///     removes a post-process for the iterates
     205            0 :                 void remove_postprocess_corr (SmartPtr<IPProcessVector<vector_type> > p)
     206              :                 {
     207            0 :                         m_corr_post_process.remove (p);
     208            0 :                 }
     209              : 
     210              :         protected:
     211              :         ///     prepares the convergence check output
     212            0 :                 void prepare_conv_check()
     213              :                 {
     214            0 :                         convergence_check()->set_name(name());
     215            0 :                         convergence_check()->set_symbol('%');
     216            0 :                         if(preconditioner().valid())
     217              :             {
     218              :                 std::string s;
     219            0 :                 if(preconditioner().valid())
     220            0 :                     s = std::string(" (Precond: ") + preconditioner()->name() + ")";
     221              :                 else
     222              :                     s = " (No Preconditioner) ";
     223            0 :                 convergence_check()->set_info(s);
     224              :             }
     225            0 :                 }
     226              :         
     227              :         /// debugger output: solution, correction, defect
     228            0 :                 void write_debugXCD(vector_type &x, vector_type &c, vector_type &d, int loopCnt, bool bWriteC)
     229              :                 {
     230            0 :                         if(!this->vector_debug_writer_valid()) return;
     231              :                         char ext[20]; snprintf(ext, sizeof(ext),"_iter%03d", loopCnt);
     232            0 :                         write_debug(d, std::string("LS_Defect") + ext + ".vec");
     233            0 :                         if(bWriteC) write_debug(c, std::string("LS_Correction") + ext + ".vec");
     234            0 :                         write_debug(x, std::string("LS_Solution") + ext + ".vec");
     235              :                 }
     236              :                 
     237              :         /// debugger section for the preconditioner
     238            0 :                 void enter_precond_debug_section(int loopCnt)
     239              :                 {
     240            0 :                         if(!this->vector_debug_writer_valid()) return;
     241              :                         char ext[20]; snprintf(ext, sizeof(ext),"_iter%03d", loopCnt);
     242            0 :                         this->enter_vector_debug_writer_section(std::string("LS_Precond_") + ext);
     243              :                 }
     244              : 
     245              :         protected:
     246              :         ///     postprocessor for the correction in the iterations
     247              :                 PProcessChain<vector_type> m_corr_post_process;
     248              : };
     249              : 
     250              : } // end namespace ug
     251              : 
     252              : #endif /* __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__LINEAR_SOLVER__ */
        

Generated by: LCOV version 2.0-1