Lattices
Octet-truss
from pathlib import Path
import cadquery as cq
import numpy as np
from microgen import Cylinder, Phase, Rve, cutPhases, meshPeriodic, periodic
# ----------LOADTXT------------------------------------------------------------------------------------------#
# dir = os.path.dirname(os.path.realpath("__file__"))
# # path
# path_data = dir + "/"
# Ngeomphase_file = "test_octet.dat"
# # fichier
# NPhases_file = path_data + Ngeomphase_file
NPhases_file = str(Path(__file__).parent / "test_octet.dat")
dt = np.dtype(
[
("number", int),
("shape", np.str_, 10),
("xc", np.float64),
("yc", np.float64),
("zc", np.float64),
("psi", np.float64),
("theta", np.float64),
("phi", np.float64),
("a1", np.float64),
("a2", np.float64),
]
)
# précision du type des données
DATA = np.loadtxt(
NPhases_file,
dtype=dt,
usecols=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
skiprows=1,
unpack=True,
ndmin=1,
)
xc = DATA[2]
yc = DATA[3]
zc = DATA[4]
psi = DATA[5]
theta = DATA[6]
phi = DATA[7]
height = DATA[8]
radius = DATA[9]
# sections = read_sections(path_data,section_file)
rve = Rve(dim=1)
listPhases = []
listPeriodicPhases = []
n = len(xc)
for i in range(0, n):
elem = Cylinder(
center=(xc[i] - 0.5, yc[i] - 0.5, zc[i] - 0.5),
orientation=(psi[i], theta[i], phi[i]),
height=height[i],
radius=radius[i],
)
listPhases.append(Phase(shape=elem.generate()))
for phase_elem in listPhases:
periodicPhase = periodic(phase=phase_elem, rve=rve)
listPeriodicPhases.append(periodicPhase)
phases_cut = cutPhases(phaseList=listPeriodicPhases, reverseOrder=False)
compound = cq.Compound.makeCompound([phase.shape for phase in phases_cut])
step_file = str(Path(__file__).parent / "octettruss.step")
stl_file = str(Path(__file__).parent / "octettruss.stl")
cq.exporters.export(compound, step_file)
cq.exporters.export(compound, stl_file)
vtk_file = str(Path(__file__).parent / "octettruss.vtk")
meshPeriodic(
mesh_file=step_file,
rve=rve,
listPhases=phases_cut,
order=1,
size=0.03,
output_file=vtk_file,
)
Honeycomb
from pathlib import Path
import cadquery as cq
import numpy as np
from microgen import Box, ExtrudedPolygon, Phase, cutPhaseByShapeList, mesh
side_length = 2.5 # side in mm of the hexagon
poly_height = 2.5 # height in mm of the hexagon
theta = 30 * np.pi / 180 # half angle of the hexagone
h0 = 0.5 * poly_height
h1 = np.cos(theta) * side_length
h2 = abs(np.sin(theta) * side_length)
thickness = 30 # mm
data_file = str(Path(__file__).parent / "seedList.data")
with open(data_file) as f:
seedList = [[1, 1, 1]]
seedList = np.genfromtxt(f, delimiter="\t")
box = Box(dim=(thickness, 60, 60))
shapeList = []
for seed in seedList:
poly = ExtrudedPolygon(
center=(seed[0] - thickness, seed[1], seed[2]),
listCorners=[
(0, h2 + h0),
(h1, h0),
(h1, -h0),
(0, -h2 - h0),
(-h1, -h0),
(-h1, h0),
(0, h2 + h0),
],
height=thickness,
)
shapeList.append(poly.generate())
boxPhase = Phase(shape=box.generate())
honeycomb = cutPhaseByShapeList(phaseToCut=boxPhase, cqShapeList=shapeList)
step_file = str(Path(__file__).parent / "honeycomb.step")
stl_file = str(Path(__file__).parent / "honeycomb.stl")
cq.exporters.export(honeycomb.shape, step_file)
cq.exporters.export(honeycomb.shape, stl_file)
vtk_file = str(Path(__file__).parent / "honeycomb.vtk")
mesh(
mesh_file=step_file,
listPhases=[honeycomb],
size=1,
order=1,
output_file=vtk_file,
)
Preset strut-based lattices
from pathlib import Path
import numpy as np
import pyvista as pv
from microgen import (
BodyCenteredCubic,
Cubic,
Cuboctahedron,
Diamond,
FaceCenteredCubic,
Octahedron,
OctetTruss,
RhombicCuboctahedron,
RhombicDodecahedron,
TruncatedCube,
TruncatedCuboctahedron,
TruncatedOctahedron,
)
preset_lattice_list = [
BodyCenteredCubic(strut_radius=0.1),
Cubic(strut_radius=0.1),
Cuboctahedron(strut_radius=0.1),
Diamond(strut_radius=0.1),
FaceCenteredCubic(strut_radius=0.1),
Octahedron(strut_radius=0.1),
OctetTruss(strut_radius=0.1),
RhombicCuboctahedron(strut_radius=0.1),
RhombicDodecahedron(strut_radius=0.1),
TruncatedCube(strut_radius=0.1),
TruncatedCuboctahedron(strut_radius=0.1),
TruncatedOctahedron(strut_radius=0.1),
]
meshes = pv.PolyData()
N_COL = 4
n_row = np.ceil(len(preset_lattice_list) / N_COL)
for i, lattice in enumerate(preset_lattice_list):
i_x = i % N_COL
i_y = i // N_COL
mesh = lattice.generate_vtk()
mesh.translate(
[1.2 * (i_x - 0.5 * (N_COL - 1)), -1.2 * (i_y - 0.5 * (n_row - 1)), 0],
inplace=True,
)
meshes.append_polydata(mesh, inplace=True)
stl_file = Path(__file__).parent / "lattices.stl"
meshes.save(stl_file)
Custom strut-based lattices
from itertools import product
from pathlib import Path
import cadquery as cq
import numpy as np
from microgen import CustomLattice
# Generate custom auxetic strut lattice based on
# DOI:10.1007/s00707-019-02387-x and
# https://doi.org/10.1016/j.ijmecsci.2017.05.048
theta = np.pi / 3
l2 = 1.0 / (2.0 * np.sin(theta)) # l
l1 = 0.5 + l2 * np.cos(theta) # h
l3 = (l1 / 2.0) - np.cos(theta)
outer_cube_vertices = np.array(list(product([-0.5, 0.5], repeat=3)))
z_axis_faces_centers = np.array([[0, 0, z] for z in [0.5, -0.5]])
z_axis_reentrant_vertices = np.array([[0, 0, z] for z in [l3, -l3]])
xy_face_reentrant_vertices = np.array(
[[x, y, z] for x, y in product([0.5, -0.5], [0.0]) for z in [l1 / 2, -l1 / 2]]
+ [[x, y, z] for x, y in product([0.0], [0.5, -0.5]) for z in [l1 / 2, -l1 / 2]]
)
outer_cube_edges_reentrant_vertices = np.array(
list(product([0.5, -0.5], [0.5, -0.5], [l3, -l3]))
)
base_vertices = np.vstack(
[
outer_cube_vertices,
outer_cube_edges_reentrant_vertices,
xy_face_reentrant_vertices,
z_axis_faces_centers,
z_axis_reentrant_vertices,
]
)
strut_heights = np.array([l1] * 4 + [l2] * 24 + [l3 + 0.5] * 10)
l1_strut_vertex_pairs = np.array([[16, 17], [20, 21], [18, 19], [22, 23]])
l2_strut_vertex_pairs = np.array(
[
[18, 15],
[19, 14],
[18, 13],
[12, 19],
[15, 22],
[14, 23],
[23, 10],
[11, 22],
[11, 16],
[10, 17],
[16, 9],
[8, 17],
[9, 20],
[8, 21],
[13, 20],
[12, 21],
[20, 27],
[18, 27],
[27, 22],
[16, 27],
[23, 26],
[17, 26],
[26, 21],
[26, 19],
]
)
half_l1_strut_vertex_pairs = np.array(
[
[9, 7],
[11, 5],
[8, 6],
[10, 4],
[26, 25],
[12, 2],
[13, 3],
[27, 24],
[15, 1],
[14, 0],
]
)
strut_vertex_pairs = np.vstack(
[l1_strut_vertex_pairs, l2_strut_vertex_pairs, half_l1_strut_vertex_pairs]
)
auxetic_lattice = CustomLattice(
strut_radius=0.1,
strut_heights=strut_heights,
base_vertices=base_vertices,
strut_vertex_pairs=strut_vertex_pairs,
strut_joints=True,
)
shape = auxetic_lattice.generate()
stl_file = Path(__file__).parent / "auxetic_custom_lattice.stl"
cq.exporters.export(shape, stl_file.name)