Loading [MathJax]/extensions/tex2jax.js
Plugins
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
39namespace ug{
40
41template <int dim> struct face_type_traits
42{
43 typedef void face_type0;
44 typedef void face_type1;
45};
46
47template <> struct face_type_traits<1>
48{
49 typedef ReferenceVertex face_type0;
50 typedef ReferenceVertex face_type1;
51};
52
53template <> struct face_type_traits<2>
54{
55 typedef ReferenceEdge face_type0;
56 typedef ReferenceEdge face_type1;
57};
58
59template <> 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
70template<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
115template <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;
123 typedef typename domain_type::position_accessor_type position_accessor_type;
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
163template <typename TGridFunction>
164class 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
177 typedef typename algebra_type::matrix_type matrix_type;
178
180 typedef typename algebra_type::vector_type vector_type;
181
184
186 static const int blockSize = algebra_type::blockSize;
187
189 typedef typename domain_type::grid_type grid_type;
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
209 typedef typename domain_type::position_accessor_type position_accessor_type;
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:
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,
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
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,
1152 const std::vector<number>* vScaleMass = NULL,
1153 const std::vector<number>* vScaleStiff = NULL)
1154 {
1155 if (vSol == SPNULL)
1156 if (m_bLinUpConvDefect==false)
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_ */
parameterString s
Definition Biogas.lua:2
T * 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
size_t constraining_dofs_index(size_t i) const
number constraining_dofs_weight(size_t i) 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_bary() const
size_t num_scvf() const
size_t num_scv() const
const SCV & scv(size_t i) const
const CONSTRAINED_DOF & constrained_dof(size_t i) const
void update(GridObject *elem, const MathVector< worldDim > *vCornerCoords, const ISubsetHandler *ish=NULL)
const SCVF & scvf(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
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
SmartPtr< TGrid > grid()
void CollectCornerCoordinates(int base_object_id, std::vector< typename TDomain::position_type > &vCornerCoordsOut, GridObject &elem, const TDomain &domain, bool clearContainer)
size_t num_subsets() const
void SetAttachmentValues(TAttachmentAccessor &aaVal, TIter elemsBegin, TIter elemsEnd, const TVal &val)
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)
CT_CONSTRAINTS
ReferenceObjectID
double VecProd(const double &a, const double &b)
const number & DoFRef(const TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
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