Visualization of triply periodic minimal surfaces (TPMS)¶

  • Contributor: Philip Eisenlohr (eisenlohr@egr.msu.edu)
  • DAMASK version: 3.0.0-beta3
  • Prerequisites (Python): pyvista, ipywidgets
  • Postrequisites (software): ParaView or other VTK renderer

importing any supporting modules¶

In [1]:
import numpy as np
import pyvista as pv
import ipywidgets as widgets
import damask

pv.set_jupyter_backend('static')

defining variable aspects of the resulting geometry¶

In [2]:
surface = widgets.Dropdown(
    options=list(damask.GeomGrid._minimal_surface),
    description='Minimal Surface:',
    width=400,
    disabled=False,
    )
grid = widgets.IntSlider(
    value=64,
    min=16,
    max=256,
    step=2,
    description='Grid:',
    disabled=False,
    continuous_update=False,
    orientation='horizontal',
    readout=True,
    readout_format='d'
    )
periods = widgets.IntSlider(
    value=1,
    min=1,
    max=4,
    step=1,
    description='Periods:',
    disabled=False,
    continuous_update=False,
    orientation='horizontal',
    readout=True,
    readout_format='d'
    )
threshold = widgets.FloatSlider(
    value=0.0,
    min=-1,
    max=1,
    step=0.05,
    description='Threshold:',
    disabled=False,
    continuous_update=False,
    orientation='horizontal',
    readout=True,
    readout_format='.2f'
    )

problem setup¶

Select which triply periodic minimal surface to visualize at what grid resolution and with how many periods in the filled volume

In [3]:
display(surface,grid,periods,threshold)
Dropdown(description='Minimal Surface:', options=('Schwarz P', 'Double Primitive', 'Schwarz D', 'Complementary…
IntSlider(value=64, continuous_update=False, description='Grid:', max=256, min=16, step=2)
IntSlider(value=1, continuous_update=False, description='Periods:', max=4, min=1)
FloatSlider(value=0.0, continuous_update=False, description='Threshold:', max=1.0, min=-1.0, step=0.05)

generate resulting TPMS¶

In [4]:
tpms = damask.GeomGrid.from_minimal_surface([grid.value]*3,np.ones(3),
                                             surface.value,
                                             threshold=threshold.value,
                                             periods=periods.value)\
                  .vicinity_offset()
In [5]:
# transform into pyvista mesh
mesh = pv.ImageData(dimensions=tpms.cells+1,
                    spacing=tpms.size/tpms.cells)
mesh['material'] = tpms.material.flatten(order='F')

visualize TPMS¶

In [6]:
# generate an interactive visualization of the interface
pl = pv.Plotter()
pl.set_background('white')
pl.add_mesh_threshold(mesh)
pl.show()
In [7]:
# export VTK dataset
mesh.save(f'TPMS_{surface.value}_{threshold.value}_{grid.value}.vti')