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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2014-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Arne Nägel
       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__DEBUG_ITERATOR__
      34              : #define __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__DEBUG_ITERATOR__
      35              : 
      36              : #include "lib_algebra/operator/interface/preconditioner.h"
      37              : #include "lib_algebra/operator/interface/preconditioned_linear_operator_inverse.h"
      38              : #include "lib_algebra/algebra_common/sparsematrix_util.h"
      39              : #include "lib_algebra/operator/debug_writer.h"
      40              : 
      41              : 
      42              : #ifdef UG_PARALLEL
      43              :         #include "lib_algebra/parallelization/parallelization.h"
      44              :         #include "lib_algebra/parallelization/parallel_matrix_overlap_impl.h"
      45              : #endif
      46              : 
      47              : namespace ug{
      48              : 
      49              : /// Debugging iterator
      50              : /**
      51              :  * This class implements an iterator that can be used for debugging:
      52              :  *
      53              :  * It wraps for an ILinearIterator<typename TAlgebra::vector_type> object, which can be used as usual,
      54              :  * i.e., all call are forwarded. Moreover, this class can determine the algebarically smooth error. In order to doso, one must specify a solver.
      55              :  * This solver is called once during initialization.
      56              :  *
      57              :  * This class is a VectorDebugWritingObject <typename TAlgebra::vector_type>. If a DebugWriter is supplied using use the set_debug routines, the smooth error is written to file.
      58              :  *
      59              :  */
      60              : template <typename TAlgebra>
      61              : class DebugIterator :
      62              : public virtual ILinearIterator<typename TAlgebra::vector_type>,
      63              : public VectorDebugWritingObject <typename TAlgebra::vector_type>
      64              : {
      65              :         public:
      66              :         //      Algebra type
      67              :                 typedef TAlgebra algebra_type;
      68              : 
      69              :         //      Vector type
      70              :                 typedef typename TAlgebra::vector_type vector_type;
      71              : 
      72              :         //      Matrix type
      73              :                 typedef typename TAlgebra::matrix_type matrix_type;
      74              : 
      75              :         //      Base type
      76              :                 typedef ILinearIterator<typename TAlgebra::vector_type> base_type;
      77              : 
      78              :                 typedef IPreconditionedLinearOperatorInverse<vector_type> solver_type;
      79              :         private:
      80              :                 typedef VectorDebugWritingObject <typename TAlgebra::vector_type> vdwo_type;
      81              : 
      82              :         public:
      83              :         ///     Constructor
      84            0 :                 DebugIterator() : from(0.0), to (1.0)
      85              :                 {
      86            0 :                         MatrixOperator<matrix_type, vector_type> *ptr =new MatrixOperator<matrix_type, vector_type>();
      87            0 :                         m_pOperator  = SmartPtr<MatrixOperator<matrix_type, vector_type> >(ptr);
      88            0 :                 };
      89              : 
      90            0 :                 DebugIterator(SmartPtr<base_type> pprecond, SmartPtr<solver_type> psolver) : from(0.0), to (1.0)
      91              :                 {
      92            0 :                         set_preconditioner(pprecond);
      93            0 :                         set_solver(psolver);
      94            0 :                         MatrixOperator<matrix_type, vector_type> *ptr =new MatrixOperator<matrix_type, vector_type>();
      95            0 :                         m_pOperator  = SmartPtr<MatrixOperator<matrix_type, vector_type> >(ptr);
      96            0 :                 };
      97              : 
      98              :         ///     Clone
      99            0 :                 virtual SmartPtr<ILinearIterator<vector_type> > clone()
     100              :                 {
     101            0 :                         SmartPtr<DebugIterator<algebra_type> > newInst(new DebugIterator<algebra_type> ());
     102            0 :                         newInst->set_damp(this->damping());
     103            0 :                         newInst->set_preconditioner(this->get_preconditioner()->clone());  // clone preconditioner
     104            0 :                         newInst->set_solver(this->get_solver());                                                     // keep solver (initialized below)
     105            0 :                         newInst->set_debug(this->vdwo_type::vector_debug_writer());
     106            0 :                         newInst->from = this->from;
     107            0 :                         newInst->to = this->to;
     108            0 :                         return newInst;
     109              :                 }
     110              : 
     111              :         ///     returns if parallel solving is supported
     112            0 :                 virtual bool supports_parallel() const
     113              :                 {
     114            0 :                         if(m_pprecond.valid())
     115            0 :                                 return m_pprecond->supports_parallel();
     116              :                         return true;
     117              :                 }
     118              : 
     119              :         /// specify the real preconditioner (used for iterating)
     120            0 :                 void set_preconditioner(SmartPtr<base_type> pprecond) {m_pprecond=pprecond;}
     121              :         /// specify the solver that will be used for debugging (optional)
     122            0 :                 void set_solver(SmartPtr<solver_type> psolver) {m_solver=psolver;}
     123              :         /// specify bounds for random initial guess (optional)
     124            0 :                 void set_random_bounds(double a, double b){from =a; to=b;}
     125              : 
     126            0 :                 void set_solution(SmartPtr<vector_type> sol)
     127            0 :                 {m_spSolVector = sol;}
     128              : 
     129              :         protected:
     130              :         /// get reference to 'real' preconditioner
     131              :                 SmartPtr<base_type> get_preconditioner() {return m_pprecond;}
     132              :         /// get reference to aux. solver
     133              :                 SmartPtr<solver_type> get_solver() {return m_solver;}
     134              : 
     135              : 
     136              :         ///     name of preconditioner
     137            0 :                 virtual const char* name() const
     138            0 :                 {return "DebugIterator";}
     139              : 
     140              : 
     141              :                 /// init (expensive)
     142            0 :                 virtual bool init(SmartPtr<ILinearOperator<vector_type> > J,
     143              :                                 const vector_type& u)
     144              :                 {
     145              :                         //      cast to matrix based operator
     146            0 :                         SmartPtr<MatrixOperator<matrix_type, vector_type> > pOp =
     147              :                                         J.template cast_dynamic<MatrixOperator<matrix_type, vector_type> >();
     148              : 
     149              :                         //      Check that matrix if of correct type
     150            0 :                         if(pOp.invalid())
     151            0 :                                 UG_THROW(name() << "::init': Passed Operator is "
     152              :                                                 "not based on matrix. This Preconditioner can only "
     153              :                                                 "handle matrix-based operators.");
     154              : 
     155              :                         //      forward request to matrix based implementation
     156            0 :                         return init(pOp);
     157              :                 }
     158              : 
     159              :                 /// init (expensive)
     160            0 :                 virtual bool init(SmartPtr<ILinearOperator<vector_type> > L)
     161              :                 {
     162              :                         //      cast to matrix based operator
     163            0 :                         SmartPtr<MatrixOperator<matrix_type, vector_type> > pOp =
     164              :                                         L.template cast_dynamic<MatrixOperator<matrix_type, vector_type> >();
     165              : 
     166              :                         //      Check that matrix if of correct type
     167            0 :                         if(pOp.invalid())
     168            0 :                                 UG_THROW(name() << "::init': Passed Operator is "
     169              :                                                 "not based on matrix. This Preconditioner can only "
     170              :                                                 "handle matrix-based operators.");
     171              : 
     172              :                         //      forward request to matrix based implementation
     173            0 :                         return init(pOp);
     174              :                 }
     175              : 
     176              :                 /// init (expensive, since it calls \sa find_smooth_error)
     177            0 :                 bool init(SmartPtr<MatrixOperator<matrix_type, vector_type> > pOp)
     178              :                 {
     179            0 :                         m_pOperator->get_matrix() = pOp->get_matrix();
     180              :                         //m_pOperator->get_matrix().set_as_copy_of(pOp->get_matrix());
     181              : #ifdef UG_PARALLEL
     182              :                         //m_pOperator->get_matrix().set_storage_Type(pOp->get_matrix()->get_storage_type());
     183              : #endif
     184            0 :                         m_pprecond->init(pOp);
     185              : 
     186              :                         //write_debug(pOp->get_matrix(), "DebugMatrix");
     187            0 :                         find_smooth_error();
     188              : 
     189            0 :                         return true;
     190              :                 }
     191              : 
     192              :         /// Determines algebraically smooth error
     193              :         /** Solves Ae=0 starting from a random initial guess.
     194              :          * \returns true, iff error was determined*/
     195            0 :                 bool find_smooth_error()
     196              :                 {
     197            0 :                         if (m_solver.invalid())
     198              :                         {
     199              :                                 UG_LOG("WARNING: cannot find smooth error; no solver supplied!");
     200            0 :                                 return false;
     201              :                         }
     202              : 
     203            0 :                         if (m_spSolVector.invalid())
     204              :                         {
     205              :                                 UG_LOG("WARNING: cannot find smooth error; no valid vector !");
     206            0 :                                 return false;
     207              :                         }
     208              : 
     209              :                         //vector_type myRhs(m_pOperator->get_matrix().num_rows());
     210              :                         //vector_type myError(m_pOperator->get_matrix().num_rows());
     211              :                         
     212              :                         SmartPtr<vector_type> myError = m_spSolVector;
     213            0 :                         SmartPtr<vector_type> myRhs = m_spSolVector->clone_without_values();
     214              : 
     215              :                         myError->set(0.0);
     216            0 :                         myError->set_random(from, to);
     217              : 
     218              :                         myRhs->set(0.0);
     219              : 
     220            0 :                         this->write_debug(*myError, "DebugIterError0");
     221            0 :                         m_solver->init(m_pOperator);
     222            0 :                         m_solver->apply(*myError, *myRhs);
     223              : 
     224            0 :                         this->write_debug(*myError, "DebugIterErrorS");
     225              : 
     226              :                         return true;
     227              :                 }
     228              : 
     229              :         /// forwarding call to original preconditioner
     230            0 :                 virtual bool apply(vector_type& c, const vector_type& d)
     231              :                 {
     232            0 :                         return m_pprecond->apply(c, d);
     233              :                 }
     234              : 
     235              :         /// forwarding call to original preconditioner
     236            0 :                 virtual bool apply_update_defect(vector_type& c, vector_type& d)
     237              :                 {
     238            0 :                         return (m_pprecond->apply_update_defect(c, d));
     239              :                 }
     240              : 
     241              :         protected:
     242              : 
     243              :                 SmartPtr<base_type> m_pprecond;
     244              : 
     245              :                 SmartPtr<solver_type> m_solver;
     246              :                 SmartPtr<MatrixOperator<matrix_type, vector_type> > m_pOperator;
     247              :                 SmartPtr<vector_type> m_spSolVector;
     248              : 
     249              :                 double from, to;
     250              : 
     251              : };
     252              : 
     253              : 
     254              : 
     255              : } // end namespace ug
     256              : 
     257              : #endif // __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__TRANSFORMING__
        

Generated by: LCOV version 2.0-1