14 #if !defined(KRATOS_SPLIT_TETRAHEDRA_UTILITIES_INCLUDED )
15 #define KRATOS_SPLIT_TETRAHEDRA_UTILITIES_INCLUDED
65 template<
class TMatrixType,
class TVectorType,
class TGradientType>
67 TVectorType& rVolumes, TMatrixType& rShapeFunctionValues,
68 TVectorType& rPartitionsSign, TVectorType& rEdgeAreas)
73 const int n_edges = 6;
75 const int edge_i[] = {0, 0, 0, 1, 1, 2};
76 const int edge_j[] = {1, 2, 3, 2, 3, 3};
91 for (
unsigned int i = 0;
i < 4;
i++)
92 for (
unsigned int j = 0;
j < 3;
j++)
93 aux_coordinates(
i,
j) = rPoints(
i,
j);
94 for (
unsigned int i = 4;
i < 8;
i++)
95 for (
unsigned int j = 0;
j < 3;
j++)
96 aux_coordinates(
i,
j) = -10000.0;
98 int split_edge[] = {0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1};
102 int n_negative_distance_nodes = 0;
103 int n_positive_distance_nodes = 0;
113 double max_lenght = 0.0;
114 for (
int edge = 0; edge < n_edges; edge++)
116 const int i = edge_i[edge];
117 const int j = edge_j[edge];
119 double dx = rPoints(
j, 0) - rPoints(
i, 0);
120 double dy = rPoints(
j, 1) - rPoints(
i, 1);
121 double dz = rPoints(
j, 2) - rPoints(
i, 2);
123 double l = sqrt(dx * dx + dy * dy + dz * dz);
128 edges_length[edge] =
l;
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];
211 base_point[0] = aux_coordinates(4,0);
212 base_point[1] = aux_coordinates(4,1);
213 base_point[2] = aux_coordinates(4,2);
215 for (
int i_node = 0; i_node <
n_nodes; i_node++)
217 double d = (rPoints(i_node,0) - base_point[0]) * grad_d[0] +
218 (rPoints(i_node,1) - base_point[1]) * grad_d[1] +
219 (rPoints(i_node,2) - base_point[2]) * grad_d[2] ;
220 abs_distance[i_node] = fabs(
d);
225 for (
int i_node = 0; i_node <
n_nodes; i_node++)
227 if (rDistances[i_node] < 0.00)
230 negative_distance_nodes[n_negative_distance_nodes++] = i_node;
235 positive_distance_nodes[n_positive_distance_nodes++] = i_node;
242 if (rDistances[
i] < 0.0)
243 exact_distance[
i] = -abs_distance[
i];
245 exact_distance[
i] = abs_distance[
i];
255 int number_of_splitted_edges = new_node_id - 4;
257 double volume = edges_dx[0] * edges_dy[1] * edges_dz[2] -
258 edges_dx[0] * edges_dz[1] * edges_dy[2] +
259 edges_dy[0] * edges_dz[1] * edges_dx[2] -
260 edges_dy[0] * edges_dx[1] * edges_dz[2] +
261 edges_dz[0] * edges_dx[1] * edges_dy[2] -
262 edges_dz[0] * edges_dy[1] * edges_dx[2];
264 const double one_sixth = 1.00 / 6.00;
268 if (number_of_splitted_edges == 0)
272 double min_distance = 1e9;
273 for (
int j = 0;
j < 4;
j++)
274 if(exact_distance[
j] < min_distance) min_distance = exact_distance[
j];
276 if(min_distance < 0.0)
277 rPartitionsSign[0] = -1.0;
279 rPartitionsSign[0] = 1.0;
283 if(rShapeFunctionValues.size1() != 4 || rShapeFunctionValues.size2() != 4)
284 rShapeFunctionValues.resize(4,4,
false);
292 int n_splitted_edges;
298 KRATOS_THROW_ERROR(std::logic_error,
"requiring an internal node for splitting ... can not accept this",
"");
301 if(rShapeFunctionValues.size1() != (
unsigned int)(nel)*4 || rShapeFunctionValues.size2() != 4)
302 rShapeFunctionValues.resize(nel*4,4,
false);
304 std::vector< array_1d<double, 3 > >center_position(4);
306 if(rVolumes.size() != (
unsigned int)(nel)*4)
307 rVolumes.resize(nel*4,
false);
312 for (
int i = 0;
i < nel;
i++)
318 double sub_volume = ComputeSubTetraVolumeAndGaussPoints(aux_coordinates, gauss_volumes, center_position, i0, i1, i2, i3);
320 local_subtet_indices[0] =
t[
i*4];
321 local_subtet_indices[1] =
t[
i*4+1];
322 local_subtet_indices[2] =
t[
i*4+2];
323 local_subtet_indices[3] =
t[
i*4+3];
325 AddToEdgeAreas3D(rEdgeAreas,exact_distance,local_subtet_indices,sub_volume);
327 for(
unsigned int k=0;
k<4;
k++)
329 rVolumes[
i*4+
k] = gauss_volumes[
k];
332 ComputeElementCoordinates(
N, center_position[
k], rPoints,
volume);
334 for (
int j = 0;
j < 4;
j++)
335 rShapeFunctionValues(
i*4+
k,
j) =
N[
j];
347 double max_aux_dist_on_cut = -1;
348 for (
int edge = 0; edge < n_edges; edge++)
350 const int i = edge_i[edge];
351 const int j = edge_j[edge];
352 if (rDistances[
i] * rDistances[
j] < 0.0)
354 const double tmp = fabs(rDistances[
i]) / (fabs(rDistances[
i]) + fabs(rDistances[
j]));
357 double abs_dist_on_cut = abs_distance[
i] *
tmp + abs_distance[
j] * (1.00 -
tmp);
359 if(abs_dist_on_cut > max_aux_dist_on_cut) max_aux_dist_on_cut = abs_dist_on_cut;
364 if(max_aux_dist_on_cut < 1
e-9*max_lenght)
365 max_aux_dist_on_cut = 1
e-9*max_lenght;
374 double abs_dist = 0.0;
375 for (
int j = 0;
j < 4;
j++)
377 dist += rShapeFunctionValues(
i,
j) * exact_distance[
j];
378 abs_dist += rShapeFunctionValues(
i,
j) * abs_distance[
j];
382 rPartitionsSign[
i] = -1.0;
384 rPartitionsSign[
i] = 1.0;
397 const int i0,
const int i1,
const int i2,
const int i3)
399 double x10 = aux_coordinates(i1, 0) - aux_coordinates(i0, 0);
400 double y10 = aux_coordinates(i1, 1) - aux_coordinates(i0, 1);
401 double z10 = aux_coordinates(i1, 2) - aux_coordinates(i0, 2);
403 double x20 = aux_coordinates(i2, 0) - aux_coordinates(i0, 0);
404 double y20 = aux_coordinates(i2, 1) - aux_coordinates(i0, 1);
405 double z20 = aux_coordinates(i2, 2) - aux_coordinates(i0, 2);
407 double x30 = aux_coordinates(i3, 0) - aux_coordinates(i0, 0);
408 double y30 = aux_coordinates(i3, 1) - aux_coordinates(i0, 1);
409 double z30 = aux_coordinates(i3, 2) - aux_coordinates(i0, 2);
411 double detJ = x10 * y20 * z30 - x10 * y30 * z20 + y10 * z20 * x30 - y10 * x20 * z30 + z10 * x20 * y30 - z10 * y20 * x30;
412 double vol = detJ * 0.1666666666666666666667;
414 for (
unsigned int i = 0;
i < 3;
i++)
416 center_position[
i] = aux_coordinates(i0,
i) + aux_coordinates(i1,
i) + aux_coordinates(i2,
i) + aux_coordinates(i3,
i);
418 center_position *= 0.25;
425 static double ComputeSubTetraVolumeAndGaussPoints(
const BoundedMatrix<double, 3, 8 > & aux_coordinates,
427 std::vector< array_1d<double, 3 > >& center_position,
428 const int i0,
const int i1,
const int i2,
const int i3)
430 double x10 = aux_coordinates(i1, 0) - aux_coordinates(i0, 0);
431 double y10 = aux_coordinates(i1, 1) - aux_coordinates(i0, 1);
432 double z10 = aux_coordinates(i1, 2) - aux_coordinates(i0, 2);
434 double x20 = aux_coordinates(i2, 0) - aux_coordinates(i0, 0);
435 double y20 = aux_coordinates(i2, 1) - aux_coordinates(i0, 1);
436 double z20 = aux_coordinates(i2, 2) - aux_coordinates(i0, 2);
438 double x30 = aux_coordinates(i3, 0) - aux_coordinates(i0, 0);
439 double y30 = aux_coordinates(i3, 1) - aux_coordinates(i0, 1);
440 double z30 = aux_coordinates(i3, 2) - aux_coordinates(i0, 2);
442 double detJ = x10 * y20 * z30 - x10 * y30 * z20 + y10 * z20 * x30 - y10 * x20 * z30 + z10 * x20 * y30 - z10 * y20 * x30;
443 double vol = detJ * 0.1666666666666666666667;
445 for (
unsigned int i = 0;
i < 4;
i++)
447 volumes[
i] = 0.25*vol;
451 for (
unsigned int i = 0;
i < 3;
i++)
453 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);
456 for (
unsigned int i = 0;
i < 3;
i++)
458 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);
462 for (
unsigned int i = 0;
i < 3;
i++)
464 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);
468 for (
unsigned int i = 0;
i < 3;
i++)
470 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);
477 template<
class TMatrixType>
478 static void ComputeElementCoordinates(array_1d<double, 4 > &
N,
479 const array_1d<double, 3 > & center_position,
480 const TMatrixType& rPoints,
483 double x0 = rPoints(0, 0);
484 double y0 = rPoints(0, 1);
485 double z0 = rPoints(0, 2);
486 double x1 = rPoints(1, 0);
487 double y1 = rPoints(1, 1);
488 double z1 = rPoints(1, 2);
489 double x2 = rPoints(2, 0);
490 double y2 = rPoints(2, 1);
491 double z2 = rPoints(2, 2);
492 double x3 = rPoints(3, 0);
493 double y3 = rPoints(3, 1);
494 double z3 = rPoints(3, 2);
496 double xc = center_position[0];
497 double yc = center_position[1];
498 double zc = center_position[2];
500 double inv_vol = 1.0 / vol;
505 N[0] = CalculateVol(
x1, y1, z1, x3, y3, z3,
x2, y2, z2,
xc,
yc, zc) * inv_vol;
506 N[1] = CalculateVol(x0, y0, z0,
x2, y2, z2, x3, y3, z3,
xc,
yc, zc) * inv_vol;
507 N[2] = CalculateVol(x3, y3, z3,
x1, y1, z1, x0, y0, z0,
xc,
yc, zc) * inv_vol;
508 N[3] = CalculateVol(
x1, y1, z1,
x2, y2, z2, x0, y0, z0,
xc,
yc, zc) * inv_vol;
513 static inline double CalculateVol(
const double x0,
const double y0,
const double z0,
514 const double x1,
const double y1,
const double z1,
515 const double x2,
const double y2,
const double z2,
516 const double x3,
const double y3,
const double z3)
518 double x10 =
x1 - x0;
519 double y10 = y1 - y0;
520 double z10 = z1 - z0;
522 double x20 =
x2 - x0;
523 double y20 = y2 - y0;
524 double z20 = z2 - z0;
526 double x30 = x3 - x0;
527 double y30 = y3 - y0;
528 double z30 = z3 - z0;
530 double detJ = x10 * y20 * z30 - x10 * y30 * z20 + y10 * z20 * x30 - y10 * x20 * z30 + z10 * x20 * y30 - z10 * y20 * x30;
531 return detJ * 0.1666666666666666666667;
535 template<
class TVectorType>
536 static void AddToEdgeAreas3D(TVectorType& rEdgeAreas,
537 const array_1d<double, 3+1 >& exact_distance,
538 const array_1d<double, 3+1 >& indices,
539 const double sub_volume)
543 unsigned int ncut=0, pos=0, positive_pos=0;
544 for(
unsigned int i=0;
i<3+1;
i++)
550 else if(exact_distance[indices[
i]] > 0)
552 positive_pos = indices[
i];
557 if(ncut == 3 && pos==1)
559 double edge_area = sub_volume*3.0/fabs(exact_distance[positive_pos]);
560 edge_area /=
static_cast<double>(3);
561 for(
unsigned int i=0;
i<3+1;
i++)
565 int edge_index = indices[
i] - 3 - 1;
566 rEdgeAreas[edge_index] += edge_area;
Definition: amatrix_interface.h:41
Definition: split_tetrahedra_utilities.h:45
static int CalculateSplitTetrahedraShapeFuncions(TMatrixType const &rPoints, TGradientType const &DN_DX, TVectorType &rDistances, TVectorType &rVolumes, TMatrixType &rShapeFunctionValues, TVectorType &rPartitionsSign, TVectorType &rEdgeAreas)
Definition: split_tetrahedra_utilities.h:66
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