15 #if !defined(KRATOS_ENRICHMENT_UTILITIES_DUPLICATE_DOFS_INCLUDED )
16 #define KRATOS_ENRICHMENT_UTILITIES_DUPLICATE_DOFS_INCLUDED
88 template<
class TMatrixType,
class TVectorType,
class TGradientType>
90 TVectorType& rDistances, TVectorType& rVolumes, TMatrixType& rShapeFunctionValues,
91 TVectorType& rPartitionsSign, std::vector<TMatrixType>& rGradientsValue, TMatrixType& NEnriched)
96 const int n_edges = 6;
98 const int edge_i[] = {0, 0, 0, 1, 1, 2};
99 const int edge_j[] = {1, 2, 3, 2, 3, 3};
114 for (
unsigned int i = 0;
i < 4;
i++)
115 for (
unsigned int j = 0;
j < 3;
j++)
116 aux_coordinates(
i,
j) = rPoints(
i,
j);
117 for (
unsigned int i = 4;
i < 8;
i++)
118 for (
unsigned int j = 0;
j < 3;
j++)
119 aux_coordinates(
i,
j) = -10000.0;
121 int split_edge[] = {0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1};
126 int n_negative_distance_nodes = 0;
127 int n_positive_distance_nodes = 0;
147 double max_lenght = 0.0;
148 for (
int edge = 0; edge < n_edges; edge++)
150 const int i = edge_i[edge];
151 const int j = edge_j[edge];
153 double dx = rPoints(
j, 0) - rPoints(
i, 0);
154 double dy = rPoints(
j, 1) - rPoints(
i, 1);
155 double dz = rPoints(
j, 2) - rPoints(
i, 2);
157 double l = sqrt(dx * dx + dy * dy + dz * dz);
162 edges_length[edge] =
l;
169 for(
unsigned int i=0;
i<4;
i++)
170 if(fabs(rDistances[
i]) < 1
e-4*max_lenght) rDistances[
i]=1
e-4*max_lenght;
174 for (
unsigned int i = 0;
i < 4;
i++)
175 abs_distance[
i] = fabs(rDistances[
i]);
180 double norm =
norm_2(grad_d);
182 if(norm < 1
e-10) norm=1
e-10;
187 for (
int edge = 0; edge < n_edges; edge++)
189 const int i = edge_i[edge];
190 const int j = edge_j[edge];
191 if (rDistances[
i] * rDistances[
j] < 0.0)
193 const double tmp = fabs(rDistances[
i]) / (fabs(rDistances[
i]) + fabs(rDistances[
j]));
195 split_edge[edge + 4] = new_node_id;
196 edge_division_i[edge] =
tmp;
197 edge_division_j[edge] = 1.00 -
tmp;
200 for (
unsigned int k = 0;
k < 3;
k++)
201 aux_coordinates(new_node_id,
k) = rPoints(
i,
k) * edge_division_j[edge] + rPoints(
j,
k) * edge_division_i[edge];
212 base_point[0] = aux_coordinates(4,0);
213 base_point[1] = aux_coordinates(4,1);
214 base_point[2] = aux_coordinates(4,2);
217 for (
int i_node = 0; i_node <
n_nodes; i_node++)
219 double d = (rPoints(i_node,0) - base_point[0]) * grad_d[0] +
220 (rPoints(i_node,1) - base_point[1]) * grad_d[1] +
221 (rPoints(i_node,2) - base_point[2]) * grad_d[2] ;
222 abs_distance[i_node] = fabs(
d);
228 for (
int i_node = 0; i_node <
n_nodes; i_node++)
238 if (rDistances[i_node] < 0.00)
241 negative_distance_nodes[n_negative_distance_nodes++] = i_node;
246 positive_distance_nodes[n_positive_distance_nodes++] = i_node;
253 if (rDistances[
i] < 0.0)
254 exact_distance[
i] = -abs_distance[
i];
256 exact_distance[
i] = abs_distance[
i];
266 int number_of_splitted_edges = new_node_id - 4;
268 double volume = edges_dx[0] * edges_dy[1] * edges_dz[2] -
269 edges_dx[0] * edges_dz[1] * edges_dy[2] +
270 edges_dy[0] * edges_dz[1] * edges_dx[2] -
271 edges_dy[0] * edges_dx[1] * edges_dz[2] +
272 edges_dz[0] * edges_dx[1] * edges_dy[2] -
273 edges_dz[0] * edges_dy[1] * edges_dx[2];
275 const double one_sixth = 1.00 / 6.00;
280 if (number_of_splitted_edges == 0)
292 double min_distance = 1e9;
293 for (
int j = 0;
j < 4;
j++)
294 if(exact_distance[
j] < min_distance) min_distance = exact_distance[
j];
299 if(min_distance < 0.0)
300 rPartitionsSign[0] = -1.0;
302 rPartitionsSign[0] = 1.0;
306 if(rShapeFunctionValues.size1() != 4 || rShapeFunctionValues.size2() != 4)
307 rShapeFunctionValues.resize(4,4,
false);
313 if(NEnriched.size1() != 0 || NEnriched.size2() != 0)
314 NEnriched.resize(0,0,
false);
317 if(rGradientsValue.size() !=0)
318 rGradientsValue.resize(0);
332 int n_splitted_edges;
341 KRATOS_THROW_ERROR(std::logic_error,
"requiring an internal node for splitting ... can not accept this",
"");
345 if(rShapeFunctionValues.size1() != (
unsigned int)(nel)*4 || rShapeFunctionValues.size2() != 4)
346 rShapeFunctionValues.resize(nel*4,4,
false);
348 std::vector< array_1d<double, 3 > >center_position(4);
350 if(rVolumes.size() != (
unsigned int)(nel)*4)
351 rVolumes.resize(nel*4,
false);
353 for (
int i = 0;
i < nel;
i++)
360 ComputeSubTetraVolumeAndGaussPoints(aux_coordinates, gauss_volumes, center_position, i0, i1, i2, i3);
362 for(
unsigned int k=0;
k<4;
k++)
364 rVolumes[
i*4+
k] = gauss_volumes[
k];
367 ComputeElementCoordinates(
N, center_position[
k], rPoints,
volume);
369 for (
int j = 0;
j < 4;
j++)
370 rShapeFunctionValues(
i*4+
k,
j) =
N[
j];
401 double max_aux_dist_on_cut = -1;
402 for (
int edge = 0; edge < n_edges; edge++)
404 const int i = edge_i[edge];
405 const int j = edge_j[edge];
406 if (rDistances[
i] * rDistances[
j] < 0.0)
408 const double tmp = fabs(rDistances[
i]) / (fabs(rDistances[
i]) + fabs(rDistances[
j]));
411 double abs_dist_on_cut = abs_distance[
i] *
tmp + abs_distance[
j] * (1.00 -
tmp);
413 if(abs_dist_on_cut > max_aux_dist_on_cut) max_aux_dist_on_cut = abs_dist_on_cut;
420 if(max_aux_dist_on_cut < 1
e-9*max_lenght)
421 max_aux_dist_on_cut = 1
e-9*max_lenght;
435 double abs_dist = 0.0;
436 for (
int j = 0;
j < 4;
j++)
438 dist += rShapeFunctionValues(
i,
j) * exact_distance[
j];
439 abs_dist += rShapeFunctionValues(
i,
j) * abs_distance[
j];
443 rPartitionsSign[
i] = -1.0;
445 rPartitionsSign[
i] = 1.0;
447 rGradientsValue[
i] = DN_DX;
450 for(
unsigned int j = 0 ;
j<rShapeFunctionValues.size2();
j++)
452 if(exact_distance[
j]*
dist > 0)
460 NEnriched(
i,
j) = disc_factor * rShapeFunctionValues(
i,
j);
463 for(
unsigned int k=0;
k<3;
k++)
465 rGradientsValue[
i](
j,
k) *= disc_factor;
497 const int i0,
const int i1,
const int i2,
const int i3)
499 double x10 = aux_coordinates(i1, 0) - aux_coordinates(i0, 0);
500 double y10 = aux_coordinates(i1, 1) - aux_coordinates(i0, 1);
501 double z10 = aux_coordinates(i1, 2) - aux_coordinates(i0, 2);
503 double x20 = aux_coordinates(i2, 0) - aux_coordinates(i0, 0);
504 double y20 = aux_coordinates(i2, 1) - aux_coordinates(i0, 1);
505 double z20 = aux_coordinates(i2, 2) - aux_coordinates(i0, 2);
507 double x30 = aux_coordinates(i3, 0) - aux_coordinates(i0, 0);
508 double y30 = aux_coordinates(i3, 1) - aux_coordinates(i0, 1);
509 double z30 = aux_coordinates(i3, 2) - aux_coordinates(i0, 2);
511 double detJ = x10 * y20 * z30 - x10 * y30 * z20 + y10 * z20 * x30 - y10 * x20 * z30 + z10 * x20 * y30 - z10 * y20 * x30;
512 double vol = detJ * 0.1666666666666666666667;
514 for (
unsigned int i = 0;
i < 3;
i++)
516 center_position[
i] = aux_coordinates(i0,
i) + aux_coordinates(i1,
i) + aux_coordinates(i2,
i) + aux_coordinates(i3,
i);
518 center_position *= 0.25;
524 static void ComputeSubTetraVolumeAndGaussPoints(
const BoundedMatrix<double, 3, 8 > & aux_coordinates,
526 std::vector< array_1d<double, 3 > >& center_position,
527 const int i0,
const int i1,
const int i2,
const int i3)
529 double x10 = aux_coordinates(i1, 0) - aux_coordinates(i0, 0);
530 double y10 = aux_coordinates(i1, 1) - aux_coordinates(i0, 1);
531 double z10 = aux_coordinates(i1, 2) - aux_coordinates(i0, 2);
533 double x20 = aux_coordinates(i2, 0) - aux_coordinates(i0, 0);
534 double y20 = aux_coordinates(i2, 1) - aux_coordinates(i0, 1);
535 double z20 = aux_coordinates(i2, 2) - aux_coordinates(i0, 2);
537 double x30 = aux_coordinates(i3, 0) - aux_coordinates(i0, 0);
538 double y30 = aux_coordinates(i3, 1) - aux_coordinates(i0, 1);
539 double z30 = aux_coordinates(i3, 2) - aux_coordinates(i0, 2);
541 double detJ = x10 * y20 * z30 - x10 * y30 * z20 + y10 * z20 * x30 - y10 * x20 * z30 + z10 * x20 * y30 - z10 * y20 * x30;
542 double vol = detJ * 0.1666666666666666666667;
544 for (
unsigned int i = 0;
i < 4;
i++)
546 volumes[
i] = 0.25*vol;
550 for (
unsigned int i = 0;
i < 3;
i++)
552 center_position[0][
i] = 0.58541020*aux_coordinates(i0,
i) + 0.13819660*aux_coordinates(i1,
i) + 0.13819660*aux_coordinates(i2,
i) + 0.13819660*aux_coordinates(i3,
i);
555 for (
unsigned int i = 0;
i < 3;
i++)
557 center_position[1][
i] = 0.13819660*aux_coordinates(i0,
i) + 0.58541020*aux_coordinates(i1,
i) + 0.13819660*aux_coordinates(i2,
i) + 0.13819660*aux_coordinates(i3,
i);
561 for (
unsigned int i = 0;
i < 3;
i++)
563 center_position[2][
i] = 0.13819660*aux_coordinates(i0,
i) + 0.13819660*aux_coordinates(i1,
i) + 0.58541020*aux_coordinates(i2,
i) + 0.13819660*aux_coordinates(i3,
i);
567 for (
unsigned int i = 0;
i < 3;
i++)
569 center_position[3][
i] = 0.13819660*aux_coordinates(i0,
i) + 0.13819660*aux_coordinates(i1,
i) + 0.13819660*aux_coordinates(i2,
i) + 0.58541020*aux_coordinates(i3,
i);
575 template<
class TMatrixType>
576 static void ComputeElementCoordinates(array_1d<double, 4 > &
N,
const array_1d<double, 3 > & center_position,
const TMatrixType& rPoints,
const double vol)
578 double x0 = rPoints(0, 0);
579 double y0 = rPoints(0, 1);
580 double z0 = rPoints(0, 2);
581 double x1 = rPoints(1, 0);
582 double y1 = rPoints(1, 1);
583 double z1 = rPoints(1, 2);
584 double x2 = rPoints(2, 0);
585 double y2 = rPoints(2, 1);
586 double z2 = rPoints(2, 2);
587 double x3 = rPoints(3, 0);
588 double y3 = rPoints(3, 1);
589 double z3 = rPoints(3, 2);
591 double xc = center_position[0];
592 double yc = center_position[1];
593 double zc = center_position[2];
595 double inv_vol = 1.0 / vol;
600 N[0] = CalculateVol(
x1, y1, z1, x3, y3, z3,
x2, y2, z2,
xc,
yc, zc) * inv_vol;
601 N[1] = CalculateVol(x0, y0, z0,
x2, y2, z2, x3, y3, z3,
xc,
yc, zc) * inv_vol;
602 N[2] = CalculateVol(x3, y3, z3,
x1, y1, z1, x0, y0, z0,
xc,
yc, zc) * inv_vol;
603 N[3] = CalculateVol(
x1, y1, z1,
x2, y2, z2, x0, y0, z0,
xc,
yc, zc) * inv_vol;
607 static inline double CalculateVol(
const double x0,
const double y0,
const double z0,
608 const double x1,
const double y1,
const double z1,
609 const double x2,
const double y2,
const double z2,
610 const double x3,
const double y3,
const double z3
613 double x10 =
x1 - x0;
614 double y10 = y1 - y0;
615 double z10 = z1 - z0;
617 double x20 =
x2 - x0;
618 double y20 = y2 - y0;
619 double z20 = z2 - z0;
621 double x30 = x3 - x0;
622 double y30 = y3 - y0;
623 double z30 = z3 - z0;
625 double detJ = x10 * y20 * z30 - x10 * y30 * z20 + y10 * z20 * x30 - y10 * x20 * z30 + z10 * x20 * y30 - z10 * y20 * x30;
626 return detJ * 0.1666666666666666666667;
630 static inline void CalculateGeometryData(
631 const BoundedMatrix<double, 3, 3 > & coordinates,
632 BoundedMatrix<double,3,2>& DN_DX,
633 array_1d<double,3>&
N,
636 double x10 = coordinates(1,0) - coordinates(0,0);
637 double y10 = coordinates(1,1) - coordinates(0,1);
639 double x20 = coordinates(2,0) - coordinates(0,0);
640 double y20 = coordinates(2,1) - coordinates (0,1);
648 double detJ = x10 * y20-y10 * x20;
650 DN_DX(0,0) = -y20 + y10;
651 DN_DX(0,1) = x20 - x10;
658 N[0] = 0.333333333333333;
659 N[1] = 0.333333333333333;
660 N[2] = 0.333333333333333;
666 static inline double CalculateVolume2D(
667 const BoundedMatrix<double, 3, 3 > & coordinates)
669 double x10 = coordinates(1,0) - coordinates(0,0);
670 double y10 = coordinates(1,1) - coordinates(0,1);
672 double x20 = coordinates(2,0) - coordinates(0,0);
673 double y20 = coordinates(2,1) - coordinates (0,1);
674 double detJ = x10 * y20-y10 * x20;
678 static inline bool CalculatePosition(
const BoundedMatrix<double, 3, 3 > & coordinates,
679 const double xc,
const double yc,
const double zc,
680 array_1d<double, 3 > &
N
683 double x0 = coordinates(0,0);
684 double y0 = coordinates(0,1);
685 double x1 = coordinates(1,0);
686 double y1 = coordinates(1,1);
687 double x2 = coordinates(2,0);
688 double y2 = coordinates(2,1);
690 double area = CalculateVol(x0, y0,
x1, y1,
x2, y2);
691 double inv_area = 0.0;
698 inv_area = 1.0 / area;
702 N[0] = CalculateVol(
x1, y1,
x2, y2,
xc,
yc) * inv_area;
703 N[1] = CalculateVol(
x2, y2, x0, y0,
xc,
yc) * inv_area;
704 N[2] = CalculateVol(x0, y0,
x1, y1,
xc,
yc) * inv_area;
707 if (
N[0] >= 0.0 &&
N[1] >= 0.0 &&
N[2] >= 0.0 &&
N[0] <= 1.0 &&
N[1] <= 1.0 &&
N[2] <= 1.0)
713 static inline double CalculateVol(
const double x0,
const double y0,
714 const double x1,
const double y1,
715 const double x2,
const double y2
718 return 0.5 * ((
x1 - x0)*(y2 - y0)- (y1 - y0)*(
x2 - x0));
721 static inline void CalculateGeometryData(
722 const BoundedMatrix<double, 3, 3 > & coordinates,
723 BoundedMatrix<double,3,2>& DN_DX,
726 double x10 = coordinates(1,0) - coordinates(0,0);
727 double y10 = coordinates(1,1) - coordinates(0,1);
729 double x20 = coordinates(2,0) - coordinates(0,0);
730 double y20 = coordinates(2,1) - coordinates (0,1);
738 double detJ = x10 * y20-y10 * x20;
740 DN_DX(0,0) = -y20 + y10;
741 DN_DX(0,1) = x20 - x10;
Definition: enrichment_utilities_duplicate_dofs.h:63
static int CalculateTetrahedraEnrichedShapeFuncions(TMatrixType const &rPoints, TGradientType const &DN_DX, TVectorType &rDistances, TVectorType &rVolumes, TMatrixType &rShapeFunctionValues, TVectorType &rPartitionsSign, std::vector< TMatrixType > &rGradientsValue, TMatrixType &NEnriched)
Definition: enrichment_utilities_duplicate_dofs.h:89
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_THROW_ERROR(ExceptionType, ErrorMessage, MoreInfo)
Definition: define.h:77
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
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
Internals::Matrix< double, AMatrix::dynamic, 1 > Vector
Definition: amatrix_interface.h:472
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
REACTION_CHECK_STIFFNESS_FACTOR int
Definition: contact_structural_mechanics_application_variables.h:75
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
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