Note
Go to the end to download the full example code
Parametric study#
This example shows how you can use PyAdditive to perform a parametric study.
The intended audience is a user who desires to optimize additive machine parameters
to achieve a specific result. Here, the ParametricStudy
class is used to
conduct a parametric study. While this is not required, the ParametricStudy
class provides data management and visualization features that ease the task.
Units are SI (m, kg, s, K) unless otherwise noted.
Perform required imports and create a study#
Perform the required import and create a ParametricStudy
instance.
from ansys.additive.core import Additive, SimulationStatus, SimulationType
from ansys.additive.core.parametric_study import ColumnNames, ParametricStudy
import ansys.additive.core.parametric_study.display as display
study = ParametricStudy("demo-study")
Saving parametric study to /home/runner/work/pyadditive/pyadditive/examples/demo-study.ps
Get the study file name#
The current state of the parametric study is saved to a file upon each update. You can retrieve the name of the file as shown below. This file uses a binary format and is not human readable.
print(study.file_name)
/home/runner/work/pyadditive/pyadditive/examples/demo-study.ps
Select a material for the study#
Select a material to use in the study. The material name must be known by the Additive service. You can connect to the Additive service and print a list of available materials prior to selecting one.
additive = Additive()
print("Available material names: {}".format(additive.materials_list()))
material = "IN718"
user data path: /home/runner/.local/share/pyadditive
Available material names: ['316L', 'Ti64', '17-4PH', 'CoCr', 'IN718', 'IN625', 'AlSi10Mg', 'Al357']
Create a single bead evaluation#
Parametric studies often start with single bead simulations in order to
determine melt pool statistics. Here, the
generate_single_bead_permutations()
method is used to
generate single bead simulation permutations. The parameters
for the generate_single_bead_permutations()
method allow you to
specify a range of machine parameters and filter them by energy density. Not all
the parameters shown are required. Optional parameters that are not specified
use default values defined in the MachineConstants
class.
import numpy as np
# Specify a range of laser powers. Valid values are 50 to 700 W.
initial_powers = np.linspace(50, 700, 7)
# Specify a range of laser scan speeds. Valid values are 0.35 to 2.5 m/s.
initial_scan_speeds = np.linspace(0.35, 2.5, 5)
# Specify powder layer thicknesses. Valid values are 10e-6 to 100e-6 m.
initial_layer_thicknesses = [40e-6, 50e-6]
# Specify laser beam diameters. Valid values are 20e-6 to 140e-6 m.
initial_beam_diameters = [80e-6]
# Specify heater temperatures. Valid values are 20 - 500 C.
initial_heater_temps = [80]
# Restrict the permutations within a range of energy densities
# For single bead, the energy density is laser power / (laser scan speed * layer thickness).
min_energy_density = 2e6
max_energy_density = 8e6
# Specify a bead length in meters.
bead_length = 0.001
study.generate_single_bead_permutations(
material_name=material,
bead_length=bead_length,
laser_powers=initial_powers,
scan_speeds=initial_scan_speeds,
layer_thicknesses=initial_layer_thicknesses,
beam_diameters=initial_beam_diameters,
heater_temperatures=initial_heater_temps,
min_area_energy_density=min_energy_density,
max_area_energy_density=max_energy_density,
)
Show the simulations as a table#
You can use the display
package to list the simulations as a table.
display.show_table(study)
show_table
Skip some simulations#
If you are working with a large parametric study, you may want to skip some
simulations to reduce processing time. To do so, set the simulation status
to SimulationStatus.SKIP
which is defined in the SimulationStatus
class. Here, a DataFrame
object is obtained, a filter is
applied to get a list of simulation IDs, and then the status is updated on the
simulations with those IDs.
df = study.data_frame()
# Get IDs for single bead simulations with laser power below 75 W.
ids = df.loc[
(df[ColumnNames.LASER_POWER] < 75) & (df[ColumnNames.TYPE] == SimulationType.SINGLE_BEAD),
ColumnNames.ID,
].tolist()
study.set_status(ids, SimulationStatus.SKIP)
display.show_table(study)
show_table
Run single bead simulations#
Run the simulations using the run_simulations()
method. All simulations
with a SimulationStatus.PENDING
status are executed.
study.run_simulations(additive)
2024-02-21 03:22:39 Completed 0 of 31 simulations
2024-02-21 03:23:00 Completed 1 of 31 simulations
2024-02-21 03:23:14 Completed 2 of 31 simulations
2024-02-21 03:23:26 Completed 3 of 31 simulations
2024-02-21 03:23:38 Completed 4 of 31 simulations
2024-02-21 03:23:51 Completed 5 of 31 simulations
2024-02-21 03:24:04 Completed 6 of 31 simulations
2024-02-21 03:24:16 Completed 7 of 31 simulations
2024-02-21 03:24:28 Completed 8 of 31 simulations
2024-02-21 03:24:41 Completed 9 of 31 simulations
2024-02-21 03:24:53 Completed 10 of 31 simulations
2024-02-21 03:25:11 Completed 11 of 31 simulations
2024-02-21 03:25:22 Completed 12 of 31 simulations
2024-02-21 03:25:33 Completed 13 of 31 simulations
2024-02-21 03:25:47 Completed 14 of 31 simulations
2024-02-21 03:25:58 Completed 15 of 31 simulations
2024-02-21 03:26:10 Completed 16 of 31 simulations
2024-02-21 03:26:25 Completed 17 of 31 simulations
2024-02-21 03:26:37 Completed 18 of 31 simulations
2024-02-21 03:26:48 Completed 19 of 31 simulations
2024-02-21 03:27:01 Completed 20 of 31 simulations
2024-02-21 03:27:15 Completed 21 of 31 simulations
2024-02-21 03:27:30 Completed 22 of 31 simulations
2024-02-21 03:27:44 Completed 23 of 31 simulations
2024-02-21 03:28:05 Completed 24 of 31 simulations
2024-02-21 03:28:26 Completed 25 of 31 simulations
2024-02-21 03:28:39 Completed 26 of 31 simulations
2024-02-21 03:28:54 Completed 27 of 31 simulations
2024-02-21 03:29:08 Completed 28 of 31 simulations
2024-02-21 03:29:29 Completed 29 of 31 simulations
2024-02-21 03:29:45 Completed 30 of 31 simulations
2024-02-21 03:29:56 Completed 31 of 31 simulations
Save the study to a CSV file#
The parametric study is saved with each update in a binary format.
For other formats, use the to_*
methods provided by the DataFrame
class.
study.data_frame().to_csv("demo-study.csv")
Load a previously saved study#
Load a previously saved study using the static
ParameticStudy.load()
method.
study2 = ParametricStudy.load("demo-study.ps")
display.show_table(study2)
show_table
Plot single bead results#
Plot the single bead results using the
single_bead_eval_plot()
method.
display.single_bead_eval_plot(study)
single_bead_eval_plot
Create a porosity evaluation#
You can use the insights gained from the single bead evaluation to
generate parameters for a porosity evaluation. Alternatively, you can
perform a porosity evaluation without a previous single bead evaluation.
Here, the laser power and scan speeds are determined by filtering the
single bead results where the ratio of the melt pool reference depth
to reference width is within a specified range. Additionally, the simulations
are restricted to a minimum build rate, which is calculated as
scan speed * layer thickness * hatch spacing. The
generate_porosity_permutations()
method is used to add
porosity simulations to the study.
df = study.data_frame()
df = df[
(df[ColumnNames.MELT_POOL_REFERENCE_DEPTH_OVER_WIDTH] >= 0.3)
& (df[ColumnNames.MELT_POOL_REFERENCE_DEPTH_OVER_WIDTH] <= 0.65)
]
study.generate_porosity_permutations(
material_name=material,
laser_powers=df[ColumnNames.LASER_POWER].unique(),
scan_speeds=df[ColumnNames.SCAN_SPEED].unique(),
size_x=1e-3,
size_y=1e-3,
size_z=1e-3,
layer_thicknesses=[40e-6],
heater_temperatures=[80],
beam_diameters=[80e-6],
start_angles=[45],
rotation_angles=[67.5],
hatch_spacings=[100e-6],
min_build_rate=5e-9,
iteration=1,
)
Run porosity simulations#
Run the simulations using the run_simulations()
method.
study.run_simulations(additive)
2024-02-21 03:30:00 Completed 0 of 15 simulations
2024-02-21 03:30:50 Completed 1 of 15 simulations
2024-02-21 03:31:27 Completed 2 of 15 simulations
2024-02-21 03:31:59 Completed 3 of 15 simulations
2024-02-21 03:32:53 Completed 4 of 15 simulations
2024-02-21 03:33:32 Completed 5 of 15 simulations
2024-02-21 03:34:05 Completed 6 of 15 simulations
2024-02-21 03:35:14 Completed 7 of 15 simulations
2024-02-21 03:35:57 Completed 8 of 15 simulations
2024-02-21 03:36:30 Completed 9 of 15 simulations
2024-02-21 03:38:29 Completed 10 of 15 simulations
2024-02-21 03:39:17 Completed 11 of 15 simulations
2024-02-21 03:39:52 Completed 12 of 15 simulations
2024-02-21 03:42:47 Completed 13 of 15 simulations
2024-02-21 03:43:59 Completed 14 of 15 simulations
2024-02-21 03:44:37 Completed 15 of 15 simulations
Plot porosity results#
Plot the porosity simulation results using the
porosity_contour_plot()
method.
display.porosity_contour_plot(study)
porosity_contour_plot
Create a microstructure evaluation#
Here a set of microstructure simulations is generated using many of the same
parameters used for the porosity simulations. The parameters cooling_rate
,
thermal_gradient
, melt_pool_width
, and melt_pool_depth
are not
specified so they are calculated. The
generate_microstructure_permutations()
method is used to add
microstructure simulations to the study.
df = study.data_frame()
df = df[(df[ColumnNames.TYPE] == SimulationType.POROSITY)]
study.generate_microstructure_permutations(
material_name=material,
laser_powers=df[ColumnNames.LASER_POWER].unique(),
scan_speeds=df[ColumnNames.SCAN_SPEED].unique(),
size_x=1e-3,
size_y=1e-3,
size_z=1.1e-3,
sensor_dimension=1e-4,
layer_thicknesses=df[ColumnNames.LAYER_THICKNESS].unique(),
heater_temperatures=df[ColumnNames.HEATER_TEMPERATURE].unique(),
beam_diameters=df[ColumnNames.BEAM_DIAMETER].unique(),
start_angles=df[ColumnNames.START_ANGLE].unique(),
rotation_angles=df[ColumnNames.ROTATION_ANGLE].unique(),
hatch_spacings=df[ColumnNames.HATCH_SPACING].unique(),
iteration=2,
)
Run microstructure simulations#
Run the simulations using the run_simulations()
method.
study.run_simulations(additive)
2024-02-21 03:44:39 Completed 0 of 15 simulations
2024-02-21 03:46:52 Completed 1 of 15 simulations
2024-02-21 03:48:32 Completed 2 of 15 simulations
2024-02-21 03:49:56 Completed 3 of 15 simulations
2024-02-21 03:52:08 Completed 4 of 15 simulations
2024-02-21 03:53:50 Completed 5 of 15 simulations
2024-02-21 03:55:15 Completed 6 of 15 simulations
2024-02-21 03:57:32 Completed 7 of 15 simulations
2024-02-21 03:59:15 Completed 8 of 15 simulations
2024-02-21 04:00:40 Completed 9 of 15 simulations
2024-02-21 04:02:57 Completed 10 of 15 simulations
2024-02-21 04:04:44 Completed 11 of 15 simulations
2024-02-21 04:06:11 Completed 12 of 15 simulations
2024-02-21 04:08:32 Completed 13 of 15 simulations
2024-02-21 04:10:18 Completed 14 of 15 simulations
2024-02-21 04:11:49 Completed 15 of 15 simulations
Plot microstructure results#
Plot and compare the average grain sizes from the microstructure simulations
using the ave_grain_size_plot()
method.
display.ave_grain_size_plot(study)
ave_grain_size_plot
Total running time of the script: (49 minutes 40.241 seconds)