Plugins
disc_constraint_fvcr.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2014: 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 #ifndef __H__UG__PLUGINS__NAVIER_STOKES__INCOMPRESSIBLE__FVCR__CGRAD_CONSTRAINT_H_
34 #define __H__UG__PLUGINS__NAVIER_STOKES__INCOMPRESSIBLE__FVCR__CGRAD_CONSTRAINT_H_
35 
38 
39 namespace ug{
40 
41 template <int dim> struct face_type_traits
42 {
43  typedef void face_type0;
44  typedef void face_type1;
45 };
46 
47 template <> struct face_type_traits<1>
48 {
49  typedef ReferenceVertex face_type0;
50  typedef ReferenceVertex face_type1;
51 };
52 
53 template <> struct face_type_traits<2>
54 {
55  typedef ReferenceEdge face_type0;
56  typedef ReferenceEdge face_type1;
57 };
58 
59 template <> struct face_type_traits<3>
60 {
61  typedef ReferenceTriangle face_type0;
62  typedef ReferenceQuadrilateral face_type1;
63 };
64 
65 // parameters:
66 // secure_container& sides : as given by associated_elements collection computed beforehand
67 // const TGridFunction& u : grid function
68 // std::vector<MultiIndex<2> > multInd : constrained dof_indices computed beforehand
69 // size_t fct, specifies funtion used in multi index computation, default 0
70 template<typename side_type,typename secure_container,typename TGridFunction>
71  void get_constrained_sides_cr(secure_container& sides,const TGridFunction& u,std::vector<MultiIndex<2> > multInd,size_t fct = 0){
72  size_t nOfSides = sides.size();
73  ConstrainingEdge* cEdge=NULL;
74  ConstrainingFace* cFace=NULL;
75  Edge* edge;
76  Face* face;
77  size_t nc;
79  typedef typename TGridFunction::domain_type domain_type;
81  static const int dim = domain_type::dim;
83  std::vector<MultiIndex<2> > seMultInd;
84  for (size_t i=0;i<nOfSides;i++){
85  if (dim==2){
86  cEdge = dynamic_cast<ConstrainingEdge*>(sides[i]);
87  if (cEdge==NULL) continue;
88  nc = cEdge->num_constrained_edges();
89  cEdge->constrained_edge(0);
90  }
91  else{
92  cFace = dynamic_cast<ConstrainingFace*>(sides[i]);
93  if (cFace==NULL) continue;
94  nc = cFace->num_constrained_faces();
95  }
96  for (size_t k=0;k<nc;k++){
97  if (dim==2){
98  edge = dynamic_cast<Edge*>(cEdge->constrained_edge(k));
99  u.inner_dof_indices(edge,fct,seMultInd);
100  } else {
101  face = dynamic_cast<Face*>(cFace->constrained_face(k));
102  u.inner_dof_indices(face,fct,seMultInd);
103  }
104  for(size_t j=nOfSides;j<multInd.size();j++){
105  if (multInd[j][0]==seMultInd[0][0]){
106  if (dim==2) sides.push_back(dynamic_cast<side_type*>(edge));
107  else sides.push_back(dynamic_cast<side_type*>(face));
108  break;
109  }
110  }
111  }
112  }
113 }
114 
115 template <typename TGridFunction,typename side_type,typename constraining_side_type,typename VType>
117  // domain type
118  typedef typename TGridFunction::domain_type domain_type;
119  typedef typename domain_type::grid_type grid_type;
120  static const int dim = domain_type::dim;
122  typedef typename TGridFunction::template traits<constraining_side_type>::const_iterator cSideIterator;
124  typedef typename TGridFunction::template dim_traits<dim>::grid_base_object elem_type;
125  domain_type& domain = *m_uInfo->domain().get();
127  position_accessor_type posAcc = m_uInfo->domain()->position_accessor();
128  cSideIterator cSideIter = m_uInfo->template begin<constraining_side_type>(SurfaceView::SHADOW_RIM);
129  cSideIterator cSideIterEnd = m_uInfo->template end<constraining_side_type>(SurfaceView::SHADOW_RIM);
130  for( ;cSideIter !=cSideIterEnd; ++cSideIter){
131  constraining_side_type* cSide = *cSideIter;
132  typename grid_type::template traits<elem_type>::secure_container assoElements;
133  typedef typename grid_type::template traits<side_type>::secure_container side_secure_container;
134  side_secure_container sides;
135  // get associated element
136  domain.grid()->associated_elements(assoElements, cSide);
137  elem_type* elem = assoElements[0];
138  domain.grid()->associated_elements_sorted(sides, elem);
139  std::vector<DoFIndex> ind;
140  m_uInfo->dof_indices(elem,0,ind,true,true);
141  get_constrained_sides_cr<side_type,side_secure_container,TGridFunction>(sides,*m_uInfo,ind);
142  elem = assoElements[0];
143  std::vector<MathVector<dim> > vCorner;
144  CollectCornerCoordinates(vCorner, *elem, posAcc);
145  geo.update_hanging(elem, &(vCorner[0]), domain.subset_handler().get());
146  for (size_t i=0;i<geo.num_constrained_dofs();i++){
147  const typename DimCRFVGeometry<dim>::CONSTRAINED_DOF& cd = geo.constrained_dof(i);
148  const size_t index = cd.index();
149  if (dynamic_cast<side_type*>(sides[index])!=dynamic_cast<side_type*>(*cSideIter)) continue;
150  aaData[sides[index]]*=0;
151  for (size_t j=0;j<cd.num_constraining_dofs();j++){
152  VType localValue;
153  size_t cdIndex = cd.constraining_dofs_index(j);
154  localValue = aaData[sides[cdIndex]];
155  localValue *= cd.constraining_dofs_weight(j);
156  aaData[sides[index]] += localValue;
157  }
158  }
159  }
160 }
161 
162 
163 template <typename TGridFunction>
164 class DiscConstraintFVCR: public IDomainConstraint<typename TGridFunction::domain_type, typename TGridFunction::algebra_type>
165 {
166  public:
167  typedef typename TGridFunction::domain_type TDomain;
168  typedef typename TGridFunction::algebra_type TAlgebra;
169 
171  static const int dim = TDomain::dim;
172 
175 
178 
181 
184 
186  static const int blockSize = algebra_type::blockSize;
187 
190 
192  typedef typename TGridFunction::template dim_traits<dim>::grid_base_object elem_type;
193 
195  typedef typename elem_type::side side_type;
196 
198  typedef typename TGridFunction::template dim_traits<dim>::const_iterator ElemIterator;
199 
201  typedef typename TGridFunction::template traits<side_type>::const_iterator SideIterator;
202 
203  static const size_t _P_ = dim;
204 
207 
210 
212 
213  typedef std::vector<std::pair<DoFIndex, MathVector<dim> > > vIndexPosPair;
214  typedef std::vector<std::vector<std::pair<DoFIndex, MathVector<dim> > > > vvIndexPosPair;
215  typedef std::pair<MathVector<dim>, MathVector<dim> > MathVector_Pair;
216 
221 
226 
231 
236 
239 
240  private:
248  bool m_limiter;
250  // zero gradient subset group
252 
253  public:
254  void init(SmartPtr<TGridFunction> u,bool bLinUpConvDefect,bool bLinUpConvJacobian,bool bLinPressureDefect,bool bLinPressureJacobian,bool bAdaptive,bool bLimiter){
255  m_u = u;
256  domain_type& domain = *m_u->domain().get();
257  grid_type& grid = *domain.grid();
258  m_grid = &grid;
259  m_ish = m_u->domain()->subset_handler().get();
260  m_bLinPressureDefect = bLinPressureDefect;
261  m_bLinPressureJacobian = bLinPressureJacobian;
262  m_bLinUpConvDefect = bLinUpConvDefect;
263  m_bLinUpConvJacobian = bLinUpConvJacobian;
264  m_bAdaptive=bAdaptive;
265  m_limiter=bLimiter;
266  if (m_bLinUpConvDefect==true){
267  // attach
268  grid.template attach_to<side_type>(aGrad);
269  grid.template attach_to<side_type>(aVol);
270  // access
273  }
274  if (m_bLinUpConvJacobian==true){
275  grid.template attach_to<side_type>(aGradSh);
276  grid.template attach_to<side_type>(aGradShInd);
279  }
280  if (m_bLinUpConvJacobian==true) if (bAdaptive==false) compute_grad_shapes();
281  }
282 
284  void set_zero_grad_bnd(const char* subsets){
285  try{
286  m_zeroGradSg = m_u->subset_grp_by_name(subsets);
287  }UG_CATCH_THROW("ERROR while parsing Subsets.");
288  }
289 
290  void set_limiter(bool bLimiter){
291  m_limiter = bLimiter;
292  }
293 
296  init(u,true,false,true,false,false,false);
297  };
298 
299  DiscConstraintFVCR(SmartPtr<TGridFunction> u,bool bLinUpConvDefect,bool bLinUpConvJacobian,bool bLinPressureDefect,bool bLinPressureJacobian,bool bAdaptive){
300  init(u,bLinUpConvDefect,bLinUpConvJacobian,bLinPressureDefect,bLinPressureJacobian,bAdaptive,false);
301  };
302 
303  DiscConstraintFVCR(SmartPtr<TGridFunction> u,bool bLinUpConvDefect,bool bLinUpConvJacobian,bool bLinPressureDefect,bool bLinPressureJacobian,bool bAdaptive,bool bLimiter){
304  init(u,bLinUpConvDefect,bLinUpConvJacobian,bLinPressureDefect,bLinPressureJacobian,bAdaptive,bLimiter);
305  };
306 
307  DiscConstraintFVCR(SmartPtr<TGridFunction> u,bool bLinUpConvDefect,bool bLinUpConvJacobian,bool bLinPressureDefect,bool bLinPressureJacobian,bool bAdaptive,const char* subsets){
308  init(u,bLinUpConvDefect,bLinUpConvJacobian,bLinPressureDefect,bLinPressureJacobian,bAdaptive,false);
309  set_zero_grad_bnd(subsets);
310  };
311 
312  DiscConstraintFVCR(SmartPtr<TGridFunction> u,bool bLinUpConvDefect,bool bLinUpConvJacobian,bool bLinPressureDefect,bool bLinPressureJacobian,
313  bool bAdaptive,bool bLimiter,const char* subsets){
314  init(u,bLinUpConvDefect,bLinUpConvJacobian,bLinPressureDefect,bLinPressureJacobian,bAdaptive,bLimiter);
315  set_zero_grad_bnd(subsets);
316  };
317 
320 
321  bool zeroGradBndElem(typename grid_type::template traits<side_type>::secure_container sides){
322  for (size_t i=0;i<sides.size();i++){
323  int si=m_ish->get_subset_index(sides[i]);
324  if (m_zeroGradSg.contains(si)) return true;
325  }
326  return false;
327  }
328 
331  domain_type& domain = *m_u->domain().get();
332 
333  // create Multiindex
334  std::vector<DoFIndex> multInd;
335 
336  position_accessor_type aaPos = m_u->domain()->position_accessor();
337 
338  typename grid_type::template traits<side_type>::secure_container sides;
339  std::vector<MathVector<dim> > vCorner;
340  std::vector<DoFIndex> ind;
341 
342  // create a FV Geometry for the dimension
344 
345  SetAttachmentValues(acVol, m_grid->template begin<side_type>(), m_grid->template end<side_type>(), 0);
346 
347  // resize shape indices
348  for(int si = 0; si < domain.subset_handler()->num_subsets(); ++si)
349  {
350  SideIterator iter = m_u->template begin<side_type>(si);
351  SideIterator iterEnd = m_u->template end<side_type>(si);
352  for( ;iter !=iterEnd; ++iter)
353  {
354  side_type* side = *iter;
355  acGradSh[side].clear();
356  }
357  }
358 
359  // compute gradient in sides
360  for(int si = 0; si < domain.subset_handler()->num_subsets(); ++si)
361  {
362  ElemIterator iter = m_u->template begin<elem_type>(si);
363  ElemIterator iterEnd = m_u->template end<elem_type>(si);
364 
365  // loop elements of dimension
366  for( ;iter !=iterEnd; ++iter)
367  {
368  // get Elem
369  elem_type* elem = *iter;
370 
371  // get sides of element
372  m_grid->associated_elements_sorted(sides, elem );
373 
374  // reference object type
375  // ReferenceObjectID roid = elem->reference_object_id();
376 
377  // get corners of element
378  CollectCornerCoordinates(vCorner, *elem, aaPos);
379 
380  // evaluate finite volume geometry
381  geo.update(elem, &(vCorner[0]), domain.subset_handler().get());
382 
383  static const size_t maxNumSCVF = DimCRFVGeometry<dim>::maxNumSCVF;
384 
386 
387  typename grid_type::template traits<side_type>::secure_container sides;
388 
389  UG_ASSERT(dynamic_cast<elem_type*>(elem) != NULL, "Only elements of type elem_type are currently supported");
390 
391  domain.grid()->associated_elements_sorted(sides, static_cast<elem_type*>(elem) );
392 
393  size_t nofsides = geo.num_scv();
394 
395  m_u->dof_indices(elem,0,ind);
396 
397  // loop sides
398  for (size_t s=0;s < nofsides;s++)
399  {
400  // get scv for sh
401  const typename DimCRFVGeometry<dim>::SCV& scv = geo.scv(s);
402 
403  side_type* localside = sides[s];
404 
405  size_t currentInd = acGradSh[localside].size();
406  if (currentInd==0){
407  currentInd=1;
408  acGradSh[localside].resize(nofsides);
409  acGradShInd[localside].resize(nofsides);
410  acGradSh[localside][0]=0;
411  acGradShInd[localside][0]=ind[s];
412  }
413  else {
414  acGradSh[localside].resize(currentInd+nofsides-1);
415  acGradShInd[localside].resize(currentInd+nofsides-1);
416  }
417 
418  // volume of scv
419  number vol = scv.volume();
420 
421  for (size_t sh=0;sh < nofsides;sh++)
422  {
423  if (sh==s){
424  for (int d0=0;d0<dim;d0++){
425  acGradSh[localside][0][d0] += scv.global_grad(sh)[d0]*vol;
426  //UG_LOG("# " << d0 << " " << scv.global_grad(sh)[d0] << "\n");
427  }
428  } else {
429  for (int d0=0;d0<dim;d0++){
430  acGradSh[localside][currentInd][d0] = scv.global_grad(sh)[d0]*vol;
431  //UG_LOG("# " << d0 << " " << scv.global_grad(sh)[d0] << "\n");
432  }
433  acGradShInd[localside][currentInd] = ind[sh];
434  currentInd++;
435  }
436  }
437  acVol[sides[s]] += vol;
438  //UG_LOG("uGrad = " << acUGrad[sides[s]] << " vGrad = " << acVGrad[sides[s]] << " vol = " << acVol[sides[s]] << " div err = " << std::abs(acUGrad[sides[s]][0]+acVGrad[sides[s]][1]) << "\n");
439  }
440 
441  }
442  }
443  PeriodicBoundaryManager* pbm = (domain.grid())->periodic_boundary_manager();
444  // complete computation by averaging
445  for(int si = 0; si < domain.subset_handler()->num_subsets(); ++si)
446  {
447  SideIterator sideIter = m_u->template begin<side_type>(si);
448  SideIterator sideIterEnd = m_u->template end<side_type>(si);
449  for( ;sideIter !=sideIterEnd; sideIter++)
450  {
451  side_type* side = *sideIter;
452  if (pbm && pbm->is_slave(side)){
453  continue;
454  }
455  number vol = acVol[side];
456  for (size_t i=0;i<acGradSh[side].size();i++){
457  acGradSh[side][i]/=(number)vol;
458  //UG_LOG(i << " (" << acGradSh[side][i][0] << "," << acGradSh[side][i][1] << ")\n");
459  }
460  }
461  }
462  }
463 
464  // add linear pressure part and linear velocity upwind part to jacobian
465  virtual void adjust_jacobian(matrix_type& J, const vector_type& u,
466  ConstSmartPtr<DoFDistribution> dd, int type, number time = 0.0,
467  ConstSmartPtr<VectorTimeSeries<vector_type> > vSol = NULL,const number s_a0 = 1.0){
468  if ((m_bLinUpConvJacobian==false)&&(m_bLinPressureJacobian==false)) return;
469  // compute new velocity gradient shapes in adaptive case
470  if ((m_bAdaptive==true)&&(m_bLinUpConvJacobian==true)) compute_grad_shapes();
471 
472  domain_type& domain = *m_u->domain().get();
473 
474  // create Multiindex
475  std::vector<DoFIndex> multInd;
476 
477  position_accessor_type aaPos = m_u->domain()->position_accessor();
478 
479  typename grid_type::template traits<side_type>::secure_container sides;
480  std::vector<MathVector<dim> > vCorner;
481  std::vector<DoFIndex> ind;
482 
483  DoFIndex localInd;
484  localInd[1]=0;
485  DoFIndex shapeInd;
486  shapeInd[1]=0;
487 
488  // create a FV Geometry for the dimension
490 
491  for(int si = 0; si < domain.subset_handler()->num_subsets(); ++si)
492  {
493  // get iterators
494  ElemIterator iter = dd->template begin<elem_type>(si);
495  ElemIterator iterEnd = dd->template end<elem_type>(si);
496 
497  // loop elements of dimension
498  for( ;iter !=iterEnd; ++iter)
499  {
500  // get Elem
501  elem_type* elem = *iter;
502 
503  // get sides of element
504  m_grid->associated_elements_sorted(sides, elem );
505 
506  // leave out boundary elements if boundaries were specified
507  if (m_zeroGradSg.size()>0){
508  if (zeroGradBndElem(sides)) continue;
509  }
510 
511  // get corners of element
512  CollectCornerCoordinates(vCorner, *elem, aaPos);
513 
514  // evaluate finite volume geometry
515  geo.update(elem, &(vCorner[0]), domain.subset_handler().get());
516 
518  if (m_bLinUpConvJacobian==true){
519 
520  static const size_t maxNumSCVF = DimCRFVGeometry<dim>::maxNumSCVF;
521  MathVector<dim> StdVel[maxNumSCVF];
522 
523  m_u->dof_indices(elem,0,ind);
524 
525  for(size_t ip = 0; ip < geo.num_scvf(); ++ip)
526  {
527  const typename DimCRFVGeometry<dim>::SCVF& scvf = geo.scvf(ip);
528  VecSet(StdVel[ip], 0.0);
529  for(int d1 = 0; d1 < dim; ++d1){
530  dd->dof_indices(elem,0,ind);
531  for(size_t sh = 0; sh < sides.size(); ++sh){
532  localInd[0]=ind[sh][0]+d1;
533  StdVel[ip][d1] += DoFRef(u,localInd) * scvf.shape(sh);
534  }
535  }
536  }
537  for(size_t ip = 0; ip < geo.num_scvf(); ++ip){
538  const typename DimCRFVGeometry<dim>::SCVF& scvf = geo.scvf(ip);
539  // compute product of standard velocity and normal
540  // const number prod = VecProd(StdVel[ip], scvf.normal()) * m_imDensitySCVF[ip];
541  const number prod = s_a0 * VecProd(StdVel[ip], scvf.normal());
542  size_t base;
543  if (prod>0)
544  base = scvf.from();
545  else
546  base = scvf.to();
547  side_type* baseSide = sides[base];
548  MathVector<dim> distVec;
549  VecSubtract(distVec, scvf.global_ip(),geo.scv(base).global_ip());
550  for (int d0=0;d0<dim;d0++){
551  size_t shapeSize = acGradShInd[baseSide].size();
552  for (size_t sh=0;sh<shapeSize;sh++){
553  for (int d1=0;d1<dim;d1++){
554  number flux = prod * distVec[d1] * acGradSh[baseSide][sh][d1];
555  localInd[0]=ind[scvf.from()][0]+d0;
556  shapeInd[0]=acGradShInd[baseSide][sh][0]+d0;
557  DoFRef(J,localInd,shapeInd)+= flux;
558  localInd[0]=ind[scvf.to()][0]+d0;
559  DoFRef(J,localInd,shapeInd)-= flux;
560  }
561  }
562  }
563  }
564  }
565 
567  if (m_bLinPressureJacobian==true){
568 
569  // get sides of element
570  m_grid->associated_elements_sorted(sides, elem );
571 
572  // reference object type
573  ReferenceObjectID roid = elem->reference_object_id();
574 
575  // compute size (volume) of element
576  const number elemSize = ElementSize<dim>(roid, &vCorner[0]);
577 
578  typename grid_type::template traits<elem_type>::secure_container assoElements;
579 
580  std::vector<DoFIndex> elemInd(sides.size()+1);
581 
582  dd->inner_dof_indices(elem,_P_,ind);
583  elemInd[0] = ind[0];
584 
585  //UG_LOG("0 " << elemInd[0] << "\n");
586 
587  size_t gradShapesSize = 1;
588 
589  //UG_LOG(elem << "\n");
590 
591  MathMatrix<2*dim+1,dim> gradShapes;
592  for (int sh=0;sh<2*dim+1;sh++) for (int d0=0;d0<dim;d0++) gradShapes[sh][d0]=0;
593 
594  for (size_t s=0;s<sides.size();s++){
595  m_grid->associated_elements(assoElements,sides[s]);
596  // face value is average of associated elements
597  size_t numOfAsso = assoElements.size();
598  const typename DimCRFVGeometry<dim>::SCV& scv = geo.scv(s);
599  if (numOfAsso==1){
600  for (int d=0;d<dim;d++) gradShapes[0][d]+=scv.normal()[d];
601  continue;
602  }
603  for (size_t i=0;i<numOfAsso;i++){
604  dd->inner_dof_indices(assoElements[i],_P_,ind);
605  //UG_LOG(assoElements[i] << "\n");
606  if (assoElements[i]!=elem) break;
607  }
608  elemInd[gradShapesSize] = ind[0];
609  //UG_LOG(gradShapesSize << " " << elemInd[gradShapesSize] << "\n");
610  for (int d=0;d<dim;d++){
611  gradShapes[0][d]+=0.5*scv.normal()[d];
612  gradShapes[gradShapesSize][d]+=0.5*scv.normal()[d];
613  }
614  gradShapesSize++;
615  }
616  gradShapes/=(number)elemSize;
617  //UG_LOG("gradShapesSize=" << gradShapesSize << "\n");
618  //UG_LOG(gradShapes << "\n");
619  // for debug set grad shapes to trivial
620  //for (int d2=0;d2<dim;d2++) gradShapes[0][d2]=1;
621  //for (size_t sh=0;sh<gradShapesSize;sh++)for (int d2=0;d2<dim;d2++) gradShapes[sh][d2]=0;
622 
623 
624  for (int d1=0;d1<dim;d1++){
625  dd->dof_indices(elem, d1 , multInd);
626  for(size_t ip = 0; ip < geo.num_scvf(); ++ip)
627  {
628  // get current SCVF
629  const typename DimCRFVGeometry<dim>::SCVF& scvf = geo.scvf(ip);
630  MathVector<dim> distVec;
631  VecSubtract(distVec,scvf.global_ip(),geo.global_bary());
632 
633  for (size_t sh=0;sh<gradShapesSize;sh++){
634  for (int d2=0;d2<dim;d2++){
635  number flux = s_a0 * distVec[d2]*gradShapes[sh][d2];
636  //UG_LOG("from = " << multInd[scvf.from()] << " p = " << elemInd[sh] << "\n");
637  DoFRef(J,multInd[scvf.from()],elemInd[sh])+= flux * scvf.normal()[d1];
638  //UG_LOG("to = " << multInd[scvf.to()] << " p = " << elemInd[sh] << "\n");
639  DoFRef(J,multInd[scvf.to()],elemInd[sh])-= flux * scvf.normal()[d1];
640  }
641  }
642  }
643  }
644  }
645  }
646  }
647  };
648 
649  // add linear pressure part to defect
650  virtual void add_pressure_defect(vector_type& d, const vector_type& u,
651  ConstSmartPtr<DoFDistribution> dd,const number time = 0.0,const number s_a = 1.0){
652  domain_type& domain = *m_u->domain().get();
653 
654  // create Multiindex
655  std::vector<DoFIndex> multInd;
656 
657  position_accessor_type aaPos = m_u->domain()->position_accessor();
658 
659  typedef typename grid_type::template traits<side_type>::secure_container secure_container;
660 
661  secure_container sides;
662  std::vector<MathVector<dim> > vCorner;
663  std::vector<DoFIndex> ind;
664 
665  // create a FV Geometry for the dimension
667 
668  for(int si = 0; si < domain.subset_handler()->num_subsets(); ++si)
669  {
670  ElemIterator iter = dd->template begin<elem_type>(si);
671  ElemIterator iterEnd = dd->template end<elem_type>(si);
672 
673  // loop elements of dimension
674  for( ;iter !=iterEnd; ++iter)
675  {
676  // get Elem
677  elem_type* elem = *iter;
678 
679  // get sides of element
680  m_grid->associated_elements_sorted(sides, elem );
681 
682  size_t sidesNaturalSize = sides.size();
683 
684  if (!m_bAdaptive)
685  geo.update(elem, &(vCorner[0]), domain.subset_handler().get());
686  else{
687  geo.update_hanging(elem, &(vCorner[0]), domain.subset_handler().get());
688  if (geo.num_constrained_dofs()>0){
689  dd->dof_indices(elem,0,ind,true,true);
690  get_constrained_sides_cr<side_type,secure_container,TGridFunction>(sides,*m_u,ind);
691  }
692  }
693 
694  // leave out boundary elements if boundaries were specified
695  if (m_zeroGradSg.size()>0){
696  if (zeroGradBndElem(sides)) continue;
697  }
698 
699  // reference object type
700  ReferenceObjectID roid = elem->reference_object_id();
701 
702  // get corners of element
703  CollectCornerCoordinates(vCorner, *elem, aaPos);
704 
705  // evaluate finite volume geometry
706  geo.update(elem, &(vCorner[0]), domain.subset_handler().get());
707 
708  // compute size (volume) of element
709  const number elemSize = ElementSize<dim>(roid, &vCorner[0]);
710 
711  typename grid_type::template traits<elem_type>::secure_container assoElements;
712 
713  dd->inner_dof_indices(elem,_P_,ind);
714 
715  number elemValue = DoFRef(u,ind[0]);
716 
717  MathVector<dim> grad;
718  VecSet(grad, 0);
719 
720  for (size_t i=0;i<geo.num_scv();i++){
721  const typename DimCRFVGeometry<dim>::SCV& scv = geo.scv(i);
722  size_t s = scv.node_id();
723  m_grid->associated_elements(assoElements,sides[s]);
724  size_t numOfAsso = assoElements.size();
725  if (numOfAsso==1){
726  if (m_bAdaptive){
727  // hanging node subedge case, only associated element is neighbour
728  if (s>=sidesNaturalSize){
729  dd->inner_dof_indices(assoElements[0],_P_,ind);
730  }
731  } else {
732  for (int d=0;d<dim;d++) grad[d]+=scv.normal()[d]*elemValue;
733  continue;
734  }
735  } else {
736  for (size_t i=0;i<numOfAsso;i++){
737  dd->inner_dof_indices(assoElements[i],_P_,ind);
738  //UG_LOG(assoElements[i] << "\n");
739  if (assoElements[i]!=elem) break;
740  }
741  }
742  for (int d=0;d<dim;d++) grad[d]+=0.5*(elemValue+DoFRef(u,ind[0]))*scv.normal()[d];
743  }
744  grad/=(number)elemSize;
745  for(size_t ip = 0; ip < geo.num_scvf(); ++ip)
746  {
747  // get current SCVF
748  const typename DimCRFVGeometry<dim>::SCVF& scvf = geo.scvf(ip);
749  MathVector<dim> distVec;
750  VecSubtract(distVec,scvf.global_ip(),geo.global_bary());
751  number pressureAddition = 0;
752  for (int j=0;j<dim;j++)
753  pressureAddition+=grad[j]*distVec[j];
754  pressureAddition*=s_a;
755 
756  for (int d1=0;d1<dim;d1++){
757  dd->dof_indices(elem, d1 , multInd);
758  //UG_LOG("from = " << multInd[scvf.from()] << " p = " << elemInd[sh] << "\n");
759  DoFRef(d,multInd[scvf.from()]) += pressureAddition * scvf.normal()[d1];
760  //UG_LOG("to = " << multInd[scvf.to()] << " p = " << elemInd[sh] << "\n");
761  DoFRef(d,multInd[scvf.to()]) -= pressureAddition * scvf.normal()[d1];
762  }
763  }
764  }
765  }
766  };
767 
768  // add linear pressure part and linear velocity upwind part to defect
769  virtual void add_defect(vector_type& d, const vector_type& u,
770  ConstSmartPtr<DoFDistribution> dd,const number time = 0.0,const number s_a = 1.0){
771  domain_type& domain = *m_u->domain().get();
772 
773  // create Multiindex
774  std::vector<DoFIndex> multInd;
775 
776  position_accessor_type posAcc = m_u->domain()->position_accessor();
777 
778  typedef typename grid_type::template traits<side_type>::secure_container secure_container;
779 
780  secure_container sides;
781  std::vector<MathVector<dim> > vCorner;
782  std::vector<DoFIndex> ind;
783 
784  // create a FV Geometry for the dimension
786 
787  // initialize attachment value
788  SetAttachmentValues(acVol, dd->template begin<side_type>(), dd->template end<side_type>(), 0);
789  SetAttachmentValues(acGrad, dd->template begin<side_type>(), dd->template end<side_type>(), 0);
790 
791  // compute velocity gradient in sides by assembling averaged gradients
792  for(int si = 0; si < domain.subset_handler()->num_subsets(); ++si)
793  {
794  ElemIterator iter = dd->template begin<elem_type>(si);
795  ElemIterator iterEnd = dd->template end<elem_type>(si);
796 
797  // loop elements of dimension
798  for( ;iter !=iterEnd; ++iter)
799  {
800  // get Elem
801  elem_type* elem = *iter;
802 
803  // get corners of element
804  CollectCornerCoordinates(vCorner, *elem, posAcc);
805 
806  // evaluate finite volume geometry
807  if (!m_bAdaptive)
808  geo.update(elem, &(vCorner[0]), domain.subset_handler().get());
809  else
810  geo.update_hanging(elem, &(vCorner[0]), domain.subset_handler().get());
811 
812  static const size_t maxNumSCVF = DimCRFVGeometry<dim>::maxNumSCVF;
813 
815 
816  UG_ASSERT(dynamic_cast<elem_type*>(elem) != NULL, "Only elements of type elem_type are currently supported");
817 
818  domain.grid()->associated_elements_sorted(sides, static_cast<elem_type*>(elem) );
819 
820  size_t nNaturalSides = sides.size();
821 
822  if (geo.num_constrained_dofs()>0){
823  dd->dof_indices(elem,0,ind,true,true);
824  get_constrained_sides_cr<side_type,secure_container>(sides,*m_u,multInd,0);
825  }
826 
827  for (int d0=0;d0<dim;d0++){
828  for (size_t s=0;s<nNaturalSides;s++){
829  dd->inner_dof_indices(sides[s], d0, multInd);
830  uValue[s][d0]=DoFRef(u,multInd[0]);
831  //UG_LOG("u(" << s << "," << d0 << ") = " << uValue[s][d0] << "\n");
832  }
833  }
834 
835  // storage for global gradient
836  MathMatrix<dim,dim> globalGrad;
837  for (int d=0;d<dim;d++) for (int d1=0;d1<dim;d1++) globalGrad[d][d1]=0;
838 
839  size_t nofsides = geo.num_scv();
840 
841  // loop sides
842  for (size_t i=0;i < nofsides;i++)
843  {
844  // get scv for sh
845  const typename DimCRFVGeometry<dim>::SCV& scv = geo.scv(i);
846 
847  size_t s = scv.node_id();
848 
849  // reset global gradient
850  for (int d0=0;d0<dim;d0++)
851  for (int d1=0;d1<dim;d1++)
852  globalGrad[d0][d1] = 0.0;
853 
854  for (int d0=0;d0<dim;d0++)
855  // sum up gradients of shape functions in side
856  for(size_t sh = 0 ; sh < nofsides; ++sh)
857  {
858  for (int d1=0;d1<dim;d1++) globalGrad[d0][d1]+=uValue[sh][d0] * scv.global_grad(sh)[d1];
859  // if (d==1) UG_LOG(" " << scv.global_grad(sh) << "\n");
860  //if (d==1) UG_LOG(globalGrad[d] << "\n");
861  //if (d==1) UG_LOG("uValue(" << sh << "," << d << ") = " << uValue[sh][d] << "\n");
862  }
863 
864  // volume of scv
865  number vol = scv.volume();
866 
867  // scale gradient by volume
868  globalGrad *= vol;
869 
870  // add both values to attachements
871  acGrad[sides[s]] += globalGrad;
872  acVol[sides[s]] += vol;
873  // UG_LOG("uGrad = " << acGrad[sides[s]][0][0] << "," << acGrad[sides[s]][0][1] << " vGrad = " << acGrad[sides[s]][1][0] << "," << acGrad[sides[s]][1][1] << " vol = " << acVol[sides[s]] << "\n"); // " div err = " << std::abs(acGrad[sides[s]][0]+acGrad[sides[s]][1]) << "\n");
874  }
875  }
876  }
877  PeriodicBoundaryManager* pbm = (domain.grid())->periodic_boundary_manager();
878  // complete velocity gradient computation by averaging
879  for(int si = 0; si < domain.subset_handler()->num_subsets(); ++si)
880  {
881  SideIterator sideIter = dd->template begin<side_type>(si);
882  SideIterator sideIterEnd = dd->template end<side_type>(si);
883  for( ;sideIter !=sideIterEnd; sideIter++)
884  {
885  side_type* side = *sideIter;
886  if (pbm && pbm->is_slave(side)){
887  continue;
888  }
889  acGrad[side]/=(number)acVol[side];
890  }
891  }
892  if (dim==2) constrainingSideAveraging<TGridFunction,side_type,ConstrainingEdge,dimMat>(acGrad,m_u);
893  else {
894  constrainingSideAveraging<TGridFunction,side_type,ConstrainingTriangle,dimMat>(acGrad,m_u);
895  constrainingSideAveraging<TGridFunction,side_type,ConstrainingQuadrilateral,dimMat>(acGrad,m_u);
896  }
897  // limit valus, so that that no new maximum and minimum values occur in corners of scv
898  // in linear reconstruction with computed gradient
899  if (m_limiter==true){
900  for(int si = 0; si < domain.subset_handler()->num_subsets(); ++si){
901  SideIterator sideIter = m_u->template begin<side_type>(si);
902  SideIterator sideIterEnd = m_u->template end<side_type>(si);
903  for( ;sideIter !=sideIterEnd; ++sideIter)
904  {
905  side_type* side = *sideIter;
906  // UG_LOG("---------\n");
907  typename grid_type::template traits<elem_type>::secure_container assoElements;
908  m_grid->associated_elements(assoElements,side);
909  MathVector<dim> bary[2];
910  MathVector<dim> sideBary;
911  MathVector<dim> sideValue;
912  // compute barycenter of side
913  const size_t numVertices = side->num_vertices();
914  sideBary = 0;
915  std::vector<MathVector<dim> > coCoord(numVertices);
916  for(size_t i = 0; i < numVertices; ++i){
917  coCoord[i] = posAcc[side->vertex(i)];
918  sideBary += coCoord[i];
919  }
920  sideBary /= numVertices;
921  // get velocity value in side
922  for (int d0=0;d0<dim;d0++){
923  dd->inner_dof_indices(side,d0,multInd);
924  sideValue[d0]=DoFRef(u,multInd[0]);
925  }
926  MathVector<dim> nbhoodMin;
927  MathVector<dim> nbhoodMax;
928  for (int d=0;d<dim;d++) nbhoodMin[d] = sideValue[d];
929  for (int d=0;d<dim;d++) nbhoodMax[d] = sideValue[d];
930  secure_container assoElementSides;
931  // compute max/min over associated elements
932  for (size_t el=0;el<assoElements.size();el++){
933  // get sides of element
934  m_grid->associated_elements(assoElementSides, assoElements[el]);
935  // compute barycenter of element
936  const size_t numVertices = assoElements[el]->num_vertices();
937  bary[el] = 0;
938  for(size_t i = 0; i < numVertices; ++i){
939  bary[el] += posAcc[assoElements[el]->vertex(i)];
940  }
941  bary[el] /= numVertices;
942  // compute maximum and minimum
943  for (int d0=0;d0<dim;d0++){
944  for (size_t s=0;s<assoElementSides.size();s++){
945  dd->inner_dof_indices(assoElementSides[s], d0, multInd);
946  number uValue=DoFRef(u,multInd[0]);
947  if (uValue<nbhoodMin[d0]) nbhoodMin[d0]=uValue;
948  if (uValue>nbhoodMax[d0]) nbhoodMax[d0]=uValue;
949  }
950  }
951  // also use neighbour sides of given side
952  for (size_t i=0;i<side->num_vertices();i++){
953  secure_container neighbourSides;
954  m_grid->associated_elements(neighbourSides,side);
955  for (size_t j=0;j<neighbourSides.size();j++){
956  if (neighbourSides[j]==side) continue;
957  for (int d0=0;d0<dim;d0++){
958  dd->inner_dof_indices(neighbourSides[j], d0, multInd);
959  number uValue=DoFRef(u,multInd[0]);
960  if (uValue<nbhoodMin[d0]) nbhoodMin[d0]=uValue;
961  if (uValue>nbhoodMax[d0]) nbhoodMax[d0]=uValue;
962  }
963  }
964  }
965  }
966  // add barycenter coords to evaluated coordinates (corners of the scv)
967  coCoord.resize(numVertices+assoElements.size());
968  for (size_t i=0;i<assoElements.size();i++){
969  coCoord[numVertices+i] = bary[i];
970  }
971  for (size_t i=0;i<coCoord.size();i++){
972  MathVector<dim> distVec;
973  VecSubtract(distVec,coCoord[i],sideBary);
974  for (int d0=0;d0<dim;d0++){
975  number uValue = sideValue[d0];
976  number addValue=0;
977  for (int d1=0;d1<dim;d1++){
978  addValue += distVec[d1]*acGrad[side][d0][d1];
979  }
980  if (addValue<1e-12) continue;
981  if (addValue<0){
982  if (uValue+addValue<nbhoodMin[d0]){
983  number alpha = (nbhoodMin[d0]-uValue)/addValue;
984  // UG_LOG("alpha=" << alpha << "\n");
985  for (int d1=0;d1<dim;d1++) acGrad[side][d0][d1] *= alpha;
986  }
987  } else {
988  if (uValue+addValue>nbhoodMax[d0]){
989  number alpha = (nbhoodMax[d0]-uValue)/addValue;
990  // UG_LOG("alpha=" << alpha << "\n");
991  for (int d1=0;d1<dim;d1++) acGrad[side][d0][d1] *= alpha;
992  }
993  }
994  }
995  }
996  }
997  }
998  } // end of limiting procedure
999  // compute defect
1000  for(int si = 0; si < domain.subset_handler()->num_subsets(); ++si)
1001  {
1002  ElemIterator iter = dd->template begin<elem_type>(si);
1003  ElemIterator iterEnd = dd->template end<elem_type>(si);
1004 
1005  // loop elements of dimension
1006  for( ;iter !=iterEnd; ++iter)
1007  {
1008  // get Elem
1009  elem_type* elem = *iter;
1010 
1011  typename grid_type::template traits<side_type>::secure_container sides;
1012 
1013  // get sides of element
1014  m_grid->associated_elements_sorted(sides, elem);
1015 
1016  size_t sidesNaturalSize = sides.size();
1017 
1018  // leave out boundary elements if boundaries were specified
1019  if (m_zeroGradSg.size()>0){
1020  if (zeroGradBndElem(sides)) continue;
1021  }
1022 
1023  // get corners of element
1024  CollectCornerCoordinates(vCorner, *elem, posAcc);
1025 
1026  // evaluate finite volume geometry
1027  if (!m_bAdaptive)
1028  geo.update(elem, &(vCorner[0]), domain.subset_handler().get());
1029  else{
1030  geo.update_hanging(elem, &(vCorner[0]), domain.subset_handler().get(),true);
1031  if (geo.num_constrained_dofs()>0){
1032  dd->dof_indices(elem,0,ind,true,true);
1033  get_constrained_sides_cr<side_type,secure_container>(sides,*m_u,ind);
1034  }
1035  }
1036 
1037  static const size_t maxNumSCVF = DimCRFVGeometry<dim>::maxNumSCVF;
1038  MathVector<dim> StdVel[maxNumSCVF];
1039 
1040  for(size_t ip = 0; ip < geo.num_scvf(); ++ip)
1041  {
1042  const typename DimCRFVGeometry<dim>::SCVF& scvf = geo.scvf(ip);
1043  VecSet(StdVel[ip], 0.0);
1044 
1045  for(size_t sh = 0; sh < sides.size(); ++sh){
1046  for(int d1 = 0; d1 < dim; ++d1){
1047  dd->inner_dof_indices(sides[sh], d1, multInd);
1048  StdVel[ip][d1] += DoFRef(u,multInd[0]) * scvf.shape(sh);
1049  }
1050  }
1051  }
1052 
1053  number elemPressureValue=0, pressure=0;
1054  MathVector<dim> pGrad;
1055  VecSet(pGrad, 0);
1056 
1058  if (m_bLinPressureDefect==true){
1059  // reference object type
1060  ReferenceObjectID roid = elem->reference_object_id();
1061 
1062  // compute size (volume) of element
1063  const number elemSize = ElementSize<dim>(roid, &vCorner[0]);
1064 
1065  typename grid_type::template traits<elem_type>::secure_container assoElements;
1066 
1067  dd->inner_dof_indices(elem,dim,multInd);
1068  elemPressureValue = DoFRef(u,multInd[0]);
1069 
1070  for (size_t i=0;i<geo.num_scv();i++){
1071  const typename DimCRFVGeometry<dim>::SCV& scv = geo.scv(i);
1072  size_t s = scv.node_id();
1073  m_grid->associated_elements(assoElements,sides[s]);
1074  size_t numOfAsso = assoElements.size();
1075  if (numOfAsso==1){
1076  if (m_bAdaptive){
1077  // hanging node subedge case, only associated element is neighbour
1078  if (s>=sidesNaturalSize){
1079  dd->inner_dof_indices(assoElements[0],_P_,ind);
1080  }
1081  } else {
1082  for (int d=0;d<dim;d++) pGrad[d]+=scv.normal()[d]*elemPressureValue;
1083  continue;
1084  }
1085  } else {
1086  for (size_t i=0;i<numOfAsso;i++){
1087  dd->inner_dof_indices(assoElements[i],_P_,ind);
1088  //UG_LOG(assoElements[i] << "\n");
1089  if (assoElements[i]!=elem) break;
1090  }
1091  }
1092  for (int d=0;d<dim;d++) pGrad[d]+=0.5*(elemPressureValue+DoFRef(u,ind[0]))*scv.normal()[d];
1093  }
1094  pGrad/=(number)elemSize;
1095  }
1096 
1097  size_t base;
1098  MathVector<dim> distVec;
1099  for(size_t ip = 0; ip < geo.num_scvf(); ++ip){
1100  const typename DimCRFVGeometry<dim>::SCVF& scvf = geo.scvf(ip);
1101  const number flux = s_a * VecProd(StdVel[ip], scvf.normal());
1102 
1103  if (flux>0)
1104  base = scvf.from();
1105  else
1106  base = scvf.to();
1107 
1109  if (m_bLinPressureDefect==true){
1110  MathVector<dim> distVecBary;
1111  VecSubtract(distVecBary,scvf.global_ip(),geo.global_bary());
1112  number pressureFlux = 0;//
1113  // pressureFlux = elemPressureValue;
1114  for (int j=0;j<dim;j++)
1115  pressureFlux+=pGrad[j]*distVecBary[j];
1116  pressure = s_a * pressureFlux;
1117  }
1118 
1119  for(int d1 = 0; d1 < dim; ++d1)
1120  {
1121 // dd->inner_dof_indices(sides[base],d1,multInd);
1122 // number upwindVel = DoFRef(u,multInd[0]);
1123  number upwindVel = 0;
1124  VecSubtract(distVec, scvf.global_ip(),geo.scv(base).global_ip());
1125  // UG_LOG("grad = " << acGrad[sides[base]][d1][0] << "," << acGrad[sides[base]][d1][1] << "\n");
1126  // UG_LOG("distVec = " << distVec << "\n");
1127  for (int d2=0;d2<dim;d2++){
1128  upwindVel+=(acGrad[sides[base]])[d1][d2]*distVec[d2];
1129  }
1130  // UG_LOG("upv(" << ip+1 << "," << d1+1 << ")=" << upwindVel << "\n");
1131  dd->dof_indices(elem,d1,multInd);
1132  DoFRef(d,multInd[scvf.from()]) += upwindVel * flux;
1133  DoFRef(d,multInd[scvf.to()]) -= upwindVel * flux;
1134 
1136  if (m_bLinPressureDefect==true){
1137  DoFRef(d,multInd[scvf.from()]) += pressure * scvf.normal()[d1];
1138  DoFRef(d,multInd[scvf.to()]) -= pressure * scvf.normal()[d1];
1139  }
1140  }
1141  }
1142  }
1143  }
1144 
1145  }
1146 
1149  virtual void adjust_defect(vector_type& d, const vector_type& u,
1150  ConstSmartPtr<DoFDistribution> dd, int type, number time = 0.0,
1152  const std::vector<number>* vScaleMass = NULL,
1153  const std::vector<number>* vScaleStiff = NULL)
1154  {
1155  if (vSol == SPNULL)
1156  if (m_bLinUpConvDefect==false)
1157  add_pressure_defect(d,u,dd);
1158  else
1159  add_defect(d,u,dd);
1160  else {
1161  // loop all time points and assemble them
1162  for(size_t t = 0; t < vScaleStiff->size(); ++t){
1163  if ((*vScaleStiff)[t]==0) continue;
1164  if (m_bLinUpConvDefect==false)
1165  add_pressure_defect(d,*(vSol->solution(t)),dd,time,(*vScaleStiff)[t]);
1166  else
1167  add_defect(d,*(vSol->solution(t)),dd,time,(*vScaleStiff)[t]);
1168  }
1169  }
1170  };
1172 
1175  virtual void adjust_linear(matrix_type& mat, vector_type& rhs,
1176  ConstSmartPtr<DoFDistribution> dd, int type, number time = 0.0){};
1178 
1181  virtual void adjust_rhs(vector_type& rhs, const vector_type& u,
1182  ConstSmartPtr<DoFDistribution> dd, int type, number time = 0.0){};
1184 
1188  int type, number time = 0.0){};
1189 
1191  virtual int type() const {return CT_CONSTRAINTS;}
1192 };
1193 
1194 } // end namespace ug
1195 
1196 // #include "CGradUpwind_constraint_impl.h"
1197 
1198 #endif /* __H__UG__PLUGINS__NAVIER_STOKES__INCOMPRESSIBLE__FVCR__CGRAD_CONSTRAINT_H_ */
TGridFunction * get()
Edge * constrained_edge(size_t ind) const
size_t num_constrained_edges() const
Face * constrained_face(size_t ind) const
size_t num_constrained_faces() const
const MathVector< worldDim > & global_ip() const
const MathVector< worldDim > & normal() const
number shape(size_t sh) const
const MathVector< worldDim > & global_grad(size_t sh) const
size_t node_id() const
const MathVector< worldDim > & normal() const
const MathVector< worldDim > & global_ip() const
const SCV & scv(size_t i) const
size_t num_scvf() const
size_t num_scv() const
const SCVF & scvf(size_t i) const
void update(GridObject *elem, const MathVector< worldDim > *vCornerCoords, const ISubsetHandler *ish=NULL)
const MathVector< worldDim > global_bary() const
const CONSTRAINED_DOF & constrained_dof(size_t i) const
size_t num_constrained_dofs() const
void update_hanging(GridObject *elem, const MathVector< worldDim > *vCornerCoords, const ISubsetHandler *ish=NULL, bool keepSCV=false, bool keepSCVF=false)
Definition: disc_constraint_fvcr.h:165
std::pair< MathVector< dim >, MathVector< dim > > MathVector_Pair
Definition: disc_constraint_fvcr.h:215
ANumber aVol
Definition: disc_constraint_fvcr.h:233
algebra_type::vector_type vector_type
Type of algebra vector.
Definition: disc_constraint_fvcr.h:180
bool m_limiter
Definition: disc_constraint_fvcr.h:248
virtual void adjust_jacobian(matrix_type &J, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0, ConstSmartPtr< VectorTimeSeries< vector_type > > vSol=NULL, const number s_a0=1.0)
Definition: disc_constraint_fvcr.h:465
Attachment< std::vector< DoFIndex > > ASizetArray
Definition: disc_constraint_fvcr.h:223
virtual int type() const
returns the type of the constraints
Definition: disc_constraint_fvcr.h:1191
TGridFunction::template dim_traits< dim >::grid_base_object elem_type
element type
Definition: disc_constraint_fvcr.h:192
domain_type::position_accessor_type position_accessor_type
position accessor
Definition: disc_constraint_fvcr.h:209
aSideNumber acVol
Definition: disc_constraint_fvcr.h:228
virtual void adjust_linear(matrix_type &mat, vector_type &rhs, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0)
Definition: disc_constraint_fvcr.h:1175
ASizetArray aGradShInd
Definition: disc_constraint_fvcr.h:235
static const size_t _P_
Definition: disc_constraint_fvcr.h:203
virtual void add_defect(vector_type &d, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, const number time=0.0, const number s_a=1.0)
Definition: disc_constraint_fvcr.h:769
PeriodicAttachmentAccessor< side_type, ANumber > aSideNumber
Definition: disc_constraint_fvcr.h:220
TGridFunction::domain_type TDomain
Definition: disc_constraint_fvcr.h:167
ISubsetHandler * m_ish
Definition: disc_constraint_fvcr.h:249
bool m_bAdaptive
Definition: disc_constraint_fvcr.h:243
std::vector< std::vector< std::pair< DoFIndex, MathVector< dim > > > > vvIndexPosPair
Definition: disc_constraint_fvcr.h:214
void compute_grad_shapes()
compute gradient shapes for velocity on rotated elements
Definition: disc_constraint_fvcr.h:330
static const int dim
world Dimension
Definition: disc_constraint_fvcr.h:171
elem_type::side side_type
side type
Definition: disc_constraint_fvcr.h:195
virtual void adjust_solution(vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0)
Definition: disc_constraint_fvcr.h:1187
bool m_bLinUpConvDefect
Definition: disc_constraint_fvcr.h:246
domain_type::grid_type grid_type
grid type
Definition: disc_constraint_fvcr.h:189
domain_traits< TDomain::dim >::grid_base_object grid_base_object
Type of geometric base object.
Definition: disc_constraint_fvcr.h:206
TGridFunction::algebra_type TAlgebra
Definition: disc_constraint_fvcr.h:168
aSideDimMat acGrad
Definition: disc_constraint_fvcr.h:227
~DiscConstraintFVCR()
destructor
Definition: disc_constraint_fvcr.h:319
Attachment< dimMat > AMathDimMat
Definition: disc_constraint_fvcr.h:218
DiscConstraintFVCR(SmartPtr< TGridFunction > u)
constructor
Definition: disc_constraint_fvcr.h:295
algebra_type::matrix_type matrix_type
Type of algebra matrix.
Definition: disc_constraint_fvcr.h:177
bool zeroGradBndElem(typename grid_type::template traits< side_type >::secure_container sides)
Definition: disc_constraint_fvcr.h:321
virtual void adjust_defect(vector_type &d, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0, ConstSmartPtr< VectorTimeSeries< vector_type > > vSol=SPNULL, const std::vector< number > *vScaleMass=NULL, const std::vector< number > *vScaleStiff=NULL)
Definition: disc_constraint_fvcr.h:1149
TGridFunction::template dim_traits< dim >::const_iterator ElemIterator
element iterator
Definition: disc_constraint_fvcr.h:198
AMathDimMat aGrad
Definition: disc_constraint_fvcr.h:232
void set_zero_grad_bnd(const char *subsets)
set boundaries, in associated elements there is no linear pressure and no linear velocity upwind
Definition: disc_constraint_fvcr.h:284
aSideSizetArray acGradShInd
Definition: disc_constraint_fvcr.h:230
std::vector< std::pair< DoFIndex, MathVector< dim > > > vIndexPosPair
Definition: disc_constraint_fvcr.h:213
ANumberArray aGradSh
Definition: disc_constraint_fvcr.h:234
virtual void add_pressure_defect(vector_type &d, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, const number time=0.0, const number s_a=1.0)
Definition: disc_constraint_fvcr.h:650
SubsetGroup m_zeroGradSg
Definition: disc_constraint_fvcr.h:251
DiscConstraintFVCR(SmartPtr< TGridFunction > u, bool bLinUpConvDefect, bool bLinUpConvJacobian, bool bLinPressureDefect, bool bLinPressureJacobian, bool bAdaptive)
Definition: disc_constraint_fvcr.h:299
TAlgebra algebra_type
Algebra type.
Definition: disc_constraint_fvcr.h:174
virtual void adjust_rhs(vector_type &rhs, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0)
Definition: disc_constraint_fvcr.h:1181
TDomain domain_type
Type of Domain.
Definition: disc_constraint_fvcr.h:183
PeriodicAttachmentAccessor< side_type, ASizetArray > aSideSizetArray
Definition: disc_constraint_fvcr.h:225
TGridFunction::template traits< side_type >::const_iterator SideIterator
side iterator
Definition: disc_constraint_fvcr.h:201
DiscConstraintFVCR(SmartPtr< TGridFunction > u, bool bLinUpConvDefect, bool bLinUpConvJacobian, bool bLinPressureDefect, bool bLinPressureJacobian, bool bAdaptive, bool bLimiter)
Definition: disc_constraint_fvcr.h:303
DiscConstraintFVCR(SmartPtr< TGridFunction > u, bool bLinUpConvDefect, bool bLinUpConvJacobian, bool bLinPressureDefect, bool bLinPressureJacobian, bool bAdaptive, const char *subsets)
Definition: disc_constraint_fvcr.h:307
face_type_traits< dim >::face_type0 face_type0
Definition: disc_constraint_fvcr.h:237
grid_type * m_grid
Definition: disc_constraint_fvcr.h:242
PeriodicAttachmentAccessor< side_type, AMathDimMat > aSideDimMat
Definition: disc_constraint_fvcr.h:219
static const size_t maxShapeSize
Definition: disc_constraint_fvcr.h:211
aSideNumberArray acGradSh
Definition: disc_constraint_fvcr.h:229
SmartPtr< TGridFunction > m_u
Definition: disc_constraint_fvcr.h:241
static const int blockSize
blockSize of used algebra
Definition: disc_constraint_fvcr.h:186
DiscConstraintFVCR(SmartPtr< TGridFunction > u, bool bLinUpConvDefect, bool bLinUpConvJacobian, bool bLinPressureDefect, bool bLinPressureJacobian, bool bAdaptive, bool bLimiter, const char *subsets)
Definition: disc_constraint_fvcr.h:312
void init(SmartPtr< TGridFunction > u, bool bLinUpConvDefect, bool bLinUpConvJacobian, bool bLinPressureDefect, bool bLinPressureJacobian, bool bAdaptive, bool bLimiter)
Definition: disc_constraint_fvcr.h:254
bool m_bLinUpConvJacobian
Definition: disc_constraint_fvcr.h:247
bool m_bLinPressureJacobian
Definition: disc_constraint_fvcr.h:245
Attachment< std::vector< MathVector< dim > > > ANumberArray
Definition: disc_constraint_fvcr.h:222
MathMatrix< dim, dim > dimMat
Definition: disc_constraint_fvcr.h:217
face_type_traits< dim >::face_type1 face_type1
Definition: disc_constraint_fvcr.h:238
bool m_bLinPressureDefect
Definition: disc_constraint_fvcr.h:244
void set_limiter(bool bLimiter)
Definition: disc_constraint_fvcr.h:290
PeriodicAttachmentAccessor< side_type, ANumberArray > aSideNumberArray
Definition: disc_constraint_fvcr.h:224
algebra_type::vector_type vector_type
algebra_type::matrix_type matrix_type
ConstSmartPtr< DoFDistribution > dd(const GridLevel &gl) const
int get_subset_index(const char *name) const
bool access(Grid &g, TAttachment &a)
bool is_slave(TElem *) const
bool contains(const char *name) const
size_t size() const
static const int blockSize
ParallelMatrix< SparseMatrix< double > > matrix_type
ParallelVector< Vector< double > > vector_type
Grid::VertexAttachmentAccessor< position_attachment_type > position_accessor_type
SmartPtr< TGrid > grid()
void CollectCornerCoordinates(int base_object_id, std::vector< typename TDomain::position_type > &vCornerCoordsOut, GridObject &elem, const TDomain &domain, bool clearContainer)
static const int dim
TGrid grid_type
size_t num_subsets() const
void SetAttachmentValues(TAttachmentAccessor &aaVal, TIter elemsBegin, TIter elemsEnd, const TVal &val)
StringTable s
const NullSmartPtr SPNULL
#define UG_ASSERT(expr, msg)
#define UG_CATCH_THROW(msg)
double number
void VecSubtract(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
const number & DoFRef(const TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
CT_CONSTRAINTS
ReferenceObjectID
double VecProd(const double &a, const double &b)
void VecSet(vector_t &dest, number alpha, const std::vector< size_t > vIndex)
void get_constrained_sides_cr(secure_container &sides, const TGridFunction &u, std::vector< MultiIndex< 2 > > multInd, size_t fct=0)
Definition: disc_constraint_fvcr.h:71
void constrainingSideAveraging(PeriodicAttachmentAccessor< side_type, Attachment< VType > > &aaData, SmartPtr< TGridFunction > m_uInfo)
Definition: disc_constraint_fvcr.h:116