15 #if !defined(KRATOS_DISCONTINUOUS_UTILITIES_INCLUDED )
16 #define KRATOS_DISCONTINUOUS_UTILITIES_INCLUDED
78 array_1d<
double,(3*(3-1))>& rPartitionsSign, std::vector<Matrix>& rGradientsValue,
86 const int n_edges = 6;
87 const double one_quarter=0.25;
89 const int edge_i[] = {0, 0, 0, 1, 1, 2};
90 const int edge_j[] = {1, 2, 3, 2, 3, 3};
102 CalculateGeometryData(rPoints, DN_DX, tot_vol);
104 const double epsilon = 1
e-15;
105 const double near_factor = 1.00e-12;
119 for (
unsigned int i = 0;
i < 4;
i++)
120 for (
unsigned int j = 0;
j < 3;
j++)
121 aux_coordinates(
i,
j) = rPoints(
i,
j);
122 for (
unsigned int i = 4;
i < 8;
i++)
123 for (
unsigned int j = 0;
j < 3;
j++)
124 aux_coordinates(
i,
j) = -10000.0;
126 int split_edge[] = {0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1};
130 int n_negative_distance_nodes = 0;
131 int n_positive_distance_nodes = 0;
139 double norm =
norm_2(grad_d);
148 double max_lenght = 0.0;
149 for (
int edge = 0; edge < n_edges; edge++)
151 const int i = edge_i[edge];
152 const int j = edge_j[edge];
154 double dx = rPoints(
j, 0) - rPoints(
i, 0);
155 double dy = rPoints(
j, 1) - rPoints(
i, 1);
156 double dz = rPoints(
j, 2) - rPoints(
i, 2);
158 double l = sqrt(dx * dx + dy * dy + dz * dz);
163 edges_length[edge] =
l;
169 double relatively_close = near_factor*max_lenght;
172 for (
unsigned int i=0;
i<4;
i++)
174 if(std::abs(rDistances[
i]) < relatively_close)
176 collapsed_node[
i] =
true;
181 collapsed_node[
i] =
false;
184 abs_distance[
i] = std::abs(rDistances[
i]);
188 for (
int edge = 0; edge < n_edges; edge++)
190 const int i = edge_i[edge];
191 const int j = edge_j[edge];
192 if (rDistances[
i] * rDistances[
j] < 0.0)
194 const double tmp = std::abs(rDistances[
i]) / (std::abs(rDistances[
i]) + std::abs(rDistances[
j]));
196 if (collapsed_node[
i] ==
false && collapsed_node[
j] ==
false)
198 split_edge[edge + 4] = new_node_id;
199 edge_division_i[edge] =
tmp;
200 edge_division_j[edge] = 1.00 -
tmp;
203 for (
unsigned int k = 0;
k < 3;
k++)
204 aux_coordinates(new_node_id,
k) = rPoints(
i,
k) * edge_division_j[edge] + rPoints(
j,
k) * edge_division_i[edge];
215 base_point[0] = aux_coordinates(4,0);
216 base_point[1] = aux_coordinates(4,1);
217 base_point[2] = aux_coordinates(4,2);
220 for (
int i_node = 0; i_node <
n_nodes; i_node++)
222 double d = (rPoints(i_node,0) - base_point[0]) * grad_d[0] +
223 (rPoints(i_node,1) - base_point[1]) * grad_d[1] +
224 (rPoints(i_node,2) - base_point[2]) * grad_d[2] ;
225 abs_distance[i_node] = std::abs(
d);
231 for (
int i_node = 0; i_node <
n_nodes; i_node++)
233 if (rDistances[i_node] < 0.00)
236 negative_distance_nodes[n_negative_distance_nodes++] = i_node;
241 positive_distance_nodes[n_positive_distance_nodes++] = i_node;
248 if (rDistances[
i] < 0.0)
249 exact_distance[
i] = -abs_distance[
i];
251 exact_distance[
i] = abs_distance[
i];
261 int number_of_splitted_edges = new_node_id - 4;
263 double volume = edges_dx[0] * edges_dy[1] * edges_dz[2] -
264 edges_dx[0] * edges_dz[1] * edges_dy[2] +
265 edges_dy[0] * edges_dz[1] * edges_dx[2] -
266 edges_dy[0] * edges_dx[1] * edges_dz[2] +
267 edges_dz[0] * edges_dx[1] * edges_dy[2] -
268 edges_dz[0] * edges_dy[1] * edges_dx[2];
270 const double one_sixth = 1.00 / 6.00;
275 if (number_of_splitted_edges == 0)
281 double min_distance = 1e9;
282 for (
int j = 0;
j < 4;
j++)
283 if(exact_distance[
j] < min_distance) min_distance = exact_distance[
j];
285 if(min_distance < 0.0)
286 rPartitionsSign[0] = -1.0;
288 rPartitionsSign[0] = 1.0;
292 for (
int j = 0;
j < 4;
j++)
293 rShapeFunctionValues(0,
j) = 0.25;
304 int n_splitted_edges;
312 KRATOS_ERROR <<
"Requiring an internal node for splitting ... can not accept this";
318 for (
int i = 0;
i < nel;
i++)
322 double sub_volume = ComputeSubTetraVolumeAndCenter(aux_coordinates, center_position, i0, i1, i2, i3);
325 local_subtet_indices[0] =
t[
i*4];
326 local_subtet_indices[1] =
t[
i*4+1];
327 local_subtet_indices[2] =
t[
i*4+2];
328 local_subtet_indices[3] =
t[
i*4+3];
330 AddToEdgeAreas<3>(edge_areas,exact_distance,local_subtet_indices,sub_volume);
337 partition_nodes[0]=i0;
338 partition_nodes[1]=i1;
339 partition_nodes[2]=i2;
340 partition_nodes[3]=i3;
341 for (
unsigned int j=0;
j!=4;
j++)
342 for (
unsigned int k=0;
k!=3;
k++)
344 const int node_id=partition_nodes[
j];
345 coord_subdomain(
j,
k)= aux_coordinates(
node_id ,
k );
348 CalculateGeometryData(coord_subdomain, DN_DX_subdomain, temp_area);
350 rVolumes[
i] = sub_volume;
355 ComputeElementCoordinates(
N, center_position, rPoints,
volume);
359 for (
int j = 0;
j < 4;
j++) {
360 rShapeFunctionValues(
i,
j) =
N[
j];
361 dist += rShapeFunctionValues(
i,
j) * exact_distance[
j];
366 rPartitionsSign[
i] = -1.0;
368 rPartitionsSign[
i] = 1.0;
370 double partition_sign=rPartitionsSign[
i];
373 for (
int j=0;
j<4;
j++)
375 if((partition_sign*rDistances(
j))>0)
378 for (
unsigned int k=0;
k<4;
k++)
380 const int current_node= partition_nodes[
k];
381 bool add_contribution=
false;
385 add_contribution=
true;
389 for (
unsigned int edge=0; edge!=6 ; edge++)
391 if (split_edge[4+edge]==current_node)
393 const int i_node = edge_i[edge];
394 const int j_node = edge_j[edge];
395 if (i_node==
j || j_node==
j)
396 add_contribution=
true;
403 if (add_contribution)
405 Nenriched(
i,
j)+=one_quarter;
406 rGradientsValue[
i](
j,0)+=DN_DX_subdomain(
k,0);
407 rGradientsValue[
i](
j,1)+=DN_DX_subdomain(
k,1);
408 rGradientsValue[
i](
j,2)+=DN_DX_subdomain(
k,2);
422 Nenriched(0,0) = 0.0;
424 for (
int j = 0;
j < 3;
j++)
425 rGradientsValue[0](0,
j) = 0.0;
438 array_1d<
double,(3*(2-1))>& rVolumes,
439 BoundedMatrix<
double, 3*(2-1), (2+1) >& rGPShapeFunctionValues,
440 array_1d<
double,(3*(2-1))>& rPartitionsSign,
441 std::vector<Matrix>& rGradientsValue,
448 const double unsigned_distance_0 = std::abs(rDistances(0));
449 const double unsigned_distance_1 = std::abs(rDistances(1));
450 const double unsigned_distance_2 = std::abs(rDistances(2));
453 const double longest_distance =
std::max(unsigned_distance_0,
std::max(unsigned_distance_1, unsigned_distance_2));
456 const double tolerable_distance = longest_distance*0.001;
458 if (unsigned_distance_0 < tolerable_distance)
460 rDistances[0] = tolerable_distance;
462 if (unsigned_distance_1 < tolerable_distance)
464 rDistances[1] = tolerable_distance;
466 if (unsigned_distance_2 < tolerable_distance)
468 rDistances[2] = tolerable_distance;
472 const double one_third = 1.0/3.0;
478 const double Area = CalculateVol(rPoints(0,0), rPoints(0,1),
479 rPoints(1,0), rPoints(1,1),
480 rPoints(2,0), rPoints(2,1));
487 if( (rDistances(0)*rDistances(1))>0.0 && (rDistances(0)*rDistances(2))>0.0 )
490 rGPShapeFunctionValues(0,0) = one_third;
491 rGPShapeFunctionValues(0,1) = one_third;
492 rGPShapeFunctionValues(0,2) = one_third;
493 rNenriched(0,0) = 0.0;
495 rDistances[0] = (rDistances(0) < 0.0) ? -1.0 : 1.0;
504 cut_edges[0] = ((rDistances(0)*rDistances(1))<0.0) ? true :
false;
505 cut_edges[1] = ((rDistances(1)*rDistances(2))<0.0) ? true :
false;
506 cut_edges[2] = ((rDistances(2)*rDistances(0))<0.0) ? true :
false;
510 for (
unsigned int i=0;
i<3;
i++)
512 const unsigned int edge_begin_node =
i;
513 const unsigned int edge_end_node = (
i+1 == 3) ? 0 :
i+1;
515 if(cut_edges(
i) ==
true)
517 aux_nodes_relative_locations(
i)=std::abs(rDistances(edge_end_node)/(rDistances(edge_end_node)-rDistances(edge_begin_node) ) ) ;
518 aux_nodes_father_nodes(
i,0)=edge_begin_node;
519 aux_nodes_father_nodes(
i,1)=edge_end_node;
523 if(std::abs(rDistances(edge_end_node))>std::abs(rDistances(edge_begin_node)))
525 aux_nodes_relative_locations(
i)=0.0;
526 aux_nodes_father_nodes(
i,0)=edge_end_node;
527 aux_nodes_father_nodes(
i,1)=edge_end_node;
531 aux_nodes_relative_locations(
i)=1.0;
532 aux_nodes_father_nodes(
i,0)=edge_begin_node;
533 aux_nodes_father_nodes(
i,1)=edge_begin_node;
538 for (
unsigned int j=0;
j<2;
j++)
540 aux_points(
i,
j)= rPoints(edge_begin_node,
j) * aux_nodes_relative_locations(
i) + rPoints(edge_end_node,
j) * (1.0- aux_nodes_relative_locations(
i));
545 unsigned int aux_counter = 0;
548 for (
unsigned int iedge = 0; iedge<3; ++iedge)
550 if (cut_edges(iedge) ==
true)
552 intersection_aux_points(aux_counter, 0) = aux_points(iedge, 0);
553 intersection_aux_points(aux_counter, 1) = aux_points(iedge, 1);
558 const double intersection_length = std::sqrt(std::pow(intersection_aux_points(0,0)-intersection_aux_points(1,0), 2) +
559 std::pow(intersection_aux_points(0,1)-intersection_aux_points(1,1), 2));
561 rEdgeAreas[0] = (cut_edges(0) ==
true) ? intersection_length*0.5 : 0.0;
562 rEdgeAreas[1] = (cut_edges(1) ==
true) ? intersection_length*0.5 : 0.0;
563 rEdgeAreas[2] = (cut_edges(2) ==
true) ? intersection_length*0.5 : 0.0;
578 unsigned int partition_number=0;
580 for (
unsigned int i=0;
i<4;
i++)
583 const unsigned int j_aux = (
i+2 > 2) ?
i-1 :
i+2;
588 partition_nodes_id(
i,0) =
i;
589 partition_nodes_id(
i,1) =
i+2;
590 partition_nodes_id(
i,2) = j_aux;
594 partition_father_nodes(0,0)=
i;
595 partition_father_nodes(0,1)=
i;
596 partition_father_nodes(1,0)=aux_nodes_father_nodes(
i,0);
597 partition_father_nodes(1,1)=aux_nodes_father_nodes(
i,1);
598 partition_father_nodes(2,0)=aux_nodes_father_nodes(j_aux,0);
599 partition_father_nodes(2,1)=aux_nodes_father_nodes(j_aux,1);
601 coord_subdomain(0,0)=rPoints(
i,0);
602 coord_subdomain(0,1)=rPoints(
i,1);
603 coord_subdomain(1,0)=aux_points(
i,0);
604 coord_subdomain(1,1)=aux_points(
i,1);
605 coord_subdomain(2,0)=aux_points(j_aux,0);
606 coord_subdomain(2,1)=aux_points(j_aux,1);
611 partition_father_nodes=aux_nodes_father_nodes;
612 coord_subdomain=aux_points;
617 CalculateGeometryData(coord_subdomain, DN_DX_subdomain, temp_area);
619 if (temp_area > std::numeric_limits<double>::epsilon())
621 rVolumes(partition_number) = temp_area;
624 const double x_GP_partition = one_third * ( coord_subdomain(0,0) + coord_subdomain(1,0) + coord_subdomain(2,0) );
625 const double y_GP_partition = one_third * ( coord_subdomain(0,1) + coord_subdomain(1,1) + coord_subdomain(2,1) );
626 const double z_GP_partition = 0.0;
629 coord_subdomain = rPoints;
632 CalculatePosition ( coord_subdomain , x_GP_partition ,y_GP_partition ,z_GP_partition ,
N);
635 const double partition_sign = (
N(0)*rDistances(0) +
N(1)*rDistances(1) +
N(2)*rDistances(2))/std::abs(
N(0)*rDistances(0) +
N(1)*rDistances(1) +
N(2)*rDistances(2));
636 rPartitionsSign(partition_number) = partition_sign;
639 for (
int j=0;
j<3;
j++)
641 if((partition_sign*rDistances(
j)) > 0)
644 for (
unsigned int k=0;
k<3;
k++)
646 if (partition_father_nodes(
k,0)==
j || partition_father_nodes(
k,1)==
j )
648 rNenriched(partition_number,
j) += one_third;
649 rGradientsValue[partition_number](
j,0) += DN_DX_subdomain(
k,0);
650 rGradientsValue[partition_number](
j,1) += DN_DX_subdomain(
k,1);
657 rGPShapeFunctionValues(partition_number,0) =
N(0);
658 rGPShapeFunctionValues(partition_number,1) =
N(1);
659 rGPShapeFunctionValues(partition_number,2) =
N(2);
667 CalculateGeometryData(rPoints, rDN_DX, tot_area);
680 array_1d<
double,(3*(2-1))>& rVolumes,
681 BoundedMatrix<
double, 3*(2-1), (2+1) >& rGPShapeFunctionValues,
682 array_1d<
double,(3*(2-1))>& rPartitionsSign,
683 std::vector<Matrix>& rGradientsValue,
691 const double one_third=1.0/3.0;
696 rGPShapeFunctionValues(0,0)=one_third;
697 rGPShapeFunctionValues(0,1)=one_third;
698 rGPShapeFunctionValues(0,2)=one_third;
701 const double Area = CalculateVol(rOriginalPoints(0,0), rOriginalPoints(0,1),
702 rOriginalPoints(1,0), rOriginalPoints(1,1),
703 rOriginalPoints(2,0), rOriginalPoints(2,1));
709 if( (rDistances(0)*rDistances(1))>0.0 && (rDistances(0)*rDistances(2))>0.0 )
712 rGPShapeFunctionValues(0,0)=one_third;
713 rGPShapeFunctionValues(0,1)=one_third;
714 rGPShapeFunctionValues(0,2)=one_third;
715 Nenriched(0,0) = 0.0;
716 for (
int j = 0;
j < 3;
j++)
717 rGradientsValue[0](0,
j) = 0.0;
718 if (rDistances(0) < 0.0) rPartitionsSign[0] = -1.0;
719 else rPartitionsSign[0] = 1.0;
724 if ((rDistances(0)*rDistances(1))<0.0)
728 if ((rDistances(1)*rDistances(2))<0.0)
732 if ((rDistances(2)*rDistances(0))<0.0)
742 const double unsigned_distance0=std::abs(rDistances(0));
743 const double unsigned_distance1=std::abs(rDistances(1));
744 const double unsigned_distance2=std::abs(rDistances(2));
746 double longest_distance=std::abs(unsigned_distance0);
747 if (unsigned_distance1>longest_distance)
748 longest_distance=unsigned_distance1;
749 if (unsigned_distance2>longest_distance)
750 longest_distance=unsigned_distance2;
752 const double tolerable_distance =longest_distance*0.001;
754 if (unsigned_distance0<tolerable_distance)
755 rDistances[0]=tolerable_distance*(rDistances[0]/std::abs(rDistances[0]));
756 if (unsigned_distance1<tolerable_distance)
757 rDistances[1]=tolerable_distance*(rDistances[1]/std::abs(rDistances[1]));
758 if (unsigned_distance2<tolerable_distance)
759 rDistances[2]=tolerable_distance*(rDistances[2]/std::abs(rDistances[2]));
762 for (
unsigned int i=0;
i<3;
i++)
764 int edge_begin_node=
i;
765 int edge_end_node=
i+1;
766 if (edge_end_node==3) edge_end_node=0;
768 if(cut_edges(
i)==
true)
770 aux_nodes_relative_locations(
i)=std::abs(rDistances(edge_end_node)/(rDistances(edge_end_node)-rDistances(edge_begin_node) ) ) ;
771 aux_nodes_father_nodes(
i,0)=edge_begin_node;
772 aux_nodes_father_nodes(
i,1)=edge_end_node;
776 if(std::abs(rDistances(edge_end_node))>std::abs(rDistances(edge_begin_node)))
778 aux_nodes_relative_locations(
i)=0.0;
779 aux_nodes_father_nodes(
i,0)=edge_end_node;
780 aux_nodes_father_nodes(
i,1)=edge_end_node;
784 aux_nodes_relative_locations(
i)=1.0;
785 aux_nodes_father_nodes(
i,0)=edge_begin_node;
786 aux_nodes_father_nodes(
i,1)=edge_begin_node;
791 for (
unsigned int j=0;
j<2;
j++)
792 aux_points(
i,
j)= rOriginalPoints(edge_begin_node,
j) * aux_nodes_relative_locations(
i) + rOriginalPoints(edge_end_node,
j) * (1.0- aux_nodes_relative_locations(
i));
796 double x_reference=aux_points(0,0);
797 double y_reference=aux_points(0,1);
800 if (cut_edges[0]==
false)
802 x_reference=aux_points(1,0);
803 y_reference=aux_points(1,1);
804 const double one_over_interfase_lenght = 1.0/sqrt( pow((aux_points(2,0) - x_reference),2) + pow((aux_points(2,1) - y_reference),2));
805 cosinus = (aux_points(2,0) - x_reference)*one_over_interfase_lenght;
806 sinus = - (aux_points(2,1) - y_reference)*one_over_interfase_lenght;
808 else if(cut_edges[1]==
true)
810 const double one_over_interfase_lenght = 1.0/sqrt( pow((aux_points(1,0) - x_reference),2) + pow((aux_points(1,1) - y_reference),2));
811 cosinus = (aux_points(1,0) - x_reference)*one_over_interfase_lenght;
812 sinus = - (aux_points(1,1) - y_reference)*one_over_interfase_lenght;
816 const double one_over_interfase_lenght = 1.0/sqrt( pow((aux_points(2,0) - x_reference),2) + pow((aux_points(2,1) - y_reference),2));
817 cosinus = (aux_points(2,0) - x_reference)*one_over_interfase_lenght;
818 sinus = - (aux_points(2,1) - y_reference)*one_over_interfase_lenght;
821 for (
unsigned int i=0;
i<3;
i++)
823 rRotatedPoints(
i,0)= cosinus * (rOriginalPoints(
i,0)-x_reference) - sinus * (rOriginalPoints(
i,1)-y_reference);
824 rRotatedPoints(
i,1)= cosinus * (rOriginalPoints(
i,1)-y_reference) + sinus * (rOriginalPoints(
i,0)-x_reference);
827 double aux_x_coord=aux_points(
i,0);
828 aux_points(
i,0)= cosinus * (aux_x_coord-x_reference) - sinus * (aux_points(
i,1)-y_reference);
829 aux_points(
i,1)= cosinus * (aux_points(
i,1)-y_reference) + sinus * (aux_x_coord-x_reference);
833 CalculateGeometryData(rRotatedPoints, DN_DX_in_local_axis, temp_area);
835 rRotationMatrix(0,0)=cosinus;
836 rRotationMatrix(0,1)= sinus;
837 rRotationMatrix(1,0)= -sinus;
838 rRotationMatrix(1,1)=cosinus;
849 unsigned int partition_number=0;
852 for (
unsigned int i=0;
i<4;
i++)
854 unsigned int j_aux =
i + 2;
855 if (j_aux>2) j_aux -= 3;
860 partition_father_nodes(0,0)=
i;
861 partition_father_nodes(0,1)=
i;
862 partition_father_nodes(1,0)=aux_nodes_father_nodes(
i,0);
863 partition_father_nodes(1,1)=aux_nodes_father_nodes(
i,1);
864 partition_father_nodes(2,0)=aux_nodes_father_nodes(j_aux,0);
865 partition_father_nodes(2,1)=aux_nodes_father_nodes(j_aux,1);
867 coord_subdomain(0,0)=rRotatedPoints(
i,0);
868 coord_subdomain(0,1)=rRotatedPoints(
i,1);
869 coord_subdomain(1,0)=aux_points(
i,0);
870 coord_subdomain(1,1)=aux_points(
i,1);
871 coord_subdomain(2,0)=aux_points(j_aux,0);
872 coord_subdomain(2,1)=aux_points(j_aux,1);
877 partition_father_nodes=aux_nodes_father_nodes;
878 coord_subdomain=aux_points;
882 CalculateGeometryData(coord_subdomain, DN_DX_subdomain, temp_area);
883 if (temp_area > std::numeric_limits<double>::epsilon())
885 rVolumes(partition_number)=temp_area;
887 double x_GP_partition = one_third * ( coord_subdomain(0,0) + coord_subdomain(1,0) + coord_subdomain(2,0) );
888 double y_GP_partition = one_third * ( coord_subdomain(0,1) + coord_subdomain(1,1) + coord_subdomain(2,1) );
889 double z_GP_partition = 0.0;
891 coord_subdomain = rRotatedPoints;
893 CalculatePosition ( coord_subdomain , x_GP_partition ,y_GP_partition ,z_GP_partition ,
N);
895 const double partition_sign = (
N(0)*rDistances(0) +
N(1)*rDistances(1) +
N(2)*rDistances(2))/std::abs(
N(0)*rDistances(0) +
N(1)*rDistances(1) +
N(2)*rDistances(2));
896 rPartitionsSign(partition_number)=partition_sign;
898 for (
int j=0;
j<3;
j++)
900 if((partition_sign*rDistances(
j))>0)
903 for (
unsigned int k=0;
k<3;
k++)
904 if (partition_father_nodes(
k,0)==
j || partition_father_nodes(
k,1)==
j )
906 Nenriched(partition_number,
j)+=one_third;
907 rGradientsValue[partition_number](
j,0)+=DN_DX_subdomain(
k,0);
908 rGradientsValue[partition_number](
j,1)+=DN_DX_subdomain(
k,1);
914 rGPShapeFunctionValues(partition_number,0)=
N(0);
915 rGPShapeFunctionValues(partition_number,1)=
N(1);
916 rGPShapeFunctionValues(partition_number,2)=
N(2);
932 template<
class TMatrixType>
933 static void CopyShapeFunctionsValues(TMatrixType& rShapeFunctionValues,
int OriginId,
int DestinationId)
937 rShapeFunctionValues(DestinationId,
i) = rShapeFunctionValues(OriginId,
i);
940 template<
class TMatrixType,
class TVectorType>
941 static void Divide1To2(array_1d<double, 6 >
const& EdgeDivisionI, array_1d<double, 6 >
const& EdgeDivisionJ,
int Edge,
942 int Volume1Id,
int Volume2Id,
double Volume, TMatrixType& rShapeFunctionValues, TVectorType& rVolumes)
944 const int edge_i[] = {0, 0, 0, 1, 1, 2};
945 const int edge_j[] = {1, 2, 3, 2, 3, 3};
947 const double division_i = EdgeDivisionI[Edge];
948 const double division_j = EdgeDivisionJ[Edge];
950 rVolumes[Volume1Id] = division_i * Volume;
951 rVolumes[Volume2Id] = division_j * Volume;
953 const int i = edge_i[Edge];
954 const int j = edge_j[Edge];
956 double delta1 = rShapeFunctionValues(Volume1Id,
i) * (1.00 - division_i);
957 rShapeFunctionValues(Volume1Id,
i) += delta1;
958 rShapeFunctionValues(Volume1Id,
j) -= delta1;
960 double delta2 = rShapeFunctionValues(Volume2Id,
i) * (1.00 - division_j);
961 rShapeFunctionValues(Volume2Id,
j) += delta2;
962 rShapeFunctionValues(Volume2Id,
i) -= delta2;
965 static double ComputeSubTetraVolumeAndCenter(
const BoundedMatrix<double, 3, 8 > & rAuxCoordinates,
966 array_1d<double, 3 > & rCenterPosition,
967 const int i0,
const int i1,
const int i2,
const int i3)
969 const double x10 = rAuxCoordinates(i1, 0) - rAuxCoordinates(i0, 0);
970 const double y10 = rAuxCoordinates(i1, 1) - rAuxCoordinates(i0, 1);
971 const double z10 = rAuxCoordinates(i1, 2) - rAuxCoordinates(i0, 2);
973 const double x20 = rAuxCoordinates(i2, 0) - rAuxCoordinates(i0, 0);
974 const double y20 = rAuxCoordinates(i2, 1) - rAuxCoordinates(i0, 1);
975 const double z20 = rAuxCoordinates(i2, 2) - rAuxCoordinates(i0, 2);
977 const double x30 = rAuxCoordinates(i3, 0) - rAuxCoordinates(i0, 0);
978 const double y30 = rAuxCoordinates(i3, 1) - rAuxCoordinates(i0, 1);
979 const double z30 = rAuxCoordinates(i3, 2) - rAuxCoordinates(i0, 2);
981 const double detJ = x10 * y20 * z30 - x10 * y30 * z20 + y10 * z20 * x30 - y10 * x20 * z30 + z10 * x20 * y30 - z10 * y20 * x30;
982 const double vol = detJ / 6.0;
984 for (
unsigned int i = 0;
i < 3;
i++)
986 rCenterPosition[
i] = rAuxCoordinates(i0,
i) + rAuxCoordinates(i1,
i) + rAuxCoordinates(i2,
i) + rAuxCoordinates(i3,
i);
989 rCenterPosition *= 0.25;
994 template<
class TMatrixType>
995 static void ComputeElementCoordinates(array_1d<double, 4 > & rN,
996 const array_1d<double, 3 > & rCenterPosition,
997 const TMatrixType& rPoints,
1000 const double x0 = rPoints(0, 0);
1001 const double y0 = rPoints(0, 1);
1002 const double z0 = rPoints(0, 2);
1003 const double x1 = rPoints(1, 0);
1004 const double y1 = rPoints(1, 1);
1005 const double z1 = rPoints(1, 2);
1006 const double x2 = rPoints(2, 0);
1007 const double y2 = rPoints(2, 1);
1008 const double z2 = rPoints(2, 2);
1009 const double x3 = rPoints(3, 0);
1010 const double y3 = rPoints(3, 1);
1011 const double z3 = rPoints(3, 2);
1013 const double xc = rCenterPosition[0];
1014 const double yc = rCenterPosition[1];
1015 const double zc = rCenterPosition[2];
1017 const double inv_vol = 1.0 / Vol;
1019 rN[0] = CalculateVol(
x1, y1, z1, x3, y3, z3,
x2, y2, z2,
xc,
yc, zc) * inv_vol;
1020 rN[1] = CalculateVol(x0, y0, z0,
x2, y2, z2, x3, y3, z3,
xc,
yc, zc) * inv_vol;
1021 rN[2] = CalculateVol(x3, y3, z3,
x1, y1, z1, x0, y0, z0,
xc,
yc, zc) * inv_vol;
1022 rN[3] = CalculateVol(
x1, y1, z1,
x2, y2, z2, x0, y0, z0,
xc,
yc, zc) * inv_vol;
1025 static inline double CalculateVol(
const double x0,
const double y0,
const double z0,
1026 const double x1,
const double y1,
const double z1,
1027 const double x2,
const double y2,
const double z2,
1028 const double x3,
const double y3,
const double z3)
1030 const double x10 =
x1 - x0;
1031 const double y10 = y1 - y0;
1032 const double z10 = z1 - z0;
1034 const double x20 =
x2 - x0;
1035 const double y20 = y2 - y0;
1036 const double z20 = z2 - z0;
1038 const double x30 = x3 - x0;
1039 const double y30 = y3 - y0;
1040 const double z30 = z3 - z0;
1042 const double detJ = x10 * y20 * z30 - x10 * y30 * z20 + y10 * z20 * x30 - y10 * x20 * z30 + z10 * x20 * y30 - z10 * y20 * x30;
1047 static inline double CalculateVol(
const double x0,
const double y0,
1048 const double x1,
const double y1,
1049 const double x2,
const double y2)
1051 return 0.5 * ((
x1 - x0)*(y2 - y0)- (y1 - y0)*(
x2 - x0));
1054 static inline void CalculateGeometryData(
const BoundedMatrix<double, 3, 2 > & rCoordinates,
1055 BoundedMatrix<double,3,2>& rDN_DX,
1058 const double x10 = rCoordinates(1,0) - rCoordinates(0,0);
1059 const double y10 = rCoordinates(1,1) - rCoordinates(0,1);
1061 const double x20 = rCoordinates(2,0) - rCoordinates(0,0);
1062 const double y20 = rCoordinates(2,1) - rCoordinates (0,1);
1069 const double detJ = x10 * y20-y10 * x20;
1071 rDN_DX(0,0) = -y20 + y10;
1072 rDN_DX(0,1) = x20 - x10;
1083 static inline void CalculateGeometryData(
const BoundedMatrix<double, 4, 3 > & rCoordinates,
1084 BoundedMatrix<double,4,3>& rDN_DX,
1087 const double x10 = rCoordinates(1,0) - rCoordinates(0,0);
1088 const double y10 = rCoordinates(1,1) - rCoordinates(0,1);
1089 const double z10 = rCoordinates(1,2) - rCoordinates(0,2);
1091 const double x20 = rCoordinates(2,0) - rCoordinates(0,0);
1092 const double y20 = rCoordinates(2,1) - rCoordinates (0,1);
1093 const double z20 = rCoordinates(2,2) - rCoordinates (0,2);
1095 const double x30 = rCoordinates(3,0) - rCoordinates(0,0);
1096 const double y30 = rCoordinates(3,1) - rCoordinates (0,1);
1097 const double z30 = rCoordinates(3,2) - rCoordinates (0,2);
1099 const double detJ = x10 * y20 * z30 - x10 * y30 * z20 + y10 * z20 * x30 - y10 * x20 * z30 + z10 * x20 * y30 - z10 * y20 * x30;
1101 rDN_DX(0,0) = -y20 * z30 + y30 * z20 + y10 * z30 - z10 * y30 - y10 * z20 + z10 * y20;
1102 rDN_DX(0,1) = -z20 * x30 + x20 * z30 - x10 * z30 + z10 * x30 + x10 * z20 - z10 * x20;
1103 rDN_DX(0,2) = -x20 * y30 + y20 * x30 + x10 * y30 - y10 * x30 - x10 * y20 + y10 * x20;
1104 rDN_DX(1,0) = y20 * z30 - y30 * z20;
1105 rDN_DX(1,1) = z20 * x30 - x20 * z30;
1106 rDN_DX(1,2) = x20 * y30 - y20 * x30;
1107 rDN_DX(2,0) = -y10 * z30 + z10 * y30;
1108 rDN_DX(2,1) = x10 * z30 - z10 * x30;
1109 rDN_DX(2,2) = -x10 * y30 + y10 * x30;
1110 rDN_DX(3,0) = y10 * z20 - z10 * y20;
1111 rDN_DX(3,1) = -x10 * z20 + z10 * x20;
1112 rDN_DX(3,2) = x10 * y20 - y10 * x20;
1116 rVolume = detJ / 6.0;
1119 static inline void CalculatePosition(
const BoundedMatrix<double, 3, 2 > & rCoordinates,
1123 array_1d<double, 3 > & rN)
1125 const double x0 = rCoordinates(0,0);
1126 const double y0 = rCoordinates(0,1);
1127 const double x1 = rCoordinates(1,0);
1128 const double y1 = rCoordinates(1,1);
1129 const double x2 = rCoordinates(2,0);
1130 const double y2 = rCoordinates(2,1);
1132 const double area = CalculateVol(x0, y0,
x1, y1,
x2, y2);
1133 double inv_area = 0.0;
1140 inv_area = 1.0 / area;
1143 rN[0] = CalculateVol(
x1, y1,
x2, y2,
xc,
yc) * inv_area;
1144 rN[1] = CalculateVol(
x2, y2, x0, y0,
xc,
yc) * inv_area;
1145 rN[2] = CalculateVol(x0, y0,
x1, y1,
xc,
yc) * inv_area;
1149 static void AddToEdgeAreas(array_1d<
double, (TDim-1)*3 >& rEdgeAreas,
1150 const array_1d<double, TDim+1 >& rExactDistance,
1151 const array_1d<double, TDim+1 >& rIndices,
1152 const double SubVolume)
1156 unsigned int ncut=0, pos=0, positive_pos=0;
1157 for(
unsigned int i=0;
i<TDim+1;
i++)
1159 if(rIndices[
i] > TDim)
1163 else if(rExactDistance[rIndices[
i]] > 0)
1165 positive_pos = rIndices[
i];
1170 if(ncut == TDim && pos==1)
1172 double edge_area = SubVolume*3.0/std::abs(rExactDistance[positive_pos]);
1173 edge_area /=
static_cast<double>(TDim);
1174 for(
unsigned int i=0;
i<TDim+1;
i++)
1176 if( rIndices[
i] > TDim)
1178 int edge_index = rIndices[
i] - TDim - 1;
1179 rEdgeAreas[edge_index] += edge_area;
Definition: discont_utils.h:42
static int CalculateDiscontinuousShapeFunctions(BoundedMatrix< double,(3+1), 3 > &rPoints, BoundedMatrix< double,(3+1), 3 > &DN_DX, array_1d< double,(3+1)> &rDistances, array_1d< double,(3 *(3-1))> &rVolumes, BoundedMatrix< double, 3 *(3-1),(3+1) > &rShapeFunctionValues, array_1d< double,(3 *(3-1))> &rPartitionsSign, std::vector< Matrix > &rGradientsValue, BoundedMatrix< double, 3 *(3-1),(3+1)> &Nenriched, array_1d< double, 6 > &edge_areas)
Definition: discont_utils.h:73
static int CalculateDiscontinuousShapeFunctions(const BoundedMatrix< double,(2+1), 2 > &rPoints, BoundedMatrix< double,(2+1), 2 > &rDN_DX, array_1d< double,(2+1)> &rDistances, array_1d< double,(3 *(2-1))> &rVolumes, BoundedMatrix< double, 3 *(2-1),(2+1) > &rGPShapeFunctionValues, array_1d< double,(3 *(2-1))> &rPartitionsSign, std::vector< Matrix > &rGradientsValue, BoundedMatrix< double, 3 *(2-1),(2+1)> &rNenriched, array_1d< double, 3 > &rEdgeAreas)
Definition: discont_utils.h:435
static int CalculateDiscontinuousShapeFunctionsInLocalAxis(BoundedMatrix< double,(2+1), 2 > &rOriginalPoints, BoundedMatrix< double,(2+1), 2 > &rRotatedPoints, BoundedMatrix< double,(2+1), 2 > &DN_DX_original, array_1d< double,(2+1)> &rDistances, array_1d< double,(3 *(2-1))> &rVolumes, BoundedMatrix< double, 3 *(2-1),(2+1) > &rGPShapeFunctionValues, array_1d< double,(3 *(2-1))> &rPartitionsSign, std::vector< Matrix > &rGradientsValue, BoundedMatrix< double, 3 *(2-1),(2+1)> &Nenriched, BoundedMatrix< double,(2), 2 > &rRotationMatrix, BoundedMatrix< double,(2+1), 2 > &DN_DX_in_local_axis)
Definition: discont_utils.h:675
Definition: amatrix_interface.h:41
static int Split_Tetrahedra(const int edges[6], int t[56], int *nel, int *splitted_edges, int *nint)
Function to split a tetrahedron For a given edges splitting pattern, this function computes the inter...
Definition: split_tetrahedra.h:177
static void TetrahedraGetNewConnectivityGID(const int tetra_index, const int t[56], const int aux_ids[11], int *id0, int *id1, int *id2, int *id3)
Returns the ids of a subtetra Provided the splitting connectivities array and the array containing th...
Definition: split_tetrahedra.h:150
static void TetrahedraSplitMode(int aux_ids[11], int edge_ids[6])
Returns the edges vector filled with the splitting pattern. Provided the array of nodal ids,...
Definition: split_tetrahedra.h:91
Short class definition.
Definition: array_1d.h:61
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_ERROR
Definition: exception.h:161
static double max(double a, double b)
Definition: GeometryFunctions.h:79
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
AMatrix::TransposeMatrix< const T > trans(const T &TheMatrix)
Definition: amatrix_interface.h:486
float dist
Definition: edgebased_PureConvection.py:89
x2
Definition: generate_frictional_mortar_condition.py:122
x1
Definition: generate_frictional_mortar_condition.py:121
tuple tmp
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:98
int n_nodes
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:15
int t
Definition: ode_solve.py:392
int d
Definition: ode_solve.py:397
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
int node_id
Definition: read_stl.py:12
float xc
Definition: rotating_cone.py:77
float yc
Definition: rotating_cone.py:78
N
Definition: sensitivityMatrix.py:29
volume
Definition: sp_statistics.py:15
number_of_partitions
Definition: square_domain.py:61
integer i
Definition: TensorModule.f:17
integer l
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31