ug4
composite_conv_check_impl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2015: G-CSC, Goethe University Frankfurt
3  * Author: Markus Breit
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__LIB_DISC__OPERATOR__COMPOSITE_CONVERGENCE_CHECK_IMPL__
34 #define __H__LIB_DISC__OPERATOR__COMPOSITE_CONVERGENCE_CHECK_IMPL__
35 
36 #include "composite_conv_check.h"
38 #include <boost/core/enable_if.hpp>
39 
40 namespace ug{
41 
43 // Composite convergence check
45 
46 template <class TVector, class TDomain>
49  : m_spApprox(spApproxSpace),
50  m_bCheckRest(true), m_restMinDefect(1-12), m_restRelReduction(1-10),
51  m_currentStep(0), m_maxSteps(100),
52  m_verbose(true), m_supress_unsuccessful(false),
53  m_offset(0), m_symbol('%'), m_name("Iteration"), m_info(""),
54  m_bTimeMeas(true), m_bAdaptive(false)
55 {
57 }
58 
59 template <class TVector, class TDomain>
62  int maxSteps, number minDefect, number relReduction)
63  : m_spApprox(spApproxSpace),
64  m_bCheckRest(true), m_restMinDefect(minDefect), m_restRelReduction(relReduction),
65  m_currentStep(0), m_maxSteps(maxSteps),
66  m_verbose(true), m_supress_unsuccessful(false),
67  m_offset(0), m_symbol('%'), m_name("Iteration"), m_info(""),
68  m_bTimeMeas(true), m_bAdaptive(false)
69 {
71 }
72 
73 template <class TVector, class TDomain>
75 {
76  ConstSmartPtr<DoFDistribution> dd = m_spApprox->dof_distribution(GridLevel(level, GridLevel::SURFACE));
77  extract_dof_indices(dd);
78 
79  update_rest_check();
80 }
81 
82 
83 template <class TVector, class TDomain>
84 template <typename TBaseElem>
87 {
89 
90  const SurfaceView& sv = *dd->surface_view();
91  const MultiGrid& mg = *dd->multi_grid();
92 
93  // We need to iterate over SurfaceView::ALL unknowns here since, in parallel,
94  // it is possible for the shadowing elems of SHADOW_RIM_COPY elem to be located
95  // on a different processor!
96  // (cf. DoFDistribution::reinit() implementation comments)
97 
98  // iterate all elements (including SHADOW_RIM_COPY!)
99  iter = dd->template begin<TBaseElem>(SurfaceView::ALL);
100  iterEnd = dd->template end<TBaseElem>(SurfaceView::ALL);
101 
102  // loop over all elements
103  std::vector<DoFIndex> vInd;
104  for (; iter != iterEnd; ++iter)
105  {
106  TBaseElem* elem = *iter;
107  if (sv.is_contained(elem, dd->grid_level(), SurfaceView::SHADOW_RIM_COPY))
108  {
109  if (mg.num_children<TBaseElem>(elem) > 0)
110  {
111  TBaseElem* child = mg.get_child<TBaseElem>(elem, 0);
112  if (sv.is_contained(child, dd->grid_level(), SurfaceView::SURFACE_RIM))
113  continue;
114  }
115  }
116 
117  for (size_t fi = 0; fi < dd->num_fct(); fi++)
118  {
119  // inner multi indices of the grid object for a function component
120  dd->inner_dof_indices(elem, fi, vInd);
121 
122  // remember multi indices
123  for (size_t dof = 0; dof < vInd.size(); dof++)
124  m_vNativCmpInfo[fi].vMultiIndex.push_back(vInd[dof]);
125  }
126  }
127  // note: no duplicate indices possible
128 }
129 
130 template <class TVector, class TDomain>
133 {
134  // compute indices for faster access later
135  m_vNativCmpInfo.clear();
136  m_vNativCmpInfo.resize(dd->num_fct());
137  if(dd->max_dofs(VERTEX)) extract_dof_indices<Vertex>(dd);
138  if(dd->max_dofs(EDGE)) extract_dof_indices<Edge>(dd);
139  if(dd->max_dofs(FACE)) extract_dof_indices<Face>(dd);
140  if(dd->max_dofs(VOLUME)) extract_dof_indices<Volume>(dd);
141 
142  for(size_t i = 0; i < m_vNativCmpInfo.size(); ++i)
143  m_vNativCmpInfo[i].name = dd->name(i);
144 
145  m_numAllDoFs = 0;
146  for(size_t i = 0; i < m_vNativCmpInfo.size(); ++i)
147  m_numAllDoFs += m_vNativCmpInfo[i].vMultiIndex.size();
148 }
149 
150 
151 template <class TVector, class TDomain>
153 norm(const TVector& vec, const std::vector<DoFIndex>& vMultiIndex)
154 {
155 #ifdef UG_PARALLEL
156 
157  // make vector d additive unique
158  if (!const_cast<TVector*>(&vec)->change_storage_type(PST_UNIQUE))
159  UG_THROW("CompositeConvCheck::norm(): Cannot change ParallelStorageType to unique.");
160 #endif
161 
162  double norm = 0.0;
163  size_t sz = vMultiIndex.size();
164  for (size_t dof = 0; dof < sz; ++dof)
165  {
166  const number val = DoFRef(vec, vMultiIndex[dof]);
167  norm += (double) (val*val);
168  }
169 
170 #ifdef UG_PARALLEL
171  // sum squared local norms
172  //if (!vec.layouts()->proc_comm().empty())
173  //norm = vec.layouts()->proc_comm().allreduce(norm, PCL_RO_SUM);
174 
175  // In the lines above,
176  // racing conditions occur in cases where a process has no elements,
177  // since the defect would be 0 for them then and iteration_ended() would return true;
178  // ergo: the empty processors would wait at the next global communication involving them
179  // while non-empty processors might encounter a different communication event before.
180  // This results in error messages like MPI ERROR: MPI_ERR_TRUNCATE: message truncated.
181 
182  // The lines below, however, result in Bi-CGSTAB going down in the first step with
183  // "minOrthogonality failed" in settings with empty processes as they will compute
184  // a zero (local) dot_product r*r0, but with (global) r=r0 != 0.
185  // Therefore switching to old alternative here. MPI_ERR_TRUNCATE should be prevented
186  // by not communicating globally, but only with the processes that really need to be
187  // involved (i.e. NO empty processes), if possible.
188 
189  pcl::ProcessCommunicator commWorld;
190  norm = commWorld.allreduce(norm, PCL_RO_SUM);
191 #endif
192 
193  // return global norm
194  return sqrt((number) norm);
195 }
196 
197 
198 template <class TVector, class TDomain>
200 {
202  new CompositeConvCheck<TVector, TDomain>(m_spApprox));
203 
204  // use std assignment (implicit member-wise is fine here)
205  *newInst = *this;
206  return newInst;
207 }
208 
209 template <class TVector, class TDomain>
211 set_component_check(const std::vector<std::string>& vFctName,
212  const std::vector<number>& vMinDefect,
213  const std::vector<number>& vRelReduction)
214 {
215  if(vFctName.size() != vMinDefect.size() || vFctName.size() != vRelReduction.size())
216  UG_THROW("CompositeConvCheck: Please specify one value for each cmp.");
217 
218  for(size_t cmp = 0; cmp < vFctName.size(); ++cmp)
219  set_component_check(vFctName[cmp], vMinDefect[cmp], vRelReduction[cmp]);
220 
221 }
222 
223 template <class TVector, class TDomain>
225 set_component_check(const std::string& vFctName,
226  const std::vector<number>& vMinDefect,
227  const std::vector<number>& vRelReduction)
228 {
229  set_component_check(TokenizeTrimString(vFctName), vMinDefect, vRelReduction);
230 }
231 
232 
233 template <class TVector, class TDomain>
235 set_component_check(const std::vector<std::string>& vFctName,
236  const number minDefect,
237  const number relReduction)
238 {
239  for(size_t cmp = 0; cmp < vFctName.size(); ++cmp)
240  set_component_check(vFctName[cmp], minDefect, relReduction);
241 }
242 
243 template <class TVector, class TDomain>
245 set_all_component_check(const number minDefect,
246  const number relReduction)
247 {
248  for(size_t fct = 0; fct < m_spApprox->num_fct(); ++fct){
249  std::string name = m_spApprox->name(fct);
250  set_component_check(name, minDefect, relReduction);
251  }
252 }
253 
254 template <class TVector, class TDomain>
256 set_component_check(const std::string& fctNames,
257  const number minDefect,
258  const number relReduction)
259 {
260  std::vector<std::string> vName = TokenizeTrimString(fctNames);
261 
262  for(size_t i = 0; i < vName.size(); ++i)
263  {
264  const int fct = m_spApprox->fct_id_by_name(vName[i].c_str());
265 
266  // search for single component
267  size_t cmp = 0;
268  for(; cmp < m_CmpInfo.size(); ++cmp){
269 
270  // not checking rest
271  if(m_CmpInfo[cmp].isRest) continue;
272 
273  // only single valued checked
274  if(m_CmpInfo[cmp].vFct.size() != 1) continue;
275 
276  // check if component found
277  if(m_CmpInfo[cmp].vFct[0] == fct)
278  break;
279  }
280 
281  // if not found add new one
282  if(cmp == m_CmpInfo.size())
283  m_CmpInfo.push_back(CmpInfo());
284 
285  // set values
286  m_CmpInfo[cmp].isRest = false;
287  m_CmpInfo[cmp].vFct.clear();
288  m_CmpInfo[cmp].vFct.push_back(fct);
289  m_CmpInfo[cmp].name = vName[i];
290  m_CmpInfo[cmp].minDefect = minDefect;
291  m_CmpInfo[cmp].relReduction = relReduction;
292  }
293 
294  // update rest values
295  update_rest_check();
296 }
297 
298 template <class TVector, class TDomain>
300 set_group_check(const std::vector<std::string>& vFctName,
301  const number minDefect,
302  const number relReduction)
303 {
304  std::vector<int> vFct(vFctName.size());
305  for(size_t i = 0; i < vFctName.size(); ++i){
306  std::string name = TrimString(vFctName[i]);
307  vFct[i] = m_spApprox->fct_id_by_name(name.c_str());
308  }
309 
310  // search for group
311  size_t cmp = 0;
312  for(; cmp < m_CmpInfo.size(); ++cmp){
313 
314  // not checking rest
315  if(m_CmpInfo[cmp].isRest) continue;
316 
317  // only single valued checked
318  if(m_CmpInfo[cmp].vFct.size() != vFct.size()) continue;
319 
320  // check if component found
321  bool bFound = true;
322  for(size_t i = 0; i < vFct.size(); ++i){
323  if(m_CmpInfo[cmp].vFct[i] != vFct[i])
324  bFound = false;
325  }
326 
327  if(bFound) break;
328  }
329 
330  // if not found add new one
331  if(cmp == m_CmpInfo.size())
332  m_CmpInfo.push_back(CmpInfo());
333 
334  std::string name("");
335  for(size_t fct = 0; fct < vFct.size(); ++fct){
336  if(!name.empty()) name.append(", ");
337  name.append(m_vNativCmpInfo[vFct[fct]].name);
338  }
339 
340  // set values
341  m_CmpInfo[cmp].isRest = false;
342  m_CmpInfo[cmp].vFct = vFct;
343  m_CmpInfo[cmp].name = name;
344  m_CmpInfo[cmp].minDefect = minDefect;
345  m_CmpInfo[cmp].relReduction = relReduction;
346 
347  // update rest values
348  update_rest_check();
349 }
350 
351 template <class TVector, class TDomain>
353 set_group_check(const std::string& fctNames,
354  const number minDefect,
355  const number relReduction)
356 {
357  set_group_check(TokenizeTrimString(fctNames), minDefect, relReduction);
358 }
359 
360 template <class TVector, class TDomain>
363 {
364  // remove old rest
365  for(size_t cmp = 0; cmp < m_CmpInfo.size(); ++cmp)
366  if(m_CmpInfo[cmp].isRest)
367  m_CmpInfo.erase(m_CmpInfo.begin()+cmp);
368 
369  // check if rest required
370  if(!m_bCheckRest) return;
371 
372  // detect used functions
373  std::vector<bool> vUsed(m_vNativCmpInfo.size(), false);
374  for(size_t cmp = 0; cmp < m_CmpInfo.size(); ++cmp)
375  {
376  for(size_t i = 0; i < m_CmpInfo[cmp].vFct.size(); ++i)
377  vUsed[ m_CmpInfo[cmp].vFct[i] ] = true;
378  }
379 
380  std::vector<int> vFct;
381  std::string name("");
382 
383  for(size_t fct = 0; fct < vUsed.size(); ++fct){
384  if(vUsed[fct]) continue;
385 
386  vFct.push_back(fct);
387  if(!name.empty()) name.append(", ");
388  name.append(m_vNativCmpInfo[fct].name);
389  }
390 
391  // if no rest --> not added
392  if(vFct.empty()) return;
393 
394  // add new rest
395  m_CmpInfo.push_back(CmpInfo());
396  m_CmpInfo.back().isRest = true;
397  m_CmpInfo.back().vFct = vFct;
398  m_CmpInfo.back().name = name;
399  m_CmpInfo.back().minDefect = m_restMinDefect;
400  m_CmpInfo.back().relReduction = m_restRelReduction;
401 }
402 
403 template <class TVector, class TDomain>
405 {
406  UG_THROW( "This method cannot be used to set defect values,\n"
407  "since obviously this class is meant for an individual\n"
408  "defect calculation of more than one function\n"
409  "(use start(TVector& d) instead).");
410 }
411 
412 
413 template <typename TVector, typename Enable = void>
415 {
416  static const size_t block_size = 1;
417 };
418 
419 // specialization for all blocked vector types
420 template <typename TVector>
421 struct MyVectorTraits<TVector, typename boost::enable_if_c<TVector::value_type::is_static>::type>
422 {
423  static const size_t block_size = TVector::value_type::static_size;
424 };
425 
426 
427 template <class TVector, class TDomain>
429 {
430  // if meshing is adaptive, prepare convCheck for possibly new grid
431  if (m_bAdaptive)
432  set_level(GridLevel::TOP);
433 
434  // assert correct number of dofs
435  if (vec.size() * MyVectorTraits<TVector>::block_size != m_numAllDoFs)
436  {
437  UG_THROW("Number of dofs in CompositeConvCheck does not match "
438  "number of dofs given in vector from algorithm (" << m_numAllDoFs
439  << ", but " << vec.size() << " given). \nMake sure that you set "
440  "the right grid level via set_level().");
441  }
442 
443  // start time measurement
444  if (m_bTimeMeas) m_stopwatch.start();
445 
446  // update native defects
447  for (size_t fct = 0; fct < m_vNativCmpInfo.size(); fct++){
448  m_vNativCmpInfo[fct].initDefect = norm(vec, m_vNativCmpInfo[fct].vMultiIndex);
449  m_vNativCmpInfo[fct].currDefect = m_vNativCmpInfo[fct].initDefect;
450  }
451 
452  // update grouped defects
453  for (size_t cmp = 0; cmp < m_CmpInfo.size(); cmp++){
454  CmpInfo& cmpInfo = m_CmpInfo[cmp];
455 
456  cmpInfo.currDefect = 0.0;
457  for(size_t i = 0; i < cmpInfo.vFct.size(); ++i)
458  cmpInfo.currDefect += pow(m_vNativCmpInfo[cmpInfo.vFct[i]].currDefect, 2);
459  cmpInfo.currDefect = sqrt(cmpInfo.currDefect);
460 
461  cmpInfo.initDefect = cmpInfo.currDefect;
462  }
463 
464  m_currentStep = 0;
465 
466  if (m_verbose)
467  {
468  UG_LOG("\n");
469 
470  // number of symbols to print before name and info
471  int num_sym = 18;
472  int num_line_length = 80;
473 
474  int max_length = std::max(m_name.length(), m_info.length());
475  int space_left = std::max(num_line_length - max_length - num_sym, 0);
476 
477  // print name line
478  print_offset();
479  UG_LOG(repeat(m_symbol, num_sym));
480  int pre_space = (int)(max_length -(int)m_name.length()) / 2;
481  UG_LOG(repeat(' ', pre_space));
482  UG_LOG(" "<< m_name << " ");
483  UG_LOG(repeat(' ', max_length - pre_space -m_name.length()));
484  UG_LOG(repeat(m_symbol, space_left));
485  UG_LOG("\n");
486  // print info line
487  print_offset();
488  if (m_info.length() > 0)
489  {
490  UG_LOG(repeat(m_symbol, num_sym));
491  UG_LOG(" "<< m_info << " ");
492  UG_LOG(repeat(' ', max_length-m_info.length()));
493  UG_LOG(repeat(m_symbol, space_left));
494  UG_LOG("\n");
495  }
496  else
497  {
498  UG_LOG("\n");
499  }
500 
501  // start iteration output
502  print_offset();
503  UG_LOG(" Iter Defect Required Rate "
504  "Reduction Required Component(s)\n");
505 
506  for (size_t cmp = 0; cmp < m_CmpInfo.size(); cmp++)
507  {
508  CmpInfo& cmpInfo = m_CmpInfo[cmp];
509 
510  print_offset();
511  if(cmp != 0) {UG_LOG(" " );}
512  else {UG_LOG(std::right << std::setw(5) << step() << " ");}
513 
514  UG_LOG(std::scientific << cmpInfo.currDefect << " ");
515  UG_LOG(std::scientific << std::setprecision(3) << cmpInfo.minDefect << " " << std::setprecision(6) );
516  UG_LOG(std::scientific << " ----- " << " ");
517  UG_LOG(std::scientific << " -------- " << " ");
518  UG_LOG(std::scientific << std::setprecision(3) << cmpInfo.relReduction << " " << std::setprecision(6));
519  UG_LOG(std::scientific << cmpInfo.name << "\n");
520  }
521  }
522 }
523 
524 
525 template <class TVector, class TDomain>
527 {
528  UG_THROW( "This method cannot be used to update defect values,\n"
529  "since obviously this class is meant for an individual\n"
530  "defect calculation of more than one function\n"
531  "(use update(TVector& d) instead).");
532 }
533 
534 
535 template <class TVector, class TDomain>
537 {
538  // assert correct number of dofs
539  if (vec.size() * MyVectorTraits<TVector>::block_size != m_numAllDoFs)
540  {
541  UG_THROW("Number of dofs in CompositeConvCheck does not match"
542  "number of dofs given in vector from algorithm (" << m_numAllDoFs <<
543  ", but " << vec.size() << " given). \nMake sure that you set the "
544  "right grid level via set_level().");
545  }
546 
547  // update native defects
548  for (size_t fct = 0; fct < m_vNativCmpInfo.size(); fct++){
549  m_vNativCmpInfo[fct].lastDefect = m_vNativCmpInfo[fct].currDefect;
550  m_vNativCmpInfo[fct].currDefect = norm(vec, m_vNativCmpInfo[fct].vMultiIndex);
551  }
552 
553  // update grouped defects
554  for (size_t cmp = 0; cmp < m_CmpInfo.size(); cmp++){
555  CmpInfo& cmpInfo = m_CmpInfo[cmp];
556 
557  cmpInfo.lastDefect = cmpInfo.currDefect;
558 
559  cmpInfo.currDefect = 0.0;
560  for(size_t i = 0; i < cmpInfo.vFct.size(); ++i)
561  cmpInfo.currDefect += pow(m_vNativCmpInfo[cmpInfo.vFct[i]].currDefect, 2);
562  cmpInfo.currDefect = sqrt(cmpInfo.currDefect);
563  }
564 
565  m_currentStep++;
566 
567  if (m_verbose)
568  {
569  for (size_t cmp = 0; cmp < m_CmpInfo.size(); cmp++)
570  {
571  CmpInfo& cmpInfo = m_CmpInfo[cmp];
572 
573  print_offset();
574  if(cmp != 0) {UG_LOG(" " );}
575  else {UG_LOG(std::right << std::setw(5) << step() << " ");}
576 
577  UG_LOG(std::scientific << cmpInfo.currDefect << " ");
578  UG_LOG(std::scientific << std::setprecision(3) << cmpInfo.minDefect << " " << std::setprecision(6));
579  if(cmpInfo.lastDefect != 0.0){
580  UG_LOG(std::scientific << std::setprecision(3) << cmpInfo.currDefect / cmpInfo.lastDefect << " "<< std::setprecision(6));
581  } else {
582  UG_LOG(std::scientific << " ----- " << " ");
583  }
584  if(cmpInfo.initDefect != 0.0){
585  UG_LOG(std::scientific << cmpInfo.currDefect / cmpInfo.initDefect << " ");
586  } else {
587  UG_LOG(std::scientific << " -------- " << " ");
588  }
589  UG_LOG(std::scientific << std::setprecision(3) << cmpInfo.relReduction << " " << std::setprecision(6));
590  UG_LOG(std::scientific << cmpInfo.name << "\n");
591  }
592  }
593 }
594 
595 
596 template <class TVector, class TDomain>
598 {
599  if (step() >= m_maxSteps) return true;
600 
601  bool ended = true;
602  for (size_t cmp = 0; cmp < m_CmpInfo.size(); cmp++)
603  {
604  CmpInfo& cmpInfo = m_CmpInfo[cmp];
605 
606  if (!is_valid_number(cmpInfo.currDefect)) return true;
607 
608  bool cmpFinished = false;
609  if(cmpInfo.currDefect < cmpInfo.minDefect) cmpFinished = true;
610  if(cmpInfo.initDefect != 0.0)
611  if((cmpInfo.currDefect/cmpInfo.initDefect) < cmpInfo.relReduction)
612  cmpFinished = true;
613 
614  ended = ended && cmpFinished;
615  }
616 
617  return ended;
618 }
619 
620 
621 template <class TVector, class TDomain>
623 {
624  if (m_bTimeMeas) m_stopwatch.stop();
625 
626  bool success = true;
627 
628  if (step() > m_maxSteps){
629  print_offset();
630  UG_LOG("Maximum numbers of "<< m_maxSteps <<
631  " iterations reached without convergence.\n");
632  success = false;
633  }
634 
635  for (size_t cmp = 0; cmp < m_CmpInfo.size(); cmp++)
636  {
637  CmpInfo& cmpInfo = m_CmpInfo[cmp];
638 
639  if (!is_valid_number(cmpInfo.currDefect))
640  {
641  success = false;
642  if (m_verbose)
643  {
644  print_offset();
645  UG_LOG("Current defect for '" << cmpInfo.name <<
646  "' is not a valid number.\n");
647  }
648  }
649 
650  bool cmpFinished = false;
651  if (cmpInfo.currDefect < cmpInfo.minDefect)
652  {
653  if (m_verbose)
654  {
655  print_offset();
656  UG_LOG("Absolute defect of " << cmpInfo.minDefect << " for '"
657  << cmpInfo.name << "' reached after " << step() << " steps.\n");
658  }
659  cmpFinished = true;
660  }
661 
662  if (cmpInfo.initDefect != 0.0)
663  {
664  if (cmpInfo.currDefect/cmpInfo.initDefect < cmpInfo.relReduction)
665  {
666  if (m_verbose)
667  {
668  print_offset();
669  UG_LOG("Relative reduction of " << cmpInfo.relReduction << " for '"
670  << cmpInfo.name << "' reached after " << step() << " steps.\n");
671  }
672  cmpFinished = true;
673  }
674  }
675 
676  if (!cmpFinished) success = false;
677  }
678 
679  if (m_verbose)
680  {
681  print_offset();
682  UG_LOG(repeat(m_symbol, 5));
683  std::stringstream tmsg;
684  if (m_bTimeMeas)
685  {
686  number time = m_stopwatch.ms()/1000.0;
687  tmsg << " (t: " << std::setprecision(3) << time << "s; t/it: "
688  << time / step() << "s)";
689  }
690  if (success) {UG_LOG(" Iteration converged" << tmsg.str() << " ");}
691  else {UG_LOG(" Iteration not successful" << tmsg.str() << " ");}
692  UG_LOG(repeat(m_symbol, 5));
693  UG_LOG("\n\n");
694  }
695 
696  return success || m_supress_unsuccessful;
697 }
698 
699 
700 template <class TVector, class TDomain>
702 {
703  // step 1: whitespace
704  UG_LOG(repeat(' ', m_offset));
705 
706  // step 2: print style character
707  UG_LOG(m_symbol << " ");
708 }
709 
710 template <class TVector, class TDomain>
712 {
713  print_offset();
714  UG_LOG(line << "\n");
715 }
716 
717 
718 template <class TVector, class TDomain>
720 {
721  if (value == 0.0) return true;
722  else return (value >= std::numeric_limits<number>::min()
723  && value <= std::numeric_limits<number>::max()
724  && value == value && value >= 0.0);
725 }
726 
727 } // end namespace ug
728 
729 
730 #endif /* __H__LIB_DISC__OPERATOR__COMPOSITE_CONVERGENCE_CHECK_IMPL__ */
731 
location name
Definition: checkpoint_util.lua:128
Definition: smart_pointer.h:296
Definition: smart_pointer.h:108
Definition: pcl_process_communicator.h:70
void allreduce(const void *sendBuf, void *recBuf, int count, DataType type, ReduceOperation op) const
performs MPI_Allreduce on the processes of the communicator.
Definition: pcl_process_communicator.cpp:318
base class for approximation spaces without type of algebra or dof distribution
Definition: approximation_space.h:279
Definition: composite_conv_check.h:67
void set_group_check(const std::vector< std::string > &vFctName, const number minDefect, const number relReduction)
Definition: composite_conv_check_impl.h:300
void set_level(int level)
set level of grid, where defect vectors come from
Definition: composite_conv_check_impl.h:74
CompositeConvCheck(SmartPtr< ApproximationSpace< TDomain > > approx)
Definition: composite_conv_check_impl.h:48
void start(const TVector &d)
computes the start defect and set it
Definition: composite_conv_check_impl.h:428
void print_offset()
Definition: composite_conv_check_impl.h:701
bool is_valid_number(number value)
Definition: composite_conv_check_impl.h:719
void set_component_check(const std::string &vFctName, const std::vector< number > &vMinDefect, const std::vector< number > &vRelReduction)
Definition: composite_conv_check_impl.h:225
void print_line(std::string line)
prints a line using prefixes
Definition: composite_conv_check_impl.h:711
void extract_dof_indices(ConstSmartPtr< DoFDistribution > dd)
extracts multi-indices for a fct-comp on a element type
Definition: composite_conv_check_impl.h:86
void update_rest_check()
Definition: composite_conv_check_impl.h:362
number norm(const TVector &vec, const std::vector< DoFIndex > &index)
calculates the 2-norm of the entries of the vector vec specified by index
Definition: composite_conv_check_impl.h:153
void update(const TVector &d)
computes the defect and sets it a the next defect value
Definition: composite_conv_check_impl.h:536
void update_defect(number newDefect)
sets the update for the current defect
Definition: composite_conv_check_impl.h:526
bool iteration_ended()
Definition: composite_conv_check_impl.h:597
virtual SmartPtr< IConvergenceCheck< TVector > > clone()
clones this instance
Definition: composite_conv_check_impl.h:199
void start_defect(number initialDefect)
defect control
Definition: composite_conv_check_impl.h:404
void set_all_component_check(const number minDefect, const number relReduction)
sets check for all components in approximation space
Definition: composite_conv_check_impl.h:245
bool post()
Definition: composite_conv_check_impl.h:622
Definition: grid_level.h:42
@ TOP
Definition: grid_level.h:45
@ SURFACE
Definition: grid_level.h:48
Definition: multi_grid.h:72
TChild * get_child(TElem *elem, size_t ind) const
returns the i-th child of the given child-type
Definition: multi_grid.h:268
size_t num_children(TElem *elem) const
returns the number of children of the given child-type
Definition: multi_grid.h:225
Const iterator to traverse the surface of a multi-grid hierarchy.
Definition: surface_view.h:237
Represents the surface view of a multi-grid hierarchy.
Definition: surface_view.h:61
bool is_contained(TGeomObj *obj, const GridLevel &gl, SurfaceState validStates=ALL) const
returns if the element is contained in the surface view
Definition: surface_view_impl.hpp:442
@ SURFACE_RIM
Definition: surface_view.h:94
@ ALL
Definition: surface_view.h:102
@ SHADOW_RIM_COPY
Definition: surface_view.h:95
@ PST_UNIQUE
Definition: parallel_storage_type.h:70
#define PCL_RO_SUM
Definition: pcl_methods.h:63
base_type::TBaseElem TBaseElem
string repeat(char c, int nr)
Builds a string with specified repetitions of given character.
Definition: string_util.cpp:346
#define UG_THROW(msg)
Definition: error.h:57
#define UG_LOG(msg)
Definition: log.h:367
double number
Definition: types.h:124
Definition: boost_serialization_routines.h:49
the ug namespace
number & DoFRef(TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
Definition: multi_index.h:276
void TokenizeTrimString(const string &str, vector< string > &vToken, const char delimiter)
Definition: string_util.cpp:83
string TrimString(const string &str)
Definition: string_util.cpp:104
@ VOLUME
Definition: grid_base_objects.h:63
@ VERTEX
Definition: grid_base_objects.h:60
@ EDGE
Definition: grid_base_objects.h:61
@ FACE
Definition: grid_base_objects.h:62
Definition: composite_conv_check.h:238
number relReduction
Relative reduction required for component.
Definition: composite_conv_check.h:249
std::vector< int > vFct
Index of components.
Definition: composite_conv_check.h:241
number currDefect
Current Defect of component.
Definition: composite_conv_check.h:245
std::string name
Name of components.
Definition: composite_conv_check.h:242
number initDefect
Initial Defect of component.
Definition: composite_conv_check.h:244
number minDefect
Minimal required Defect of component.
Definition: composite_conv_check.h:248
number lastDefect
Last Defect if component.
Definition: composite_conv_check.h:246
Definition: composite_conv_check_impl.h:415
static const size_t block_size
Definition: composite_conv_check_impl.h:416