33 #ifndef __H__UG__PLUGINS__NAVIER_STOKES__INCOMPRESSIBLE__NAVIER_STOKES_TOOLS__
34 #define __H__UG__PLUGINS__NAVIER_STOKES__INCOMPRESSIBLE__NAVIER_STOKES_TOOLS__
53 template <
typename TGr
idFunction>
56 typedef typename TGridFunction::domain_type domain_type;
71 typedef typename TGridFunction::template dim_traits<dim>::grid_base_object elem_type;
74 typedef typename elem_type::side side_type;
78 aVertexNumber m_acVolume;
82 typedef typename TGridFunction::template dim_traits<dim>::const_iterator ElemIterator;
92 int spaceDim = uLagrange.num_fct();
93 if ((
int)uLagrange.num_fct()==
dim) spaceDim=
dim;
95 for (
int i=0;i<spaceDim;i++){
97 UG_THROW(
"First parameter must be of Lagrange 1 type.");
100 UG_THROW(
"Second parameter must be of CR type.");
116 grid.template attach_to<Vertex>(m_aVolume);
117 m_acVolume.access(
grid,m_aVolume);
128 std::vector<DoFIndex> multInd;
130 static const size_t MaxNumSidesOfElem = 10;
133 std::vector<MVD> uValue(MaxNumSidesOfElem);
136 for(
int si = 0; si < uLagrange.num_subsets(); ++si){
140 for( ;iter !=iterEnd; ++iter){
142 if (pbm && pbm->
is_slave(vrt))
continue;
143 for (
int d=0;d<spaceDim;d++){
144 uLagrange.inner_dof_indices(vrt, d, multInd);
145 DoFRef(uLagrange,multInd[0])=0;
150 for(
int si = 0; si < uLagrange.num_subsets(); ++si)
153 ElemIterator iter = uLagrange.template begin<elem_type>(si);
154 ElemIterator iterEnd = uLagrange.template end<elem_type>(si);
157 for( ;iter !=iterEnd; ++iter)
160 elem_type* elem = *iter;
170 const size_t numVertices = elem->num_vertices();
171 for(
size_t i = 0; i < numVertices; ++i){
172 vVrt[i] = elem->vertex(i);
173 coCoord[i] = posAcc[vVrt[i]];
176 typename grid_type::template traits<side_type>::secure_container sides;
178 UG_ASSERT(
dynamic_cast<elem_type*
>(elem) != NULL,
"Only elements of type elem_type are currently supported");
180 grid.associated_elements_sorted(sides,
static_cast<elem_type*
>(elem) );
182 size_t nofsides = sides.size();
183 for (
size_t s=0;
s < nofsides;
s++)
185 for (
int d=0;d<spaceDim;d++){
187 uCR.inner_dof_indices(sides[
s], d, multInd);
189 uValue[
s][d]=
DoFRef(uCR,multInd[0]);
194 geo.
update(elem, &(coCoord[0]), uLagrange.domain()->subset_handler().get());
195 for(
size_t i = 0; i < numVertices; ++i){
198 m_acVolume[vVrt[i]]+=scvVol;
199 std::vector<number> vShape;
202 for (
size_t s=0;
s<nofsides;
s++)
203 for (
int d=0;d<spaceDim;d++)
204 localValue[d]+=vShape[
s]*uValue[
s][d];
205 for (
int d=0;d<spaceDim;d++){
206 uLagrange.inner_dof_indices(vVrt[i], d, multInd);
207 DoFRef(uLagrange,multInd[0])+=scvVol*localValue[d];
210 if (uLagrange.num_fct()==
dim+1){
211 uLagrange.inner_dof_indices(elem,
dim,multInd);
217 for(
int si = 0; si < uLagrange.num_subsets(); ++si){
221 for( ;iter !=iterEnd; ++iter){
223 if (pbm && pbm->
is_slave(vrt))
continue;
224 for (
int d=0;d<spaceDim;d++){
225 uLagrange.inner_dof_indices(vrt, d, multInd);
226 DoFRef(uLagrange,multInd[0])/=m_acVolume[vrt];
234 template <
typename TGr
idFunction>
238 typedef typename TGridFunction::domain_type domain_type;
253 typedef typename TGridFunction::template dim_traits<dim>::grid_base_object elem_type;
256 typedef typename elem_type::side side_type;
260 aSideNumber m_acVolume;
264 typedef typename TGridFunction::template dim_traits<dim>::const_iterator ElemIterator;
267 typedef typename TGridFunction::template traits<side_type>::const_iterator SideIterator;
275 grid.template attach_to<side_type>(m_aVolume);
276 m_acVolume.access(
grid,m_aVolume);
281 UG_THROW(
"Component " << 0 <<
" in approximation space of parameter 1 must be of Crouzeix-Raviart type.");
284 for (
int d=0;d<
dim;d++){
286 UG_THROW(
"Component " << d <<
" in approximation space of parameter 2 must be of Crouzeix-Raviart type.");
297 std::vector<DoFIndex> multInd;
299 for(
int si = 0; si < u.num_subsets(); ++si)
303 ElemIterator iter = u.template begin<elem_type>(si);
304 ElemIterator iterEnd = u.template end<elem_type>(si);
307 for( ;iter !=iterEnd; ++iter)
310 elem_type* elem = *iter;
312 const size_t numVertices = elem->num_vertices();
313 for(
size_t i = 0; i < numVertices; ++i){
314 vVrt[i] = elem->vertex(i);
315 coCoord[i] = posAcc[vVrt[i]];
318 geo.
update(elem, &(coCoord[0]), u.domain()->subset_handler().get());
320 size_t nofsides = geo.
num_scv();
322 typename grid_type::template traits<side_type>::secure_container sides;
324 UG_ASSERT(
dynamic_cast<elem_type*
>(elem) != NULL,
"Only elements of type elem_type are currently supported");
326 grid.associated_elements_sorted(sides,
static_cast<elem_type*
>(elem) );
328 static const size_t MaxNumSidesOfElem = 18;
331 std::vector<MVD> uValue(MaxNumSidesOfElem);
333 for (
size_t s=0;
s < nofsides;
s++)
335 for (
int d=0;d<
dim;d++){
337 u.dof_indices(sides[
s], d, multInd);
339 uValue[
s][d]=
DoFRef(u,multInd[0]);
343 for (
size_t s=0;
s < nofsides;
s++)
348 for(
size_t sh = 0 ; sh < nofsides; ++sh){
356 vort.dof_indices(sides[
s], 0, multInd);
357 DoFRef(vort,multInd[0])+=localvort;
358 m_acVolume[sides[
s]] += vol;
364 for(
int si = 0; si < u.num_subsets(); ++si)
366 SideIterator sideIter = vort.template begin<side_type>(si);
367 SideIterator sideIterEnd = vort.template end<side_type>(si);
368 for( ;sideIter !=sideIterEnd; sideIter++)
371 side_type* elem = *sideIter;
373 if (pbm && pbm->
is_slave(elem))
continue;
374 vort.dof_indices(elem, 0, multInd);
375 DoFRef(vort,multInd[0])/=m_acVolume[elem];
378 if (
DoFRef(vort,multInd[0])*
DoFRef(vort,multInd[0])>maxvort*maxvort){
379 maxvort =
DoFRef(vort,multInd[0]);
383 grid.template detach_from<side_type>(m_aVolume);
386 template <
typename TGr
idFunction>
390 typedef typename TGridFunction::domain_type domain_type;
405 typedef typename TGridFunction::template dim_traits<dim>::grid_base_object elem_type;
409 aSideNumber m_acVolume;
413 typedef typename TGridFunction::template dim_traits<dim>::const_iterator ElemIterator;
424 grid.template attach_to<Vertex>(m_aVolume);
425 m_acVolume.access(
grid,m_aVolume);
430 UG_THROW(
"Component " << 0 <<
" in approximation space of parameter 1 must be of Crouzeix-Raviart type.");
433 for (
int d=0;d<
dim;d++){
435 UG_THROW(
"Component " << d <<
" in approximation space of parameter 2 must be of Crouzeix-Raviart type.");
446 std::vector<DoFIndex> multInd;
448 for(
int si = 0; si < u.num_subsets(); ++si)
452 ElemIterator iter = u.template begin<elem_type>(si);
453 ElemIterator iterEnd = u.template end<elem_type>(si);
456 for( ;iter !=iterEnd; ++iter)
459 elem_type* elem = *iter;
461 const size_t numVertices = elem->num_vertices();
462 for(
size_t i = 0; i < numVertices; ++i){
463 vVrt[i] = elem->vertex(i);
464 coCoord[i] = posAcc[vVrt[i]];
468 geo.
update(elem, &(coCoord[0]), u.domain()->subset_handler().get());
470 static const size_t MaxNumSidesOfElem = 18;
473 std::vector<MVD> uValue(MaxNumSidesOfElem);
475 for (
size_t co=0;co < numVertices;co++)
477 for (
int d=0;d<
dim;d++){
479 u.dof_indices(elem->vertex(co), d, multInd);
481 uValue[co][d]=
DoFRef(u,multInd[0]);
485 for (
size_t co=0;co < numVertices;co++)
490 for(
size_t sh = 0 ; sh < scv.
num_sh(); ++sh){
498 vort.dof_indices(elem->vertex(co), 0, multInd);
499 DoFRef(vort,multInd[0])+=localvort;
500 m_acVolume[elem->vertex(co)] += vol;
506 for(
int si = 0; si < u.num_subsets(); ++si)
509 VertexConstIterator vertexIter = vort.template begin<Vertex>(si);
510 VertexConstIterator vertexIterEnd = vort.template end<Vertex>(si);
511 for( ;vertexIter !=vertexIterEnd; vertexIter++)
514 Vertex* vrt = *vertexIter;
516 if (pbm && pbm->
is_slave(vrt))
continue;
517 vort.dof_indices(vrt, 0, multInd);
518 DoFRef(vort,multInd[0])/=m_acVolume[vrt];
519 if (
DoFRef(vort,multInd[0])*
DoFRef(vort,multInd[0])>maxvort*maxvort){
520 maxvort =
DoFRef(vort,multInd[0]);
524 grid.template detach_from<Vertex>(m_aVolume);
527 template <
typename TGr
idFunction>
530 vorticityFV1<TGridFunction>(vort,u);
533 vorticityFVCR<TGridFunction>(vort,u);
535 UG_LOG(
"Function type " << vort.local_finite_element_id(0) <<
" not supported in vorticity computation.");
539 template <
typename TGr
idFunction>
542 const number vReferenceValue[])
545 number maxdiff = 0, diffsum = 0;
548 for(
size_t i = 0; i < vPos.size(); ++i)
551 const number ref = vReferenceValue[i];
553 const number localdiff = std::abs(ref-val);
554 maxdiff = std::max(localdiff, maxdiff);
555 diffsum += localdiff;
557 table(i+1, 0) << std::setw(2) << i+1;
558 table(i+1, 1) << std::fixed << std::setprecision(4) << vPos[i];
559 table(i+1, 2) << std::fixed << std::setprecision(8) << val;
560 table(i+1, 3) << std::fixed << std::setprecision(7) << ref;
561 table(i+1, 4) << std::scientific << std::setprecision( 3 ) << localdiff;
564 UG_LOG(
"\t Max Diff: " << maxdiff <<
"\n")
565 UG_LOG(
"\t Average Diff: " << diffsum/vPos.size() <<
"\n\n");
567 UG_LOG(
"DrivenCavityEvalAtPoints: Failed. Compile without dimension 3 to use this command.\n");
571 template <
typename TGr
idFunction>
575 const size_t numGhiaPoints = 17;
577 const number vertGhiaPosX = 0.5;
578 const number vertGhiaPosY[17]={0.0000,0.0547,0.0625,0.0703,0.1016,0.1719,0.2813,0.4531,0.5000,0.6172,0.7344,0.8516,0.9531,0.9609,0.9688,0.9766,1.0000};
579 const number vertGhia_100[17] ={0.,-0.03717,-0.04192,-0.04775,-0.06434,-0.10150,-0.15662,-0.2109,-0.20581,-0.13641,0.00332,0.23151,0.68717,0.73722,0.78871,0.84123,1.};
580 const number vertGhia_400[17] ={0.,-0.08186,-0.09266,-0.10338,-0.14612,-0.24299,-0.32726,-0.17119,-0.11477,0.02135,0.16256,0.29093,0.55892,0.61756,0.68439,0.75837,1.};
581 const number vertGhia_1000[17] ={0.,-0.18109,-0.20196,-0.22220,-0.29730,-0.38289,-0.27805,-0.10648,-0.06080,0.05702,0.18719,0.33304,0.46604,0.51117,0.57492,0.65928,1.};
582 const number vertGhia_3200[17] ={0.00000,-0.32407,-0.35344,-0.37827,-0.41933,-0.34323,-0.24427,-0.086636,-0.04272,0.07156,0.19791,0.34682,0.46101,0.46547,0.48296,0.53236,1.00000};
583 const number vertGhia_5000[17] ={0.00000,-0.41165,-0.42901,-0.43643,-0.40435,-0.33050,-0.22855,-0.07404,-0.03039,0.08183,0.20087,0.33556,0.46036,0.45992,0.46120,0.48223,1.00000};
584 const number vertGhia_7500[17] ={0.00000,-0.43154,-0.43590,-0.43025,-0.38324,-0.32393,-0.23176,-0.07503,-0.03800,0.08342,0.20591,0.34228,0.47167,0.47323,0.47048,0.47244,1.00000};
585 const number vertGhia_10000[17]={0.00000,-0.42735,-0.42537,-0.41657,-0.38000,-0.32709,-0.23186,-0.07540,-0.03111,0.08344,0.20673,0.34635,0.47804,0.48070,0.47783,0.47221,1.00000};
587 const number horizGhiaPosX[17]= {0.0000,0.0625,0.0703,0.0781,0.0938,0.1563,0.2266,0.2344,0.5000,0.8047,0.8594,0.9063,0.9453,0.9531,0.9609,0.9688,1.0000};
588 const number horizGhiaPosY = 0.5;
589 const number horizGhia100[17] ={0.00000,0.09233,0.10091,0.10890,0.12317,0.16077,0.17507,0.17527,0.05454,-0.24533,-0.22445,-0.16914,-0.10313,-0.08864,-0.07391,-0.05906,0.00000};
590 const number horizGhia400[17] ={0.00000,0.18360,0.19713,0.20920,0.22965,0.28124,0.30203,0.30174,0.05186,-0.38598,-0.44993,-0.3827,-0.22847,-0.19254,-0.15663,-0.12146,0.00000};
591 const number horizGhia1000[17] ={0.00000,0.27485,0.29012,0.30353,0.32627,0.37095,0.33075,0.32235,0.02526,-0.31966,-0.42665,-0.51550,-0.39188,-0.33714,-0.27669,-0.21388,0.00000};
592 const number horizGhia3200[17] ={0.00000,0.39560,0.40917,0.41906,0.42768,0.37119,0.29030,0.28188,0.00999,-0.31184,-0.37401,-0.44307,-0.54053,-0.52357,-0.47425,-0.39017,0.00000};
593 const number horizGhia5000[17] ={0.00000,0.42447,0.43329,0.43648,0.42951,0.35368,0.28066,0.27280,0.00945,-0.30018,-0.36214,-0.41442,-0.52876,-0.55408,-0.55069,-0.49774,0.00000};
594 const number horizGhia7500[17] ={0.00000,0.43979,0.44030,0.43564,0.41824,0.35060,0.28117,0.27348,0.00824,-0.30448,-0.36213,-0.41050,-0.48590,-0.52347,-0.55216,-0.53858,0.00000};
595 const number horizGhia10000[17]={0.00000,0.43983,0.43733,0.43124,0.41487,0.35070,0.28003,0.27224,0.00831,-0.30719,-0.36737,-0.41496,-0.45863,-0.49099,-0.52987,-0.54302,0.00000};
597 const number* vertGhia = NULL;
598 const number* horizGhia = NULL;
601 case 100: vertGhia = vertGhia_100; horizGhia = horizGhia100;
break;
602 case 400: vertGhia = vertGhia_400; horizGhia = horizGhia400;
break;
603 case 1000: vertGhia = vertGhia_1000; horizGhia = horizGhia1000;
break;
604 case 3200: vertGhia = vertGhia_3200; horizGhia = horizGhia3200;
break;
605 case 5000: vertGhia = vertGhia_5000; horizGhia = horizGhia5000;
break;
606 case 7500: vertGhia = vertGhia_7500; horizGhia = horizGhia7500;
break;
607 case 10000: vertGhia = vertGhia_10000; horizGhia = horizGhia10000;
break;
612 const number vertBotella_1000[17]={0.0000000 , -0.1812881 , -0.2023300 , -0.2228955 , -0.3004561 , -0.3885691 , -0.2803696 , -0.1081999 , -0.0620561 ,
613 0.0570178 , 0.1886747 , 0.3372212 , 0.4723329 , 0.5169277 , 0.5808359 , 0.6644227 , 1.0000000};
614 const number horizBotella_1000[17]={0.0000000 , 0.2807056 , 0.2962703 , 0.3099097 , 0.3330442 , 0.3769189 , 0.3339924 , 0.3253592 , 0.0257995 ,
615 -0.3202137 , -0.4264545 , -0.5264392 , -0.4103754 , -0.3553213 , -0.2936869 , -0.2279225 , 0.0000000};
618 const number vertUG4_3200[17]={0, -3.565562e-01, -3.854442e-01,-4.083199e-01,-4.329174e-01, -3.455453e-01,-2.425736e-01,-8.123961e-02,-3.689807e-02,7.721821e-02,2.018428e-01,
619 3.482477e-01,4.618284e-01,4.654109e-01,4.811885e-01,5.280763e-01,1};
620 const number horizUG4_3200[17]={0,3.961922e-01,4.113146e-01,4.224736e-01,4.327940e-01,3.771819e-01,2.964934e-01,2.881224e-01,1.425516e-02,-3.136940e-01,
621 -3.787908e-01,-4.436374e-01,-5.672544e-01,-5.610925e-01,-5.200556e-01,-4.390652e-01,0};
624 const size_t numErturkPoints = 23;
625 const number vertErturkPosX = 0.5;
626 const number vertErturkPosY[23]={1.00000,0.99000,0.98000,0.97000,0.96000,0.95000,0.94000,0.93000,0.92000,0.91000,0.90000,0.50000,0.20000,0.18000,0.16000,0.14000,0.12000,0.10000,0.08000,0.06000,0.04000,0.02000,0.00000};
627 const number horizErturkPosX[23]={1.00000,0.98500,0.97000,0.95500,0.94000,0.92500,0.91000,0.89500,0.88000,0.86500,0.85000,0.50000,0.15000,0.13500,0.12000,0.10500,0.09000,0.07500,0.06000,0.04500,0.03000,0.01500,0.00000};
628 const number horizErturkPosY = 0.5;
629 const number horizErturk_1000[23] ={0.00000,-0.09730,-0.21730,-0.34000,-0.44170,-0.50520,-0.52630,-0.51320,-0.48030,-0.44070,-0.40280,0.02580,0.37560,0.37050,0.36050,0.34600,0.32730,0.30410,0.27460,0.23490,0.17920,0.10190,0.00000};
630 const number horizErturk_2500[23] ={0.0000,-0.1675,-0.3725,-0.5192,-0.5603,-0.5268,-0.4741,-0.4321,-0.4042,-0.3843,-0.3671,0.0160,0.3918,0.4078,0.4187,0.4217,0.4142,0.3950,0.3649,0.3238,0.2633,0.1607,0.0000};
631 const number horizErturk_5000[23] ={0.0000,-0.2441,-0.5019,-0.5700,-0.5139,-0.4595,-0.4318,-0.4147,-0.3982,-0.3806,-0.3624,0.0117,0.3699,0.3878,0.4070,0.4260,0.4403,0.4426,0.4258,0.3868,0.3263,0.2160,0.0000};
632 const number horizErturk_7500[23] ={0.0000,-0.2991,-0.5550,-0.5434,-0.4748,-0.4443,-0.4283,-0.4118,-0.3938,-0.3755,-0.3574,0.0099,0.3616,0.3779,0.3950,0.4137,0.4337,0.4495,0.4494,0.4210,0.3608,0.2509,0.0000};
633 const number horizErturk_10000[23]={0.0000,-0.3419,-0.5712,-0.5124,-0.4592,-0.4411,-0.4256,-0.4078,-0.3895,-0.3715,-0.3538,0.0088,0.3562,0.3722,0.3885,0.4056,0.4247,0.4449,0.4566,0.4409,0.3844,0.2756,0.0000};
634 const number horizErturk_12500[23]={0.0000,-0.3762,-0.5694,-0.4899,-0.4534,-0.4388,-0.4221,-0.4040,-0.3859,-0.3682,-0.3508,0.0080,0.3519,0.3678,0.3840,0.4004,0.4180,0.4383,0.4563,0.4522,0.4018,0.2940,0.0000};
635 const number horizErturk_15000[23]={0.0000,-0.4041,-0.5593,-0.4754,-0.4505,-0.4361,-0.4186,-0.4005,-0.3828,-0.3654,-0.3481,0.0074,0.3483,0.3641,0.3801,0.3964,0.4132,0.4323,0.4529,0.4580,0.4152,0.3083,0.0000};
636 const number horizErturk_17500[23]={0.0000,-0.4269,-0.5460,-0.4664,-0.4482,-0.4331,-0.4153,-0.3975,-0.3800,-0.3627,-0.3457,0.0069,0.3452,0.3608,0.3767,0.3929,0.4093,0.4273,0.4484,0.4602,0.4254,0.3197,0.0000};
637 const number horizErturk_20000[23]={0.0000,-0.4457,-0.5321,-0.4605,-0.4459,-0.4300,-0.4122,-0.3946,-0.3774,-0.3603,-0.3434,0.0065,0.3423,0.3579,0.3736,0.3897,0.4060,0.4232,0.4438,0.4601,0.4332,0.3290,0.0000};
638 const number horizErturk_21000[23]={0.0000,-0.4522,-0.5266,-0.4588,-0.4449,-0.4287,-0.4110,-0.3936,-0.3764,-0.3593,-0.3425,0.0063,0.3413,0.3567,0.3725,0.3885,0.4048,0.4218,0.4420,0.4596,0.4357,0.3323,0.0000};
639 const number vertErturk_1000[23] ={1.00000,0.84860,0.70650,0.59170,0.51020,0.45820,0.42760,0.41010,0.39930,0.39130,0.38380,-0.06200,-0.37560,-0.38690,-0.38540,-0.36900,-0.33810,-0.29600,-0.24720,-0.19510,-0.13920,-0.07570,0.00000};
640 const number vertErturk_2500[23] ={1.0000,0.7704,0.5924,0.4971,0.4607,0.4506,0.4470,0.4424,0.4353,0.4256,0.4141,-0.0403,-0.3228,-0.3439,-0.3688,-0.3965,-0.4200,-0.4250,-0.3979,-0.3372,-0.2547,-0.1517,0.0000};
641 const number vertErturk_5000[23] ={1.0000,0.6866,0.5159,0.4749,0.4739,0.4738,0.4683,0.4582,0.4452,0.4307,0.4155,-0.0319,-0.3100,-0.3285,-0.3467,-0.3652,-0.3876,-0.4168,-0.4419,-0.4272,-0.3480,-0.2223,0.0000};
642 const number vertErturk_7500[23] ={1.0000,0.6300,0.4907,0.4817,0.4860,0.4824,0.4723,0.4585,0.4431,0.4275,0.4123,-0.0287,-0.3038,-0.3222,-0.3406,-0.3587,-0.3766,-0.3978,-0.4284,-0.4491,-0.3980,-0.2633,0.0000};
643 const number vertErturk_10000[23]={1.0000,0.5891,0.4837,0.4891,0.4917,0.4843,0.4711,0.4556,0.4398,0.4243,0.4095,-0.0268,-0.2998,-0.3179,-0.3361,-0.3543,-0.3721,-0.3899,-0.4142,-0.4469,-0.4259,-0.2907,0.0000};
644 const number vertErturk_12500[23]={1.0000,0.5587,0.4833,0.4941,0.4937,0.4833,0.4684,0.4523,0.4366,0.4216,0.4070,-0.0256,-0.2967,-0.3146,-0.3326,-0.3506,-0.3685,-0.3859,-0.4054,-0.4380,-0.4407,-0.3113,0.0000};
645 const number vertErturk_15000[23]={1.0000,0.5358,0.4850,0.4969,0.4937,0.4811,0.4653,0.4492,0.4338,0.4190,0.4047,-0.0247,-0.2942,-0.3119,-0.3297,-0.3474,-0.3652,-0.3827,-0.4001,-0.4286,-0.4474,-0.3278,0.0000};
646 const number vertErturk_17500[23]={1.0000,0.5183,0.4871,0.4982,0.4925,0.4784,0.4622,0.4463,0.4312,0.4166,0.4024,-0.0240,-0.2920,-0.3096,-0.3271,-0.3446,-0.3622,-0.3797,-0.3965,-0.4206,-0.4490,-0.3412,0.0000};
647 const number vertErturk_20000[23]={1.0000,0.5048,0.4889,0.4985,0.4906,0.4754,0.4592,0.4436,0.4287,0.4142,0.4001,-0.0234,-0.2899,-0.3074,-0.3248,-0.3422,-0.3595,-0.3769,-0.3936,-0.4143,-0.4475,-0.3523,0.0000};
648 const number vertErturk_21000[23]={1.0000,0.5003,0.4895,0.4983,0.4897,0.4742,0.4580,0.4425,0.4277,0.4132,0.3992,-0.0232,-0.2892,-0.3066,-0.3239,-0.3412,-0.3585,-0.3758,-0.3925,-0.4121,-0.4463,-0.3562,0.0000};
651 const number* horizErturk = NULL;
652 const number* vertErturk = NULL;
655 case 1000: horizErturk = horizErturk_1000; vertErturk = vertErturk_1000;
break;
656 case 2500: horizErturk = horizErturk_2500; vertErturk = vertErturk_2500;
break;
657 case 5000: horizErturk = horizErturk_5000; vertErturk = vertErturk_5000;
break;
658 case 7500: horizErturk = horizErturk_7500; vertErturk = vertErturk_7500;
break;
659 case 10000: horizErturk = horizErturk_10000; vertErturk = vertErturk_10000;
break;
660 case 15000: horizErturk = horizErturk_15000; vertErturk = vertErturk_15000;
break;
661 case 12500: horizErturk = horizErturk_12500; vertErturk = vertErturk_12500;
break;
662 case 17500: horizErturk = horizErturk_17500; vertErturk = vertErturk_17500;
break;
663 case 20000: horizErturk = horizErturk_20000; vertErturk = vertErturk_20000;
break;
664 case 21000: horizErturk = horizErturk_21000; vertErturk = vertErturk_21000;
break;
671 std::vector<MathVector<2> > vPos(numGhiaPoints);
673 if(vertGhia != NULL && horizGhia != NULL)
675 UG_LOG(
" ------ Ghia, Re = " << Re <<
": u values on a vertical line through x = 0.5 ------\n");
676 for(
size_t i = 0; i < numGhiaPoints; ++i) vPos[i] = MathVector<2>(vertGhiaPosX, vertGhiaPosY[i]);
677 DrivenCavityEvalAtPoints<TGridFunction>(vPos, uGFEval, vertGhia);
679 UG_LOG(
" ------ Ghia, Re = " << Re <<
": v values on a horizontal line through y = 0.5 ------\n");
680 for(
size_t i = 0; i < numGhiaPoints; ++i) vPos[i] = MathVector<2>(horizGhiaPosX[i], horizGhiaPosY);
681 DrivenCavityEvalAtPoints<TGridFunction>(vPos, vGFEval, horizGhia);
686 UG_LOG(
" ------ Botella/Peyret, Re = " << Re <<
": u values on a vertical line through x = 0.5 ------\n");
687 for(
size_t i = 0; i < numGhiaPoints; ++i) vPos[i] = MathVector<2>(vertGhiaPosX, vertGhiaPosY[i]);
688 DrivenCavityEvalAtPoints<TGridFunction>(vPos, uGFEval, vertBotella_1000);
690 UG_LOG(
" ------ Botella/Peyret, Re = " << Re <<
": v values on a horizontal line through y = 0.5 ------\n");
691 for(
size_t i = 0; i < numGhiaPoints; ++i) vPos[i] = MathVector<2>(horizGhiaPosX[i], horizGhiaPosY);
692 DrivenCavityEvalAtPoints<TGridFunction>(vPos, vGFEval, horizBotella_1000);
697 UG_LOG(
" ------ ug4, Re = " << Re <<
": u values on a vertical line through x = 0.5 ------\n");
698 for(
size_t i = 0; i < numGhiaPoints; ++i) vPos[i] = MathVector<2>(vertGhiaPosX, vertGhiaPosY[i]);
699 DrivenCavityEvalAtPoints<TGridFunction>(vPos, uGFEval, vertUG4_3200);
701 UG_LOG(
" ------ ug4, Re = " << Re <<
": v values on a horizontal line through y = 0.5 ------\n");
702 for(
size_t i = 0; i < numGhiaPoints; ++i) vPos[i] = MathVector<2>(horizGhiaPosX[i], horizGhiaPosY);
703 DrivenCavityEvalAtPoints<TGridFunction>(vPos, vGFEval, horizUG4_3200);
706 if(horizErturk != NULL && vertErturk != NULL)
708 vPos.resize(numErturkPoints);
709 UG_LOG(
" ------ Erturk, Re = " << Re <<
": u values on a vertical line through x = 0.5 ------\n");
710 for(
size_t i = 0; i < numErturkPoints; ++i) vPos[i] = MathVector<2>(vertErturkPosX, vertErturkPosY[i]);
711 DrivenCavityEvalAtPoints<TGridFunction>(vPos, uGFEval, vertErturk);
713 UG_LOG(
" ------ Erturk, Re = " << Re <<
": v values on a horizontal line through y = 0.5 ------\n");
714 for(
size_t i = 0; i < numErturkPoints; ++i) vPos[i] = MathVector<2>(horizErturkPosX[i], horizErturkPosY);
715 DrivenCavityEvalAtPoints<TGridFunction>(vPos, vGFEval, horizErturk);
731 template<
typename TGr
idFunction>
734 typedef typename TGridFunction::domain_type domain_type;
740 typedef typename TGridFunction::template dim_traits<dim>::const_iterator ElemIterator;
743 typedef typename TGridFunction::template dim_traits<dim>::grid_base_object elem_type;
746 typedef typename elem_type::side side_type;
754 domain_type& domain = *u.domain().get();
759 std::vector<DoFIndex > multInd;
769 for(
int si = 0; si < domain.subset_handler()->
num_subsets(); ++si)
772 ElemIterator iter = u.template begin<elem_type>(si);
773 ElemIterator iterEnd = u.template end<elem_type>(si);
776 for( ;iter !=iterEnd; ++iter)
779 elem_type* elem = *iter;
781 const size_t numVertices = elem->num_vertices();
785 for(
size_t i = 0; i < numVertices; ++i){
786 vVrt[i] = elem->vertex(i);
787 coCoord[i] = posAcc[vVrt[i]];
804 typename grid_type::template traits<side_type>::secure_container sides;
806 UG_ASSERT(
dynamic_cast<elem_type*
>(elem) != NULL,
"Only elements of type elem_type are currently supported");
808 domain.grid()->associated_elements_sorted(sides,
static_cast<elem_type*
>(elem) );
811 std::vector<number> vShape;
814 geo.
update(elem, &(coCoord[0]), domain.subset_handler().get());
816 rTrialSpace.
shapes(vShape, localBary);
818 size_t nofsides = geo.
num_scv();
822 for (
size_t s=0;
s<nofsides;
s++){
824 for (
int d=0;d<
dim;d++){
825 u.dof_indices(sides[
s], d, multInd);
826 localbaryV[d]=
DoFRef(u,multInd[0]);
828 localbaryV *= vShape[
s];
831 for (
size_t i=0;i<nofsides;i++){
834 for (
size_t j=i+1;j<nofsides;j++){
840 if (localCfl>maxCfl) maxCfl=localCfl;
845 UG_LOG(
"Max CFL number is " << maxCfl <<
"\n");
850 template<
typename TGr
idFunction>
858 typedef typename TGridFunction::domain_type domain_type;
864 typedef typename TGridFunction::template dim_traits<dim>::const_iterator ElemIterator;
867 typedef typename TGridFunction::template dim_traits<dim>::grid_base_object elem_type;
870 typedef typename elem_type::side side_type;
876 domain_type& domain = *u.domain().get();
879 std::vector<DoFIndex> multInd;
890 for(
int si = 0; si < domain.subset_handler()->
num_subsets(); ++si)
893 ElemIterator iter = u.template begin<elem_type>(si);
894 ElemIterator iterEnd = u.template end<elem_type>(si);
897 for( ;iter !=iterEnd; ++iter)
900 elem_type* elem = *iter;
902 const size_t numVertices = elem->num_vertices();
906 for(
size_t i = 0; i < numVertices; ++i){
907 vVrt[i] = elem->vertex(i);
908 coCoord[i] = posAcc[vVrt[i]];
925 typename grid_type::template traits<side_type>::secure_container sides;
927 UG_ASSERT(
dynamic_cast<elem_type*
>(elem) != NULL,
"Only elements of type elem_type are currently supported");
929 domain.grid()->associated_elements_sorted(sides,
static_cast<elem_type*
>(elem) );
932 std::vector<number> vShape;
935 geo.
update(elem, &(coCoord[0]), domain.subset_handler().get());
937 rTrialSpace.
shapes(vShape, localBary);
939 size_t nofsides = geo.
num_scv();
944 for (
size_t s=0;
s<nofsides;
s++){
947 for (
int d=0;d<
dim;d++){
948 u.dof_indices(sides[
s], d, multInd);
949 localValue[d]=
DoFRef(u,multInd[0]);
951 localValue *= vShape[
s];
953 elementVolume += scv.
volume();
955 for (
int d=0;d<
dim;d++){
956 totalE += elementVolume*value[d]*value[d];
959 totalVol+=elementVolume;
964 UG_LOG(
"Total kinetic energy in domain is " << totalE <<
"\n");
981 template <
typename TGr
idFunction>
984 const char* BndSubsets,
const char* InnerSubsets,
990 typedef typename TGridFunction::template dim_traits<dim>::grid_base_object grid_base_object;
991 typedef typename TGridFunction::template dim_traits<dim>::const_iterator const_iterator;
995 SubsetGroup innerSSGrp(spGridFct->domain()->subset_handler());
996 if(InnerSubsets != NULL){
999 UG_THROW(
"DragDrift: Subsets '"<<InnerSubsets<<
"' do not have same dimension."
1000 "Can not integrate on subsets of different dimensions.");
1008 SubsetGroup bndSSGrp(spGridFct->domain()->subset_handler());
1009 if(BndSubsets != NULL)
1012 UG_THROW(
"DragDrift: No boundary subsets passed.");
1015 const FunctionGroup vFctID = spGridFct->fct_grp_by_name(vCmp);
1016 std::vector<LFEID> vLFEID;
1017 for(
size_t fct = 0; fct < vFctID.
size(); ++fct){
1018 vLFEID.push_back(spGridFct->lfeid(vFctID[fct]));
1026 for(
size_t i = 0; i < innerSSGrp.
size(); ++i)
1029 const int si = innerSSGrp[i];
1035 if(innerSSGrp.
dim(i) !=
dim)
1036 UG_THROW(
"DragDrift: Dimension of inner subset is "<<
1037 innerSSGrp.
dim(i)<<
", but only World Dimension "<<
dim<<
1038 " subsets can be used for inner subsets.");
1042 const_iterator iterBegin = spGridFct->template begin<grid_base_object>(si);
1043 const_iterator iterEnd = spGridFct->template end<grid_base_object>(si);
1044 const_iterator iter = iterBegin;
1047 = spGridFct->domain()->position_accessor();
1049 Grid&
grid = *spGridFct->domain()->grid();
1057 std::vector<MathVector<WorldDim> > vCorner;
1058 std::vector<int> vSubsetIndex;
1061 for(; iter != iterEnd; ++iter)
1064 Element* pElem = *iter;
1074 grid.associated_elements_sorted(vSide, pElem);
1075 vSubsetIndex.resize(vSide.
size());
1076 for(
size_t i = 0; i < vSide.
size(); ++i)
1080 = ReferenceMappingProvider::get<dim, WorldDim>(elemRoid, vCorner);
1083 = ReferenceElementProvider::get<dim>(elemRoid);
1086 std::vector<DoFIndex> vInd;
1087 std::vector<std::vector<number> > vvValue(vFctID.
size());
1088 for(
size_t fct = 0; fct < vvValue.size(); ++fct){
1089 spGridFct->dof_indices(pElem, vFctID[fct], vInd);
1090 vvValue[fct].resize(vInd.size());
1091 for(
size_t sh = 0; sh < vInd.size(); ++sh)
1092 vvValue[fct][sh] =
DoFRef(*spGridFct, vInd[sh]);
1094 const static int _P_ =
dim;
1097 for(
size_t side = 0; side < vSide.
size(); ++side)
1100 if(!bndSSGrp.
contains(vSubsetIndex[side]))
continue;
1103 Side* pSide = vSide[side];
1105 std::vector<MathVector<WorldDim> > vSideCorner(rRefElem.
num(
dim-1, side, 0));
1106 std::vector<MathVector<dim> > vLocalSideCorner(rRefElem.
num(
dim-1, side, 0));
1107 for(
size_t co = 0; co < vSideCorner.size(); ++co){
1108 vSideCorner[co] = vCorner[rRefElem.
id(
dim-1, side, 0, co)];
1109 vLocalSideCorner[co] = rRefElem.
corner(rRefElem.
id(
dim-1, side, 0, co));
1119 ElementNormal<WorldDim>(sideRoid, Normal, &vSideCorner[0]);
1125 Tangental[0] = Normal[
dim-1];
1126 Tangental[
dim-1] = -Normal[0];
1129 const number* vWeight = rSideQuadRule.weights();
1130 const size_t nip = rSideQuadRule.
size();
1131 std::vector<MathVector<dim> > vLocalIP(nip);
1132 std::vector<MathVector<dim> > vGlobalIP(nip);
1137 for(
size_t ip = 0; ip < nip; ++ip)
1138 map.local_to_global(vLocalIP[ip], rSideQuadRule.point(ip));
1140 for(
size_t ip = 0; ip < nip; ++ip)
1147 map2.jacobian_transposed(&(vJT[0]), rSideQuadRule.points(), nip);
1149 std::vector<MathMatrix<dim, WorldDim> > vElemJT(nip);
1153 for(
size_t ip = 0; ip < nip; ++ip)
1156 std::vector<MathVector<dim> > vvLocGradV[
dim];
1157 std::vector<MathVector<dim> > vvGradV[
dim];
1160 for(
int d1 = 0; d1 <
dim; ++d1){
1162 LocalFiniteElementProvider::get<dim>(elemRoid, vLFEID[d1]);
1163 rTrialSpaceP.
grads(vvLocGradV[d1], vLocalIP[ip]);
1165 vvGradV[d1].resize(vvLocGradV[d1].size());
1166 for(
size_t sh = 0; sh < vvGradV[d1].size(); ++sh)
1167 MatVecMult(vvGradV[d1][sh], JTInv, vvLocGradV[d1][sh]);
1171 for(
int d1 = 0; d1 <
dim; ++d1){
1172 for(
int d2 = 0; d2 <
dim; ++d2){
1173 gradVel(d1, d2) = 0.0;
1174 for(
size_t sh = 0; sh < vvValue[d1].size(); ++sh)
1175 gradVel(d1, d2) += vvValue[d1][sh] * vvGradV[d1][sh][d2];
1181 LocalFiniteElementProvider::get<dim>(elemRoid, vLFEID[_P_]);
1182 std::vector<number> vShapeP;
1183 rTrialSpaceP.
shapes(vShapeP, vLocalIP[ip]);
1186 for(
size_t sh = 0; sh < vvValue[_P_].size(); ++sh)
1187 pressure += vShapeP[sh] * vvValue[_P_][sh];
1194 const number weightIP = vWeight[ip];
1200 int_drag += weightIP * det *
1201 (kinVisco*density *
VecDot(diffFlux, Tangental) * Normal[
dim-1]
1202 - pressure * Normal[0]);
1203 int_lift -= weightIP * det *
1204 (kinVisco*density *
VecDot(diffFlux, Tangental) * Normal[0]
1205 + pressure * Normal[
dim-1]);
1224 std::vector<number> vals(2);
size_t allreduce(const size_t &t, pcl::ReduceOperation op) const
const MathVector< worldDim > & global_grad(size_t sh) const
const MathVector< worldDim > & global_ip() const
const SCV & scv(size_t i) const
void update(GridObject *elem, const MathVector< worldDim > *vCornerCoords, const ISubsetHandler *ish=NULL)
const MathVector< dim > & local_ip() const
const MathVector< worldDim > & global_grad(size_t sh) const
const SCV & scv(size_t i) const
void update(GridObject *elem, const MathVector< worldDim > *vCornerCoords, const ISubsetHandler *ish=NULL)
const MathVector< dim, int > * corner() const
virtual void jacobian_transposed(MathMatrix< dim, worldDim > &JT, const MathVector< dim > &locPos) const=0
virtual void local_to_global(MathVector< worldDim > &globPos, const MathVector< dim > &locPos) const=0
virtual void global_to_local(MathVector< dim > &locPos, const MathVector< worldDim > &globPos, const size_t maxIter=1000, const number tol=1e-10) const=0
void evaluate_global(number &value, const MathVector< dim > &x) const
int get_subset_index(const char *name) const
virtual void grads(std::vector< std::vector< grad_type > > &vvGrad, const std::vector< MathVector< dim > > &vLocPos) const=0
virtual void shapes(std::vector< std::vector< shape_type > > &vvShape, const std::vector< MathVector< dim > > &vLocPos) const=0
bool is_slave(TElem *) const
static const QuadratureRule< TDim > & get(ReferenceObjectID roid, size_t order, QuadType type=BEST)
size_t num(int dim) const
int id(int dim_i, size_t i, int dim_j, size_t j) const
static DimReferenceMapping< TDim, TWorldDim > & get(ReferenceObjectID roid)
bool contains(const char *name) const
void add(const char *name)
Grid::VertexAttachmentAccessor< position_attachment_type > position_accessor_type
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)
MathMatrix< N, M, T >::value_type Inverse(MathMatrix< N, M, T > &mOut, const MathMatrix< M, N, T > &m)
vector< string > TokenizeString(const char *str, const char delimiter=',')
#define UG_ASSERT(expr, msg)
void MatVecMult(vector_t_out &vOut, const matrix_t &m, const vector_t_in &v)
vector_t::value_type VecTwoNormSq(const vector_t &v)
void VecNormalize(vector_t &vOut, const vector_t &v)
void VecSubtract(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
void VecScale(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
int local(bglp_vertex_descriptor p)
const number & DoFRef(const TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
ElementStorage< Vertex >::SectionContainer::iterator VertexIterator
std::vector< number > DragLift(SmartPtr< TGridFunction > spGridFct, const char *vCmp, const char *BndSubsets, const char *InnerSubsets, number kinVisco, number density, int quadOrder)
Definition: navier_stokes_tools.h:982
void vorticityFV1(TGridFunction &vort, TGridFunction &u)
Definition: navier_stokes_tools.h:387
bool SameDimensionsInAllSubsets(const SubsetGroup &subsetGroup)
void DrivenCavityLinesEval(SmartPtr< TGridFunction > u, std::vector< std::string > vVelCmp, size_t Re)
Definition: navier_stokes_tools.h:572
void DrivenCavityEvalAtPoints(const std::vector< MathVector< 2 > > &vPos, GlobalGridFunctionNumberData< TGridFunction > &GFEval, const number vReferenceValue[])
Definition: navier_stokes_tools.h:540
void vorticityFVCR(TGridFunction &vort, TGridFunction &u)
Definition: navier_stokes_tools.h:235
number kineticEnergy(TGridFunction &u)
Definition: navier_stokes_tools.h:851
void interpolateCRToLagrange(TGridFunction &uLagrange, TGridFunction &uCR)
Definition: navier_stokes_tools.h:54
void vorticity(TGridFunction &vort, TGridFunction &u)
Definition: navier_stokes_tools.h:528
void RemoveLowerDimSubsets(SubsetGroup &subsetGroup)
MathMatrix< 0, 0, T >::value_type SqrtGramDeterminant(const MathMatrix< 0, 0, T > &m)
void cflNumber(TGridFunction &u, number deltaT)
Definition: navier_stokes_tools.h:732
geometry_traits< TElem >::const_iterator const_iterator