ElementsToSimplicesConverter
Splits all non-simplex elements in a mesh into simplices.
An input mesh, as specified in the "input" parameter, will be modified to replace each non-simplex mesh element with a set of simplices connecting the same nodes. Each quad is split into 2 triangles, each pyramid into 2 tetrahedra, each prism into 3 tets, and each cube into 6 tets.
The input mesh must be "flat", not hierarchically refined.
The algorithm in 2D splits quads along their shortest interior diagonal, to try to improve element quality.
Currently the algorithm in 3D uses node ids to decide on splitting directions in a consistent way across face neighbors; this may change in the future.
In 3D, the geometry of any non-planar quadrilateral faces of cubes and/or prisms will not be exactly preserved, due to the change from bilinear or biquadratic mapping on quadrilaterals to linear or quadratic mapping on the triangles that replace them.
input
C++ Type:MeshGeneratorName
Controllable:No
Description:Input mesh to convert to all-simplex mesh
(test/tests/meshgenerators/manifold_subdomain/cone.i)
expected = '2975'
!include check.i
[Mesh]
[disk]
type = ConcentricCircleMeshGenerator
num_sectors = 6
radii = '0.9'
rings = '10'
has_outer_square = false
preserve_volumes = false
[]
[cone]
type = ParsedNodeTransformGenerator
input = disk
z_function = '0.9 - sqrt(x * x + y * y)'
[]
[surface_quads]
type = StitchMeshGenerator
inputs = 'cone disk'
stitch_boundaries_pairs = 'outer outer'
clear_stitched_boundary_ids = true
[]
[background]
type = GeneratedMeshGenerator
dim = 3
nx = 25
ny = 25
nz = 25
xmin = -1
xmax = 1
ymin = -1
ymax = 1
zmax = 1
[]
[surface]
type = ElementsToSimplicesConverter
input = surface_quads
[]
[tag]
type = ManifoldSubdomainGenerator
input = background
manifold = surface
block_id = 1
[]
[remove]
type = BlockDeletionGenerator
input = tag
block = '0'
[]
[]
(test/tests/meshgenerators/elements_to_simplices_converter/simple_convert.i)
[Mesh]
[gmg]
type = GeneratedMeshGenerator
dim = 3
nx = 1
ny = 2
nz = 2
[]
[block_1]
type = ParsedSubdomainMeshGenerator
input = gmg
combinatorial_geometry = 'z>0.5'
block_id = 1
[]
[convert]
type = ElementsToSimplicesConverter
input = block_1
[]
# Simplices conversion currently depends on element id numbering
allow_renumbering = false
[]
(test/tests/meshgenerators/elements_to_simplices_converter/hex_prism_convert.i)
[Mesh]
[accg]
type = FileMeshGenerator
file = 'hex_prism_2d.e'
[]
[extrude]
type = AdvancedExtruderGenerator
input = accg
heights = '0.4 0.8 1.2'
num_layers = '1 2 3'
direction = '0 0 1'
bottom_boundary = '200'
top_boundary = '300'
subdomain_swaps = '10 11 15 16;
10 12 15 17;
10 13 15 18'
[]
[convert]
type = ElementsToSimplicesConverter
input = extrude
[]
# Simplices conversion currently depends on element id numbering
allow_renumbering = false
[]
(modules/xfem/test/tests/solid_mechanics_basic/double_cantilever_crack.i)
# 3D Double Cantiler beam example.
# Figure 9 in: Belytschko and Black (1999)
# https://doi.org/10.1002/(SICI)1097-0207(19990620)45:5<601::AID-NME598>3.0.CO;2-S
# to reproduce literature results the mesh must be refined, in addition to using smaller fracture domain integral radii and smaller crack growth increments
# search comments for "to reproduce literature use"
L = 11.8
H = 3.94
W = 4
poissons = 0.3
youngs = 3e7
a = 3.94
da = 0.3
dtheta = 5.71 # 1.43, 2.86, 5.71
[GlobalParams]
displacements = 'disp_x disp_y disp_z'
volumetric_locking_correction = true
[]
[XFEM]
geometric_cut_userobjects = 'cut_mesh'
qrule = volfrac
output_cut_plane = true
[]
[Mesh]
[cut_profile]
type = PolyLineMeshGenerator
loop = false
points = '-0.01 0 -2.01
${a} 0 -2.01
${fparse a+da*cos(dtheta*pi/180)} ${fparse da*sin(dtheta*pi/180)} -2.01'
[]
[cut_surfaace]
type = AdvancedExtruderGenerator
input = cut_profile
direction = '0 0 1'
heights = '4.02'
num_layers = '3'
biases = '1'
[]
[tri]
type = ElementsToSimplicesConverter
input = cut_surfaace
save_with_name = cut_mesh
[]
[gen]
type = GeneratedMeshGenerator
dim = 3
nx = 30 # to reproduce literature use 240
ny = 11 # to reproduce literature use 81
nz = 4 # to reproduce literature use 10
xmin = 0
xmax = ${L}
ymin = '-${fparse H/2}'
ymax = '${fparse H/2}'
zmin = '-${fparse W/2}'
zmax = '${fparse W/2}'
elem_type = HEX8
[]
[bottom_left_elem]
type = ParsedGenerateSideset
input = gen
combinatorial_geometry = 'x < 0.21'
normal = '0 -1 0'
include_only_external_sides=true
new_sideset_name = bottom_left_elem
[]
[top_left_elem]
type = ParsedGenerateSideset
input = bottom_left_elem
combinatorial_geometry = 'x < 0.21'
normal = '0 1 0'
include_only_external_sides=true
new_sideset_name = top_left_elem
[]
final_generator = 'top_left_elem'
[]
[Functions]
[growth_func_v]
type = ParsedFunction
expression = 0.21 # to reproduce literature use 0.0125
[]
[]
[UserObjects]
[cut_mesh]
type = CrackMeshCut3DUserObject
mesh_generator_name = 'cut_mesh'
growth_dir_method = MAX_HOOP_STRESS
size_control = 1
n_step_growth = 1
growth_rate = growth_func_v
[]
[]
[DomainIntegral]
integrals = 'Jintegral InteractionIntegralKI InteractionIntegralKII'
displacements = 'disp_x disp_y disp_z'
crack_front_points_provider = cut_mesh
crack_direction_method = CurvedCrackFront
radius_inner = 0.42 # to reproduce literature use 0.1
radius_outer = 1.0 # to reproduce literature use 0.3
poissons_ratio = ${poissons}
youngs_modulus = ${youngs}
incremental = false
[]
[Physics/SolidMechanics/QuasiStatic]
[all]
strain = SMALL
incremental = false
generate_output = 'stress_xx stress_yy stress_zz vonmises_stress max_principal_stress'
add_variables = true
[]
[]
[BCs]
[right_x]
type = DirichletBC
boundary = 'right'
variable = disp_x
value = 0
[]
[right_y]
type = DirichletBC
boundary = 'right'
variable = disp_y
value = 0
[]
[right_z]
type = DirichletBC
boundary = 'right'
variable = disp_z
value = 0
[]
[planar_z]
type = DirichletBC
boundary = 'front back'
variable = disp_z
value = 0
[]
[bottom_left_elem_y]
type = NeumannBC
boundary = 'bottom_left_elem'
variable = disp_y
value = -1000
[]
[top_left_elem_y]
type = NeumannBC
boundary = 'top_left_elem'
variable = disp_y
value = 1000
[]
[]
[Materials]
[elasticity_tensor]
type = ComputeIsotropicElasticityTensor
youngs_modulus = ${youngs}
poissons_ratio = ${poissons}
[]
[stress]
type = ComputeLinearElasticStress
[]
[]
[Executioner]
type = Transient
solve_type = 'NEWTON'
petsc_options_iname = '-pc_type -pc_hypre_type -ksp_gmres_restart'
petsc_options_value = 'hypre boomeramg 31'
# petsc_options_iname = '-pc_type -pc_factor_mat_solver_package -pc_factor_shift_type -pc_factor_shift_amount'
# petsc_options_value = ' lu superlu_dist NONZERO 1e-20'
line_search = 'none'
nl_abs_tol = 1e-7
dt = 1.0
end_time = 8 # to reproduce literature use 100
max_xfem_update = 1
[]
[Outputs]
csv = true
execute_on=final
[]