150 if(m_NumberLevels==(
int)max_number_levels)
151 UG_THROW (
"FractDimadapt: Not enough Levels allocated!");
161 UG_LOG(
"mark vertices\n");
164 for (
int lev = 0; lev < m_NumberLevels; lev++)
168 for (
size_t i = 0; i < m_fractSsGrp.size (); i++)
170 int si = m_fractSsGrp [i];
172 t_elem_iter list_end = m_spSH->template end<element_type> (si, lev);
173 for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, lev);
174 iElem != list_end; ++iElem)
177 for (
size_t j = 0; j < elem->num_vertices (); j++)
179 Vertex * vert = elem->vertex(j);
180 m_aaVertAuxMarks [vert] = (! vert->
is_constrained ())? F_INNER : F_OUTER;
189 for (
int si = 0; si < m_spSH->num_subsets (); si++)
192 t_elem_iter list_end = m_spSH->template end<element_type> (si, lev);
193 for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, lev);
194 iElem != list_end; ++iElem)
197 for (
size_t i = 0; i < elem->num_vertices (); i++)
198 m_aaVertAuxMarks [elem->vertex(i)] = F_OUTER;
205 NumberFractNodes[0] = 0.0;
206 for (
size_t i = 0; i < m_fractSsGrp.size (); i++)
208 int si = m_fractSsGrp [i];
209 t_elem_iter list_end = m_spSH->template end<element_type> (si, 0);
210 for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, 0);
211 iElem != list_end; ++iElem)
214 for (
size_t j = 0; j < elem->num_vertices (); j++)
216 Vertex * vert = elem->vertex(j);
217 int mark = m_aaVertAuxMarks [vert];
220 FractNode[0][NumberFractNodes[0]][0] = vert;
221 NumberFractNodes[0]++;
222 if(NumberFractNodes[0]==(
int)max_number_fracture_midnodes)
223 UG_THROW (
"FractDimadapt: Not enough Fracture nodes allocated!");
224 m_aaVertAuxMarks [vert] = F_MID;
231 number c =
VecDot(posAcc[FractNode[0][0][0]],m_fractNormal);
232 for (
int lev = 1; lev < m_NumberLevels; lev++)
234 NumberFractNodes[lev] = 0.0;
235 for (
size_t i = 0; i < m_fractSsGrp.size (); i++)
237 int si = m_fractSsGrp [i];
238 t_elem_iter list_end = m_spSH->template end<element_type> (si, lev);
239 for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, lev);
240 iElem != list_end; ++iElem)
243 for (
size_t j = 0; j < elem->num_vertices (); j++)
245 Vertex * vert = elem->vertex(j);
246 int mark = m_aaVertAuxMarks [vert];
252 FractNode[lev][NumberFractNodes[lev]][0] = vert;
253 NumberFractVertNodes[lev][NumberFractNodes[lev]] = 0.0;
254 NumberFractNodes[lev]++;
255 if(NumberFractNodes[lev]==(
int)max_number_fracture_midnodes)
256 UG_THROW (
"FractDimadapt: Not enough Fracture nodes allocated!");
257 m_aaVertAuxMarks [vert] = F_MID;
268 tangential[0]= m_fractNormal[1];
269 tangential[1]= -m_fractNormal[0];
271 for (
int lev = 0; lev < m_NumberLevels; lev++)
273 int TriangleCount = 0;
274 std::vector<int> bnd_count(NumberFractNodes[lev]);
275 for (
int k = 0; k < NumberFractNodes[lev]; k++)
277 for (
size_t i = 0; i < m_fractSsGrp.size (); i++)
279 int si = m_fractSsGrp [i];
280 t_elem_iter list_end = m_spSH->template end<element_type> (si, lev);
281 for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, lev);
282 iElem != list_end; ++iElem)
285 for (
size_t j = 0; j < elem->num_vertices (); j++)
287 Vertex * vert = elem->vertex(j);
288 int mark = m_aaVertAuxMarks [vert];
289 if(mark == F_MID || mark == F_BND || mark == F_VERT)
292 UG_THROW (
"FractDimadapt:Fracture marks not set correctly!");
297 for (
int k = 0; k < NumberFractNodes[lev]; k++)
299 Vertex * midvert = FractNode[lev][k][0];
301 c_b =
VecDot(posAcc[midvert],tangential);
302 if(fabs(c_b-c_a)<eps)
307 FractNode[lev][k][bnd_count[k]+1] = vert;
309 m_aaVertAuxMarks [vert] = F_BND;
310 k=NumberFractNodes[lev];
312 else if(mark == F_INNER)
315 FractNode[lev][k][3+NumberFractVertNodes[lev][k]] = vert;
316 NumberFractVertNodes[lev][k]++;
317 if(NumberFractVertNodes[lev][k]== (
int)max_number_fracture_layers)
318 UG_THROW (
"FractDimadapt: Not enough Fracture vert nodes allocated!");
319 m_FractureIsFullDimensional = 1;
320 m_aaVertAuxMarks [vert] = F_VERT;
321 k=NumberFractNodes[lev];
322 if(m_FirstFullLevel < 0)
324 m_FirstFullLevel = lev;
328 UG_THROW (
"FractDimadapt:Fracture marks maybe not set correctly!");
334 m_aaVertAuxMarks [vert] = F_CORNER;
335 CornerTriangleList[lev][TriangleCount] = elem;
338 if(TriangleCount > 4)
339 UG_THROW (
"FractDimadapt: Something wrong with corner triangle identification"<<TriangleCount);
349 for (
int k = 0; k < NumberFractNodes[lev]; k++)
358 FractNode[lev][k][1] = NULL;
359 FractNode[lev][k][2] = NULL;
369 UG_THROW (
"FractDimadapt: Wrong number fract boundary nodes!"<<bnd_count[k]);
373 if(deg_count!=0 && deg_count!=2)
374 UG_THROW (
"FractDimadapt: Wrong number fract boundary nodes (degcount)!");
380 if(m_FractureIsFullDimensional < 0)
383 int lev = m_NumberLevels-1;
387 coords_1 = posAcc[FractNode[lev][k][0]];
388 coords_2 = posAcc[FractNode[lev][k][1]];
392 m_FractureIsFullDimensional = 1;
393 m_FirstFullLevel = m_NumberLevels;
398 if(m_FractureIsFullDimensional == 1)
400 for (
int lev = 0; lev < m_NumberLevels; lev++)
402 for (
int k = 0; k < NumberFractNodes[lev]; k++)
405 coords_1 = posAcc[FractNode[lev][k][0]];
406 coords_2 = posAcc[FractNode[lev][k][1]];
408 m_aaVertexShift [FractNode[lev][k][1]] = shift;
409 coords_2 = posAcc[FractNode[lev][k][2]];
411 m_aaVertexShift [FractNode[lev][k][2]] = shift;
436 for (
int lev = 0; lev < m_NumberLevels; lev++)
438 for (
size_t i = 0; i < m_fractSsGrp.size (); i++)
440 int si = m_fractSsGrp [i];
441 t_elem_iter list_end = m_spSH->template end<element_type> (si, lev);
442 for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, lev);
443 iElem != list_end; ++iElem)
451 for (
size_t j = 0; j < edge_list.
size (); j++)
453 Edge * edge = edge_list [j];
454 bool has_inner =
false, has_outer =
false;
456 bool has_vert =
false;
459 for (
size_t co = 0; co < n_co; co++)
461 int mark = vert_mark (edge->
vertex (co));
464 else if (mark == F_MID)
466 else if (mark == F_CORNER)
468 else if (mark == F_VERT)
471 UG_THROW (
"FractDimadapt:Fracture marks maybe not set correctly!");
474 if (has_inner && has_outer)
475 m_aaEdgeAuxMarks [edge] = F_VERT;
477 m_aaEdgeAuxMarks [edge] = F_VERT;
480 m_aaEdgeAuxMarks [edge] = F_MID;
484 m_aaEdgeAuxMarks [edge] = F_BND;
543 const std::vector<number> pnt,
554 std::vector<DoFIndex> multInd;
558 number c_1,c_2,c_ave=0,c_jump=0;
559 number p_1,p_2,p_ave=0,p_jump=0;
564 for (
int d=0;d < dim;d++)
565 eval_point[d] = pnt[d];
566 int toplevel = m_NumberLevels-1;
569 if(m_FirstFullLevel < 0)
570 UG_THROW (
"FractDimadapt:get_ave_val: FirstFullLevel not set");
576 for (
int k = 0; k < NumberFractNodes[toplevel]; k++)
578 coords_1 = posAcc[FractNode[toplevel][k][0]];
584 if(m_FractureIsFullDimensional == 1)
587 Vertex * vert = FractNode[toplevel][k][0];
588 u.dof_indices(vert, 0, multInd);
589 c_ave = 2*
DoFRef(u,multInd[0]);
590 u.dof_indices(vert, 1, multInd);
591 p_ave = 2*
DoFRef(u,multInd[0]);
592 for (
int i = 3; i < NumberFractVertNodes[toplevel][k]+3; i++)
594 u.dof_indices(FractNode[toplevel][k][i], 0, multInd);
595 c_ave += 2*
DoFRef(u,multInd[0]);
596 u.dof_indices(FractNode[toplevel][k][i], 1, multInd);
597 p_ave += 2*
DoFRef(u,multInd[0]);
600 coords_1 = posAcc[FractNode[toplevel][k][1]];
601 u.dof_indices(FractNode[toplevel][k][1], 0, multInd);
603 u.dof_indices(FractNode[toplevel][k][1], 1, multInd);
605 coords_2 = posAcc[FractNode[toplevel][k][2]];
606 u.dof_indices(FractNode[toplevel][k][2], 0, multInd);
608 u.dof_indices(FractNode[toplevel][k][2], 1, multInd);
614 if(diff[dim-1]>1e-10)
619 else if(diff[dim-1]<-1e-10)
624 else if(fabs(diff[dim-1])<1e-10)
626 if(fabs(diff[0])<1e-10 && fabs(diff[dim-2])<1e-10)
628 UG_THROW (
"FractDimadapt:get_ave_val: full-dim fracture with Fracture width 0!");
630 UG_THROW (
"FractDimadapt:get_ave_val: Horizontal fracture not yet considered for jump");
635 c_ave /= (NumberFractVertNodes[toplevel][k]+1)*2+2;
636 p_ave /= (NumberFractVertNodes[toplevel][k]+1)*2+2;
641 Vertex * vert = FractNode[toplevel][k][0];
642 u.dof_indices(vert, 0, multInd);
643 c_ave =
DoFRef(u,multInd[0]);
644 u.dof_indices(vert, 1, multInd);
645 p_ave =
DoFRef(u,multInd[0]);
647 u.dof_indices(FractNode[toplevel][k][1], 0, multInd);
649 u.dof_indices(FractNode[toplevel][k][1], 1, multInd);
652 u.dof_indices(FractNode[toplevel][k][2], 0, multInd);
654 u.dof_indices(FractNode[toplevel][k][2], 1, multInd);
661 if(shift[dim-1]>1e-10)
666 else if(shift[dim-1]<1e-10)
671 else if(fabs(shift[dim-1])<1e-10)
673 if(fabs(shift[0])<1e-10 && fabs(shift[1])<1e-10)
675 UG_THROW (
"FractDimadapt:get_ave_val: shift not set!");
677 UG_THROW (
"FractDimadapt:get_ave_val: Horizontal fracture not yet considered for jump");
686 density_func(c_ave,density,buffer);
687 number p_hydro = m_aperture*density*m_Gravity[dim-1];
693 k=NumberFractNodes[toplevel];
697 UG_THROW (
"FractDimadapt:get_ave_val: No inner fracture node at this position found!");
699 UG_LOG(
"\t t " << time<<
" c_ave "<<c_ave<<
" c_1 "<<c_1<<
" c_2 "<<c_2<<
" c_jump "<<c_jump <<
"\n");
700 UG_LOG(
"\t t " << time<<
" p_ave "<<p_ave<<
" p_1 "<<p_1<<
" p_2 "<<p_2<<
" p_jump "<<p_jump <<
"\n");
702 file = fopen(
"ave_c.dat",
"a");
703 fprintf(file,
"%g %g %g\n",time,c_ave,c_jump);
705 file = fopen(
"ave_p.dat",
"a");
706 fprintf(file,
"%g %g %g\n",time,p_ave,p_jump);
723 UG_LOG(
"evaluate_criterion\n");
725 if(m_permeability_f==0.0)
726 UG_THROW (
"FractDimadapt: Permeability not set. Use 'add_permeability'");
729 UG_THROW (
"FractDimadapt:evaluate_crit: Fracture manager not closed");
733 static const size_t maxLayerSideCorners = fract_manager_type::maxLayerSideCorners;
750 std::vector<DoFIndex> multInd;
764 number scale = m_permeability_f;
769 for (
size_t j = 0; j < m_fractSsGrp.size (); j++)
771 int si = m_fractSsGrp [j];
772 bool isFracture = fractManager->
contains (si);
774 for (t_elem_iter iElem = m_spSH->template begin<element_type> (si,m_NumberLevels-1);
775 iElem != m_spSH->template end<element_type> (si,m_NumberLevels-1); ++iElem)
780 const size_t numVertices = elem->num_vertices();
783 for(
size_t i = 0; i < numVertices; ++i)
784 coCoord[i] = posAcc[elem->vertex(i)];
789 TConsGravity ConsGravityMethod;
792 size_t n_co, inner_side_idx, outer_side_idx;
793 size_t inner_side_corners [maxLayerSideCorners];
794 size_t outer_side_corners [maxLayerSideCorners];
795 DFside_type * inner_side, * outer_side;
796 size_t ass_co [2*maxLayerSideCorners];
798 number DensityCo[maxLayerSideCorners];
799 number ViscosityCo[maxLayerSideCorners];
800 number cValue[maxLayerSideCorners];
801 number pValue[maxLayerSideCorners];
805 inner_side, inner_side_idx, inner_side_corners,
806 outer_side, outer_side_idx, outer_side_corners, ass_co);
812 for (
size_t co = 0; co < n_co; co++)
813 vSideCornerCoords [co] = posAcc [elem->vertex(inner_side_corners[co])];
814 lowgeo->
update (inner_side, vSideCornerCoords, m_spSH.get());
816 UG_CATCH_THROW(
"EvaluateCriterion: Cannot update the Finite Volume Geometry for a fracture element.");
817 const size_t numSh = lowgeo->
num_sh();
818 const size_t numScvf = lowgeo->
num_scvf();
821 for (
size_t sh=0; sh < numSh; sh++)
823 size_t co = inner_side_corners[sh];
824 Vertex *vert = elem->vertex(co);
825 u.dof_indices(vert, 0, multInd);
826 cValue[sh] =
DoFRef(u,multInd[0]);
827 density_func(cValue[sh],DensityCo[sh],d_Density);
828 viscosity_func(cValue[sh],ViscosityCo[sh],d_Visc);
829 u.dof_indices(vert, 1, multInd);
830 pValue[sh] =
DoFRef(u,multInd[0]);
836 ConsGravityMethod.template prepare<dim>
837 (vConsGravity, numSh, lowgeo->
corners(), DensityCo, m_Gravity);
839 UG_CATCH_THROW (
"EvaluateCriterion: Cannot prepare Consistent Gravity.");
841 for (
size_t ip=0; ip < numScvf; ip++)
852 const typename TFractFVGeom::SCVF& scvf = lowgeo->
scvf(ip);
857 for(
size_t co = 0 ; co < scvf.num_sh(); ++co){
860 c_ip += cValue[co] * scvf.shape(co);
862 density_func(c_ip,DensityIP,d_Density);
863 viscosity_func(c_ip,ViscosityIP,d_Visc);
867 ConsGravityMethod.template compute<dim>
868 (Vel, scvf.local_ip(), scvf.JTInv(), scvf.local_grad_vector(), vConsGravity);
873 VecScale (DarcyVel, Vel, m_permeability_f / ViscosityIP);
875 absDarcy = fabs(absDarcy);
879 vorticity = m_permeability_f / ViscosityIP * d_Density * m_Gravity[1] * grad_c_ip[0];
882 q_rot = m_aperture/2 * m_permeability_f/m_permeability_m *
vorticity
883 * c_ip / omega_theta;
887 theta = absDarcy / fabs(q_rot);
889 theta_inv = fabs(q_rot) / absDarcy;
892 if(theta > theta_max)
894 if(theta_inv > theta_inv_max)
895 theta_inv_max = theta_inv;
898 if(q_rot > q_rot_max)
902 if(theta < theta_min || theta_min==0)
908 std::vector<number> DensityCo(numVertices);
909 std::vector<number> ViscosityCo(numVertices);
910 std::vector<number> cValue(numVertices);
911 std::vector<number> pValue(numVertices);
915 TConsGravity ConsGravityMethod;
919 fullgeo.
update(elem, &(coCoord[0]), u.domain()->subset_handler().get());
920 const size_t numSh = fullgeo.
num_sh();
921 const size_t numScvf = fullgeo.
num_scvf();
923 for (
size_t co=0; co < numVertices; co++)
925 Vertex *vert = elem->vertex(co);
926 u.dof_indices(vert, 0, multInd);
927 cValue[co] =
DoFRef(u,multInd[0]);
928 density_func(cValue[co],DensityCo[co],d_Density);
929 viscosity_func(cValue[co],ViscosityCo[co],d_Visc);
930 u.dof_indices(vert, 1, multInd);
931 pValue[co] =
DoFRef(u,multInd[0]);
937 ConsGravityMethod.template prepare<dim>
938 (vConsGravity, numSh, coCoord, &DensityCo[0], m_Gravity);
940 UG_CATCH_THROW (
"EvaluateCriterion: Cannot prepare Consistent Gravity.");
942 for (
size_t ip=0;ip < numScvf;ip++)
959 for(
size_t co = 0 ; co < scvf.
num_sh(); ++co){
962 c_ip += cValue[co] * scvf.
shape(co);
964 density_func(c_ip,DensityIP,d_Density);
965 viscosity_func(c_ip,ViscosityIP,d_Visc);
969 ConsGravityMethod.template compute<dim>
976 VecScale (DarcyVel, Vel, m_permeability_f / ViscosityIP);
978 absDarcy = fabs(absDarcy);
982 vorticity = m_permeability_f / ViscosityIP * d_Density * m_Gravity[1] * grad_c_ip[0];
984 vort_test = m_permeability_f / ViscosityIP * 25.0/1025.0 * 1000 / (1 - 25.0/1025.0 *c_ip) / (1 - 25.0/1025.0 *c_ip)* m_Gravity[1] * grad_c_ip[0];
987 q_rot = m_aperture/2 * m_permeability_f/m_permeability_m *
vorticity * c_ip / omega_theta;
989 test = m_aperture * m_permeability_f/m_permeability_m * vort_test * c_ip / 50.0 /10.0 /0.25;
993 theta = absDarcy / fabs(q_rot);
995 theta_inv = fabs(q_rot) / absDarcy;
1000 if(theta > theta_max)
1002 if(theta_inv > theta_inv_max)
1003 theta_inv_max = theta_inv;
1004 if(absDarcy > q_max)
1006 if(q_rot > q_rot_max)
1012 if(theta < theta_min || theta_min==0)
1020 number test = q_max / test_max;
1024 UG_LOG(
"\t Min: theta_min: "<< theta_min<<
" theta_inv_max: " << theta_inv_max<<
"\n");
1026 file = fopen(
"crit.dat",
"a");
1027 fprintf(file,
"%g: theta_min: %g theta_inv_max: %g theta_UG3 %g\n",time,theta_min/scale,theta_inv_max*scale,test);
1030 return theta_inv_max*scale;
1121 std::vector<DoFIndex> multInd;
1123 UG_LOG(
"transfer full to low \n");
1125 int lev = m_NumberLevels-1;
1128 number p_1_korr,p_2_korr;
1131 for (
int k = 0; k < NumberFractNodes[lev]; k++)
1135 Vertex * vert = FractNode[lev][k][0];
1136 u.dof_indices(vert, 0, multInd);
1137 c_ave = 2*
DoFRef(u,multInd[0]);
1138 u.dof_indices(vert, 1, multInd);
1139 p_ave = 2*
DoFRef(u,multInd[0]);
1141 for (
int i = 3; i < NumberFractVertNodes[lev][k]+3; i++)
1143 u.dof_indices(FractNode[lev][k][i], 0, multInd);
1144 c_ave += 2*
DoFRef(u,multInd[0]);
1145 u.dof_indices(FractNode[lev][k][i], 1, multInd);
1146 p_ave += 2*
DoFRef(u,multInd[0]);
1149 u.dof_indices(FractNode[lev][k][1], 0, multInd);
1150 c_1=
DoFRef(u,multInd[0]);
1151 u.dof_indices(FractNode[lev][k][1], 1, multInd);
1152 p_1=
DoFRef(u,multInd[0]);
1153 u.dof_indices(FractNode[lev][k][2], 0, multInd);
1154 c_2=
DoFRef(u,multInd[0]);
1155 u.dof_indices(FractNode[lev][k][2], 1, multInd);
1156 p_2=
DoFRef(u,multInd[0]);
1160 c_ave /= (NumberFractVertNodes[lev][k]+1)*2+2;
1161 p_ave /= (NumberFractVertNodes[lev][k]+1)*2+2;
1167 density_func(c_1,density,buffer);
1169 p_1_korr = p_1 + shift[dim-1]*density*m_Gravity[dim-1];
1170 density_func(c_2,density,buffer);
1171 shift = vert_shift(FractNode[lev][k][2]);
1172 p_2_korr = p_2 + shift[dim-1]*density*m_Gravity[dim-1];
1175 u.dof_indices(FractNode[lev][k][1], 1, multInd);
1176 DoFRef(u,multInd[0]) = p_1_korr;
1177 u.dof_indices(FractNode[lev][k][2], 1, multInd);
1178 DoFRef(u,multInd[0]) = p_2_korr;
1182 u.dof_indices(vert, 0, multInd);
1183 DoFRef(u,multInd[0]) = c_ave;
1184 u.dof_indices(vert, 1, multInd);
1185 DoFRef(u,multInd[0]) = p_ave;
1314 std::vector<DoFIndex> multInd;
1319 UG_LOG(
"transfer low to full \n");
1321 int lev = m_NumberLevels-1;
1322 for (
int k = 0; k < NumberFractNodes[lev]; k++)
1334 Vertex * vert = FractNode[lev][k][0];
1335 u.dof_indices(vert, 0, multInd);
1336 mid[0] =
DoFRef(u,multInd[0]);
1337 u.dof_indices(vert, 1, multInd);
1338 mid[1] =
DoFRef(u,multInd[0]);
1343 vert = FractNode[lev][k][1];
1344 u.dof_indices(vert, 0, multInd);
1345 bnd[0][0]=
DoFRef(u,multInd[0]);
1346 u.dof_indices(vert, 1, multInd);
1347 bnd[0][1]=
DoFRef(u,multInd[0]);
1348 bndpoint[0]=posAcc[vert];
1352 density_func(bnd[0][0],density,buffer);
1354 bnd[0][1] = bnd[0][1] - shift[dim-1]*density*m_Gravity[dim-1];
1355 DoFRef(u,multInd[0]) = bnd[0][1];
1359 vert = FractNode[lev][k][2];
1360 u.dof_indices(vert, 0, multInd);
1361 bnd[1][0]=
DoFRef(u,multInd[0]);
1362 u.dof_indices(vert, 1, multInd);
1363 bnd[1][1]=
DoFRef(u,multInd[0]);
1364 bndpoint[1]=posAcc[vert];
1368 density_func(bnd[1][0],density,buffer);
1370 bnd[1][1] = bnd[1][1] - shift[dim-1]*density*m_Gravity[dim-1];
1371 DoFRef(u,multInd[0]) = bnd[1][1];
1377 calculate_interpolation(bnd,mid,bndpoint,param);
1378 size_t use_linear = 0;
1379 for (
int i = 0; i < NumberFractVertNodes[lev][k]+3; i++)
1385 vert = FractNode[lev][k][i];
1386 calcpoint = posAcc[vert];
1391 for(
size_t j=0; j<2; j++)
1393 inner[j] = param[j][0]*x*x + param[j][1]*x + param[j][2];
1396 u.dof_indices(vert, j, multInd);
1397 DoFRef(u,multInd[0]) = inner[j];
1402 if(inner[0]<-1e-10 || inner[0]>1 || inner[1]<-1e-10)
1404 UG_LOG (
"FractDimadapt:transfer_low_to_full: c or p neg. Use linear fct instead");
1406 i=NumberFractVertNodes[lev][k]+3;
1411 for (
int i = 0; i < NumberFractVertNodes[lev][k]+3; i++)
1416 vert = FractNode[lev][k][i];
1424 for(
size_t j=0; j<2; j++)
1426 inner[j] = (1-x) * bnd[0][j] + x * bnd[1][j];
1429 u.dof_indices(vert, j, multInd);
1430 DoFRef(u,multInd[0]) = inner[j];
1451 if(m_FirstFullLevel < 0)
1452 UG_THROW (
"FractDimadapt:grid_transfer_full_to_low: FirstFullLevel not set");
1454 typedef typename domain_type::position_attachment_type pos_att_type;
1455 pos_att_type aPos = m_dom->position_attachment();
1457 aaPos.
access (*pMG, aPos);
1459 UG_LOG(
"grid transfer full to low \n");
1466 for (
int lev = m_FirstFullLevel; lev < m_NumberLevels; lev++)
1468 for(
int i=0; i<4; i++)
1474 std::vector<Edge*> edge_to_erase(edge_list.
size ());
1476 for (
size_t j = 0; j < edge_list.
size (); j++)
1478 Edge * edge = edge_list [j];
1479 if(edge_mark(edge)==F_MID || edge_mark(edge)==F_BND)
1481 edge_to_erase[counter]= edge;
1484 for(
int j=0; j<counter; j++)
1486 pMG->
erase(edge_to_erase[j]);
1492 for (
int lev = 0; lev < m_NumberLevels; lev++)
1494 for (
int k = 0; k < NumberFractNodes[lev]; k++)
1496 for (
int i = 3; i < NumberFractVertNodes[lev][k]+3; i++)
1498 pMG->
erase(FractNode[lev][k][i]);
1500 NumberFractVertNodes[lev][k] = 0;
1505 int baselev = m_FirstFullLevel-1;
1506 int toplev = m_NumberLevels-1;
1507 for (
int lev = baselev; lev < toplev; lev++)
1509 for (
size_t i = 0; i < m_fractSsGrp.size (); i++)
1511 int si = m_fractSsGrp [i];
1512 t_elem_iter list_end = m_spSH->template end<element_type> (si, lev);
1513 for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, lev);
1514 iElem != list_end; ++iElem)
1519 int numvert = elem->num_vertices ();
1528 int triangle_done = 0;
1529 for (
size_t j = 0; j < edge_list.
size (); j++)
1531 Edge * edge = edge_list [j];
1537 for(
int k=0; k<numvert; k++)
1539 if(elem->vertex(k)==edge->
vertex(0))
1541 if(elem->vertex((k+1)%numvert)==edge->
vertex(1))
1546 else if(elem->vertex((numvert+k-1)%numvert)==edge->
vertex(1))
1552 UG_THROW (
"FractDimadapt:grid_transfer_full_to_low: Elem Edge numbering\n");
1576 if(numvert==3 && triangle_done ==0)
1578 for(
int k=0; k<numvert; k++)
1580 Vertex *vert =elem->vertex(k);
1581 if(vert_mark(vert)==F_CORNER)
1583 if(elem->vertex(k)==edge->
vertex(0))
1585 if(elem->vertex((k+1)%numvert)==edge->
vertex(1))
1592 else if(elem->vertex((numvert+k-1)%numvert)==edge->
vertex(1))
1600 UG_THROW (
"FractDimadapt:grid_transfer_full_to_low: Triangle\n");
1602 else if(elem->vertex(k)==edge->
vertex(1))
1604 if(elem->vertex((k+1)%numvert)==edge->
vertex(0))
1611 else if(elem->vertex((numvert+k-1)%numvert)==edge->
vertex(0))
1619 UG_THROW (
"FractDimadapt:grid_transfer_full_to_low: Triangle\n");
1622 UG_THROW (
"FractDimadapt:grid_transfer_full_to_low:Triangle\n");
1639 UG_THROW (
"FractDimadapt:grid_transfer_full_to_low: wrong number corners"<<counter<<
"\n");
1642 UG_THROW (
"FractDimadapt:grid_transfer_full_to_low: wrong number corners"<<counter2<<
"\n");
1648 UG_THROW (
"FractDimadapt:grid_transfer_full_to_low: wrong number corners"<<counter<<
"\n");
1651 UG_THROW (
"FractDimadapt:grid_transfer_full_to_low: wrong number corners"<<counter2<<
"\n");
1662 for (
int lev = 0; lev < m_NumberLevels; lev++)
1664 for (
int k = 0; k < NumberFractNodes[lev]; k++)
1667 if(FractNode[lev][k][1]!=NULL && FractNode[lev][k][2]!=NULL)
1672 number debug_shift = 1e-10;
1674 shift[1] += debug_shift;
1675 else if (shift[1]<0)
1676 shift[1] -= debug_shift;
1678 VecAdd(newcoord,aaPos[FractNode[lev][k][1]],shift);
1679 aaPos[FractNode[lev][k][1]] = newcoord;
1682 shift = vert_shift(FractNode[lev][k][2]);
1686 shift[1] += debug_shift;
1687 else if (shift[1]<0)
1688 shift[1] -= debug_shift;
1690 VecAdd(newcoord,aaPos[FractNode[lev][k][2]],shift);
1691 aaPos[FractNode[lev][k][2]] = newcoord;
1698 m_FractureIsFullDimensional = 0;
1718 typedef typename domain_type::position_attachment_type pos_att_type;
1719 pos_att_type aPos = m_dom->position_attachment();
1721 aaPos.
access (*pMG, aPos);
1723 if(m_FirstFullLevel < 0)
1724 UG_THROW (
"FractDimadapt:grid_transfer_low_to_full: FirstFullLevel not set");
1726 UG_LOG(
"grid transfer low to full \n");
1734 for (
int lev = 0; lev < m_NumberLevels; lev++)
1736 for (
int k = 0; k < NumberFractNodes[lev]; k++)
1738 if(FractNode[lev][k][1]!=NULL && FractNode[lev][k][2]!=NULL)
1744 number debug_shift = 1e-10;
1746 shift[1] -= debug_shift;
1747 else if (shift[1]<0)
1748 shift[1] += debug_shift;
1750 VecSubtract(newcoord,aaPos[FractNode[lev][k][1]],shift);
1751 aaPos[FractNode[lev][k][1]] = newcoord;
1752 shift = vert_shift(FractNode[lev][k][2]);
1756 shift[1] -= debug_shift;
1757 else if (shift[1]<0)
1758 shift[1] += debug_shift;
1760 VecSubtract(newcoord,aaPos[FractNode[lev][k][2]],shift);
1761 aaPos[FractNode[lev][k][2]] = newcoord;
1770 for (
int lev = m_FirstFullLevel; lev < m_NumberLevels; lev++)
1772 for (
size_t i = 0; i < m_fractSsGrp.size (); i++)
1774 int si = m_fractSsGrp [i];
1775 Edge * edge_to_erase[200];
1777 t_elem_iter list_end = m_spSH->template end<element_type> (si, lev);
1778 for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, lev);
1779 iElem != list_end; ++iElem)
1783 for (
size_t j = 0; j < edge_list.
size (); j++)
1785 Edge * edge = edge_list [j];
1786 if(edge_mark(edge)==F_MID || edge_mark(edge)==F_BND || edge_mark(edge)==F_NONE)
1788 edge_to_erase[counter]= edge;
1789 m_aaEdgeAuxMarks [edge] = F_NONE;
1792 UG_THROW (
"FractDimadapt:grid_transfer_low_to_full: number of edges out of bounds");
1795 for(
int j=0; j<counter; j++)
1797 pMG->
erase(edge_to_erase[j]);
1803 int baselev = m_FirstFullLevel-1;
1804 int toplev = m_NumberLevels-1;
1805 for (
int lev = baselev; lev < toplev; lev++)
1807 for (
size_t i = 0; i < m_fractSsGrp.size (); i++)
1809 int si = m_fractSsGrp [i];
1810 t_elem_iter list_end = m_spSH->template end<element_type> (si, lev);
1811 for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, lev);
1812 iElem != list_end; ++iElem)
1816 if(elem->num_vertices ()==4)
1822 Vertex *newvrt_old = newvrt;
1823 for(
int recursive_lev = lev; recursive_lev < toplev-1; recursive_lev++)
1826 aaPos[newvrt] = aaPos[newvrt_old];
1827 newvrt_old = newvrt;
1832 for (
size_t j = 0; j < edge_list.
size (); j++)
1834 Edge * edge = edge_list [j];
1844 Vertex *newvrt_old = newvrt;
1845 for(
int recursive_lev = lev; recursive_lev < toplev-1; recursive_lev++)
1848 aaPos[newvrt] = aaPos[newvrt_old];
1849 newvrt_old = newvrt;
1855 if(elem->num_vertices ()==4)
1857 for(
size_t j = 0; j < 4; ++j)
1868 else if(elem->num_vertices ()==3)
1870 for (
size_t j = 0; j < edge_list.
size (); j++)
1872 Edge * edge = edge_list [j];
1886 UG_THROW (
"FractDimadapt:grid_transfer_low_to_full: only triangles and quadrilaterals so far");
1891 m_FractureIsFullDimensional = 1;
1909 UG_LOG(
"convert_tri_to_quad \n");
1912 std::vector<DoFIndex> multInd;
1921 typedef typename domain_type::position_attachment_type pos_att_type;
1922 pos_att_type aPos = m_dom->position_attachment();
1924 aaPos.
access (*pMG, aPos);
1931 const size_t max_number_deg_quadris = 2;
1932 Vertex * new_vrt_father[max_number_deg_quadris];
1933 Edge * new_degedge_father[max_number_deg_quadris];
1934 Edge * new_fulledge_father[max_number_deg_quadris];
1935 Face* new_face1_father[max_number_deg_quadris];
1936 size_t number_new_vrts = 0;
1938 size_t max_verts = max_number_deg_quadris * m_NumberLevels;
1939 std::vector<std::vector<Vertex*> > vert_pairs(max_verts);
1940 for(
size_t i = 0; i < vert_pairs.size(); ++i) vert_pairs[i].
resize(2);
1942 size_t vert_count = 0;
1946 for (
int lev = 0; lev < m_NumberLevels; lev++)
1948 size_t triangle_counter = 0;
1949 Edge * corneredge[4];
1950 Face* cornerface[4];
1960 for (
size_t h = 0; h < m_fractSsGrp.size (); h++)
1962 int si = m_fractSsGrp [h];
1963 for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, lev);
1964 iElem != m_spSH->template end<element_type> (si, lev); ++iElem)
1968 if(elem->num_vertices()==3)
1971 for (
size_t j = 0; j < edge_list.
size (); j++)
1973 Edge * edge = edge_list [j];
1974 if(edge_mark(edge)==F_MID)
1976 if(vert_mark(edge->
vertex(0))==F_CORNER)
1978 cornervrt[triangle_counter] = edge->
vertex(0);
1980 sign[triangle_counter] =
s/(fabs(
s));
1982 else if(vert_mark(edge->
vertex(1))==F_CORNER)
1984 cornervrt[triangle_counter] = edge->
vertex(1);
1986 sign[triangle_counter] =
s/(fabs(
s));
1990 UG_LOG(
"triangle mid edge with no corner node \n ");
1993 corneredge[triangle_counter] = edge;
1994 edgenum[triangle_counter] = j;
1998 UG_THROW(
"FractDimadapt:tri_to_quad: edge has more than two faces\n");
2001 for(
size_t j=0; j< 2; j++)
2005 if(nbfaces[j]->vertex(k) != elem->
vertex(k))
2011 if(equal[0]==0 && equal[1]==0)
2012 UG_THROW(
"FractDimadapt:tri_to_quad: no elem found\n");
2013 for(
size_t j=0; j< 2; j++)
2015 cornerface[triangle_counter] = nbfaces[j];
2019 for(
size_t k=0; k< elem->num_vertices(); k++)
2021 vrtlist[triangle_counter][count+k] = elem->vertex(k);
2022 if(k==edgenum[triangle_counter])
2025 vrtlist[triangle_counter][k+count] = NULL;
2030 if(triangle_counter>(2*max_number_deg_quadris))
2031 UG_THROW (
"FractDimadapt:tri_to_quad: too many corner triangles");
2038 for (
size_t i = 0; i < triangle_counter; i++)
2040 for (
size_t j = 0; j < triangle_counter; j++)
2044 if(cornervrt[i] == cornervrt[j])
2052 for (
size_t i = 0; i < triangle_counter; i++)
2068 number debug_shift = 1e-10;
2070 aaPos[newvrt][0] = aaPos[cornervrt[i]][0] + sign[i]*debug_shift;
2071 aaPos[newvrt][1] = aaPos[cornervrt[i]][1];
2076 tangential[0]= m_fractNormal[1];
2077 tangential[1]= -m_fractNormal[0];
2078 number step_x = fabs(aaPos[corneredge[i]->vertex(0)][0] - aaPos[corneredge[i]->vertex(1)][0]);
2079 number step_y= fabs(aaPos[corneredge[i]->vertex(0)][1] - aaPos[corneredge[i]->vertex(1)][1]);
2080 for(
int l=0; l<m_NumberLevels; l++)
2087 aaPos[newvrt][0] = aaPos[cornervrt[i]][0] + fabs(tangential[0]) * sign[i] * step_x;
2088 aaPos[newvrt][1] = aaPos[cornervrt[i]][1] + fabs(tangential[1]) * sign[i] * step_y;
2091 new_vrt_father[new_count] = newvrt;
2095 vert_pairs[vert_count][0] = newvrt;
2096 vert_pairs[vert_count][1] = cornervrt[i];
2106 if(corneredge[i]->vertex(0)==cornervrt[i])
2108 newparent = newedge2;
2109 new_fulledge_father[new_count] = newedge2;
2110 new_degedge_father[new_count] = newedge1;
2112 else if(corneredge[i]->vertex(1)==cornervrt[i])
2114 newparent = newedge1;
2115 new_fulledge_father[new_count] = newedge1;
2116 new_degedge_father[new_count] = newedge2;
2119 UG_THROW(
"FractDimadapt:tri_to_quad: some error in collected data\n");
2128 vrtlist[i][edgenum[i]+1] = newvrt;
2129 vrtlist[partner[i]][edgenum[partner[i]]+1] = newvrt;
2140 Face* Fchildren_list[4];
2141 Edge* Echildren_list[2];
2142 size_t num_children = 0;
2145 vrtlist[i][2],vrtlist[i][3]));
2146 m_spSH->assign_subset(face, si);
2149 for(
size_t k = 0; k < num_children; k++)
2151 for(
size_t k = 0; k < num_children; k++)
2155 for(
size_t k = 0; k < num_children; k++)
2157 for(
size_t k = 0; k < num_children; k++)
2160 new_face1_father[new_count] = face;
2163 vrtlist[partner[i]][2],vrtlist[partner[i]][3]));
2164 m_spSH->assign_subset(face, si);
2167 for(
size_t k = 0; k < num_children; k++)
2168 Fchildren_list[k] = pMG->
get_child_face(cornerface[partner[i]],k);
2169 for(
size_t k = 0; k < num_children; k++)
2173 for(
size_t k = 0; k < num_children; k++)
2174 Echildren_list[k] = pMG->
get_child_edge(cornerface[partner[i]],k);
2175 for(
size_t k = 0; k < num_children; k++)
2182 pMG->
erase(corneredge[i]);
2193 size_t this_id = max_number_deg_quadris+10;
2194 for(
size_t k = 0; k < number_new_vrts; k++)
2196 if(parent1 == new_face1_father[k] || parent2 == new_face1_father[k])
2199 if(this_id == max_number_deg_quadris+10)
2200 UG_THROW(
"FractDimadapt:tri_to_quad: parent not found in list (lev "<<lev<<
")\n");
2204 aaPos[newvrt][0] = aaPos[new_vrt_father[this_id]][0];
2205 aaPos[newvrt][1] = aaPos[new_vrt_father[this_id]][1];
2208 vert_pairs[vert_count][0] = newvrt;
2209 vert_pairs[vert_count][1] = cornervrt[i];
2212 new_vrt_father[new_count] = newvrt;
2216 Edge *newdegedge = NULL;
2217 Edge *newfulledge = NULL;
2219 if(corneredge[i]->vertex(0)==cornervrt[i])
2224 else if(corneredge[i]->vertex(1)==cornervrt[i])
2230 UG_THROW(
"FractDimadapt:tri_to_quad: some error in collected data\n");
2232 new_fulledge_father[new_count] = newfulledge;
2233 new_degedge_father[new_count] = newdegedge;
2242 vrtlist[i][edgenum[i]+1] = newvrt;
2243 vrtlist[partner[i]][edgenum[partner[i]]+1] = newvrt;
2253 Face* Fchildren_list[4];
2254 Edge* Echildren_list[2];
2255 size_t num_children = 0;
2258 vrtlist[i][2],vrtlist[i][3]),parent1);
2261 for(
size_t k = 0; k < num_children; k++)
2263 for(
size_t k = 0; k < num_children; k++)
2267 for(
size_t k = 0; k < num_children; k++)
2269 for(
size_t k = 0; k < num_children; k++)
2271 new_face1_father[new_count] = face;
2275 vrtlist[partner[i]][2],vrtlist[partner[i]][3]),parent2);
2278 for(
size_t k = 0; k < num_children; k++)
2279 Fchildren_list[k] = pMG->
get_child_face(cornerface[partner[i]],k);
2280 for(
size_t k = 0; k < num_children; k++)
2284 for(
size_t k = 0; k < num_children; k++)
2285 Echildren_list[k] = pMG->
get_child_edge(cornerface[partner[i]],k);
2286 for(
size_t k = 0; k < num_children; k++)
2292 pMG->
erase(corneredge[i]);
2318 fractManager->
close();
2325 for(
size_t i=vert_count-2; i < vert_count; i++)
2328 u.dof_indices(vert_pairs[i][1], 0, multInd);
2329 c =
DoFRef(u,multInd[0]);
2330 u.dof_indices(vert_pairs[i][0], 0, multInd);
2331 DoFRef(u,multInd[0]) = c;
2333 u.dof_indices(vert_pairs[i][1], 1, multInd);
2335 u.dof_indices(vert_pairs[i][0], 1, multInd);
2351 UG_LOG(
"convert_quad_to_tri \n");
2354 std::vector<DoFIndex> multInd;
2363 typedef typename domain_type::position_attachment_type pos_att_type;
2364 pos_att_type aPos = m_dom->position_attachment();
2366 aaPos.
access (*pMG, aPos);
2372 size_t num_vert = 2 * m_NumberLevels;
2373 std::vector<Vertex*> vertex_to_erase(num_vert);
2374 size_t vert_count = 0;
2376 for (
int lev = 0; lev < m_NumberLevels; lev++)
2378 size_t triangle_counter = 0;
2380 Edge * corneredge[4];
2382 Face* cornerface[4];
2390 for (
size_t h = 0; h < m_fractSsGrp.size (); h++)
2392 int si = m_fractSsGrp [h];
2396 for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, lev);
2397 iElem != m_spSH->template end<element_type> (si, lev); ++iElem)
2400 for (
size_t j = 0; j < elem->num_vertices (); j++)
2402 Vertex * vert = elem->vertex(j);
2404 if(vert_mark(vert) == F_CORNER)
2406 if(elem->num_vertices ()!=4)
2407 UG_THROW(
"FractDimadapt:quad_to_tri: corner elem is no quadrilateral\n");
2410 cornervrt[triangle_counter] = vert;
2413 for (
size_t i = 0; i < edge_list.
size (); i++)
2415 Edge * edge = edge_list [i];
2416 if(vert_mark(edge->
vertex(0)) == F_MID)
2418 if(vert_mark(edge->
vertex(1)) == F_MID)
2420 midedge[triangle_counter] = edge;
2422 else if(vert_mark(edge->
vertex(1)) == F_CORNER)
2424 corneredge[triangle_counter] = edge;
2425 triquadvrt[triangle_counter] = edge->
vertex(0);
2426 edge_num[triangle_counter] = 1;
2429 else if(vert_mark(edge->
vertex(0)) == F_CORNER)
2431 if(vert_mark(edge->
vertex(1)) == F_MID)
2433 corneredge[triangle_counter] = edge;
2434 triquadvrt[triangle_counter] = edge->
vertex(1);
2435 edge_num[triangle_counter] = 0;
2441 size_t list_num = 0;
2442 for (
size_t i = 0; i < elem->num_vertices (); i++)
2444 Vertex * covert = elem->vertex(i);
2445 if(covert != triquadvrt[triangle_counter])
2447 vrtlist[triangle_counter][list_num] = covert;
2455 UG_THROW(
"FractDimadapt:quad_to_tri: edge has more than two faces\n");
2457 for(
size_t i=0; i< 2; i++)
2461 if(nbfaces[i]->vertex(k) != elem->
vertex(k))
2467 if(equal[0]==0 && equal[1]==0)
2468 UG_THROW(
"FractDimadapt:quad_to_tri: no elem found\n");
2469 for(
size_t k=0; k < 2; k++)
2471 cornerface[triangle_counter] = nbfaces[k];
2480 for (
size_t i = 0; i < triangle_counter; i++)
2482 for (
size_t j = 0; j < triangle_counter; j++)
2486 if(cornervrt[i] == cornervrt[j])
2493 for (
size_t i = 0; i < triangle_counter; i++)
2499 vertex_to_erase[vert_count] = triquadvrt[i];
2503 Edge *newedge = NULL;
2535 Face* Fchildren_list[4];
2536 Edge* Echildren_list[2];
2537 size_t num_children = 0;
2544 m_spSH->assign_subset(face, si);
2550 vrtlist[i][2]),parentface);
2553 for(
size_t k = 0; k < num_children; k++)
2555 for(
size_t k = 0; k < num_children; k++)
2559 for(
size_t k = 0; k < num_children; k++)
2561 for(
size_t k = 0; k < num_children; k++)
2568 vrtlist[partner[i]][2]));
2569 m_spSH->assign_subset(face, si);
2575 vrtlist[partner[i]][2]),parentface);
2578 for(
size_t k = 0; k < num_children; k++)
2579 Fchildren_list[k] = pMG->
get_child_face(cornerface[partner[i]],k);
2580 for(
size_t k = 0; k < num_children; k++)
2584 for(
size_t k = 0; k < num_children; k++)
2585 Echildren_list[k] = pMG->
get_child_edge(cornerface[partner[i]],k);
2586 for(
size_t k = 0; k < num_children; k++)
2593 for (
size_t i = 0; i < vert_count; i++)
2595 pMG->
erase(vertex_to_erase[i]);
2600 fractManager->
close();