LCOV - code coverage report
Current view: top level - ugbase/lib_disc/operator/linear_operator/nested_iteration - nested_iteration_impl.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 96 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 72 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010 - 2017:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Arne Naegel
       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__NON_LINEAR_OPERATOR__NI_SOLVER__NI_IMPL__
      34              : #define __H__UG__LIB_DISC__OPERATOR__NON_LINEAR_OPERATOR__NI_SOLVER__NI_IMPL__
      35              : 
      36              : #include <iostream>
      37              : #include <sstream>
      38              : 
      39              : #include "nested_iteration.h"
      40              : #include "lib_disc/function_spaces/grid_function_util.h"
      41              : #include "common/util/string_util.h"
      42              : 
      43              : #define PROFILE_NESTED_ITER
      44              : #ifdef PROFILE_NESTED_ITER
      45              :         #define NESTED_ITER_PROFILE_FUNC()              PROFILE_FUNC_GROUP("NestedIteration")
      46              :         #define NESTED_ITER_PROFILE_BEGIN(name) PROFILE_BEGIN_GROUP(name, "NestedIteration")
      47              :         #define NESTED_ITER_PROFILE_END()               PROFILE_END()
      48              : #else
      49              :         #define NESTED_ITER_PROFILE_FUNC()
      50              :         #define NESTED_ITER_PROFILE_BEGIN(name)
      51              :         #define NESTED_ITER_PROFILE_END()
      52              : #endif
      53              : 
      54              : namespace ug{
      55              : 
      56              : template <typename TDomain, typename TAlgebra>
      57              : NestedIterationSolver<TDomain,TAlgebra>::
      58              : NestedIterationSolver(SmartPtr<ILinearOperatorInverse<vector_type> > LinearSolver) :
      59              :                         m_spLinearSolver(LinearSolver),
      60              :                         m_N(NULL),
      61              :                         m_J(NULL),
      62              :                         m_spAss(NULL),
      63              :                         m_dgbCall(0),
      64              :                         m_lastNumSteps(0),
      65              :                         m_bUseAdaptiveRefinement(true),
      66              :                         m_maxSteps(100), m_TOL(1e-3), m_absTOL(1e-12)
      67              : {};
      68              : 
      69              : template <typename TDomain, typename TAlgebra>
      70            0 : NestedIterationSolver<TDomain,TAlgebra>::
      71              : NestedIterationSolver() :
      72              :         m_spLinearSolver(NULL),
      73              :         m_N(NULL),
      74              :         m_J(NULL),
      75              :         m_spAss(NULL),
      76            0 :         m_dgbCall(0),
      77            0 :         m_lastNumSteps(0),
      78            0 :         m_bUseAdaptiveRefinement(true),
      79            0 :         m_maxSteps(100), m_TOL(1e-3), m_absTOL(1e-12)
      80              : {};
      81              : 
      82              : template <typename TDomain, typename TAlgebra>
      83            0 : NestedIterationSolver<TDomain,TAlgebra>::
      84              : NestedIterationSolver(SmartPtr<IOperator<vector_type> > N) :
      85              :         m_spLinearSolver(NULL),
      86              :         m_N(NULL),
      87              :         m_J(NULL),
      88              :         m_spAss(NULL),
      89            0 :         m_dgbCall(0),
      90            0 :         m_lastNumSteps(0),
      91            0 :         m_bUseAdaptiveRefinement(true),
      92            0 :         m_maxSteps(100), m_TOL(1e-3), m_absTOL(1e-12)
      93              : {
      94            0 :         init(N);
      95            0 : };
      96              : 
      97              : template <typename TDomain, typename TAlgebra>
      98            0 : NestedIterationSolver<TDomain,TAlgebra>::
      99              : NestedIterationSolver(SmartPtr<IAssemble<TAlgebra> > spAss) :
     100              :         m_spLinearSolver(NULL),
     101              :         m_N(NULL),
     102              :         m_J(NULL),
     103              :         m_spAss(spAss),
     104              :         m_spDomErr(spAss),
     105            0 :         m_dgbCall(0),
     106            0 :         m_lastNumSteps(0),
     107            0 :         m_baseLevel(0),
     108            0 :         m_bUseAdaptiveRefinement(true),
     109            0 :         m_maxSteps(100), m_TOL(1e-3), m_absTOL(1e-12)
     110              : {
     111            0 :         m_N = SmartPtr<AssembledOperator<TAlgebra> >(new AssembledOperator<TAlgebra>(m_spAss));
     112            0 : };
     113              : 
     114              : 
     115              : template <typename TDomain, typename TAlgebra>
     116            0 : NestedIterationSolver<TDomain,TAlgebra>::
     117              : NestedIterationSolver(SmartPtr<IAssemble<TAlgebra> > spAss, SmartPtr<IAssemble<TAlgebra> > spDomErr) :
     118              :         m_spLinearSolver(NULL),
     119              :         m_N(NULL),
     120              :         m_J(NULL),
     121              :         m_spAss(spAss),
     122              :         m_spDomErr(spDomErr),
     123            0 :         m_dgbCall(0),
     124            0 :         m_lastNumSteps(0),
     125            0 :         m_baseLevel(0),
     126            0 :         m_bUseAdaptiveRefinement(true)
     127              : {
     128            0 :         m_N = SmartPtr<AssembledOperator<TAlgebra> >(new AssembledOperator<TAlgebra>(m_spAss));
     129            0 : };
     130              : 
     131              : 
     132              : /*! Requires an AssembledOperator */
     133              : template <typename TDomain, typename TAlgebra>
     134            0 : bool NestedIterationSolver<TDomain,TAlgebra>::init(SmartPtr<IOperator<vector_type> > N)
     135              : {
     136              :         NESTED_ITER_PROFILE_BEGIN(NestedIterationSolver_init);
     137            0 :         m_N = N.template cast_dynamic<AssembledOperator<TAlgebra> >();
     138            0 :         if(m_N.invalid())
     139            0 :                 UG_THROW("NestedIterationSolver: currently only works for AssembledDiscreteOperator.");
     140              : 
     141            0 :         m_spAss = m_N->discretization();
     142            0 :         return true;
     143              : }
     144              : 
     145              : //!     todo: remove from interface
     146              : template <typename TDomain, typename TAlgebra>
     147            0 : bool NestedIterationSolver<TDomain,TAlgebra>::prepare(vector_type& u)
     148              : {
     149              : 
     150            0 :         return true;
     151              : }
     152              : 
     153              : 
     154              : //! Refines domain and provides error estimate.
     155              : /*! Values depend on m_spDomErr */
     156              : template <typename TDomain, typename TAlgebra>
     157            0 : void NestedIterationSolver<TDomain,TAlgebra>::estimate_and_mark_domain(const grid_function_type& u, SmartPtr<IElementMarkingStrategy<TDomain> > spMarking, bool bClearMarks)
     158              : {
     159              :           UG_LOG("Computing error... "<< std::endl);
     160              : 
     161              :           typedef DomainDiscretization<TDomain, TAlgebra> domain_disc_type;
     162              :          //  typedef IDomainErrorIndicator<TAlgebra> domain_indicator_type;
     163              : 
     164            0 :           SmartPtr<domain_disc_type> spDomainEstimator = m_spDomErr.template cast_dynamic<domain_disc_type>();
     165              : 
     166              :           // some checks
     167              :           UG_ASSERT(spDomainEstimator.valid(), "Huhh: No estimatable object???")
     168              :           UG_ASSERT(m_spRefiner.valid(), "Huhh: Invalid refiner???");
     169              : 
     170              :           // compute error
     171            0 :           if (m_spElemError.valid()) {
     172              :                   // debug version
     173            0 :                   spDomainEstimator->calc_error(u, u.dd(), m_spElemError.get());
     174              :           } else {
     175              :                   // standard version
     176            0 :                   spDomainEstimator->calc_error(u, u.dd());
     177              :           }
     178              : 
     179              :           // set (new) marks
     180            0 :           if (bClearMarks) m_spRefiner->clear_marks();
     181            0 :           spDomainEstimator->mark_with_strategy(*m_spRefiner, spMarking);
     182              :           UG_LOG("Estimated error: " << spMarking->global_estimated_error());
     183              : 
     184              : 
     185              : 
     186              : 
     187            0 : }
     188              : 
     189              : 
     190              : //! Coarsen all elements
     191              : template <typename TDomain, typename TAlgebra>
     192              : number NestedIterationSolver<TDomain,TAlgebra>::coarsen_domain(const grid_function_type& u)
     193              : {
     194              :         /*typedef typename domain_traits<TDomain::dim>::element_type TElem;
     195              :         SmartPtr<DoFDistribution> spDD=u.dof_distribution();
     196              :         m_spRefiner->mark(spDD->begin<TElem>(), spDD->end<TElem>(), RM_COARSEN);
     197              :         m_spRefiner->coarsen();*/
     198              :         
     199              :         return 0; // dummy value
     200              : }
     201              : 
     202              : 
     203              : //! Apply solver for top level grid function
     204              : /*! returns: approximation by nested iteration. Input values are ignored.
     205              :  *
     206              :  * */
     207              : template <typename TDomain, typename TAlgebra>
     208            0 : bool NestedIterationSolver<TDomain,TAlgebra>::apply(vector_type& u)
     209              : {
     210              : #ifdef UG_PARALLEL
     211              :         // UG_ASSERT(0, "Not implemented!")
     212              : #endif
     213              :         NESTED_ITER_PROFILE_BEGIN(NestedIterationSolver_apply);
     214              : 
     215              :         //      increase call count
     216            0 :         m_dgbCall++;
     217            0 :         grid_function_type &usol = dynamic_cast<grid_function_type&>(u);
     218              : 
     219              :         UG_ASSERT (usol.grid_level().is_surface(), "Must supply surface grid function");
     220              :         UG_ASSERT (usol.grid_level().top(), "Must supply top level grid function");
     221              :         const GridLevel& surfGridLevel = usol.grid_level();
     222              : 
     223              :         // Check for linear solver.
     224            0 :         if(m_spLinearSolver.invalid())
     225            0 :                 UG_THROW("NestedIterationSolver::apply: Linear Solver not set.");
     226              : 
     227              :         // Check for Jacobian.
     228            0 :         if(m_J.invalid() || m_J->discretization() != m_spAss) {
     229            0 :                 m_J = make_sp(new AssembledLinearOperator<TAlgebra>(m_spAss));
     230              :         }
     231              :         m_J->set_level(m_N->level());
     232              : 
     233            0 :         UG_LOG("N level: "<<m_N->level()<< std::endl);
     234            0 :         UG_LOG("u level: "<< usol.grid_level() << std::endl);
     235              : 
     236              :         // Create tmp vectors
     237            0 :         SmartPtr<vector_type> spD = u.clone_without_values();
     238              : 
     239              :         std::string ext;        //char ext[50];
     240              :         int loopCnt = 0;
     241            0 :         m_lastNumSteps = 0;
     242              :         {
     243              :                 //      write start defect for debug
     244              :                 //snprintf(ext, sizeof(ext), "_call%03d", m_dgbCall);
     245            0 :                 std::string name("NESTED_ITER_StartSolution");
     246            0 :                 ext = GetStringPrintf("_call%03d", m_dgbCall);
     247              :                 name.append(ext);
     248            0 :                 write_debug(u, name.c_str());
     249              :         }
     250              : 
     251              :         // Assembly loop (from some coarse level to TOP)
     252              :         int surfLevel = usol.grid_level().level();  // todo: should start on coarse(r) levels
     253            0 :         m_topLevel = surfLevel+m_maxSteps;
     254            0 :         for (int lev=surfLevel; lev<m_topLevel; ++lev)
     255              :         {
     256              :                 /* OLD LUA CODE:
     257              :                  *  globalDisc:assemble_linear(A, b)
     258              :                  *      globalDisc:adjust_solution(u)
     259              :                  *      solver:init(A)
     260              :                  *      solver:apply_return_defect(u,b)
     261              :                  *      // globalDisc:adjust_solution(u)
     262              :                  */
     263              : 
     264              :                 // Assemble.
     265              :                 NESTED_ITER_PROFILE_BEGIN(NestedIterationAssemble);
     266            0 :                 m_spAss->assemble_linear(*m_J, *spD, surfGridLevel);   // todo: replace for non-linear problems
     267            0 :                 m_spAss->adjust_solution(u, surfGridLevel);
     268              :                 NESTED_ITER_PROFILE_END();
     269              : 
     270              :                 //snprintf(ext, sizeof(ext),"_call%03d_iter%03d", m_dgbCall, loopCnt);
     271            0 :                 ext = GetStringPrintf("_call%03d_iter%03d", m_dgbCall, loopCnt);
     272              :                 {
     273              :                         // write initial data for debug
     274            0 :                         std::string name0("NESTED_ITER_InitialSolution"); name0.append(ext);
     275            0 :                         write_debug(u, name0.c_str());
     276            0 :                         std::string name("NESTED_ITER_InitialDefect"); name.append(ext);
     277            0 :                         write_debug(*spD, name.c_str());
     278              : 
     279              :                         //      Write Jacobian for debug
     280            0 :                         std::string matname("NESTED_ITER_Jacobian");
     281              :                         matname.append(ext);
     282            0 :                         write_debug(m_J->get_matrix(), matname.c_str());
     283              :                 }
     284              : 
     285              :                 // Initialize inverse of Jacobian.
     286              :                 try{
     287              :                         NESTED_ITER_PROFILE_BEGIN(NestedIterationPrepareLinSolver);
     288            0 :                         if(!m_spLinearSolver->init(m_J, u))
     289              :                         {
     290              :                                 UG_LOG("ERROR in 'NestedIterationSolver::apply': Cannot init Inverse Linear "
     291              :                                                 "Operator for Jacobi-Operator.\n");
     292              :                                 return false;
     293              :                         }
     294              :                         NESTED_ITER_PROFILE_END();
     295            0 :                 }UG_CATCH_THROW("NestedIterationSolver::apply: Initialization of Linear Solver failed.");
     296              : 
     297              :                 // Solve linearized system.
     298              :                 try{
     299              :                         NESTED_ITER_PROFILE_BEGIN(NewtonApplyLinSolver);
     300            0 :                         if(!m_spLinearSolver->apply(u, *spD))
     301              :                         {
     302              :                                 UG_LOG("ERROR in 'NestedIterationSolver::apply': Cannot apply Inverse Linear "
     303              :                                                 "Operator for Jacobi-Operator.\n");
     304              :                                 return false;
     305              :                         }
     306              :                         NESTED_ITER_PROFILE_END();
     307            0 :                 }UG_CATCH_THROW("NestedIterationSolver::apply: Application of Linear Solver failed.");
     308              : 
     309              :                 // Adjust solution.
     310            0 :                 m_spAss->adjust_solution(u, surfGridLevel);
     311              :                 {
     312              :                         //      write defect for debug
     313            0 :                         std::string name("NESTED_ITER_FinalDefect"); name.append(ext);
     314            0 :                         write_debug(*spD, name.c_str());
     315            0 :                         std::string name3("NESTED_ITER_FinalSolution"); name3.append(ext);
     316            0 :                         write_debug(u, name3.c_str());
     317              :                 }
     318              : 
     319              :                 // Update counter.
     320            0 :                 loopCnt++;
     321              : 
     322              :                 // Quit?
     323            0 :                 if (use_adaptive_refinement() == false) {
     324              :                         UG_LOG("SUCCESS: Non-adaptive version!" <<  std::endl);
     325              :                         break;
     326              :                 }
     327              : 
     328              :                 // Estimate and mark domain.
     329            0 :                 this->estimate_and_mark_domain(usol, m_spRefinementMarking);
     330              : 
     331              :                 //      OPTIONAL: write defect for debug
     332            0 :                 if (m_spElemError.valid())
     333              :                 {
     334            0 :                         std::string name("NESTED_ITER_Error");
     335              :                         name.append(ext);
     336            0 :                         VTKOutput<TDomain::dim> outError;
     337              :                         outError.print(name.c_str(), *m_spElemError);
     338            0 :                 }
     339              : 
     340              :                 // Check error.
     341              :                 const number err = m_spRefinementMarking->global_estimated_error();
     342            0 :                 double desiredTOL = (m_spAssociatedSpace.valid()) ? m_TOL*m_spAssociatedSpace->norm(usol) + m_absTOL : m_TOL;
     343              : 
     344            0 :                 UG_LOG("NI *** Desired tolerance: " << m_TOL << " * "<<  m_spAssociatedSpace->norm(usol) <<  " + "<< m_absTOL <<std::endl);
     345              : 
     346              :                 // Quit or continue?
     347            0 :                 if(err < desiredTOL)
     348              :                 {
     349              :                         // Quit.
     350              :                         UG_LOG("SUCCESS: Error smaller than tolerance: " << err << " < "<< desiredTOL << std::endl);
     351              :                         break;
     352              :                 } else {
     353              :                         // Refine and continue.
     354              :                         UG_LOG("FAILED: Error (still) greater than tolerance: " << err << " > "<< desiredTOL << std::endl);
     355            0 :                         m_spRefiner->refine();
     356              :                 }
     357              :         }
     358              : 
     359              : 
     360              :         return true;
     361              : }
     362              : 
     363              : 
     364              : template <typename TDomain, typename TAlgebra>
     365            0 : std::string NestedIterationSolver<TDomain,TAlgebra>::config_string() const
     366              : {
     367            0 :         std::stringstream ss;
     368            0 :         ss << "NestedIterationSolver\n";
     369            0 :         ss << " LinearSolver: ";
     370            0 :         if(m_spLinearSolver.valid())    ss << ConfigShift(m_spLinearSolver->config_string()) << "\n";
     371            0 :         else                                                    ss << " NOT SET!\n";
     372            0 :         return ss.str();
     373            0 : }
     374              : 
     375              : 
     376              : }
     377              : 
     378              : #endif /* __H__UG__LIB_DISC__OPERATOR__NON_LINEAR_OPERATOR__NESTED_ITER_SOLVER__NESTED_ITER_IMPL__ */
     379              : 
        

Generated by: LCOV version 2.0-1