ug4
line_smoothers.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2015: G-CSC, Goethe University Frankfurt
3  * Author: Christian Wehner
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 /*
34  * Gauss-Seidel type smoothers using alternating directions
35  * for handling of anisotropic problems
36  * Steps forward and backward in all coordinate directions
37  */
38 
39 #ifndef __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__LINE_SMOOTHERS__
40 #define __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__LINE_SMOOTHERS__
41 
44 
48 //#include "lib_disc/dof_manager/ordering/lexorder.h"
53 #ifdef UG_PARALLEL
56 #endif
57 
58 namespace ug{
59 
60 // extern definition (in cpp file, avoiding conflicts)
61 template<int dim>
62 extern bool ComparePosDimYDir(const std::pair<MathVector<dim>, size_t> &p1,
63  const std::pair<MathVector<dim>, size_t> &p2);
64 
65 template<int dim>
66 extern bool ComparePosDimZDir(const std::pair<MathVector<dim>, size_t> &p1,
67  const std::pair<MathVector<dim>, size_t> &p2);
68 
69 
70 // ORDER IN Y DIRECTION
71 
72 template<int dim>
73 void ComputeDirectionYOrder(std::vector<std::pair<MathVector<dim>, size_t> >& vPos,std::vector<size_t>& indY)
74 {
75  indY.resize(indY.size()+vPos.size());
76  // sort indices based on their position
77  std::sort(vPos.begin(), vPos.end(), ComparePosDimYDir<dim>);
78  // write mapping
79  for (size_t i=0; i < vPos.size(); ++i){
80  indY[i] = vPos[i].second;
81  };
82 }
83 
84 template <typename TDomain>
86  ConstSmartPtr<TDomain> domain,std::vector<size_t>& indY)
87 {
88  // Lex Ordering is only possible in this cases:
89  // b) Same number of DoFs on each geometric object (or no DoFs on object)
90  // --> in this case we can order all dofs
91  // a) different trial spaces, but DoFs for each trial spaces only on separate
92  // geometric objects. (e.g. one space only vertices, one space only on edges)
93  // --> in this case we can order all geometric objects separately
94 
95  // a) check for same number of DoFs on every geometric object
96  bool bEqualNumDoFOnEachGeomObj = true;
97  int numDoFOnGeomObj = -1;
98  for(int si = 0; si < dd->num_subsets(); ++si){
99  for(int roid = 0; roid < NUM_REFERENCE_OBJECTS; ++roid){
100  const int numDoF = dd->num_dofs((ReferenceObjectID)roid, si);
101 
102  if(numDoF == 0) continue;
103 
104  if(numDoFOnGeomObj == -1){
105  numDoFOnGeomObj = numDoF;
106  }
107  else{
108  if(numDoFOnGeomObj != numDoF)
109  bEqualNumDoFOnEachGeomObj = false;
110  }
111  }
112  }
113 
114  // b) check for non-mixed spaces
115  std::vector<bool> bSingleSpaceUsage(NUM_REFERENCE_OBJECTS, true);
116  std::vector<bool> vHasDoFs(NUM_REFERENCE_OBJECTS, false);
117  for(size_t fct = 0; fct < dd->num_fct(); ++fct){
118 
119  LFEID lfeID = dd->local_finite_element_id(fct);
121 
122  for(int roid = 0; roid < NUM_REFERENCE_OBJECTS; ++roid){
123  const int numDoF = locDoF.num_dof((ReferenceObjectID)roid);
124 
125  if(numDoF <= 0) continue;
126 
127  if(vHasDoFs[roid] == false){
128  vHasDoFs[roid] = true;
129  }
130  else{
131  bSingleSpaceUsage[roid] = false;
132  }
133  }
134  }
135  std::vector<bool> bSortableComp(dd->num_fct(), true);
136  for(size_t fct = 0; fct < dd->num_fct(); ++fct){
137 
138  LFEID lfeID = dd->local_finite_element_id(fct);
140 
141  for(int roid = 0; roid < NUM_REFERENCE_OBJECTS; ++roid){
142  if(locDoF.num_dof((ReferenceObjectID)roid) != 0){
143  if(bSingleSpaceUsage[roid] == false)
144  bSortableComp[fct] = false;
145  }
146  }
147  }
148 
149  // get position attachment
150  typedef typename std::pair<MathVector<TDomain::dim>, size_t> pos_type;
151 
152  // get positions of indices
153  std::vector<pos_type> vPositions;
154 
155  // a) we can order globally
156  if(bEqualNumDoFOnEachGeomObj)
157  {
158  ExtractPositions(domain, dd, vPositions);
159 
160  ComputeDirectionYOrder<TDomain::dim>(vPositions, indY);
161  }
162  // b) we can only order some spaces
163  else
164  {
165 // UG_LOG("OrderLex: Cannot order globally, trying to order some components:\n");
166  for(size_t fct = 0; fct < dd->num_fct(); ++fct){
167  if(bSortableComp[fct] == false){
168 // UG_LOG("OrderLex: "<<dd->name(fct)<<" NOT SORTED.\n");
169  continue;
170  }
171 
172  ExtractPositions(domain, dd, fct, vPositions);
173 
174  ComputeDirectionYOrder<TDomain::dim>(vPositions, indY);
175  }
176  }
177 };
178 
179 
180 // ORDER IN Z DIRECTION
181 
182 
183 template<int dim>
184 void ComputeDirectionZOrder(std::vector<std::pair<MathVector<dim>, size_t> >& vPos,std::vector<size_t>& indZ)
185 {
186  indZ.resize(indZ.size()+vPos.size());
187  std::sort(vPos.begin(), vPos.end(), ComparePosDimZDir<dim>);
188  for (size_t i=0; i < vPos.size(); ++i){
189  indZ[i] = vPos[i].second;
190  };
191 }
192 
193 template <typename TDomain>
195  ConstSmartPtr<TDomain> domain,std::vector<size_t>& indZ)
196 {
197  // Lex Ordering is only possible in this cases:
198  // b) Same number of DoFs on each geometric object (or no DoFs on object)
199  // --> in this case we can order all dofs
200  // a) different trial spaces, but DoFs for each trial spaces only on separate
201  // geometric objects. (e.g. one space only vertices, one space only on edges)
202  // --> in this case we can order all geometric objects separately
203 
204  // a) check for same number of DoFs on every geometric object
205  bool bEqualNumDoFOnEachGeomObj = true;
206  int numDoFOnGeomObj = -1;
207  for(int si = 0; si < dd->num_subsets(); ++si){
208  for(int roid = 0; roid < NUM_REFERENCE_OBJECTS; ++roid){
209  const int numDoF = dd->num_dofs((ReferenceObjectID)roid, si);
210 
211  if(numDoF == 0) continue;
212 
213  if(numDoFOnGeomObj == -1){
214  numDoFOnGeomObj = numDoF;
215  }
216  else{
217  if(numDoFOnGeomObj != numDoF)
218  bEqualNumDoFOnEachGeomObj = false;
219  }
220  }
221  }
222 
223  // b) check for non-mixed spaces
224  std::vector<bool> bSingleSpaceUsage(NUM_REFERENCE_OBJECTS, true);
225  std::vector<bool> vHasDoFs(NUM_REFERENCE_OBJECTS, false);
226  for(size_t fct = 0; fct < dd->num_fct(); ++fct){
227 
228  LFEID lfeID = dd->local_finite_element_id(fct);
230 
231  for(int roid = 0; roid < NUM_REFERENCE_OBJECTS; ++roid){
232  const int numDoF = locDoF.num_dof((ReferenceObjectID)roid);
233 
234  if(numDoF <= 0) continue;
235 
236  if(vHasDoFs[roid] == false){
237  vHasDoFs[roid] = true;
238  }
239  else{
240  bSingleSpaceUsage[roid] = false;
241  }
242  }
243  }
244  std::vector<bool> bSortableComp(dd->num_fct(), true);
245  for(size_t fct = 0; fct < dd->num_fct(); ++fct){
246 
247  LFEID lfeID = dd->local_finite_element_id(fct);
249 
250  for(int roid = 0; roid < NUM_REFERENCE_OBJECTS; ++roid){
251  if(locDoF.num_dof((ReferenceObjectID)roid) != 0){
252  if(bSingleSpaceUsage[roid] == false)
253  bSortableComp[fct] = false;
254  }
255  }
256  }
257 
258  // get position attachment
259  typedef typename std::pair<MathVector<TDomain::dim>, size_t> pos_type;
260 
261  // get positions of indices
262  std::vector<pos_type> vPositions;
263 
264  // a) we can order globally
265  if(bEqualNumDoFOnEachGeomObj)
266  {
267  ExtractPositions(domain, dd, vPositions);
268 
269  // get mapping: old -> new index
270  ComputeDirectionZOrder<TDomain::dim>(vPositions, indZ);
271  }
272  // b) we can only order some spaces
273  else
274  {
275 // UG_LOG("OrderLex: Cannot order globally, trying to order some components:\n");
276  for(size_t fct = 0; fct < dd->num_fct(); ++fct){
277  if(bSortableComp[fct] == false){
278  // UG_LOG("OrderLex: "<<dd->name(fct)<<" NOT SORTED.\n");
279  continue;
280  }
281 
282  ExtractPositions(domain, dd, fct, vPositions);
283 
284  // get mapping: old -> new index
285  ComputeDirectionZOrder<TDomain::dim>(vPositions, indZ);
286  }
287  }
288 };
289 
290 
291 template <typename TDomain, typename TBaseElem>
294  std::vector<size_t>& indarray,number alpha){
296 // vector for positions
297  std::vector<MathVector<TDomain::dim> > vElemPos;
298 
299 // algebra indices vector
300  std::vector<DoFIndex> ind;
301 
302  const typename TDomain::position_accessor_type& aaPos = domain->position_accessor();
303 
304 // loop all subsets
305  for(int si = 0; si < dd->num_subsets(); ++si)
306  {
307  // get iterators
308  iter = dd->template begin<TBaseElem>(si);
309  iterEnd = dd->template end<TBaseElem>(si);
310 
311  // loop all elements
312  for(;iter != iterEnd; ++iter)
313  {
314  // get vertex
315  TBaseElem* elem = *iter;
316 
317  // loop all functions
318  for(size_t fct = 0; fct < dd->num_fct(); ++fct)
319  {
320  // skip non-used function
321  if(!dd->is_def_in_subset(fct,si)) continue;
322  std::vector<Edge*> vEdge;
323  CollectEdgesSorted(vEdge, domain->grid, elem);
324  std::vector<number> edgeLength(vEdge.size());
325  std::vector<DoFIndex> ind;
326  MathVector<TDomain::dim> vCoord[2];
327  for (size_t i=0;i<vEdge.size();i++){
328  for (size_t j=0;j<2;j++) vCoord[i] = aaPos[vEdge[i]->vertex(i)];
329  edgeLength[i] = VecDistance(vCoord[0],vCoord[1]);
330  };
331  number minedgelength=edgeLength[0];
332  number maxedgelength=edgeLength[1];
333  for (size_t i=1;i<vEdge.size();i++){
334  if (edgeLength[i]<minedgelength) minedgelength=edgeLength[i];
335  if (edgeLength[i]>maxedgelength) maxedgelength=edgeLength[i];
336  };
337  if (maxedgelength/minedgelength>alpha){
338  // load indices associated with element function
339  dd->inner_dof_indices(elem, fct, ind);
340 
341  // load positions associated with element and function
342  InnerDoFPosition(vElemPos, elem, *(const_cast<TDomain*>(domain.get())),
343  dd->local_finite_element_id(fct));
344 
345  // check correct size
346  UG_ASSERT(ind.size() == vElemPos.size(), "Num MultiIndex ("<<ind.size()
347  <<") and Num Position ("<<vElemPos.size()<<") must match."
348  "GeomObject dim="<<geometry_traits<TBaseElem>::BASE_OBJECT_ID);
349 
350  // write position
351  for(size_t sh = 0; sh < ind.size(); ++sh)
352  {
353  const size_t index = ind[sh][0];
354  indarray.push_back(index);
355  }
356  };
357  };
358  };
359  };
360 };
361 
362 
363 
364 template <typename TDomain,typename TAlgebra>
365 class LineGaussSeidel : public IPreconditioner<TAlgebra>
366 {
367  public:
369  typedef TDomain domain_type;
370 
371  // Algebra type
372  typedef TAlgebra algebra_type;
373 
374  // Vector type
375  typedef typename TAlgebra::vector_type vector_type;
376 
377  // Matrix type
378  typedef typename TAlgebra::matrix_type matrix_type;
379 
382 
385 
386  protected:
387  using base_type::set_debug;
390 
391  protected:
392  // approximation space for level and surface grid
394 
395  // index sets
396  std::vector<size_t> indY;
397  std::vector<size_t> indZ;
398  size_t m_ind_end;
399 
406 
408  static const int dim = domain_type::dim;
409 
410  bool m_init;
411 
412  public:
413  // Constructor
415  m_spApproxSpace = approxSpace;
416  m_init = false;
417  m_nr_forwardx=1;
418  m_nr_backwardx=1;
419  m_nr_forwardy=1;
420  m_nr_backwardy=1;
421  m_nr_forwardz=1;
422  m_nr_backwardz=1;
423  OrderLex<TDomain>(*m_spApproxSpace,"lr");
424  };
425 
426  // Update ordering indices
427  bool update(size_t xsize){
428  indY.resize(0);
429  indZ.resize(0);
430  // lexicographic ordering of unknowns
432 // OrderLex<TDomain>(*m_spApproxSpace,"lr");
433  }
435  size_t level=3289578756;
436  for (size_t i=0;i<m_spApproxSpace->num_levels();i++){
437  if (m_spApproxSpace->dof_distribution(GridLevel(i, GridLevel::LEVEL, true))->num_indices()==xsize){
438  level = i;
439  break;
440  };
441  };
442  if (level==3289578756){
443  return false;
444  }
445  if ((dim>1)&&(m_nr_forwardy+m_nr_backwardy>0)){
446  OrderDirectionYForDofDist<TDomain>(m_spApproxSpace->dof_distribution(GridLevel(level, GridLevel::LEVEL, true)), m_spApproxSpace->domain(),indY);
447  }
448  if ((dim>2)&&(m_nr_forwardz+m_nr_backwardz>0)){
449  OrderDirectionZForDofDist<TDomain>(m_spApproxSpace->dof_distribution(GridLevel(level, GridLevel::LEVEL, true)), m_spApproxSpace->domain(),indZ);
450  }
451  };
452  m_ind_end = indY.size();
453  m_init = true;
454  return true;
455  }
456 
457  // Destructor
459  indY.clear();
460  indZ.clear();
461  };
462 
463  void set_num_steps(size_t forwardx,size_t backwardx,size_t forwardy,size_t backwardy,size_t forwardz,size_t backwardz){
464  m_nr_forwardx=forwardx;
465  m_nr_backwardx=backwardx;
466  m_nr_forwardy=forwardy;
467  m_nr_backwardy=backwardy;
468  m_nr_forwardz=forwardz;
469  m_nr_backwardz=backwardz;
470  };
471 
472  void set_num_steps(size_t forwardx,size_t backwardx,size_t forwardy,size_t backwardy){
473  m_nr_forwardx=forwardx;
474  m_nr_backwardx=backwardx;
475  m_nr_forwardy=forwardy;
476  m_nr_backwardy=backwardy;
477  m_nr_forwardz=0;
478  m_nr_backwardz=0;
479  };
480 
481  void set_num_steps(size_t forwardx,size_t backwardx){
482  m_nr_forwardx=forwardx;
483  m_nr_backwardx=backwardx;
484  m_nr_forwardy=0;
485  m_nr_backwardy=0;
486  m_nr_forwardz=0;
487  m_nr_backwardz=0;
488  };
489 
490  // Clone
492  {
494  newInst->set_debug(debug_writer());
495  newInst->set_damp(this->damping());
496  newInst->set_num_steps(this->get_num_forwardx(),this->get_num_backwardx(),this->get_num_forwardy(),this->get_num_backwardy(),
497  this->get_num_forwardz(),this->get_num_backwardz());
498  return newInst;
499  }
500 
502  virtual bool supports_parallel() const {return true;}
503 
504  public:
505  size_t get_num_forwardx(){return m_nr_forwardx;}
507  size_t get_num_forwardy(){return m_nr_forwardy;}
509  size_t get_num_forwardz(){return m_nr_forwardz;}
511 
512  protected:
513  // Name of preconditioner
514  virtual const char* name() const {return "Line Gauss-Seidel";}
515 
516  // Preprocess routine
518  {
519 #ifdef UG_PARALLEL
520  if(pcl::NumProcs() > 1)
521  {
522  // copy original matrix
523  MakeConsistent(*pOp, m_A);
524  // set zero on slaves
525  std::vector<IndexLayout::Element> vIndex;
526  CollectUniqueElements(vIndex, m_A.layouts()->slave());
527  SetDirichletRow(m_A, vIndex);
528  }
529 #endif
530  return true;
531  }
532 
533  // Postprocess routine
534  virtual bool postprocess() {return true;}
535 
536  // Stepping routine
538  {
539 #ifdef UG_PARALLEL
540  if(pcl::NumProcs() > 1)
541  {
542  // make defect unique
543  // todo: change that copying
544  vector_type dhelp;
545  dhelp.resize(d.size()); dhelp = d;
546  dhelp.change_storage_type(PST_UNIQUE);
547  if (!linegs_step(m_A, c, dhelp)) return false;
548 // if(!gs_step_LL(m_A, c, dhelp)) return false;
549  c.set_storage_type(PST_UNIQUE);
550  return true;
551  }
552  else
553 #endif
554  {
555  if(!linegs_step(*pOp, c, d)) return false;
556  // if(!gs_step_LL(mat, c, d)) return false;
557 #ifdef UG_PARALLEL
558  c.set_storage_type(PST_UNIQUE);
559 #endif
560  return true;
561  }
562  }
563 
564  protected:
565 #ifdef UG_PARALLEL
567 #endif
568 
569  bool linegs_step(const matrix_type &A, vector_type &x, const vector_type &b)
570  {
571  // gs LL has preconditioning matrix
572  // (D-L)^{-1}
573  if (m_init==false) update(x.size());
574 
575  size_t i;
576 
577  typename vector_type::value_type s;
578 
579  // forward in x direction
580  if (m_nr_forwardx>0){
581 
582  for(i=0; i < x.size(); i++)
583  {
584  s = b[i];
585 
586  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i) && it.index() < i; ++it)
587  // s -= it.value() * x[it.index()];
588  MatMultAdd(s, 1.0, s, -1.0, it.value(), x[it.index()]);
589 
590  // x[i] = s/A(i,i)
591  InverseMatMult(x[i], 1.0, A(i,i), s);
592  }
593  for (size_t count=1;count<m_nr_forwardx;count++){
594  for(i=0; i < x.size(); i++)
595  {
596  s = b[i];
597  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i); ++it){
598  if (it.index()==i) continue;
599  // s -= it.value() * x[it.index()];
600  MatMultAdd(s, 1.0, s, -1.0, it.value(), x[it.index()]);
601  }
602  // x[i] = s/A(i,i)
603  InverseMatMult(x[i], 1.0, A(i,i), s);
604  }
605  };
606  };
607 
608  // backward in x direction
609  for (size_t count=0;count<m_nr_backwardx;count++){
610  for (i=x.size()-1; (int)i>= 0; i--)
611  {
612  s = b[i];
613 
614  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i); ++it){
615  if (it.index()==i) continue;
616  // s -= it.value() * x[it.index()];
617  MatMultAdd(s, 1.0, s, -1.0, it.value(), x[it.index()]);
618  }
619  // x[i] = s/A(i,i)
620  InverseMatMult(x[i], 1.0, A(i,i), s);
621  if (i==0) break;
622  };
623  };
624 
625  if (dim==1) return true;
626 
628 
629  // forward in y direction
630  for (size_t count=0;count<m_nr_forwardy;count++){
631  for (size_t j=0;j < m_ind_end; j++){
632  i = indY[j];
633 
634  s = b[i];
635 
636  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i); ++it){
637  if (it.index()==i) continue;
638  // s -= it.value() * x[it.index()];
639  MatMultAdd(s, 1.0, s, -1.0, it.value(), x[it.index()]);
640  }
641  // x[i] = s/A(i,i)
642  InverseMatMult(x[i], 1.0, A(i,i), s);
643  }
644  };
645 
646  // backward in y direction
647  for (size_t count=0;count<m_nr_backwardy;count++){
648  for (size_t j=m_ind_end-1;(int)j >= 0; j--){
649  i = indY[j];
650 
651  s = b[i];
652 
653  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i); ++it){
654  if (it.index()==i) continue;
655  // s -= it.value() * x[it.index()];
656  MatMultAdd(s, 1.0, s, -1.0, it.value(), x[it.index()]);
657  }
658  // x[i] = s/A(i,i)
659  InverseMatMult(x[i], 1.0, A(i,i), s);
660  if (j==0) break;
661  }
662  };
663  if (dim==2) return true;
664 
665  // forward in z direction
666  for (size_t count=0;count<m_nr_forwardz;count++){
667  for (size_t j=0;j < m_ind_end; j++){
668  i = indZ[j];
669 
670  s = b[i];
671 
672  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i) ; ++it){
673  if (it.index()==i) continue;
674  // s -= it.value() * x[it.index()];
675  MatMultAdd(s, 1.0, s, -1.0, it.value(), x[it.index()]);
676  };
677  // x[i] = s/A(i,i)
678  InverseMatMult(x[i], 1.0, A(i,i), s);
679  }
680  }
681 
682  // backward in z direction
683  for (size_t count=0;count<m_nr_backwardz;count++){
684  for (size_t j=m_ind_end-1;(int)j >= 0; j--){
685  i = indZ[j];
686 
687  s = b[i];
688 
689  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i) ; ++it){
690  if (it.index()==i) continue;
691  // s -= it.value() * x[it.index()];
692  MatMultAdd(s, 1.0, s, -1.0, it.value(), x[it.index()]);
693  };
694  // x[i] = s/A(i,i)
695  InverseMatMult(x[i], 1.0, A(i,i), s);
696  if (j==0) break;
697  }
698  }
699  return true;
700  }
701 
702 };
703 
704 template <typename TDomain,typename TAlgebra>
705 class LineVanka : public IPreconditioner<TAlgebra>
706 {
707  public:
709  typedef TDomain domain_type;
710 
711  // Algebra type
712  typedef TAlgebra algebra_type;
713 
714  // Vector type
715  typedef typename TAlgebra::vector_type vector_type;
716 
717  // Matrix type
718  typedef typename TAlgebra::matrix_type matrix_type;
719 
722 
725 
726  protected:
727  using base_type::set_debug;
730 
731  protected:
732  // approximation space for level and surface grid
734 
735  // index sets
736  std::vector<size_t> indY;
737  std::vector<size_t> indZ;
738  size_t m_ind_end;
739 
746 
748  static const int dim = domain_type::dim;
749 
750  bool m_init;
751 
752  public:
755  number relax(){return m_relax;};
756 
757  protected:
759 
760  public:
761  // Constructor
763  m_spApproxSpace = approxSpace;
764  m_init = false;
765  m_nr_forwardx=1;
766  m_nr_backwardx=1;
767  m_nr_forwardy=1;
768  m_nr_backwardy=1;
769  m_nr_forwardz=1;
770  m_nr_backwardz=1;
771  m_relax=1;
772 // OrderLex<TDomain>(*m_spApproxSpace,"lr");
773  };
774 
775  // Update ordering indices
776  bool update(size_t xsize){
777  indY.resize(0);
778  indZ.resize(0);
779  // lexicographic ordering of unknowns
781 // OrderLex<TDomain>(*m_spApproxSpace,"lr");
782  }
784  size_t level=3289578756;
785  for (size_t i=0;i<m_spApproxSpace->num_levels();i++){
786  if (m_spApproxSpace->dof_distribution(GridLevel(i, GridLevel::LEVEL, true))->num_indices()==xsize){
787  level = i;
788  break;
789  };
790  };
791  if (level==3289578756){
792  return false;
793  }
794  if ((dim>1)&&(m_nr_forwardy+m_nr_backwardy>0)){
795  OrderDirectionYForDofDist<TDomain>(m_spApproxSpace->dof_distribution(GridLevel(level, GridLevel::LEVEL, true)), m_spApproxSpace->domain(),indY);
796  }
797  if ((dim>2)&&(m_nr_forwardz+m_nr_backwardz>0)){
798  OrderDirectionZForDofDist<TDomain>(m_spApproxSpace->dof_distribution(GridLevel(level, GridLevel::LEVEL, true)), m_spApproxSpace->domain(),indZ);
799  }
800  };
801  m_ind_end = indY.size();
802  m_init = true;
803  return true;
804  }
805 
806  // Destructor
808  indY.clear();
809  indZ.clear();
810  };
811 
812  void set_num_steps(size_t forwardx,size_t backwardx,size_t forwardy,size_t backwardy,size_t forwardz,size_t backwardz){
813  m_nr_forwardx=forwardx;
814  m_nr_backwardx=backwardx;
815  m_nr_forwardy=forwardy;
816  m_nr_backwardy=backwardy;
817  m_nr_forwardz=forwardz;
818  m_nr_backwardz=backwardz;
819  };
820 
821  void set_num_steps(size_t forwardx,size_t backwardx,size_t forwardy,size_t backwardy){
822  m_nr_forwardx=forwardx;
823  m_nr_backwardx=backwardx;
824  m_nr_forwardy=forwardy;
825  m_nr_backwardy=backwardy;
826  m_nr_forwardz=0;
827  m_nr_backwardz=0;
828  };
829 
830  void set_num_steps(size_t forwardx,size_t backwardx){
831  m_nr_forwardx=forwardx;
832  m_nr_backwardx=backwardx;
833  m_nr_forwardy=0;
834  m_nr_backwardy=0;
835  m_nr_forwardz=0;
836  m_nr_backwardz=0;
837  };
838 
839  // Clone
841  {
843  newInst->set_debug(debug_writer());
844  newInst->set_damp(this->damping());
845  newInst->set_num_steps(this->get_num_forwardx(),this->get_num_backwardx(),this->get_num_forwardy(),this->get_num_backwardy(),
846  this->get_num_forwardz(),this->get_num_backwardz());
847  newInst->set_relax(this->relax());
848  return newInst;
849  }
850 
852  virtual bool supports_parallel() const {return true;}
853 
854  public:
855  size_t get_num_forwardx(){return m_nr_forwardx;}
857  size_t get_num_forwardy(){return m_nr_forwardy;}
859  size_t get_num_forwardz(){return m_nr_forwardz;}
861 
862  protected:
863  // Name of preconditioner
864  virtual const char* name() const {return "Line Vanka";}
865 
866  // Preprocess routine
868  {
869 #ifdef UG_PARALLEL
870  if(pcl::NumProcs() > 1)
871  {
872  // copy original matrix
873  MakeConsistent(*pOp, m_A);
874  // set zero on slaves
875  std::vector<IndexLayout::Element> vIndex;
876  CollectUniqueElements(vIndex, m_A.layouts()->slave());
877  SetDirichletRow(m_A, vIndex);
878  }
879 #endif
880  return true;
881  }
882 
883  // Postprocess routine
884  virtual bool postprocess() {return true;}
885 
886  // Stepping routine
888  {
889 #ifdef UG_PARALLEL
890  if(pcl::NumProcs() > 1)
891  {
892  // make defect unique
893  // todo: change that copying
894  vector_type dhelp;
895  dhelp.resize(d.size()); dhelp = d;
896  dhelp.change_storage_type(PST_UNIQUE);
897  if (!linevanka_step(m_A, c, dhelp)) return false;
898 // if(!gs_step_LL(m_A, c, dhelp)) return false;
899  c.set_storage_type(PST_UNIQUE);
900  return true;
901  }
902  else
903 #endif
904  {
905  if(!linevanka_step(*pOp, c, d)) return false;
906  // if(!gs_step_LL(mat, c, d)) return false;
907 #ifdef UG_PARALLEL
908  c.set_storage_type(PST_UNIQUE);
909 #endif
910  return true;
911  }
912  }
913 
914  protected:
915 #ifdef UG_PARALLEL
917 #endif
918 
919  bool linevanka_step(const matrix_type &A, vector_type &x, const vector_type &b)
920  {
924 
925  static const int MAXBLOCKSIZE = 19;
926  size_t blockind[MAXBLOCKSIZE];
927  size_t blocksize;
928  // gs LL has preconditioning matrix
929  // (D-L)^{-1}
930  if (m_init==false) update(x.size());
931 
932  size_t i;
933  size_t nrofelements=0;
934 
935  for(i=0; i < x.size(); i++)
936  {
937  x[i]=0;
938  if (A(i,i)==0) nrofelements++;
939  };
940 
941  // forward in x direction
942  for (size_t count=0;count<m_nr_forwardx;count++){
943  for(i=0; i < x.size(); i++){
944  if (A(i,i)!=0) continue;
945  blocksize=0;
946  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i) ; ++it){
947  blockind[blocksize] = it.index();
948  x[it.index()] = 0;
949  blocksize++;
950  };
951  mat.resize(blocksize,blocksize);
952  s.resize(blocksize);
953  localx.resize(blocksize);
954  for (size_t j=0;j<blocksize;j++){
955  // fill local block matrix
956  for (size_t k=0;k<blocksize;k++){
957  mat.subassign(j,k,A(blockind[j],blockind[k]));
958  };
959  // compute rhs
960  typename vector_type::value_type sj = b[blockind[j]];
961  for(typename matrix_type::const_row_iterator it = A.begin_row(blockind[j]); it != A.end_row(blockind[j]) ; ++it){
962  MatMultAdd(sj, 1.0, sj, -1.0, it.value(), x[it.index()]);
963  };
964  s.subassign(j,sj);
965  };
966  // solve block
967  InverseMatMult(localx,1,mat,s);
968  for (size_t j=0;j<blocksize;j++){
969  x[blockind[j]] = m_relax*localx[j];
970  };
971  };
972  };
973  // backward in x direction
974  for (size_t count=0;count<m_nr_backwardx;count++){
975  for (i=x.size()-1;(int)i>= 0; i--)
976  {
977  if (A(i,i)==0){
978  blocksize=0;
979  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i) ; ++it){
980  blockind[blocksize] = it.index();
981  x[it.index()] = 0;
982  blocksize++;
983  };
984  mat.resize(blocksize,blocksize);
985  s.resize(blocksize);
986  localx.resize(blocksize);
987  for (size_t j=0;j<blocksize;j++){
988  // fill local block matrix
989  for (size_t k=0;k<blocksize;k++){
990  mat.subassign(j,k,A(blockind[j],blockind[k]));
991  };
992  // compute rhs
993  typename vector_type::value_type sj = b[blockind[j]];
994  for(typename matrix_type::const_row_iterator it = A.begin_row(blockind[j]); it != A.end_row(blockind[j]) ; ++it){
995  MatMultAdd(sj, 1.0, sj, -1.0, it.value(), x[it.index()]);
996  };
997  s.subassign(j,sj);
998  };
999  // solve block
1000  InverseMatMult(localx,1,mat,s);
1001  for (size_t j=0;j<blocksize;j++){
1002  x[blockind[j]] = m_relax*localx[j];
1003  };
1004  };
1005  if (i==0) break;
1006  };
1007  };
1008 
1009  if (dim==1) return true;
1010 
1012 
1013  // forward in y direction
1014  for (size_t count=0;count<m_nr_forwardy;count++){
1015  for (size_t sortedi=0;sortedi < m_ind_end; sortedi++){
1016  i = indY[sortedi];
1017  blocksize=0;
1018  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i) ; ++it){
1019  blockind[blocksize] = it.index();
1020  x[it.index()] = 0;
1021  blocksize++;
1022  };
1023  mat.resize(blocksize,blocksize);
1024  s.resize(blocksize);
1025  localx.resize(blocksize);
1026  for (size_t j=0;j<blocksize;j++){
1027  // fill local block matrix
1028  for (size_t k=0;k<blocksize;k++){
1029  mat.subassign(j,k,A(blockind[j],blockind[k]));
1030  };
1031  // compute rhs
1032  typename vector_type::value_type sj = b[blockind[j]];
1033  for(typename matrix_type::const_row_iterator it = A.begin_row(blockind[j]); it != A.end_row(blockind[j]) ; ++it){
1034  MatMultAdd(sj, 1.0, sj, -1.0, it.value(), x[it.index()]);
1035  };
1036  s.subassign(j,sj);
1037  };
1038  // solve block
1039  InverseMatMult(localx,1,mat,s);
1040  for (size_t j=0;j<blocksize;j++){
1041  x[blockind[j]] = m_relax*localx[j];
1042  };
1043  }
1044  };
1045 
1046  // backward in y direction
1047  for (size_t count=0;count<m_nr_backwardy;count++){
1048  for (size_t sortedi=m_ind_end-1;(int)sortedi >= 0; sortedi--){
1049  i = indY[sortedi];
1050  blocksize=0;
1051  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i) ; ++it){
1052  blockind[blocksize] = it.index();
1053  x[it.index()] = 0;
1054  blocksize++;
1055  };
1056  mat.resize(blocksize,blocksize);
1057  s.resize(blocksize);
1058  localx.resize(blocksize);
1059  for (size_t j=0;j<blocksize;j++){
1060  // fill local block matrix
1061  for (size_t k=0;k<blocksize;k++){
1062  mat.subassign(j,k,A(blockind[j],blockind[k]));
1063  };
1064  // compute rhs
1065  typename vector_type::value_type sj = b[blockind[j]];
1066  for(typename matrix_type::const_row_iterator it = A.begin_row(blockind[j]); it != A.end_row(blockind[j]) ; ++it){
1067  MatMultAdd(sj, 1.0, sj, -1.0, it.value(), x[it.index()]);
1068  };
1069  s.subassign(j,sj);
1070  };
1071  // solve block
1072  InverseMatMult(localx,1,mat,s);
1073  for (size_t j=0;j<blocksize;j++){
1074  x[blockind[j]] = m_relax*localx[j];
1075  };
1076  if (sortedi==0) break;
1077  }
1078  };
1079  if (dim==2) return true;
1080 
1081  // forward in z direction
1082  for (size_t count=0;count<m_nr_forwardz;count++){
1083  for (size_t sortedi=0;sortedi < m_ind_end; sortedi++){
1084  i = indZ[sortedi];
1085  blocksize=0;
1086  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i) ; ++it){
1087  blockind[blocksize] = it.index();
1088  x[it.index()] = 0;
1089  blocksize++;
1090  };
1091  mat.resize(blocksize,blocksize);
1092  s.resize(blocksize);
1093  localx.resize(blocksize);
1094  for (size_t j=0;j<blocksize;j++){
1095  // fill local block matrix
1096  for (size_t k=0;k<blocksize;k++){
1097  mat.subassign(j,k,A(blockind[j],blockind[k]));
1098  };
1099  // compute rhs
1100  typename vector_type::value_type sj = b[blockind[j]];
1101  for(typename matrix_type::const_row_iterator it = A.begin_row(blockind[j]); it != A.end_row(blockind[j]) ; ++it){
1102  MatMultAdd(sj, 1.0, sj, -1.0, it.value(), x[it.index()]);
1103  };
1104  s.subassign(j,sj);
1105  };
1106  // solve block
1107  InverseMatMult(localx,1,mat,s);
1108  for (size_t j=0;j<blocksize;j++){
1109  x[blockind[j]] = m_relax*localx[j];
1110  };
1111  }
1112  }
1113 
1114  // backward in z direction
1115  for (size_t count=0;count<m_nr_backwardz;count++){
1116  for (size_t sortedi=m_ind_end-1;(int)sortedi >= 0; sortedi--){
1117  i = indZ[sortedi];
1118  blocksize=0;
1119  for(typename matrix_type::const_row_iterator it = A.begin_row(i); it != A.end_row(i) ; ++it){
1120  blockind[blocksize] = it.index();
1121  x[it.index()] = 0;
1122  blocksize++;
1123  };
1124  mat.resize(blocksize,blocksize);
1125  s.resize(blocksize);
1126  localx.resize(blocksize);
1127  for (size_t j=0;j<blocksize;j++){
1128  // fill local block matrix
1129  for (size_t k=0;k<blocksize;k++){
1130  mat.subassign(j,k,A(blockind[j],blockind[k]));
1131  };
1132  // compute rhs
1133  typename vector_type::value_type sj = b[blockind[j]];
1134  for(typename matrix_type::const_row_iterator it = A.begin_row(blockind[j]); it != A.end_row(blockind[j]) ; ++it){
1135  MatMultAdd(sj, 1.0, sj, -1.0, it.value(), x[it.index()]);
1136  };
1137  s.subassign(j,sj);
1138  };
1139  // solve block
1140  InverseMatMult(localx,1,mat,s);
1141  for (size_t j=0;j<blocksize;j++){
1142  x[blockind[j]] = m_relax*localx[j];
1143  };
1144  if (sortedi==0) break;
1145  }
1146  }
1147  return true;
1148  }
1149 
1150 };
1151 
1152 } // end namespace ug
1153 
1154 #endif // __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__LINE_SMOOTHERS__
parameterString s
const T * get() const
Definition: smart_pointer.h:409
Definition: smart_pointer.h:108
base class for approximation spaces without type of algebra or dof distribution
Definition: approximation_space.h:279
Definition: local_dof_set.h:195
int num_dof(ReferenceObjectID roid) const
number of dofs on a reference element type
Definition: local_dof_set.h:210
virtual void set_debug(SmartPtr< IDebugWriter< algebra_type > > spDebugWriter)
set debug writer
Definition: debug_writer.h:384
void write_debug(const matrix_type &mat, const char *filename)
write debug output for a matrix (if debug writer set)
Definition: debug_writer.h:399
TAlgebra::vector_type vector_type
type of vector
Definition: debug_writer.h:360
SmartPtr< IDebugWriter< algebra_type > > debug_writer()
returns the debug writer
Definition: debug_writer.h:391
TAlgebra::matrix_type matrix_type
type of matrix
Definition: debug_writer.h:363
Definition: densematrix.h:57
void subassign(size_t r, size_t c, const TStorage2 &t)
Definition: densematrix.h:215
Definition: densevector.h:101
Definition: grid_level.h:42
@ LEVEL
Definition: grid_level.h:48
SmartPtr< IDamping< TAlgebra::vector_type, TAlgebra::vector_type > > damping()
returns the scaling
Definition: linear_iterator.h:173
describes a linear iterator that is based on a matrix operator
Definition: preconditioner.h:103
Identifier for Local Finite Elements.
Definition: local_finite_element_id.h:98
Definition: line_smoothers.h:366
virtual bool supports_parallel() const
returns if parallel solving is supported
Definition: line_smoothers.h:502
virtual const char * name() const
returns the name of iterator
Definition: line_smoothers.h:514
bool update(size_t xsize)
Definition: line_smoothers.h:427
void set_num_steps(size_t forwardx, size_t backwardx)
Definition: line_smoothers.h:481
size_t get_num_forwardz()
Definition: line_smoothers.h:509
matrix_type m_A
Definition: line_smoothers.h:566
SmartPtr< ApproximationSpace< TDomain > > m_spApproxSpace
Definition: line_smoothers.h:393
LineGaussSeidel(SmartPtr< ApproximationSpace< TDomain > > approxSpace)
Definition: line_smoothers.h:414
TAlgebra::vector_type vector_type
Definition: line_smoothers.h:375
~LineGaussSeidel()
Definition: line_smoothers.h:458
virtual SmartPtr< ILinearIterator< vector_type > > clone()
clone
Definition: line_smoothers.h:491
size_t get_num_forwardx()
Definition: line_smoothers.h:505
TAlgebra algebra_type
Definition: line_smoothers.h:372
size_t get_num_backwardz()
Definition: line_smoothers.h:510
virtual bool step(SmartPtr< MatrixOperator< matrix_type, vector_type > > pOp, vector_type &c, const vector_type &d)
computes a new correction c = B*d
Definition: line_smoothers.h:537
TDomain domain_type
Domain.
Definition: line_smoothers.h:369
bool m_init
Definition: line_smoothers.h:410
size_t m_ind_end
Definition: line_smoothers.h:398
size_t m_nr_backwardz
Definition: line_smoothers.h:405
IPreconditioner< TAlgebra > base_type
Base type.
Definition: line_smoothers.h:384
size_t m_nr_backwardy
Definition: line_smoothers.h:403
IPreconditioner< TAlgebra >::matrix_operator_type matrix_operator_type
Matrix Operator type.
Definition: line_smoothers.h:381
size_t m_nr_forwardz
Definition: line_smoothers.h:404
static const int dim
world dimension
Definition: line_smoothers.h:408
bool linegs_step(const matrix_type &A, vector_type &x, const vector_type &b)
Definition: line_smoothers.h:569
size_t get_num_forwardy()
Definition: line_smoothers.h:507
void set_num_steps(size_t forwardx, size_t backwardx, size_t forwardy, size_t backwardy)
Definition: line_smoothers.h:472
size_t get_num_backwardy()
Definition: line_smoothers.h:508
TAlgebra::matrix_type matrix_type
Definition: line_smoothers.h:378
virtual bool preprocess(SmartPtr< MatrixOperator< matrix_type, vector_type > > pOp)
initializes the preconditioner
Definition: line_smoothers.h:517
std::vector< size_t > indZ
Definition: line_smoothers.h:397
size_t m_nr_forwardx
Definition: line_smoothers.h:400
size_t get_num_backwardx()
Definition: line_smoothers.h:506
void set_num_steps(size_t forwardx, size_t backwardx, size_t forwardy, size_t backwardy, size_t forwardz, size_t backwardz)
Definition: line_smoothers.h:463
virtual bool postprocess()
cleans the operator
Definition: line_smoothers.h:534
size_t m_nr_forwardy
Definition: line_smoothers.h:402
std::vector< size_t > indY
Definition: line_smoothers.h:396
size_t m_nr_backwardx
Definition: line_smoothers.h:401
Definition: line_smoothers.h:706
size_t m_nr_forwardx
Definition: line_smoothers.h:740
bool update(size_t xsize)
Definition: line_smoothers.h:776
IPreconditioner< TAlgebra > base_type
Base type.
Definition: line_smoothers.h:724
size_t m_nr_backwardz
Definition: line_smoothers.h:745
virtual bool preprocess(SmartPtr< MatrixOperator< matrix_type, vector_type > > pOp)
initializes the preconditioner
Definition: line_smoothers.h:867
void set_num_steps(size_t forwardx, size_t backwardx, size_t forwardy, size_t backwardy)
Definition: line_smoothers.h:821
void set_num_steps(size_t forwardx, size_t backwardx)
Definition: line_smoothers.h:830
TAlgebra::matrix_type matrix_type
Definition: line_smoothers.h:718
virtual bool step(SmartPtr< MatrixOperator< matrix_type, vector_type > > pOp, vector_type &c, const vector_type &d)
computes a new correction c = B*d
Definition: line_smoothers.h:887
size_t get_num_forwardz()
Definition: line_smoothers.h:859
TAlgebra::vector_type vector_type
Definition: line_smoothers.h:715
std::vector< size_t > indY
Definition: line_smoothers.h:736
virtual SmartPtr< ILinearIterator< vector_type > > clone()
clone
Definition: line_smoothers.h:840
size_t m_ind_end
Definition: line_smoothers.h:738
virtual bool supports_parallel() const
returns if parallel solving is supported
Definition: line_smoothers.h:852
bool m_init
Definition: line_smoothers.h:750
size_t get_num_backwardy()
Definition: line_smoothers.h:858
number m_relax
Definition: line_smoothers.h:755
size_t get_num_forwardx()
Definition: line_smoothers.h:855
SmartPtr< ApproximationSpace< TDomain > > m_spApproxSpace
Definition: line_smoothers.h:733
std::vector< size_t > indZ
Definition: line_smoothers.h:737
TAlgebra algebra_type
Definition: line_smoothers.h:712
size_t get_num_backwardx()
Definition: line_smoothers.h:856
virtual const char * name() const
returns the name of iterator
Definition: line_smoothers.h:864
IPreconditioner< TAlgebra >::matrix_operator_type matrix_operator_type
Matrix Operator type.
Definition: line_smoothers.h:721
static const int dim
world dimension
Definition: line_smoothers.h:748
TDomain domain_type
Domain.
Definition: line_smoothers.h:709
size_t m_nr_forwardz
Definition: line_smoothers.h:744
size_t get_num_backwardz()
Definition: line_smoothers.h:860
virtual bool postprocess()
cleans the operator
Definition: line_smoothers.h:884
size_t m_nr_backwardx
Definition: line_smoothers.h:741
LineVanka(SmartPtr< ApproximationSpace< TDomain > > approxSpace)
Definition: line_smoothers.h:762
~LineVanka()
Definition: line_smoothers.h:807
matrix_type m_A
Definition: line_smoothers.h:916
size_t m_nr_backwardy
Definition: line_smoothers.h:743
size_t get_num_forwardy()
Definition: line_smoothers.h:857
bool linevanka_step(const matrix_type &A, vector_type &x, const vector_type &b)
Definition: line_smoothers.h:919
void set_num_steps(size_t forwardx, size_t backwardx, size_t forwardy, size_t backwardy, size_t forwardz, size_t backwardz)
Definition: line_smoothers.h:812
number relax()
Definition: line_smoothers.h:755
void set_relax(number omega)
set m_relaxation parameter
Definition: line_smoothers.h:754
size_t m_nr_forwardy
Definition: line_smoothers.h:742
static const CommonLocalDoFSet & get_dofs(const LFEID &id, bool bCreate=true)
returns the common dof set for all reference objects of a dimension
Definition: local_finite_element_provider.cpp:730
Definition: matrix_operator.h:49
Const iterator to traverse the surface of a multi-grid hierarchy.
Definition: surface_view.h:237
Definition: grid_base_object_traits.h:68
@ PST_UNIQUE
Definition: parallel_storage_type.h:70
void SetDirichletRow(TSparseMatrix &A, size_t i, size_t alpha)
Definition: sparsematrix_util.h:796
void CollectEdgesSorted(vector< Edge * > &vEdgesOut, Grid &grid, Vertex *v, bool clearContainer)
Collects all edges of a vertex, thus, none.
Definition: grid_util.cpp:205
int NumProcs()
returns the number of processes
Definition: pcl_base.cpp:91
void CollectUniqueElements(std::vector< typename TLayout::Element > &elemsOut, const TLayout &layout)
writes all elements in the interfaces into the resulting vector. avoids doubles.
Definition: pcl_layout_util.h:142
static const int dim
number omega
number alpha
base_type::TBaseElem TBaseElem
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
double number
Definition: types.h:124
vector_t::value_type VecDistance(const vector_t &v1, const vector_t &v2)
returns the distance of two vector_ts.
Definition: math_vector_functions_common_impl.hpp:375
the ug namespace
static const size_t MAXBLOCKSIZE
Definition: vanka.h:47
ReferenceObjectID
these ids are used to identify the shape of a geometric object.
Definition: grid_base_objects.h:74
@ NUM_REFERENCE_OBJECTS
Definition: grid_base_objects.h:85
void ComputeDirectionYOrder(std::vector< std::pair< MathVector< dim >, size_t > > &vPos, std::vector< size_t > &indY)
Definition: line_smoothers.h:73
void ExtractPositions(ConstSmartPtr< TDomain > domain, ConstSmartPtr< DoFDistribution > dd, std::vector< MathVector< TDomain::dim > > &vPos)
Definition: dof_position_util.cpp:424
bool MakeConsistent(const ParallelMatrix< matrix_type > &_mat, ParallelMatrix< matrix_type > &newMat)
Definition: parallel_matrix_overlap_impl.h:438
bool ComparePosDimYDir(const std::pair< MathVector< dim >, size_t > &p1, const std::pair< MathVector< dim >, size_t > &p2)
Definition: line_smoothers.cpp:36
void OrderDirectionZForDofDist(SmartPtr< DoFDistribution > dd, ConstSmartPtr< TDomain > domain, std::vector< size_t > &indZ)
Definition: line_smoothers.h:194
bool MatMultAdd(vector_t &dest, const number &alpha1, const vector_t &v1, const number &beta1, const matrix_t &A1, const vector_t &w1)
calculates dest = alpha1*v1 + beta1 * A1 *w1;
Definition: operations_mat.h:68
bool ComparePosDimZDir(const std::pair< MathVector< dim >, size_t > &p1, const std::pair< MathVector< dim >, size_t > &p2)
Definition: line_smoothers.cpp:82
void OrderDirectionYForDofDist(SmartPtr< DoFDistribution > dd, ConstSmartPtr< TDomain > domain, std::vector< size_t > &indY)
Definition: line_smoothers.h:85
bool InnerDoFPosition(std::vector< MathVector< dim > > &vPos, const ReferenceObjectID roid, const std::vector< MathVector< dim > > &vCornerCoord, const LFEID &lfeID)
Definition: dof_position_util.cpp:112
bool InverseMatMult(number &dest, const double &beta, const TMat &mat, const TVec &vec)
you can implement this function with GetInverse and MatMult
void collectStretchedElementIndices(ConstSmartPtr< TDomain > domain, ConstSmartPtr< DoFDistribution > dd, std::vector< size_t > &indarray, number alpha)
Definition: line_smoothers.h:292
void ComputeDirectionZOrder(std::vector< std::pair< MathVector< dim >, size_t > > &vPos, std::vector< size_t > &indZ)
Definition: line_smoothers.h:184
T value_type
Definition: sparsematrix_interface.h:2